OpenCores
URL https://opencores.org/ocsvn/openfire2/openfire2/trunk

Subversion Repositories openfire2

[/] [openfire2/] [trunk/] [rtl/] [openfire_primitives.v] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 toni32
/*      MODULE: openfire_primitives
2
 
3
        DESCRIPTION: Contains all submodules called by the design.
4
 
5
CONTENTS:
6
openfire_compare                comparator for conditional branchs & CMPU instr
7
openfire_alu
8
openfire_rf_sram                registerfile
9
 
10
TO DO:
11
 
12
AUTHOR:
13
Stephen Douglas Craven
14
Configurable Computing Lab
15
Virginia Tech
16
scraven@vt.edu
17
 
18
REVISION HISTORY:
19
Revision 0.2, 8/10/2005 SDC
20
Initial release
21
 
22
Revision 0.3, 12/17/2005 SDC
23
Fixed Register File zeroing function for simulation
24
 
25
COPYRIGHT:
26
Copyright (c) 2005 Stephen Douglas Craven
27
 
28
Permission is hereby granted, free of charge, to any person obtaining a copy of
29
this software and associated documentation files (the "Software"), to deal in
30
the Software without restriction, including without limitation the rights to
31
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
32
of the Software, and to permit persons to whom the Software is furnished to do
33
so, subject to the following conditions:
34
 
35
The above copyright notice and this permission notice shall be included in all
36
copies or substantial portions of the Software.
37
 
38
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
39
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
40
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
41
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
42
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
43
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
44
SOFTWARE        */
45
 
46
`include "openfire_define.v"
47
 
48
/**********************************
49
 * Comparator for Branches & CMPU *
50
 **********************************/
51
module openfire_compare (
52
        in0, in1, fns,          // inputs
53
        out);                           // outputs
54
 
55
input   [31:0]   in0;
56
input   [31:0]   in1;
57
input   [2:0]            fns;
58
output                  out;
59
 
60
reg                     out;
61
 
62
wire                    cmp_out;
63
 
64
`ifdef FAST_CMP
65
        wire            cmp_dual_out;
66
 
67
        // A single comparator could be used, but timing is tight.
68
        // A single comparator can reach 100 MHz in a 2vp-7 part, but not in a -6 speed grade.
69
        assign cmp_dual_out = (in0 > in1);
70
        assign cmp_out = (in0[30:0] > 0);
71
 
72
        always@(in0 or in1 or cmp_out or fns or cmp_dual_out)
73
        begin
74
 
75
                // Verilog treats all signals as unsigned
76
                case(fns)
77
                `CMP_equal:                     out <= (in0 == 0);
78
                `CMP_not_equal: out <= (in0 != 0);
79
                `CMP_lessthan:          out <= (in0[31] == 1); // negative number
80
                `CMP_lt_equal:          out <= (in0 == 0) | (in0[31] == 1);
81
                `CMP_greaterthan:       out <= cmp_out & (in0[31] == 0);
82
                `CMP_gt_equal:          out <= (cmp_out | (in0[30:0] == 0)) & (in0[31] == 0);
83
                `CMP_one:                       out <= 1'b1;    // used for unconditional branchs
84
                `CMP_dual_inputs:       out <= cmp_dual_out;  // used only for CMPU instruction
85
                default:
86
                        begin
87
                                out <= 1'b0;
88
                                $display("ERROR! Comparator set to illegal function!");
89
                        end
90
                endcase
91
        end // always@
92
`else
93
`ifdef CMP
94
        // Force tools to synthesize only a single 32-bit comparator... cannot reach 100 MHz in a 2vp speed grade 6 part
95
        reg     [31:0]  cmp_in_a;
96
        reg     [31:0]  cmp_in_b;
97
 
98
        assign cmp_out = (cmp_in_a > cmp_in_b);
99
 
100
        always@(in0 or in1 or cmp_out or fns)
101
        begin
