lm32_decoder.v

Sat, 06 Aug 2011 01:26:56 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Sat, 06 Aug 2011 01:26:56 +0100
changeset 27
d6c693415d59
parent 26
73de224304c1
permissions
-rwxr-xr-x

remove synthesis delay entities to ease merge

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