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/] [lm32/] [verilog/] [src/] [lm32_mc_arithmetic.v] - Blame information for rev 17

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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