Sat, 06 Aug 2011 00:02:46 +0100
[UPSTREAM PULL] Update baseline to LatticeMico32 v3.8 from Diamond 1.3-lm32 distribution package (datestamp May 2011)
1 // ==================================================================
2 // >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
3 // ------------------------------------------------------------------
4 // Copyright (c) 2006-2011 by Lattice Semiconductor Corporation
5 // ALL RIGHTS RESERVED
6 // ------------------------------------------------------------------
7 //
8 // IMPORTANT: THIS FILE IS AUTO-GENERATED BY THE LATTICEMICO SYSTEM.
9 //
10 // Permission:
11 //
12 // Lattice Semiconductor grants permission to use this code
13 // pursuant to the terms of the Lattice Semiconductor Corporation
14 // Open Source License Agreement.
15 //
16 // Disclaimer:
17 //
18 // Lattice Semiconductor provides no warranty regarding the use or
19 // functionality of this code. It is the user's responsibility to
20 // verify the user’s design for consistency and functionality through
21 // the use of formal verification methods.
22 //
23 // --------------------------------------------------------------------
24 //
25 // Lattice Semiconductor Corporation
26 // 5555 NE Moore Court
27 // Hillsboro, OR 97214
28 // U.S.A
29 //
30 // TEL: 1-800-Lattice (USA and Canada)
31 // 503-286-8001 (other locations)
32 //
33 // web: http://www.latticesemi.com/
34 // email: techsupport@latticesemi.com
35 //
36 // --------------------------------------------------------------------
37 // FILE DETAILS
38 // Project : LatticeMico32
39 // File : lm_mc_arithmetic.v
40 // Title : Multi-cycle arithmetic unit.
41 // Dependencies : lm32_include.v
42 // Version : 6.1.17
43 // : Initial Release
44 // Version : 7.0SP2, 3.0
45 // : No Change
46 // Version : 3.1
47 // : No Change
48 // =============================================================================
50 `include "lm32_include.v"
52 `define LM32_MC_STATE_RNG 2:0
53 `define LM32_MC_STATE_IDLE 3'b000
54 `define LM32_MC_STATE_MULTIPLY 3'b001
55 `define LM32_MC_STATE_MODULUS 3'b010
56 `define LM32_MC_STATE_DIVIDE 3'b011
57 `define LM32_MC_STATE_SHIFT_LEFT 3'b100
58 `define LM32_MC_STATE_SHIFT_RIGHT 3'b101
60 /////////////////////////////////////////////////////
61 // Module interface
62 /////////////////////////////////////////////////////
64 module lm32_mc_arithmetic (
65 // ----- Inputs -----
66 clk_i,
67 rst_i,
68 stall_d,
69 kill_x,
70 `ifdef CFG_MC_DIVIDE_ENABLED
71 divide_d,
72 modulus_d,
73 `endif
74 `ifdef CFG_MC_MULTIPLY_ENABLED
75 multiply_d,
76 `endif
77 `ifdef CFG_MC_BARREL_SHIFT_ENABLED
78 shift_left_d,
79 shift_right_d,
80 sign_extend_d,
81 `endif
82 operand_0_d,
83 operand_1_d,
84 // ----- Ouputs -----
85 result_x,
86 `ifdef CFG_MC_DIVIDE_ENABLED
87 divide_by_zero_x,
88 `endif
89 stall_request_x
90 );
92 /////////////////////////////////////////////////////
93 // Inputs
94 /////////////////////////////////////////////////////
96 input clk_i; // Clock
97 input rst_i; // Reset
98 input stall_d; // Stall instruction in D stage
99 input kill_x; // Kill instruction in X stage
100 `ifdef CFG_MC_DIVIDE_ENABLED
101 input divide_d; // Perform divide
102 input modulus_d; // Perform modulus
103 `endif
104 `ifdef CFG_MC_MULTIPLY_ENABLED
105 input multiply_d; // Perform multiply
106 `endif
107 `ifdef CFG_MC_BARREL_SHIFT_ENABLED
108 input shift_left_d; // Perform left shift
109 input shift_right_d; // Perform right shift
110 input sign_extend_d; // Whether to sign-extend (arithmetic) or zero-extend (logical)
111 `endif
112 input [`LM32_WORD_RNG] operand_0_d;
113 input [`LM32_WORD_RNG] operand_1_d;
115 /////////////////////////////////////////////////////
116 // Outputs
117 /////////////////////////////////////////////////////
119 output [`LM32_WORD_RNG] result_x; // Result of operation
120 reg [`LM32_WORD_RNG] result_x;
121 `ifdef CFG_MC_DIVIDE_ENABLED
122 output divide_by_zero_x; // A divide by zero was attempted
123 reg divide_by_zero_x;
124 `endif
125 output stall_request_x; // Request to stall pipeline from X stage back
126 wire stall_request_x;
128 /////////////////////////////////////////////////////
129 // Internal nets and registers
130 /////////////////////////////////////////////////////
132 reg [`LM32_WORD_RNG] p; // Temporary registers
133 reg [`LM32_WORD_RNG] a;
134 reg [`LM32_WORD_RNG] b;
135 `ifdef CFG_MC_DIVIDE_ENABLED
136 wire [32:0] t;
137 `endif
139 reg [`LM32_MC_STATE_RNG] state; // Current state of FSM
140 reg [5:0] cycles; // Number of cycles remaining in the operation
142 `ifdef CFG_MC_BARREL_SHIFT_ENABLED
143 reg sign_extend_x; // Whether to sign extend of zero extend right shifts
144 wire fill_value; // Value to fill with for right barrel-shifts
145 `endif
147 /////////////////////////////////////////////////////
148 // Combinational logic
149 /////////////////////////////////////////////////////
151 // Stall pipeline while any operation is being performed
152 assign stall_request_x = state != `LM32_MC_STATE_IDLE;
154 `ifdef CFG_MC_DIVIDE_ENABLED
155 // Subtraction
156 assign t = {p[`LM32_WORD_WIDTH-2:0], a[`LM32_WORD_WIDTH-1]} - b;
157 `endif
159 `ifdef CFG_MC_BARREL_SHIFT_ENABLED
160 // Determine fill value for right shift - Sign bit for arithmetic shift, or zero for logical shift
161 assign fill_value = (sign_extend_x == `TRUE) & b[`LM32_WORD_WIDTH-1];
162 `endif
164 /////////////////////////////////////////////////////
165 // Sequential logic
166 /////////////////////////////////////////////////////
168 // Perform right shift
169 always @(posedge clk_i `CFG_RESET_SENSITIVITY)
170 begin
171 if (rst_i == `TRUE)
172 begin
173 cycles <= #1 {6{1'b0}};
174 p <= #1 {`LM32_WORD_WIDTH{1'b0}};
175 a <= #1 {`LM32_WORD_WIDTH{1'b0}};
176 b <= #1 {`LM32_WORD_WIDTH{1'b0}};
177 `ifdef CFG_MC_BARREL_SHIFT_ENABLED
178 sign_extend_x <= #1 1'b0;
179 `endif
180 `ifdef CFG_MC_DIVIDE_ENABLED
181 divide_by_zero_x <= #1 `FALSE;
182 `endif
183 result_x <= #1 {`LM32_WORD_WIDTH{1'b0}};
184 state <= #1 `LM32_MC_STATE_IDLE;
185 end
186 else
187 begin
188 `ifdef CFG_MC_DIVIDE_ENABLED
189 divide_by_zero_x <= #1 `FALSE;
190 `endif
191 case (state)
192 `LM32_MC_STATE_IDLE:
193 begin
194 if (stall_d == `FALSE)
195 begin
196 cycles <= #1 `LM32_WORD_WIDTH;
197 p <= #1 32'b0;
198 a <= #1 operand_0_d;
199 b <= #1 operand_1_d;
200 `ifdef CFG_MC_DIVIDE_ENABLED
201 if (divide_d == `TRUE)
202 state <= #1 `LM32_MC_STATE_DIVIDE;
203 if (modulus_d == `TRUE)
204 state <= #1 `LM32_MC_STATE_MODULUS;
205 `endif
206 `ifdef CFG_MC_MULTIPLY_ENABLED
207 if (multiply_d == `TRUE)
208 state <= #1 `LM32_MC_STATE_MULTIPLY;
209 `endif
210 `ifdef CFG_MC_BARREL_SHIFT_ENABLED
211 if (shift_left_d == `TRUE)
212 begin
213 state <= #1 `LM32_MC_STATE_SHIFT_LEFT;
214 sign_extend_x <= #1 sign_extend_d;
215 cycles <= #1 operand_1_d[4:0];
216 a <= #1 operand_0_d;
217 b <= #1 operand_0_d;
218 end
219 if (shift_right_d == `TRUE)
220 begin
221 state <= #1 `LM32_MC_STATE_SHIFT_RIGHT;
222 sign_extend_x <= #1 sign_extend_d;
223 cycles <= #1 operand_1_d[4:0];
224 a <= #1 operand_0_d;
225 b <= #1 operand_0_d;
226 end
227 `endif
228 end
229 end
230 `ifdef CFG_MC_DIVIDE_ENABLED
231 `LM32_MC_STATE_DIVIDE:
232 begin
233 if (t[32] == 1'b0)
234 begin
235 p <= #1 t[31:0];
236 a <= #1 {a[`LM32_WORD_WIDTH-2:0], 1'b1};
237 end
238 else
239 begin
240 p <= #1 {p[`LM32_WORD_WIDTH-2:0], a[`LM32_WORD_WIDTH-1]};
241 a <= #1 {a[`LM32_WORD_WIDTH-2:0], 1'b0};
242 end
243 result_x <= #1 a;
244 if ((cycles == `LM32_WORD_WIDTH'd0) || (kill_x == `TRUE))
245 begin
246 // Check for divide by zero
247 divide_by_zero_x <= #1 b == {`LM32_WORD_WIDTH{1'b0}};
248 state <= #1 `LM32_MC_STATE_IDLE;
249 end
250 cycles <= #1 cycles - 1'b1;
251 end
252 `LM32_MC_STATE_MODULUS:
253 begin
254 if (t[32] == 1'b0)
255 begin
256 p <= #1 t[31:0];
257 a <= #1 {a[`LM32_WORD_WIDTH-2:0], 1'b1};
258 end
259 else
260 begin
261 p <= #1 {p[`LM32_WORD_WIDTH-2:0], a[`LM32_WORD_WIDTH-1]};
262 a <= #1 {a[`LM32_WORD_WIDTH-2:0], 1'b0};
263 end
264 result_x <= #1 p;
265 if ((cycles == `LM32_WORD_WIDTH'd0) || (kill_x == `TRUE))
266 begin
267 // Check for divide by zero
268 divide_by_zero_x <= #1 b == {`LM32_WORD_WIDTH{1'b0}};
269 state <= #1 `LM32_MC_STATE_IDLE;
270 end
271 cycles <= #1 cycles - 1'b1;
272 end
273 `endif
274 `ifdef CFG_MC_MULTIPLY_ENABLED
275 `LM32_MC_STATE_MULTIPLY:
276 begin
277 if (b[0] == 1'b1)
278 p <= #1 p + a;
279 b <= #1 {1'b0, b[`LM32_WORD_WIDTH-1:1]};
280 a <= #1 {a[`LM32_WORD_WIDTH-2:0], 1'b0};
281 result_x <= #1 p;
282 if ((cycles == `LM32_WORD_WIDTH'd0) || (kill_x == `TRUE))
283 state <= #1 `LM32_MC_STATE_IDLE;
284 cycles <= #1 cycles - 1'b1;
285 end
286 `endif
287 `ifdef CFG_MC_BARREL_SHIFT_ENABLED
288 `LM32_MC_STATE_SHIFT_LEFT:
289 begin
290 a <= #1 {a[`LM32_WORD_WIDTH-2:0], 1'b0};
291 result_x <= #1 a;
292 if ((cycles == `LM32_WORD_WIDTH'd0) || (kill_x == `TRUE))
293 state <= #1 `LM32_MC_STATE_IDLE;
294 cycles <= #1 cycles - 1'b1;
295 end
296 `LM32_MC_STATE_SHIFT_RIGHT:
297 begin
298 b <= #1 {fill_value, b[`LM32_WORD_WIDTH-1:1]};
299 result_x <= #1 b;
300 if ((cycles == `LM32_WORD_WIDTH'd0) || (kill_x == `TRUE))
301 state <= #1 `LM32_MC_STATE_IDLE;
302 cycles <= #1 cycles - 1'b1;
303 end
304 `endif
305 endcase
306 end
307 end
309 endmodule