1 -- `Deep Thought', a softcore CPU implemented on a FPGA
3 -- Copyright (C) 2010 Markus Hofstaetter <markus.manrow@gmx.at>
4 -- Copyright (C) 2010 Martin Perner <e0725782@student.tuwien.ac.at>
5 -- Copyright (C) 2010 Stefan Rebernig <stefan.rebernig@gmail.com>
6 -- Copyright (C) 2010 Manfred Schwarz <e0725898@student.tuwien.ac.at>
7 -- Copyright (C) 2010 Bernhard Urban <lewurm@gmail.com>
9 -- This program is free software: you can redistribute it and/or modify
10 -- it under the terms of the GNU General Public License as published by
11 -- the Free Software Foundation, either version 3 of the License, or
12 -- (at your option) any later version.
14 -- This program is distributed in the hope that it will be useful,
15 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
16 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 -- GNU General Public License for more details.
19 -- You should have received a copy of the GNU General Public License
20 -- along with this program. If not, see <http://www.gnu.org/licenses/>.
24 use IEEE.std_logic_1164.all;
25 use IEEE.numeric_std.all;
31 constant WORD_WIDTH : INTEGER := 32;
32 constant HWORD_WIDTH : INTEGER := 16;
33 constant BYTE_WIDTH : INTEGER := 8;
34 constant OPCODE_WIDTH : INTEGER := 5;
35 constant DISPL_WIDTH : INTEGER := 15;
37 subtype byte_t is std_logic_vector(BYTE_WIDTH-1 downto 0);
38 subtype hword_t is std_logic_vector(HWORD_WIDTH-1 downto 0);
39 subtype word_t is std_logic_vector(WORD_WIDTH-1 downto 0);
41 subtype gp_register_t is word_t;
43 subtype byte_en_t is std_logic_vector((gp_register_t'length/byte_t'length-1) downto 0);
45 constant REG_ZERO : gp_register_t := (others => '0');
47 constant INSTR_ADDR_WIDTH : INTEGER := 32;
48 constant PHYS_INSTR_ADDR_WIDTH : INTEGER := 10;
49 constant ROM_INSTR_ADDR_WIDTH : INTEGER := 7;
50 constant REG_ADDR_WIDTH : INTEGER := 4;
51 constant DATA_ADDR_WIDTH : INTEGER := 10;
52 constant PHYS_DATA_ADDR_WIDTH : INTEGER := 32;
54 constant NUM_OP_OPT_WIDTH : INTEGER := 6;
55 constant COND_WIDTH : INTEGER := 4;
56 constant DATA_END_ADDR : integer := ((2**DATA_ADDR_WIDTH)-1);
58 constant ROM_USE : std_logic := '1';
59 constant RAM_USE : std_logic := '0';
61 subtype instruction_word_t is std_logic_vector(WORD_WIDTH-1 downto 0);
62 subtype instruction_addr_t is std_logic_vector(INSTR_ADDR_WIDTH-1 downto 0);
63 subtype instr_addr_t is instruction_addr_t;
65 subtype gp_addr_t is std_logic_vector(REG_ADDR_WIDTH-1 downto 0);
66 subtype data_ram_word_t is std_logic_vector(WORD_WIDTH-1 downto 0);
67 subtype data_ram_addr_t is std_logic_vector(DATA_ADDR_WIDTH-1 downto 0);
69 subtype opcode_t is std_logic_vector(OPCODE_WIDTH-1 downto 0);
70 subtype condition_t is std_logic_vector(COND_WIDTH-1 downto 0);
72 --Opcode consits of decoded group information type and option bits
73 --currently not complete, might need option increase too.
74 --IMMEDIATE always in right_operand (src2)
76 constant IMM_OPT : integer := 0; -- no sharing
78 constant SUB_OPT : integer := 1;
79 constant ARITH_OPT : integer := 1;
80 constant HWORD_OPT : integer := 1;
81 constant PUSH_OPT : integer := 1;
82 constant LOW_HIGH_OPT : integer := 1;
83 constant DIRECT_JUMP_OPT : integer := 1;
85 constant CARRY_OPT : integer := 2;
86 constant BYTE_OPT : integer := 2;
87 constant LDI_REPLACE_OPT : integer := 2;
88 constant PWREN_OPT : integer := 2;
90 constant RIGHT_OPT : integer := 3;
91 constant JMP_REG_OPT : integer := 3;
92 constant ST_OPT : integer := 3; -- store opt
93 constant RET_OPT : integer := 3;
95 constant NO_PSW_OPT : integer := 4;--no sharing
96 constant NO_DST_OPT : integer := 5; --no sharing
98 type op_info_t is (ADDSUB_OP,AND_OP,OR_OP, XOR_OP,SHIFT_OP, LDST_OP, JMP_OP, JMP_ST_OP, STACK_OP);
99 subtype op_opt_t is std_logic_vector(NUM_OP_OPT_WIDTH-1 downto 0);
101 type interrupt_t is (IDLE, UART);
103 constant UART_INT_EN_BIT : integer := 1;
104 constant GLOBAL_INT_EN_BIT : integer := 0;
106 constant UART_INT_VECTOR : std_logic_vector(PHYS_INSTR_ADDR_WIDTH-1 downto 0) := (0 => '1', others => '0');
108 type instruction_rec is record
110 predicates : std_logic_vector(3 downto 0);
114 reg_dest_addr : std_logic_vector(REG_ADDR_WIDTH-1 downto 0);
115 reg_src1_addr : std_logic_vector(REG_ADDR_WIDTH-1 downto 0);
116 reg_src2_addr : std_logic_vector(REG_ADDR_WIDTH-1 downto 0);
118 immediate : std_logic_vector(WORD_WIDTH-1 downto 0);
120 displacement : gp_register_t;
122 jmptype : std_logic_vector(1 downto 0);
124 high_low, fill, signext, bp, int: std_logic;
126 op_detail : op_opt_t;
127 op_group : op_info_t;
133 type read_through_write_rec is record
135 rtw_reg : gp_register_t;
136 rtw_reg1 : std_logic;
137 rtw_reg2 : std_logic;
138 immediate : gp_register_t;
140 reg1_addr : gp_addr_t;
141 reg2_addr : gp_addr_t;
145 type dec_op is record
146 condition : condition_t;
147 op_group : op_info_t;
148 op_detail : op_opt_t;
151 displacement : gp_register_t;
152 prog_cnt : instr_addr_t;
154 src1 : gp_register_t;
155 src2 : gp_register_t;
164 type writeback_rec is record
165 -- result : in gp_register_t; --reg (alu result or jumpaddr)
166 -- result_addr : in gp_addr_t; --reg
167 address : word_t; --ureg
168 -- alu_jmp : in std_logic; --reg
169 -- br_pred : in std_logic; --reg
170 -- write_en : in std_logic; --reg (register file)
171 dmem_en : std_logic; --ureg (jump addr in mem or in address)
172 dmem_write_en : std_logic; --ureg
173 hword : std_logic; --ureg
176 data : gp_register_t;
179 type exec2wb_rec is record
180 result : gp_register_t; --reg (alu result or jumpaddr)
181 result_addr : gp_addr_t; --reg
182 address : word_t; --ureg
183 ram_data : word_t; --ureg
184 alu_jmp : std_logic; --reg
185 br_pred : std_logic; --reg
186 write_en : std_logic; --reg (register file) bei jump 1 wenn addr in result
187 dmem_en : std_logic; --ureg (jump addr in mem or in address)
188 dmem_write_en : std_logic; --ureg
189 hword : std_logic; --ureg
190 byte_s : std_logic; --ureg
193 function inc(value : in std_logic_vector; constant by : in integer := 1) return std_logic_vector;
194 function log2c(constant value : in integer range 0 to integer'high) return integer;
195 end package common_pkg;
197 package body common_pkg is
199 function inc(value : in std_logic_vector; constant by : in integer := 1) return std_logic_vector is
201 return std_logic_vector(UNSIGNED(value)+by);
204 function log2c(constant value : in integer range 0 to integer'high) return integer is
205 variable ret_value : integer;
206 variable cur_value : integer;
211 while cur_value < value loop
212 ret_value := ret_value + 1;
213 cur_value := cur_value * 2;
218 end package body common_pkg;