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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1200/] [rtl/] [verilog/] [or1200_rf.v] - Blame information for rev 744

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 10 unneback
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  OR1200's register file inside CPU                           ////
4
////                                                              ////
5
////  This file is part of the OpenRISC 1200 project              ////
6 186 julius
////  http://www.opencores.org/project,or1k                       ////
7 10 unneback
////                                                              ////
8
////  Description                                                 ////
9
////  Instantiation of register file memories                     ////
10
////                                                              ////
11
////  To Do:                                                      ////
12
////   - make it smaller and faster                               ////
13
////                                                              ////
14
////  Author(s):                                                  ////
15
////      - Damjan Lampret, lampret@opencores.org                 ////
16
////                                                              ////
17
//////////////////////////////////////////////////////////////////////
18
////                                                              ////
19
//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
20
////                                                              ////
21
//// This source file may be used and distributed without         ////
22
//// restriction provided that this copyright statement is not    ////
23
//// removed from the file and that any derivative work contains  ////
24
//// the original copyright notice and the associated disclaimer. ////
25
////                                                              ////
26
//// This source file is free software; you can redistribute it   ////
27
//// and/or modify it under the terms of the GNU Lesser General   ////
28
//// Public License as published by the Free Software Foundation; ////
29
//// either version 2.1 of the License, or (at your option) any   ////
30
//// later version.                                               ////
31
////                                                              ////
32
//// This source is distributed in the hope that it will be       ////
33
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
34
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
35
//// PURPOSE.  See the GNU Lesser General Public License for more ////
36
//// details.                                                     ////
37
////                                                              ////
38
//// You should have received a copy of the GNU Lesser General    ////
39
//// Public License along with this source; if not, download it   ////
40
//// from http://www.opencores.org/lgpl.shtml                     ////
41
////                                                              ////
42
//////////////////////////////////////////////////////////////////////
43
//
44 141 marcus.erl
// $Log: or1200_rf.v,v $
45
// Revision 2.0  2010/06/30 11:00:00  ORSoC
46
// Minor update: 
47
// Bugs fixed, coding style changed. 
48
//
49 10 unneback
 
50
// synopsys translate_off
51
`include "timescale.v"
52
// synopsys translate_on
53
`include "or1200_defines.v"
54
 
55
module or1200_rf(
56
        // Clock and reset
57
        clk, rst,
58
 
59
        // Write i/f
60 141 marcus.erl
        cy_we_i, cy_we_o, supv, wb_freeze, addrw, dataw, we, flushpipe,
61 10 unneback
 
62
        // Read i/f
63
        id_freeze, addra, addrb, dataa, datab, rda, rdb,
64
 
65
        // Debug
66 258 julius
        spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o, du_read
67 10 unneback
);
68
 
69
parameter dw = `OR1200_OPERAND_WIDTH;
70
parameter aw = `OR1200_REGFILE_ADDR_WIDTH;
71
 
72
//
73
// I/O
74
//
75
 
76
//
77
// Clock and reset
78
//
79
input                           clk;
80
input                           rst;
81
 
82
//
83
// Write i/f
84
//
85 141 marcus.erl
input                           cy_we_i;
86
output                          cy_we_o;
87 10 unneback
input                           supv;
88
input                           wb_freeze;
89
input   [aw-1:0]         addrw;
90
input   [dw-1:0]         dataw;
91
input                           we;
92
input                           flushpipe;
93
 
94
//
95
// Read i/f
96
//
97
input                           id_freeze;
98
input   [aw-1:0]         addra;
99
input   [aw-1:0]         addrb;
100
output  [dw-1:0]         dataa;
101
output  [dw-1:0]         datab;
102
input                           rda;
103
input                           rdb;
104
 
105
//
106
// SPR access for debugging purposes
107
//
108
input                           spr_cs;
109
input                           spr_write;
110
input   [31:0]                   spr_addr;
111
input   [31:0]                   spr_dat_i;
112
output  [31:0]                   spr_dat_o;
113 258 julius
input                           du_read;
114
 
