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