Mon, 05 Apr 2010 21:00:31 +0100
reduce size of caches to fit in DE1 FPGA
The default cache size makes the Icache and Dcache "just a bit" too big to
fit in the EP2C20 FPGA on the DE1 board. This commit reduces the Icache and
Dcache sizes to the defaults shown in the LatticeMico32 Processor Reference
Manual (pages 36 and 37).
philpem@0 | 1 | // ============================================================================= |
philpem@0 | 2 | // COPYRIGHT NOTICE |
philpem@0 | 3 | // Copyright 2006 (c) Lattice Semiconductor Corporation |
philpem@0 | 4 | // ALL RIGHTS RESERVED |
philpem@0 | 5 | // This confidential and proprietary software may be used only as authorised by |
philpem@0 | 6 | // a licensing agreement from Lattice Semiconductor Corporation. |
philpem@0 | 7 | // The entire notice above must be reproduced on all authorized copies and |
philpem@0 | 8 | // copies may only be made to the extent permitted by a licensing agreement from |
philpem@0 | 9 | // Lattice Semiconductor Corporation. |
philpem@0 | 10 | // |
philpem@0 | 11 | // Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada) |
philpem@0 | 12 | // 5555 NE Moore Court 408-826-6000 (other locations) |
philpem@0 | 13 | // Hillsboro, OR 97124 web : http://www.latticesemi.com/ |
philpem@0 | 14 | // U.S.A email: techsupport@latticesemi.com |
philpem@0 | 15 | // =============================================================================/ |
philpem@0 | 16 | // FILE DETAILS |
philpem@0 | 17 | // Project : LatticeMico32 |
philpem@0 | 18 | // File : lm32_decoder.v |
philpem@0 | 19 | // Title : Instruction decoder |
philpem@0 | 20 | // Dependencies : lm32_include.v |
philpem@0 | 21 | // Version : 6.1.17 |
philpem@0 | 22 | // : Initial Release |
philpem@0 | 23 | // Version : 7.0SP2, 3.0 |
philpem@0 | 24 | // : No Change |
philpem@0 | 25 | // Version : 3.1 |
philpem@0 | 26 | // : Support for static branch prediction. Information about |
philpem@0 | 27 | // : branch type is generated and passed on to the predictor. |
philpem@0 | 28 | // Version : 3.2 |
philpem@0 | 29 | // : No change |
philpem@0 | 30 | // Version : 3.3 |
philpem@0 | 31 | // : Renamed port names that conflict with keywords reserved |
philpem@0 | 32 | // : in System-Verilog. |
philpem@0 | 33 | // ============================================================================= |
philpem@0 | 34 | |
philpem@0 | 35 | `include "lm32_include.v" |
philpem@0 | 36 | |
philpem@0 | 37 | // Index of opcode field in an instruction |
philpem@0 | 38 | `define LM32_OPCODE_RNG 31:26 |
philpem@0 | 39 | `define LM32_OP_RNG 30:26 |
philpem@0 | 40 | |
philpem@0 | 41 | // Opcodes - Some are only listed as 5 bits as their MSB is a don't care |
philpem@0 | 42 | `define LM32_OPCODE_ADD 5'b01101 |
philpem@0 | 43 | `define LM32_OPCODE_AND 5'b01000 |
philpem@0 | 44 | `define LM32_OPCODE_ANDHI 6'b011000 |
philpem@0 | 45 | `define LM32_OPCODE_B 6'b110000 |
philpem@0 | 46 | `define LM32_OPCODE_BI 6'b111000 |
philpem@0 | 47 | `define LM32_OPCODE_BE 6'b010001 |
philpem@0 | 48 | `define LM32_OPCODE_BG 6'b010010 |
philpem@0 | 49 | `define LM32_OPCODE_BGE 6'b010011 |
philpem@0 | 50 | `define LM32_OPCODE_BGEU 6'b010100 |
philpem@0 | 51 | `define LM32_OPCODE_BGU 6'b010101 |
philpem@0 | 52 | `define LM32_OPCODE_BNE 6'b010111 |
philpem@0 | 53 | `define LM32_OPCODE_CALL 6'b110110 |
philpem@0 | 54 | `define LM32_OPCODE_CALLI 6'b111110 |
philpem@0 | 55 | `define LM32_OPCODE_CMPE 5'b11001 |
philpem@0 | 56 | `define LM32_OPCODE_CMPG 5'b11010 |
philpem@0 | 57 | `define LM32_OPCODE_CMPGE 5'b11011 |
philpem@0 | 58 | `define LM32_OPCODE_CMPGEU 5'b11100 |
philpem@0 | 59 | `define LM32_OPCODE_CMPGU 5'b11101 |
philpem@0 | 60 | `define LM32_OPCODE_CMPNE 5'b11111 |
philpem@0 | 61 | `define LM32_OPCODE_DIVU 6'b100011 |
philpem@0 | 62 | `define LM32_OPCODE_LB 6'b000100 |
philpem@0 | 63 | `define LM32_OPCODE_LBU 6'b010000 |
philpem@0 | 64 | `define LM32_OPCODE_LH 6'b000111 |
philpem@0 | 65 | `define LM32_OPCODE_LHU 6'b001011 |
philpem@0 | 66 | `define LM32_OPCODE_LW 6'b001010 |
philpem@0 | 67 | `define LM32_OPCODE_MODU 6'b110001 |
philpem@0 | 68 | `define LM32_OPCODE_MUL 5'b00010 |
philpem@0 | 69 | `define LM32_OPCODE_NOR 5'b00001 |
philpem@0 | 70 | `define LM32_OPCODE_OR 5'b01110 |
philpem@0 | 71 | `define LM32_OPCODE_ORHI 6'b011110 |
philpem@0 | 72 | `define LM32_OPCODE_RAISE 6'b101011 |
philpem@0 | 73 | `define LM32_OPCODE_RCSR 6'b100100 |
philpem@0 | 74 | `define LM32_OPCODE_SB 6'b001100 |
philpem@0 | 75 | `define LM32_OPCODE_SEXTB 6'b101100 |
philpem@0 | 76 | `define LM32_OPCODE_SEXTH 6'b110111 |
philpem@0 | 77 | `define LM32_OPCODE_SH 6'b000011 |
philpem@0 | 78 | `define LM32_OPCODE_SL 5'b01111 |
philpem@0 | 79 | `define LM32_OPCODE_SR 5'b00101 |
philpem@0 | 80 | `define LM32_OPCODE_SRU 5'b00000 |
philpem@0 | 81 | `define LM32_OPCODE_SUB 6'b110010 |
philpem@0 | 82 | `define LM32_OPCODE_SW 6'b010110 |
philpem@0 | 83 | `define LM32_OPCODE_USER 6'b110011 |
philpem@0 | 84 | `define LM32_OPCODE_WCSR 6'b110100 |
philpem@0 | 85 | `define LM32_OPCODE_XNOR 5'b01001 |
philpem@0 | 86 | `define LM32_OPCODE_XOR 5'b00110 |
philpem@0 | 87 | |
philpem@0 | 88 | ///////////////////////////////////////////////////// |
philpem@0 | 89 | // Module interface |
philpem@0 | 90 | ///////////////////////////////////////////////////// |
philpem@0 | 91 | |
philpem@0 | 92 | module lm32_decoder ( |
philpem@0 | 93 | // ----- Inputs ------- |
philpem@0 | 94 | instruction, |
philpem@0 | 95 | // ----- Outputs ------- |
philpem@0 | 96 | d_result_sel_0, |
philpem@0 | 97 | d_result_sel_1, |
philpem@0 | 98 | x_result_sel_csr, |
philpem@0 | 99 | `ifdef LM32_MC_ARITHMETIC_ENABLED |
philpem@0 | 100 | x_result_sel_mc_arith, |
philpem@0 | 101 | `endif |
philpem@0 | 102 | `ifdef LM32_NO_BARREL_SHIFT |
philpem@0 | 103 | x_result_sel_shift, |
philpem@0 | 104 | `endif |
philpem@0 | 105 | `ifdef CFG_SIGN_EXTEND_ENABLED |
philpem@0 | 106 | x_result_sel_sext, |
philpem@0 | 107 | `endif |
philpem@0 | 108 | x_result_sel_logic, |
philpem@0 | 109 | `ifdef CFG_USER_ENABLED |
philpem@0 | 110 | x_result_sel_user, |
philpem@0 | 111 | `endif |
philpem@0 | 112 | x_result_sel_add, |
philpem@0 | 113 | m_result_sel_compare, |
philpem@0 | 114 | `ifdef CFG_PL_BARREL_SHIFT_ENABLED |
philpem@0 | 115 | m_result_sel_shift, |
philpem@0 | 116 | `endif |
philpem@0 | 117 | w_result_sel_load, |
philpem@0 | 118 | `ifdef CFG_PL_MULTIPLY_ENABLED |
philpem@0 | 119 | w_result_sel_mul, |
philpem@0 | 120 | `endif |
philpem@0 | 121 | x_bypass_enable, |
philpem@0 | 122 | m_bypass_enable, |
philpem@0 | 123 | read_enable_0, |
philpem@0 | 124 | read_idx_0, |
philpem@0 | 125 | read_enable_1, |
philpem@0 | 126 | read_idx_1, |
philpem@0 | 127 | write_enable, |
philpem@0 | 128 | write_idx, |
philpem@0 | 129 | immediate, |
philpem@0 | 130 | branch_offset, |
philpem@0 | 131 | load, |
philpem@0 | 132 | store, |
philpem@0 | 133 | size, |
philpem@0 | 134 | sign_extend, |
philpem@0 | 135 | adder_op, |
philpem@0 | 136 | logic_op, |
philpem@0 | 137 | `ifdef CFG_PL_BARREL_SHIFT_ENABLED |
philpem@0 | 138 | direction, |
philpem@0 | 139 | `endif |
philpem@0 | 140 | `ifdef CFG_MC_BARREL_SHIFT_ENABLED |
philpem@0 | 141 | shift_left, |
philpem@0 | 142 | shift_right, |
philpem@0 | 143 | `endif |
philpem@0 | 144 | `ifdef CFG_MC_MULTIPLY_ENABLED |
philpem@0 | 145 | multiply, |
philpem@0 | 146 | `endif |
philpem@0 | 147 | `ifdef CFG_MC_DIVIDE_ENABLED |
philpem@0 | 148 | divide, |
philpem@0 | 149 | modulus, |
philpem@0 | 150 | `endif |
philpem@0 | 151 | branch, |
philpem@0 | 152 | branch_reg, |
philpem@0 | 153 | condition, |
philpem@0 | 154 | bi_conditional, |
philpem@0 | 155 | bi_unconditional, |
philpem@0 | 156 | `ifdef CFG_DEBUG_ENABLED |
philpem@0 | 157 | break_opcode, |
philpem@0 | 158 | `endif |
philpem@0 | 159 | scall, |
philpem@0 | 160 | eret, |
philpem@0 | 161 | `ifdef CFG_DEBUG_ENABLED |
philpem@0 | 162 | bret, |
philpem@0 | 163 | `endif |
philpem@0 | 164 | `ifdef CFG_USER_ENABLED |
philpem@0 | 165 | user_opcode, |
philpem@0 | 166 | `endif |
philpem@0 | 167 | csr_write_enable |
philpem@0 | 168 | ); |
philpem@0 | 169 | |
philpem@0 | 170 | ///////////////////////////////////////////////////// |
philpem@0 | 171 | // Inputs |
philpem@0 | 172 | ///////////////////////////////////////////////////// |
philpem@0 | 173 | |
philpem@0 | 174 | input [`LM32_INSTRUCTION_RNG] instruction; // Instruction to decode |
philpem@0 | 175 | |
philpem@0 | 176 | ///////////////////////////////////////////////////// |
philpem@0 | 177 | // Outputs |
philpem@0 | 178 | ///////////////////////////////////////////////////// |
philpem@0 | 179 | |
philpem@0 | 180 | output [`LM32_D_RESULT_SEL_0_RNG] d_result_sel_0; |
philpem@0 | 181 | reg [`LM32_D_RESULT_SEL_0_RNG] d_result_sel_0; |
philpem@0 | 182 | output [`LM32_D_RESULT_SEL_1_RNG] d_result_sel_1; |
philpem@0 | 183 | reg [`LM32_D_RESULT_SEL_1_RNG] d_result_sel_1; |
philpem@0 | 184 | output x_result_sel_csr; |
philpem@0 | 185 | reg x_result_sel_csr; |
philpem@0 | 186 | `ifdef LM32_MC_ARITHMETIC_ENABLED |
philpem@0 | 187 | output x_result_sel_mc_arith; |
philpem@0 | 188 | reg x_result_sel_mc_arith; |
philpem@0 | 189 | `endif |
philpem@0 | 190 | `ifdef LM32_NO_BARREL_SHIFT |
philpem@0 | 191 | output x_result_sel_shift; |
philpem@0 | 192 | reg x_result_sel_shift; |
philpem@0 | 193 | `endif |
philpem@0 | 194 | `ifdef CFG_SIGN_EXTEND_ENABLED |
philpem@0 | 195 | output x_result_sel_sext; |
philpem@0 | 196 | reg x_result_sel_sext; |
philpem@0 | 197 | `endif |
philpem@0 | 198 | output x_result_sel_logic; |
philpem@0 | 199 | reg x_result_sel_logic; |
philpem@0 | 200 | `ifdef CFG_USER_ENABLED |
philpem@0 | 201 | output x_result_sel_user; |
philpem@0 | 202 | reg x_result_sel_user; |
philpem@0 | 203 | `endif |
philpem@0 | 204 | output x_result_sel_add; |
philpem@0 | 205 | reg x_result_sel_add; |
philpem@0 | 206 | output m_result_sel_compare; |
philpem@0 | 207 | reg m_result_sel_compare; |
philpem@0 | 208 | `ifdef CFG_PL_BARREL_SHIFT_ENABLED |
philpem@0 | 209 | output m_result_sel_shift; |
philpem@0 | 210 | reg m_result_sel_shift; |
philpem@0 | 211 | `endif |
philpem@0 | 212 | output w_result_sel_load; |
philpem@0 | 213 | reg w_result_sel_load; |
philpem@0 | 214 | `ifdef CFG_PL_MULTIPLY_ENABLED |
philpem@0 | 215 | output w_result_sel_mul; |
philpem@0 | 216 | reg w_result_sel_mul; |
philpem@0 | 217 | `endif |
philpem@0 | 218 | output x_bypass_enable; |
philpem@0 | 219 | wire x_bypass_enable; |
philpem@0 | 220 | output m_bypass_enable; |
philpem@0 | 221 | wire m_bypass_enable; |
philpem@0 | 222 | output read_enable_0; |
philpem@0 | 223 | wire read_enable_0; |
philpem@0 | 224 | output [`LM32_REG_IDX_RNG] read_idx_0; |
philpem@0 | 225 | wire [`LM32_REG_IDX_RNG] read_idx_0; |
philpem@0 | 226 | output read_enable_1; |
philpem@0 | 227 | wire read_enable_1; |
philpem@0 | 228 | output [`LM32_REG_IDX_RNG] read_idx_1; |
philpem@0 | 229 | wire [`LM32_REG_IDX_RNG] read_idx_1; |
philpem@0 | 230 | output write_enable; |
philpem@0 | 231 | wire write_enable; |
philpem@0 | 232 | output [`LM32_REG_IDX_RNG] write_idx; |
philpem@0 | 233 | wire [`LM32_REG_IDX_RNG] write_idx; |
philpem@0 | 234 | output [`LM32_WORD_RNG] immediate; |
philpem@0 | 235 | wire [`LM32_WORD_RNG] immediate; |
philpem@0 | 236 | output [`LM32_PC_RNG] branch_offset; |
philpem@0 | 237 | wire [`LM32_PC_RNG] branch_offset; |
philpem@0 | 238 | output load; |
philpem@0 | 239 | wire load; |
philpem@0 | 240 | output store; |
philpem@0 | 241 | wire store; |
philpem@0 | 242 | output [`LM32_SIZE_RNG] size; |
philpem@0 | 243 | wire [`LM32_SIZE_RNG] size; |
philpem@0 | 244 | output sign_extend; |
philpem@0 | 245 | wire sign_extend; |
philpem@0 | 246 | output adder_op; |
philpem@0 | 247 | wire adder_op; |
philpem@0 | 248 | output [`LM32_LOGIC_OP_RNG] logic_op; |
philpem@0 | 249 | wire [`LM32_LOGIC_OP_RNG] logic_op; |
philpem@0 | 250 | `ifdef CFG_PL_BARREL_SHIFT_ENABLED |
philpem@0 | 251 | output direction; |
philpem@0 | 252 | wire direction; |
philpem@0 | 253 | `endif |
philpem@0 | 254 | `ifdef CFG_MC_BARREL_SHIFT_ENABLED |
philpem@0 | 255 | output shift_left; |
philpem@0 | 256 | wire shift_left; |
philpem@0 | 257 | output shift_right; |
philpem@0 | 258 | wire shift_right; |
philpem@0 | 259 | `endif |
philpem@0 | 260 | `ifdef CFG_MC_MULTIPLY_ENABLED |
philpem@0 | 261 | output multiply; |
philpem@0 | 262 | wire multiply; |
philpem@0 | 263 | `endif |
philpem@0 | 264 | `ifdef CFG_MC_DIVIDE_ENABLED |
philpem@0 | 265 | output divide; |
philpem@0 | 266 | wire divide; |
philpem@0 | 267 | output modulus; |
philpem@0 | 268 | wire modulus; |
philpem@0 | 269 | `endif |
philpem@0 | 270 | output branch; |
philpem@0 | 271 | wire branch; |
philpem@0 | 272 | output branch_reg; |
philpem@0 | 273 | wire branch_reg; |
philpem@0 | 274 | output [`LM32_CONDITION_RNG] condition; |
philpem@0 | 275 | wire [`LM32_CONDITION_RNG] condition; |
philpem@0 | 276 | output bi_conditional; |
philpem@0 | 277 | wire bi_conditional; |
philpem@0 | 278 | output bi_unconditional; |
philpem@0 | 279 | wire bi_unconditional; |
philpem@0 | 280 | `ifdef CFG_DEBUG_ENABLED |
philpem@0 | 281 | output break_opcode; |
philpem@0 | 282 | wire break_opcode; |
philpem@0 | 283 | `endif |
philpem@0 | 284 | output scall; |
philpem@0 | 285 | wire scall; |
philpem@0 | 286 | output eret; |
philpem@0 | 287 | wire eret; |
philpem@0 | 288 | `ifdef CFG_DEBUG_ENABLED |
philpem@0 | 289 | output bret; |
philpem@0 | 290 | wire bret; |
philpem@0 | 291 | `endif |
philpem@0 | 292 | `ifdef CFG_USER_ENABLED |
philpem@0 | 293 | output [`LM32_USER_OPCODE_RNG] user_opcode; |
philpem@0 | 294 | wire [`LM32_USER_OPCODE_RNG] user_opcode; |
philpem@0 | 295 | `endif |
philpem@0 | 296 | output csr_write_enable; |
philpem@0 | 297 | wire csr_write_enable; |
philpem@0 | 298 | |
philpem@0 | 299 | ///////////////////////////////////////////////////// |
philpem@0 | 300 | // Internal nets and registers |
philpem@0 | 301 | ///////////////////////////////////////////////////// |
philpem@0 | 302 | |
philpem@0 | 303 | wire [`LM32_WORD_RNG] extended_immediate; // Zero or sign extended immediate |
philpem@0 | 304 | wire [`LM32_WORD_RNG] high_immediate; // Immediate as high 16 bits |
philpem@0 | 305 | wire [`LM32_WORD_RNG] call_immediate; // Call immediate |
philpem@0 | 306 | wire [`LM32_WORD_RNG] branch_immediate; // Conditional branch immediate |
philpem@0 | 307 | wire sign_extend_immediate; // Whether the immediate should be sign extended (`TRUE) or zero extended (`FALSE) |
philpem@0 | 308 | wire select_high_immediate; // Whether to select the high immediate |
philpem@0 | 309 | wire select_call_immediate; // Whether to select the call immediate |
philpem@0 | 310 | |
philpem@0 | 311 | ///////////////////////////////////////////////////// |
philpem@0 | 312 | // Functions |
philpem@0 | 313 | ///////////////////////////////////////////////////// |
philpem@0 | 314 | |
philpem@0 | 315 | `include "lm32_functions.v" |
philpem@0 | 316 | |
philpem@0 | 317 | ///////////////////////////////////////////////////// |
philpem@0 | 318 | // Combinational logic |
philpem@0 | 319 | ///////////////////////////////////////////////////// |
philpem@0 | 320 | |
philpem@0 | 321 | // Determine opcode |
philpem@0 | 322 | assign op_add = instruction[`LM32_OP_RNG] == `LM32_OPCODE_ADD; |
philpem@0 | 323 | assign op_and = instruction[`LM32_OP_RNG] == `LM32_OPCODE_AND; |
philpem@0 | 324 | assign op_andhi = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_ANDHI; |
philpem@0 | 325 | assign op_b = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_B; |
philpem@0 | 326 | assign op_bi = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_BI; |
philpem@0 | 327 | assign op_be = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_BE; |
philpem@0 | 328 | assign op_bg = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_BG; |
philpem@0 | 329 | assign op_bge = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_BGE; |
philpem@0 | 330 | assign op_bgeu = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_BGEU; |
philpem@0 | 331 | assign op_bgu = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_BGU; |
philpem@0 | 332 | assign op_bne = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_BNE; |
philpem@0 | 333 | assign op_call = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_CALL; |
philpem@0 | 334 | assign op_calli = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_CALLI; |
philpem@0 | 335 | assign op_cmpe = instruction[`LM32_OP_RNG] == `LM32_OPCODE_CMPE; |
philpem@0 | 336 | assign op_cmpg = instruction[`LM32_OP_RNG] == `LM32_OPCODE_CMPG; |
philpem@0 | 337 | assign op_cmpge = instruction[`LM32_OP_RNG] == `LM32_OPCODE_CMPGE; |
philpem@0 | 338 | assign op_cmpgeu = instruction[`LM32_OP_RNG] == `LM32_OPCODE_CMPGEU; |
philpem@0 | 339 | assign op_cmpgu = instruction[`LM32_OP_RNG] == `LM32_OPCODE_CMPGU; |
philpem@0 | 340 | assign op_cmpne = instruction[`LM32_OP_RNG] == `LM32_OPCODE_CMPNE; |
philpem@0 | 341 | `ifdef CFG_MC_DIVIDE_ENABLED |
philpem@0 | 342 | assign op_divu = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_DIVU; |
philpem@0 | 343 | `endif |
philpem@0 | 344 | assign op_lb = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_LB; |
philpem@0 | 345 | assign op_lbu = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_LBU; |
philpem@0 | 346 | assign op_lh = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_LH; |
philpem@0 | 347 | assign op_lhu = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_LHU; |
philpem@0 | 348 | assign op_lw = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_LW; |
philpem@0 | 349 | `ifdef CFG_MC_DIVIDE_ENABLED |
philpem@0 | 350 | assign op_modu = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_MODU; |
philpem@0 | 351 | `endif |
philpem@0 | 352 | `ifdef LM32_MULTIPLY_ENABLED |
philpem@0 | 353 | assign op_mul = instruction[`LM32_OP_RNG] == `LM32_OPCODE_MUL; |
philpem@0 | 354 | `endif |
philpem@0 | 355 | assign op_nor = instruction[`LM32_OP_RNG] == `LM32_OPCODE_NOR; |
philpem@0 | 356 | assign op_or = instruction[`LM32_OP_RNG] == `LM32_OPCODE_OR; |
philpem@0 | 357 | assign op_orhi = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_ORHI; |
philpem@0 | 358 | assign op_raise = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_RAISE; |
philpem@0 | 359 | assign op_rcsr = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_RCSR; |
philpem@0 | 360 | assign op_sb = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_SB; |
philpem@0 | 361 | `ifdef CFG_SIGN_EXTEND_ENABLED |
philpem@0 | 362 | assign op_sextb = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_SEXTB; |
philpem@0 | 363 | assign op_sexth = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_SEXTH; |
philpem@0 | 364 | `endif |
philpem@0 | 365 | assign op_sh = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_SH; |
philpem@0 | 366 | `ifdef LM32_BARREL_SHIFT_ENABLED |
philpem@0 | 367 | assign op_sl = instruction[`LM32_OP_RNG] == `LM32_OPCODE_SL; |
philpem@0 | 368 | `endif |
philpem@0 | 369 | assign op_sr = instruction[`LM32_OP_RNG] == `LM32_OPCODE_SR; |
philpem@0 | 370 | assign op_sru = instruction[`LM32_OP_RNG] == `LM32_OPCODE_SRU; |
philpem@0 | 371 | assign op_sub = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_SUB; |
philpem@0 | 372 | assign op_sw = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_SW; |
philpem@0 | 373 | assign op_user = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_USER; |
philpem@0 | 374 | assign op_wcsr = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_WCSR; |
philpem@0 | 375 | assign op_xnor = instruction[`LM32_OP_RNG] == `LM32_OPCODE_XNOR; |
philpem@0 | 376 | assign op_xor = instruction[`LM32_OP_RNG] == `LM32_OPCODE_XOR; |
philpem@0 | 377 | |
philpem@0 | 378 | // Group opcodes by function |
philpem@0 | 379 | assign arith = op_add | op_sub; |
philpem@0 | 380 | assign logical = op_and | op_andhi | op_nor | op_or | op_orhi | op_xor | op_xnor; |
philpem@0 | 381 | assign cmp = op_cmpe | op_cmpg | op_cmpge | op_cmpgeu | op_cmpgu | op_cmpne; |
philpem@0 | 382 | assign bi_conditional = op_be | op_bg | op_bge | op_bgeu | op_bgu | op_bne; |
philpem@0 | 383 | assign bi_unconditional = op_bi; |
philpem@0 | 384 | assign bra = op_b | bi_unconditional | bi_conditional; |
philpem@0 | 385 | assign call = op_call | op_calli; |
philpem@0 | 386 | `ifdef LM32_BARREL_SHIFT_ENABLED |
philpem@0 | 387 | assign shift = op_sl | op_sr | op_sru; |
philpem@0 | 388 | `endif |
philpem@0 | 389 | `ifdef LM32_NO_BARREL_SHIFT |
philpem@0 | 390 | assign shift = op_sr | op_sru; |
philpem@0 | 391 | `endif |
philpem@0 | 392 | `ifdef CFG_MC_BARREL_SHIFT_ENABLED |
philpem@0 | 393 | assign shift_left = op_sl; |
philpem@0 | 394 | assign shift_right = op_sr | op_sru; |
philpem@0 | 395 | `endif |
philpem@0 | 396 | `ifdef CFG_SIGN_EXTEND_ENABLED |
philpem@0 | 397 | assign sext = op_sextb | op_sexth; |
philpem@0 | 398 | `endif |
philpem@0 | 399 | `ifdef LM32_MULTIPLY_ENABLED |
philpem@0 | 400 | assign multiply = op_mul; |
philpem@0 | 401 | `endif |
philpem@0 | 402 | `ifdef CFG_MC_DIVIDE_ENABLED |
philpem@0 | 403 | assign divide = op_divu; |
philpem@0 | 404 | assign modulus = op_modu; |
philpem@0 | 405 | `endif |
philpem@0 | 406 | assign load = op_lb | op_lbu | op_lh | op_lhu | op_lw; |
philpem@0 | 407 | assign store = op_sb | op_sh | op_sw; |
philpem@0 | 408 | |
philpem@0 | 409 | // Select pipeline multiplexor controls |
philpem@0 | 410 | always @(*) |
philpem@0 | 411 | begin |
philpem@0 | 412 | // D stage |
philpem@0 | 413 | if (call) |
philpem@0 | 414 | d_result_sel_0 = `LM32_D_RESULT_SEL_0_NEXT_PC; |
philpem@0 | 415 | else |
philpem@0 | 416 | d_result_sel_0 = `LM32_D_RESULT_SEL_0_REG_0; |
philpem@0 | 417 | if (call) |
philpem@0 | 418 | d_result_sel_1 = `LM32_D_RESULT_SEL_1_ZERO; |
philpem@0 | 419 | else if ((instruction[31] == 1'b0) && !bra) |
philpem@0 | 420 | d_result_sel_1 = `LM32_D_RESULT_SEL_1_IMMEDIATE; |
philpem@0 | 421 | else |
philpem@0 | 422 | d_result_sel_1 = `LM32_D_RESULT_SEL_1_REG_1; |
philpem@0 | 423 | // X stage |
philpem@0 | 424 | x_result_sel_csr = `FALSE; |
philpem@0 | 425 | `ifdef LM32_MC_ARITHMETIC_ENABLED |
philpem@0 | 426 | x_result_sel_mc_arith = `FALSE; |
philpem@0 | 427 | `endif |
philpem@0 | 428 | `ifdef LM32_NO_BARREL_SHIFT |
philpem@0 | 429 | x_result_sel_shift = `FALSE; |
philpem@0 | 430 | `endif |
philpem@0 | 431 | `ifdef CFG_SIGN_EXTEND_ENABLED |
philpem@0 | 432 | x_result_sel_sext = `FALSE; |
philpem@0 | 433 | `endif |
philpem@0 | 434 | x_result_sel_logic = `FALSE; |
philpem@0 | 435 | `ifdef CFG_USER_ENABLED |
philpem@0 | 436 | x_result_sel_user = `FALSE; |
philpem@0 | 437 | `endif |
philpem@0 | 438 | x_result_sel_add = `FALSE; |
philpem@0 | 439 | if (op_rcsr) |
philpem@0 | 440 | x_result_sel_csr = `TRUE; |
philpem@0 | 441 | `ifdef LM32_MC_ARITHMETIC_ENABLED |
philpem@0 | 442 | `ifdef CFG_MC_BARREL_SHIFT_ENABLED |
philpem@0 | 443 | else if (shift_left | shift_right) |
philpem@0 | 444 | x_result_sel_mc_arith = `TRUE; |
philpem@0 | 445 | `endif |
philpem@0 | 446 | `ifdef CFG_MC_DIVIDE_ENABLED |
philpem@0 | 447 | else if (divide | modulus) |
philpem@0 | 448 | x_result_sel_mc_arith = `TRUE; |
philpem@0 | 449 | `endif |
philpem@0 | 450 | `ifdef CFG_MC_MULTIPLY_ENABLED |
philpem@0 | 451 | else if (multiply) |
philpem@0 | 452 | x_result_sel_mc_arith = `TRUE; |
philpem@0 | 453 | `endif |
philpem@0 | 454 | `endif |
philpem@0 | 455 | `ifdef LM32_NO_BARREL_SHIFT |
philpem@0 | 456 | else if (shift) |
philpem@0 | 457 | x_result_sel_shift = `TRUE; |
philpem@0 | 458 | `endif |
philpem@0 | 459 | `ifdef CFG_SIGN_EXTEND_ENABLED |
philpem@0 | 460 | else if (sext) |
philpem@0 | 461 | x_result_sel_sext = `TRUE; |
philpem@0 | 462 | `endif |
philpem@0 | 463 | else if (logical) |
philpem@0 | 464 | x_result_sel_logic = `TRUE; |
philpem@0 | 465 | `ifdef CFG_USER_ENABLED |
philpem@0 | 466 | else if (op_user) |
philpem@0 | 467 | x_result_sel_user = `TRUE; |
philpem@0 | 468 | `endif |
philpem@0 | 469 | else |
philpem@0 | 470 | x_result_sel_add = `TRUE; |
philpem@0 | 471 | |
philpem@0 | 472 | // M stage |
philpem@0 | 473 | |
philpem@0 | 474 | m_result_sel_compare = cmp; |
philpem@0 | 475 | `ifdef CFG_PL_BARREL_SHIFT_ENABLED |
philpem@0 | 476 | m_result_sel_shift = shift; |
philpem@0 | 477 | `endif |
philpem@0 | 478 | |
philpem@0 | 479 | // W stage |
philpem@0 | 480 | w_result_sel_load = load; |
philpem@0 | 481 | `ifdef CFG_PL_MULTIPLY_ENABLED |
philpem@0 | 482 | w_result_sel_mul = op_mul; |
philpem@0 | 483 | `endif |
philpem@0 | 484 | end |
philpem@0 | 485 | |
philpem@0 | 486 | // Set if result is valid at end of X stage |
philpem@0 | 487 | assign x_bypass_enable = arith |
philpem@0 | 488 | | logical |
philpem@0 | 489 | `ifdef CFG_MC_BARREL_SHIFT_ENABLED |
philpem@0 | 490 | | shift_left |
philpem@0 | 491 | | shift_right |
philpem@0 | 492 | `endif |
philpem@0 | 493 | `ifdef CFG_MC_MULTIPLY_ENABLED |
philpem@0 | 494 | | multiply |
philpem@0 | 495 | `endif |
philpem@0 | 496 | `ifdef CFG_MC_DIVIDE_ENABLED |
philpem@0 | 497 | | divide |
philpem@0 | 498 | | modulus |
philpem@0 | 499 | `endif |
philpem@0 | 500 | `ifdef LM32_NO_BARREL_SHIFT |
philpem@0 | 501 | | shift |
philpem@0 | 502 | `endif |
philpem@0 | 503 | `ifdef CFG_SIGN_EXTEND_ENABLED |
philpem@0 | 504 | | sext |
philpem@0 | 505 | `endif |
philpem@0 | 506 | `ifdef CFG_USER_ENABLED |
philpem@0 | 507 | | op_user |
philpem@0 | 508 | `endif |
philpem@0 | 509 | | op_rcsr |
philpem@0 | 510 | ; |
philpem@0 | 511 | // Set if result is valid at end of M stage |
philpem@0 | 512 | assign m_bypass_enable = x_bypass_enable |
philpem@0 | 513 | `ifdef CFG_PL_BARREL_SHIFT_ENABLED |
philpem@0 | 514 | | shift |
philpem@0 | 515 | `endif |
philpem@0 | 516 | | cmp |
philpem@0 | 517 | ; |
philpem@0 | 518 | // Register file read port 0 |
philpem@0 | 519 | assign read_enable_0 = ~(op_bi | op_calli); |
philpem@0 | 520 | assign read_idx_0 = instruction[25:21]; |
philpem@0 | 521 | // Register file read port 1 |
philpem@0 | 522 | assign read_enable_1 = ~(op_bi | op_calli | load); |
philpem@0 | 523 | assign read_idx_1 = instruction[20:16]; |
philpem@0 | 524 | // Register file write port |
philpem@0 | 525 | assign write_enable = ~(bra | op_raise | store | op_wcsr); |
philpem@0 | 526 | assign write_idx = call |
philpem@0 | 527 | ? 5'd29 |
philpem@0 | 528 | : instruction[31] == 1'b0 |
philpem@0 | 529 | ? instruction[20:16] |
philpem@0 | 530 | : instruction[15:11]; |
philpem@0 | 531 | |
philpem@0 | 532 | // Size of load/stores |
philpem@0 | 533 | assign size = instruction[27:26]; |
philpem@0 | 534 | // Whether to sign or zero extend |
philpem@0 | 535 | assign sign_extend = instruction[28]; |
philpem@0 | 536 | // Set adder_op to 1 to perform a subtraction |
philpem@0 | 537 | assign adder_op = op_sub | op_cmpe | op_cmpg | op_cmpge | op_cmpgeu | op_cmpgu | op_cmpne | bra; |
philpem@0 | 538 | // Logic operation (and, or, etc) |
philpem@0 | 539 | assign logic_op = instruction[29:26]; |
philpem@0 | 540 | `ifdef CFG_PL_BARREL_SHIFT_ENABLED |
philpem@0 | 541 | // Shift direction |
philpem@0 | 542 | assign direction = instruction[29]; |
philpem@0 | 543 | `endif |
philpem@0 | 544 | // Control flow microcodes |
philpem@0 | 545 | assign branch = bra | call; |
philpem@0 | 546 | assign branch_reg = op_call | op_b; |
philpem@0 | 547 | assign condition = instruction[28:26]; |
philpem@0 | 548 | `ifdef CFG_DEBUG_ENABLED |
philpem@0 | 549 | assign break_opcode = op_raise & ~instruction[2]; |
philpem@0 | 550 | `endif |
philpem@0 | 551 | assign scall = op_raise & instruction[2]; |
philpem@0 | 552 | assign eret = op_b & (instruction[25:21] == 5'd30); |
philpem@0 | 553 | `ifdef CFG_DEBUG_ENABLED |
philpem@0 | 554 | assign bret = op_b & (instruction[25:21] == 5'd31); |
philpem@0 | 555 | `endif |
philpem@0 | 556 | `ifdef CFG_USER_ENABLED |
philpem@0 | 557 | // Extract user opcode |
philpem@0 | 558 | assign user_opcode = instruction[10:0]; |
philpem@0 | 559 | `endif |
philpem@0 | 560 | // CSR read/write |
philpem@0 | 561 | assign csr_write_enable = op_wcsr; |
philpem@0 | 562 | |
philpem@0 | 563 | // Extract immediate from instruction |
philpem@0 | 564 | |
philpem@0 | 565 | assign sign_extend_immediate = ~(op_and | op_cmpgeu | op_cmpgu | op_nor | op_or | op_xnor | op_xor); |
philpem@0 | 566 | assign select_high_immediate = op_andhi | op_orhi; |
philpem@0 | 567 | assign select_call_immediate = instruction[31]; |
philpem@0 | 568 | |
philpem@0 | 569 | assign high_immediate = {instruction[15:0], 16'h0000}; |
philpem@0 | 570 | assign extended_immediate = {{16{sign_extend_immediate & instruction[15]}}, instruction[15:0]}; |
philpem@0 | 571 | assign call_immediate = {{6{instruction[25]}}, instruction[25:0]}; |
philpem@0 | 572 | assign branch_immediate = {{16{instruction[15]}}, instruction[15:0]}; |
philpem@0 | 573 | |
philpem@0 | 574 | assign immediate = select_high_immediate == `TRUE |
philpem@0 | 575 | ? high_immediate |
philpem@0 | 576 | : extended_immediate; |
philpem@0 | 577 | |
philpem@0 | 578 | assign branch_offset = select_call_immediate == `TRUE |
philpem@0 | 579 | ? call_immediate |
philpem@0 | 580 | : branch_immediate; |
philpem@0 | 581 | |
philpem@0 | 582 | endmodule |
philpem@0 | 583 |