115 10 unneback
//
116
// Internal wires and regs
117
//
118
wire    [dw-1:0]         from_rfa;
119
wire    [dw-1:0]         from_rfb;
120
wire    [aw-1:0]         rf_addra;
121
wire    [aw-1:0]         rf_addrw;
122
wire    [dw-1:0]         rf_dataw;
123
wire                            rf_we;
124
wire                            spr_valid;
125
wire                            rf_ena;
126
wire                            rf_enb;
127
reg                             rf_we_allow;
128
 
129 258 julius
   // Logic to restore output on RFA after debug unit has read out via SPR if.
130
   // Problem was that the incorrect output would be on RFA after debug unit
131
   // had read out  - this is bad if that output is relied upon by execute
132
   // stage for next instruction. We simply save the last address for rf A and
133
   // and re-read it whenever the SPR select goes low, so we must remember
134
   // the last address and generate a signal for falling edge of SPR cs.
135
   // -- Julius
136
 
137
   // Detect falling edge of SPR select 
138
   reg                          spr_du_cs;
139
   wire                         spr_cs_fe;
140
   // Track RF A's address each time it's enabled
141
   reg  [aw-1:0]         addra_last;
142
 
143
 
144
   always @(posedge clk)
145
     if (rf_ena & !(spr_cs_fe | (du_read & spr_cs)))
146
       addra_last <= addra;
147
 
148
   always @(posedge clk)
149
     spr_du_cs <= spr_cs & du_read;
150
 
151
   assign spr_cs_fe = spr_du_cs & !(spr_cs & du_read);
152
 
153
 
