lm32_mc_arithmetic.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             : lm_mc_arithmetic.v
    19 // Title            : Multi-cycle arithmetic unit.
    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 //                  : No Change
    27 // =============================================================================
    29 `include "lm32_include.v"
    31 `define LM32_MC_STATE_RNG         2:0
    32 `define LM32_MC_STATE_IDLE        3'b000
    33 `define LM32_MC_STATE_MULTIPLY    3'b001
    34 `define LM32_MC_STATE_MODULUS     3'b010   
    35 `define LM32_MC_STATE_DIVIDE      3'b011 
    36 `define LM32_MC_STATE_SHIFT_LEFT  3'b100
    37 `define LM32_MC_STATE_SHIFT_RIGHT 3'b101
    39 /////////////////////////////////////////////////////
    40 // Module interface
    41 /////////////////////////////////////////////////////
    43 module lm32_mc_arithmetic (
    44     // ----- Inputs -----
    45     clk_i,
    46     rst_i,
    47     stall_d,
    48     kill_x,
    49 `ifdef CFG_MC_DIVIDE_ENABLED
    50     divide_d,
    51     modulus_d,
    52 `endif
    53 `ifdef CFG_MC_MULTIPLY_ENABLED
    54     multiply_d,
    55 `endif
    56 `ifdef CFG_MC_BARREL_SHIFT_ENABLED
    57     shift_left_d,
    58     shift_right_d,
    59     sign_extend_d,
    60 `endif
    61     operand_0_d,
    62     operand_1_d,
    63     // ----- Ouputs -----
    64     result_x,
    65 `ifdef CFG_MC_DIVIDE_ENABLED
    66     divide_by_zero_x,
    67 `endif
    68     stall_request_x
    69     );
    71 /////////////////////////////////////////////////////
    72 // Inputs
    73 /////////////////////////////////////////////////////
    75 input clk_i;                                    // Clock
    76 input rst_i;                                    // Reset
    77 input stall_d;                                  // Stall instruction in D stage
    78 input kill_x;                                   // Kill instruction in X stage
    79 `ifdef CFG_MC_DIVIDE_ENABLED
    80 input divide_d;                                 // Perform divide
    81 input modulus_d;                                // Perform modulus
    82 `endif
    83 `ifdef CFG_MC_MULTIPLY_ENABLED
    84 input multiply_d;                               // Perform multiply
    85 `endif
    86 `ifdef CFG_MC_BARREL_SHIFT_ENABLED
    87 input shift_left_d;                             // Perform left shift
    88 input shift_right_d;                            // Perform right shift
    89 input sign_extend_d;                            // Whether to sign-extend (arithmetic) or zero-extend (logical)
    90 `endif
    91 input [`LM32_WORD_RNG] operand_0_d;
    92 input [`LM32_WORD_RNG] operand_1_d;
    94 /////////////////////////////////////////////////////
    95 // Outputs
    96 /////////////////////////////////////////////////////
    98 output [`LM32_WORD_RNG] result_x;               // Result of operation
    99 reg    [`LM32_WORD_RNG] result_x;
   100 `ifdef CFG_MC_DIVIDE_ENABLED
   101 output divide_by_zero_x;                        // A divide by zero was attempted
   102 reg    divide_by_zero_x;
   103 `endif
   104 output stall_request_x;                         // Request to stall pipeline from X stage back
   105 wire   stall_request_x;
   107 /////////////////////////////////////////////////////
   108 // Internal nets and registers 
   109 /////////////////////////////////////////////////////
   111 reg [`LM32_WORD_RNG] p;                         // Temporary registers
   112 reg [`LM32_WORD_RNG] a;
   113 reg [`LM32_WORD_RNG] b;
   114 `ifdef CFG_MC_DIVIDE_ENABLED
   115 wire [32:0] t;
   116 `endif
   118 reg [`LM32_MC_STATE_RNG] state;                 // Current state of FSM
   119 reg [5:0] cycles;                               // Number of cycles remaining in the operation
   121 `ifdef CFG_MC_BARREL_SHIFT_ENABLED
   122 reg sign_extend_x;                              // Whether to sign extend of zero extend right shifts
   123 wire fill_value;                                // Value to fill with for right barrel-shifts
   124 `endif
   126 /////////////////////////////////////////////////////
   127 // Combinational logic
   128 /////////////////////////////////////////////////////
   130 // Stall pipeline while any operation is being performed
   131 assign stall_request_x = state != `LM32_MC_STATE_IDLE;
   133 `ifdef CFG_MC_DIVIDE_ENABLED
   134 // Subtraction
   135 assign t = {p[`LM32_WORD_WIDTH-2:0], a[`LM32_WORD_WIDTH-1]} - b;
   136 `endif
   138 `ifdef CFG_MC_BARREL_SHIFT_ENABLED
   139 // Determine fill value for right shift - Sign bit for arithmetic shift, or zero for logical shift
   140 assign fill_value = (sign_extend_x == `TRUE) & b[`LM32_WORD_WIDTH-1];
   141 `endif
   143 /////////////////////////////////////////////////////
   144 // Sequential logic
   145 /////////////////////////////////////////////////////
   147 // Perform right shift
   148 always @(posedge clk_i `CFG_RESET_SENSITIVITY)
   149 begin
   150     if (rst_i == `TRUE)
   151     begin
   152         cycles <= {6{1'b0}};
   153         p <= {`LM32_WORD_WIDTH{1'b0}};
   154         a <= {`LM32_WORD_WIDTH{1'b0}};
   155         b <= {`LM32_WORD_WIDTH{1'b0}};
   156 `ifdef CFG_MC_BARREL_SHIFT_ENABLED
   157         sign_extend_x <= 1'b0;
   158 `endif
   159 `ifdef CFG_MC_DIVIDE_ENABLED
   160         divide_by_zero_x <= `FALSE;
   161 `endif
   162         result_x <= {`LM32_WORD_WIDTH{1'b0}};
   163         state <= `LM32_MC_STATE_IDLE;
   164     end
   165     else
   166     begin
   167 `ifdef CFG_MC_DIVIDE_ENABLED
   168         divide_by_zero_x <= `FALSE;
   169 `endif
   170         case (state)
   171         `LM32_MC_STATE_IDLE:
   172         begin
   173             if (stall_d == `FALSE)                 
   174             begin          
   175                 cycles <= `LM32_WORD_WIDTH;
   176                 p <= 32'b0;
   177                 a <= operand_0_d;
   178                 b <= operand_1_d;                    
   179 `ifdef CFG_MC_DIVIDE_ENABLED
   180                 if (divide_d == `TRUE)
   181                     state <= `LM32_MC_STATE_DIVIDE;
   182                 if (modulus_d == `TRUE)
   183                     state <= `LM32_MC_STATE_MODULUS;
   184 `endif                    
   185 `ifdef CFG_MC_MULTIPLY_ENABLED
   186                 if (multiply_d == `TRUE)
   187                     state <= `LM32_MC_STATE_MULTIPLY;
   188 `endif
   189 `ifdef CFG_MC_BARREL_SHIFT_ENABLED
   190                 if (shift_left_d == `TRUE)
   191                 begin
   192                     state <= `LM32_MC_STATE_SHIFT_LEFT;
   193                     sign_extend_x <= sign_extend_d;
   194                     cycles <= operand_1_d[4:0];
   195                     a <= operand_0_d;
   196                     b <= operand_0_d;
   197                 end
   198                 if (shift_right_d == `TRUE)
   199                 begin
   200                     state <= `LM32_MC_STATE_SHIFT_RIGHT;
   201                     sign_extend_x <= sign_extend_d;
   202                     cycles <= operand_1_d[4:0];
   203                     a <= operand_0_d;
   204                     b <= operand_0_d;
   205                 end
   206 `endif
   207             end            
   208         end
   209 `ifdef CFG_MC_DIVIDE_ENABLED
   210         `LM32_MC_STATE_DIVIDE:
   211         begin
   212             if (t[32] == 1'b0)
   213             begin
   214                 p <= t[31:0];
   215                 a <= {a[`LM32_WORD_WIDTH-2:0], 1'b1};
   216             end
   217             else 
   218             begin
   219                 p <= {p[`LM32_WORD_WIDTH-2:0], a[`LM32_WORD_WIDTH-1]};
   220                 a <= {a[`LM32_WORD_WIDTH-2:0], 1'b0};
   221             end
   222             result_x <= a;
   223             if ((cycles == `LM32_WORD_WIDTH'd0) || (kill_x == `TRUE))
   224             begin
   225                 // Check for divide by zero
   226                 divide_by_zero_x <= b == {`LM32_WORD_WIDTH{1'b0}};
   227                 state <= `LM32_MC_STATE_IDLE;
   228             end
   229             cycles <= cycles - 1'b1;
   230         end
   231         `LM32_MC_STATE_MODULUS:
   232         begin
   233             if (t[32] == 1'b0)
   234             begin
   235                 p <= t[31:0];
   236                 a <= {a[`LM32_WORD_WIDTH-2:0], 1'b1};
   237             end
   238             else 
   239             begin
   240                 p <= {p[`LM32_WORD_WIDTH-2:0], a[`LM32_WORD_WIDTH-1]};
   241                 a <= {a[`LM32_WORD_WIDTH-2:0], 1'b0};
   242             end
   243             result_x <= p;
   244             if ((cycles == `LM32_WORD_WIDTH'd0) || (kill_x == `TRUE))
   245             begin
   246                 // Check for divide by zero
   247                 divide_by_zero_x <= b == {`LM32_WORD_WIDTH{1'b0}};
   248                 state <= `LM32_MC_STATE_IDLE;
   249             end
   250             cycles <= cycles - 1'b1;
   251         end
   252 `endif        
   253 `ifdef CFG_MC_MULTIPLY_ENABLED
   254         `LM32_MC_STATE_MULTIPLY:
   255         begin
   256             if (b[0] == 1'b1)
   257                 p <= p + a;
   258             b <= {1'b0, b[`LM32_WORD_WIDTH-1:1]};
   259             a <= {a[`LM32_WORD_WIDTH-2:0], 1'b0};
   260             result_x <= p;
   261             if ((cycles == `LM32_WORD_WIDTH'd0) || (kill_x == `TRUE))
   262                 state <= `LM32_MC_STATE_IDLE;
   263             cycles <= cycles - 1'b1;
   264         end
   265 `endif     
   266 `ifdef CFG_MC_BARREL_SHIFT_ENABLED
   267         `LM32_MC_STATE_SHIFT_LEFT:
   268         begin       
   269             a <= {a[`LM32_WORD_WIDTH-2:0], 1'b0};
   270             result_x <= a;
   271             if ((cycles == `LM32_WORD_WIDTH'd0) || (kill_x == `TRUE))
   272                 state <= `LM32_MC_STATE_IDLE;
   273             cycles <= cycles - 1'b1;
   274         end
   275         `LM32_MC_STATE_SHIFT_RIGHT:
   276         begin       
   277             b <= {fill_value, b[`LM32_WORD_WIDTH-1:1]};
   278             result_x <= b;
   279             if ((cycles == `LM32_WORD_WIDTH'd0) || (kill_x == `TRUE))
   280                 state <= `LM32_MC_STATE_IDLE;
   281             cycles <= cycles - 1'b1;
   282         end
   283 `endif   
   284         endcase
   285     end
   286 end 
   288 endmodule