OpenCores
URL https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk

Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc

[/] [an-fpga-implementation-of-low-latency-noc-based-mpsoc/] [trunk/] [mpsoc/] [src_processor/] [new_lm32/] [rtl/] [lm32_mc_arithmetic.v] - Blame information for rev 48

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 alirezamon
//   ==================================================================
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
// =============================================================================
49
 
50
`include "lm32_include.v"
51
 
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
59
 
60
/////////////////////////////////////////////////////
61
// Module interface
62
/////////////////////////////////////////////////////
63
 
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
    );
91
 
92
/////////////////////////////////////////////////////
93
// Inputs
94
/////////////////////////////////////////////////////
95
 
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;
114
 
115
/////////////////////////////////////////////////////
116
// Outputs
117
/////////////////////////////////////////////////////
118
 
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;
127
 
128
/////////////////////////////////////////////////////
129
// Internal nets and registers
130
/////////////////////////////////////////////////////
131
 
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
138
 
139
reg [`LM32_MC_STATE_RNG] state;                 // Current state of FSM
140
reg [5:0] cycles;                               // Number of cycles remaining in the operation
141
 
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
146
 
147
/////////////////////////////////////////////////////
148
// Combinational logic
149
/////////////////////////////////////////////////////
150
 
151
// Stall pipeline while any operation is being performed
152
assign stall_request_x = state != `LM32_MC_STATE_IDLE;
153
 
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
158
 
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
163
 
164
/////////////////////////////////////////////////////
165
// Sequential logic
166
/////////////////////////////////////////////////////
167
 
168
// Perform right shift
169
always @(posedge clk_i `CFG_RESET_SENSITIVITY)
170
begin
171
    if (rst_i == `TRUE)
172
    begin
173
        cycles <= {6{1'b0}};
174
        p <= {`LM32_WORD_WIDTH{1'b0}};
175
        a <= {`LM32_WORD_WIDTH{1'b0}};
176
        b <= {`LM32_WORD_WIDTH{1'b0}};
177
`ifdef CFG_MC_BARREL_SHIFT_ENABLED
178
        sign_extend_x <= 1'b0;
179
`endif
180
`ifdef CFG_MC_DIVIDE_ENABLED
181
        divide_by_zero_x <= `FALSE;
182
`endif
183
        result_x <= {`LM32_WORD_WIDTH{1'b0}};
184
        state <= `LM32_MC_STATE_IDLE;
185
    end
186
    else
187
    begin
188
`ifdef CFG_MC_DIVIDE_ENABLED
189
        divide_by_zero_x <= `FALSE;
190
`endif
191
        case (state)
192
        `LM32_MC_STATE_IDLE:
193
        begin
194
            if (stall_d == `FALSE)
195
            begin
196
                cycles <= `LM32_WORD_WIDTH;
197
                p <= 32'b0;
198
                a <= operand_0_d;
199
                b <= operand_1_d;
200
`ifdef CFG_MC_DIVIDE_ENABLED
201
                if (divide_d == `TRUE)
202
                    state <= `LM32_MC_STATE_DIVIDE;
203
                if (modulus_d == `TRUE)
204
                    state <= `LM32_MC_STATE_MODULUS;
205
`endif
206
`ifdef CFG_MC_MULTIPLY_ENABLED
207
                if (multiply_d == `TRUE)
208
                    state <= `LM32_MC_STATE_MULTIPLY;
209
`endif
210
`ifdef CFG_MC_BARREL_SHIFT_ENABLED
211
                if (shift_left_d == `TRUE)
212
                begin
213
                    state <= `LM32_MC_STATE_SHIFT_LEFT;
214
                    sign_extend_x <= sign_extend_d;
215
                    cycles <= operand_1_d[4:0];
216
                    a <= operand_0_d;
217
                    b <= operand_0_d;
218
                end
219
                if (shift_right_d == `TRUE)
220
                begin
221
                    state <= `LM32_MC_STATE_SHIFT_RIGHT;
222
                    sign_extend_x <= sign_extend_d;
223
                    cycles <= operand_1_d[4:0];
224
                    a <= operand_0_d;
225
                    b <= 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 <= 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 <= a;
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
        `LM32_MC_STATE_MODULUS:
253
        begin
254
            if (t[32] == 1'b0)
255
            begin
256
                p <= t[31:0];
257
                a <= {a[`LM32_WORD_WIDTH-2:0], 1'b1};
258
            end
259
            else
260
            begin
261
                p <= {p[`LM32_WORD_WIDTH-2:0], a[`LM32_WORD_WIDTH-1]};
262
                a <= {a[`LM32_WORD_WIDTH-2:0], 1'b0};
263
            end
264
            result_x <= p;
265
            if ((cycles == `LM32_WORD_WIDTH'd0) || (kill_x == `TRUE))
266
            begin
267
                // Check for divide by zero
268
                divide_by_zero_x <= b == {`LM32_WORD_WIDTH{1'b0}};
269
                state <= `LM32_MC_STATE_IDLE;
270
            end
271
            cycles <= 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 <= p + a;
279
            b <= {1'b0, b[`LM32_WORD_WIDTH-1:1]};
280
            a <= {a[`LM32_WORD_WIDTH-2:0], 1'b0};
281
            result_x <= p;
282
            if ((cycles == `LM32_WORD_WIDTH'd0) || (kill_x == `TRUE))
283
                state <= `LM32_MC_STATE_IDLE;
284
            cycles <= cycles - 1'b1;
285
        end
286
`endif
287
`ifdef CFG_MC_BARREL_SHIFT_ENABLED
288
        `LM32_MC_STATE_SHIFT_LEFT:
289
        begin
290
            a <= {a[`LM32_WORD_WIDTH-2:0], 1'b0};
291
            result_x <= a;
292
            if ((cycles == `LM32_WORD_WIDTH'd0) || (kill_x == `TRUE))
293
                state <= `LM32_MC_STATE_IDLE;
294
            cycles <= cycles - 1'b1;
295
        end
296
        `LM32_MC_STATE_SHIFT_RIGHT:
297
        begin
298
            b <= {fill_value, b[`LM32_WORD_WIDTH-1:1]};
299
            result_x <= b;
300
            if ((cycles == `LM32_WORD_WIDTH'd0) || (kill_x == `TRUE))
301
                state <= `LM32_MC_STATE_IDLE;
302
            cycles <= cycles - 1'b1;
303
        end
304
`endif
305
        endcase
306
    end
307
end
308
 
309
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.