102
                cmp_in_a        <= {1'b0, in0[30:0]};
103
                cmp_in_b        <= 0;
104
                // Verilog treats all signals as unsigned
105
                case(fns)
106
                `CMP_equal:             out <= (in0 == 0);
107
                `CMP_not_equal:         out <= (in0 != 0);
108
                `CMP_lessthan:          out <= (in0[31] == 1); // negative number
109
                `CMP_lt_equal:          out <= (in0 == 0) | (in0[31] == 1);
110
                `CMP_greaterthan:       out <= cmp_out & (in0[31] == 0);
111
                `CMP_gt_equal:          out <= (cmp_out | (in0[30:0] == 0)) & (in0[30] == 0);
112
                `CMP_one:               out <= 1'b1;    // used for unconditional branchs
113
                `CMP_dual_inputs:
114
                        begin   // used only for CMPU instruction
115
                                        cmp_in_a        <= in0;
116
                                        cmp_in_b        <= in1;
117
                                        out             <= cmp_out;
118
                        end
119
                default:
120
                        begin
121
                                out <= 1'b0;
122
                                $display("ERROR! Comparator set to illegal function!");
123
                        end
124
                endcase
125
        end // always@
126
`else // Do not allow CMPU instruction
127
 
128
        reg     [30:0]  cmp_in_a;
129
 
130
        assign cmp_out = (cmp_in_a > 0);
131
 
132
        always@(in0, in1, cmp_out, fns)
133
        begin
134
                cmp_in_a        <= in0[30:0];
135
                // Verilog treats all signals as unsigned
136
                case(fns)
137
                `CMP_equal:             out <= (in0 == 0);
138
                `CMP_not_equal:         out <= (in0 != 0);
139
                `CMP_lessthan:          out <= (in0[31] == 1); // negative number
140
                `CMP_lt_equal:          out <= (in0 == 0) | (in0[31] == 1);
141
                `CMP_greaterthan:       out <= cmp_out & (in0[31] == 0);
142
                `CMP_gt_equal:          out <= (cmp_out | (in0[30:0] == 0)) & (in0[31] == 0);
143
                `CMP_one:               out <= 1'b1;    // used for unconditional branchs
144
                default:
145
                        begin
146
                                out <= 1'b0;
147
                                $display("ERROR! Comparator set to illegal function!");
148
                        end
149
                endcase
150
        end // always@
151
`endif
152
`endif
153
 
154
endmodule
155
 
156
/**************
157
 * Custom ALU *
158
 **************/
159
module openfire_alu (
160
        a, b, c_in, fns, clock, reset, stall,   // inputs
161
        alu_result, c_out, dmem_addr,           // output
162
        alu_multicycle_instr, alu_multicycle_instr_complete);
163
 
164
input   [31:0]   a;
165
input   [31:0]   b;
166
input                           c_in;
167
input   [3:0]            fns;
168
input                           clock;
169
input                           reset;
170
input                           stall;
171
 
172
output [31:0]    alu_result;
173
output [31:0]    dmem_addr;
174
output                  c_out;
175
output                  alu_multicycle_instr;
176
output                  alu_multicycle_instr_complete;
177
 
178
reg     [31:0]   alu_result;
179
reg     [31:0]   adder_out;
180
reg                             c_out;
181
reg                             alu_multicycle_instr;
182
reg     [2:0]            mul_counter;
183
 
184
reg     [31:0]   mul_result;
185
reg     [31:0]   mul_tmp1;
186
reg     [31:0]   a_in;
187
reg     [31:0]   b_in;
188
 
189
`ifdef MUL
190
// Force tools to infer pipelined Mult - allows use of code on devices other than Xilinx FPGAs
191
// Mult takes 5 execute cycles to complete at 32-bits
192
assign alu_multicycle_instr_complete = (mul_counter == 3'b011);
193
 
194
always@(posedge clock)
195
begin
196
        if(reset)
197
                begin
198
                        a_in            <= 0;
199
                        b_in            <= 0;
200
                        mul_tmp1        <= 0;
201
                        mul_result      <= 0;
202
                        mul_counter     <= 0;
203
                end
204
        else if (~stall)
205
                begin   // infer pipelined multiplier
206
                        a_in            <= a;
207
                        b_in            <= b;
208
                        mul_tmp1        <= a_in * b_in;
209
                        mul_result      <= mul_tmp1;
210
                        if (mul_counter == 3)
211
                                mul_counter     <= 0;
212
                        else if(alu_multicycle_instr)
213
                                mul_counter     <= mul_counter + 1;
214
                end
215
end
216
`endif
217
 
218
// dmem_addr comes straight from adder to by-pass ALU output MUX for timing
219
assign dmem_addr = adder_out;
220
 
221
// ALU result selection
222
`ifdef MUL
223
always@(a or b or c_in or fns or mul_result)
224
`else
225
always@(a or b or c_in or fns)
226
`endif
227
begin
228
        {c_out, adder_out}      <= a + b + c_in;
229
        alu_multicycle_instr    <= 0;
230
        case(fns)
231
        //`ALU_add:             {c_out, alu_result} <= a + b + c_in;
232
        `ALU_logic_or:
233
                begin
234
                                alu_result <= a | b;
235
                                c_out <= 0;
236
                end
237
        `ALU_logic_and:
238
                begin
239
                                alu_result <= a & b;
240
                                c_out <= 0;
241
                end
242
        `ALU_logic_xor:
243
                begin
244
                                alu_result <= a ^ b;
245
                                c_out <= 0;
246
                end
247
        `ALU_sex8:
248
                begin
249
                                alu_result <= {{(24){a[7]}}, a[7:0]};
250
                                c_out <= 0;
251
                end
252
        `ALU_sex16:
253
                begin
254
                                alu_result <= {{(16){a[15]}}, a[15:0]};
255
                                c_out <= 0;
256
                end
257
        `ALU_shiftR_arth:
258
                begin
259
                                alu_result <= {a[31], a[31:1]};
260
                                c_out <= a[0];
261
                end
262
        `ALU_shiftR_log:
263
                begin
264
                                alu_result <= {1'b0, a[31:1]};
265
                                c_out <= a[0];
266
                end
267
        `ALU_shiftR_c:
268
                begin
269
                                alu_result <= {c_in, a[31:1]};
270
                                c_out <= a[0];
271
                end
272
        `ALU_compare:           {c_out, alu_result} <= a + b + c_in;
273
        `ALU_compare_uns:       {c_out, alu_result} <= a + b + c_in;    // comparator determines MSB
274
`ifdef MUL
275
        `ALU_multiply:
276
                begin
277
                                alu_multicycle_instr <= 1;
278
                                alu_result <= mul_result;
279
                                c_out <= 0;
280
                end
281
`endif
282
        default: //`ALU_add -- moved to default for speed considerations
283
                begin
284
                        {c_out, alu_result} <= a + b + c_in;
285
                        if(fns != `ALU_add) $display("ERROR! ALU set to illegal or unimplemented function!");
286
                end
287
        endcase
288
end // end always@
289
 
290
endmodule
291
 
292
/*********************************************
293
 * Register File SRAM                        *
294
 * Created from 2, 2-bank SRAMs              *
295
 * Async Reads, Sync Writes                  *
296
 * Targets dual-port distributed Select RAM  *
297
 *********************************************/
298
module openfire_rf_sram(
299
        clock,
300
        read_addr, write_addr, data_in, we,             // inputs
301
        read_data_out, write_data_out);                 // outputs
302
 
303
parameter       addr_width = 5; // 32 registers
304
 
305
input                           clock;
306
input   [addr_width-1:0] read_addr;
307
input   [addr_width-1:0] write_addr;
308
input   [31:0]           data_in;
309
input                           we;
310
 
311
output [31:0]    read_data_out;
312
output [31:0]    write_data_out;
313
 
314
reg     [31:0]           MEM [(1 << addr_width) - 1:0];
315
 
316
//synthesis translate_off
317
integer i;
318
initial
319
begin
320
        for(i=0; i < ( 1 << addr_width); i=i+1)
321
                MEM[i] <= 0;
322
end
323
//synthesis translate_on
324
 
325
always@(posedge clock)
326
begin
327
        if (we)
328
                MEM[write_addr] <= data_in;
329
end
330
 
331
assign read_data_out = MEM[read_addr];
332
assign write_data_out = MEM[write_addr];
333
 
334
endmodule
335
 

powered by: WebSVN 2.1.0

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