lm32_decoder.v

Mon, 05 Apr 2010 21:00:31 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Mon, 05 Apr 2010 21:00:31 +0100
changeset 6
a8e459b24c31
parent 0
cd0b58aa6f83
child 26
73de224304c1
permissions
-rw-r--r--

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).

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