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