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