154 10 unneback
//
155
// SPR access is valid when spr_cs is asserted and
156
// SPR address matches GPR addresses
157
//
158
assign spr_valid = spr_cs & (spr_addr[10:5] == `OR1200_SPR_RF);
159
 
160
//
161
// SPR data output is always from RF A
162
//
163
assign spr_dat_o = from_rfa;
164
 
165
//
166
// Operand A comes from RF or from saved A register
167
//
168 141 marcus.erl
assign dataa = from_rfa;
169 10 unneback
 
170
//
171
// Operand B comes from RF or from saved B register
172
//
173 141 marcus.erl
assign datab = from_rfb;
174 10 unneback
 
175
//
176
// RF A read address is either from SPRS or normal from CPU control
177
//
178 258 julius
assign rf_addra = (spr_valid & !spr_write) ? spr_addr[4:0] :
179
                  spr_cs_fe ? addra_last : addra;
180 10 unneback
 
181
//
182
// RF write address is either from SPRS or normal from CPU control
183
//
184
assign rf_addrw = (spr_valid & spr_write) ? spr_addr[4:0] : addrw;
185
 
186
//
187
// RF write data is either from SPRS or normal from CPU datapath
188
//
189
assign rf_dataw = (spr_valid & spr_write) ? spr_dat_i : dataw;
190
 
191
//
192
// RF write enable is either from SPRS or normal from CPU control
193
//
194 358 julius
always @(`OR1200_RST_EVENT rst or posedge clk)
195
        if (rst == `OR1200_RST_VALUE)
196 258 julius
                rf_we_allow <=  1'b1;
197 10 unneback
        else if (~wb_freeze)
198 258 julius
                rf_we_allow <=  ~flushpipe;
199 10 unneback
 
200 141 marcus.erl
assign rf_we = ((spr_valid & spr_write) | (we & ~wb_freeze)) & rf_we_allow;
201 643 julius
 
202 141 marcus.erl
assign cy_we_o = cy_we_i && ~wb_freeze && rf_we_allow;
203 258 julius
 
204 10 unneback
//
205
// CS RF A asserted when instruction reads operand A and ID stage
206
// is not stalled
207
//
208 643 julius
assign rf_ena = (rda & ~id_freeze) | (spr_valid & !spr_write) | spr_cs_fe;
209 10 unneback
 
210
//
211
// CS RF B asserted when instruction reads operand B and ID stage
212
// is not stalled
213
//
214 141 marcus.erl
assign rf_enb = rdb & ~id_freeze;
215 10 unneback
 
216
`ifdef OR1200_RFRAM_TWOPORT
217
 
218
//
219
// Instantiation of register file two-port RAM A
220
//
221
or1200_tpram_32x32 rf_a(
222
        // Port A
223
        .clk_a(clk),
224
        .rst_a(rst),
225
        .ce_a(rf_ena),
226
        .we_a(1'b0),
227
        .oe_a(1'b1),
228
        .addr_a(rf_addra),
229
        .di_a(32'h0000_0000),
230
        .do_a(from_rfa),
231
 
232
        // Port B
233
        .clk_b(clk),
234
        .rst_b(rst),
235
        .ce_b(rf_we),
236
        .we_b(rf_we),
237
        .oe_b(1'b0),
238
        .addr_b(rf_addrw),
239
        .di_b(rf_dataw),
240
        .do_b()
241
);
242
 
243
//
244
// Instantiation of register file two-port RAM B
245
//
246
or1200_tpram_32x32 rf_b(
247
        // Port A
248
        .clk_a(clk),
249
        .rst_a(rst),
250
        .ce_a(rf_enb),
251
        .we_a(1'b0),
252
        .oe_a(1'b1),
253
        .addr_a(addrb),
254
        .di_a(32'h0000_0000),
255
        .do_a(from_rfb),
256
 
257
        // Port B
258
        .clk_b(clk),
259
        .rst_b(rst),
260
        .ce_b(rf_we),
261
        .we_b(rf_we),
262
        .oe_b(1'b0),
263
        .addr_b(rf_addrw),
264
        .di_b(rf_dataw),
265
        .do_b()
266
);
267
 
268
`else
269
 
270
`ifdef OR1200_RFRAM_DUALPORT
271
 
272
//
273
// Instantiation of register file two-port RAM A
274
//
275 141 marcus.erl
   or1200_dpram #
276
     (
277
      .aw(5),
278
      .dw(32)
279
      )
280
   rf_a
281
     (
282
      // Port A
283
      .clk_a(clk),
284
      .ce_a(rf_ena),
285
      .addr_a(rf_addra),
286
      .do_a(from_rfa),
287
 
288
      // Port B
289
      .clk_b(clk),
290
      .ce_b(rf_we),
291
      .we_b(rf_we),
292
      .addr_b(rf_addrw),
293
      .di_b(rf_dataw)
294
      );
295 10 unneback
 
296 141 marcus.erl
   //
297
   // Instantiation of register file two-port RAM B
298
   //
299
   or1200_dpram #
300
     (
301
      .aw(5),
302
      .dw(32)
303
      )
304
   rf_b
305
     (
306
      // Port A
307
      .clk_a(clk),
308
      .ce_a(rf_enb),
309
      .addr_a(addrb),
310
      .do_a(from_rfb),
311
 
312
      // Port B
313
      .clk_b(clk),
314
      .ce_b(rf_we),
315
      .we_b(rf_we),
316
      .addr_b(rf_addrw),
317
      .di_b(rf_dataw)
318
      );
319
 
320 10 unneback
`else
321
 
322
`ifdef OR1200_RFRAM_GENERIC
323
 
324
//
325
// Instantiation of generic (flip-flop based) register file
326
//
327
or1200_rfram_generic rf_a(
328
        // Clock and reset
329
        .clk(clk),
330
        .rst(rst),
331
 
332
        // Port A
333
        .ce_a(rf_ena),
334
        .addr_a(rf_addra),
335
        .do_a(from_rfa),
336
 
337
        // Port B
338
        .ce_b(rf_enb),
339
        .addr_b(addrb),
340
        .do_b(from_rfb),
341
 
342
        // Port W
343
        .ce_w(rf_we),
344
        .we_w(rf_we),
345
        .addr_w(rf_addrw),
346
        .di_w(rf_dataw)
347
);
348
 
349
`else
350
 
351
//
352
// RFRAM type not specified
353
//
354
initial begin
355
        $display("Define RFRAM type.");
356
        $finish;
357
end
358
 
359
`endif
360
`endif
361
`endif
362
 
363
endmodule

powered by: WebSVN 2.1.0

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