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

Subversion Repositories openrisc_me

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 350 julius
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  OR1200's register file inside CPU                           ////
4
////                                                              ////
5
////  This file is part of the OpenRISC 1200 project              ////
6
////  http://www.opencores.org/project,or1k                       ////
7
////                                                              ////
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
// $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
 
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 483 julius
`ifdef OR1200_RAM_PARITY
60
        // Parity error indicator
61
        p_err,
62
`endif
63
 
64 350 julius
        // Write i/f
65
        cy_we_i, cy_we_o, supv, wb_freeze, addrw, dataw, we, flushpipe,
66
 
67
        // Read i/f
68
        id_freeze, addra, addrb, dataa, datab, rda, rdb,
69
 
70
        // Debug
71
        spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o, du_read
72
);
73
 
74
parameter dw = `OR1200_OPERAND_WIDTH;
75
parameter aw = `OR1200_REGFILE_ADDR_WIDTH;
76
 
77
//
78
// I/O
79
//
80
 
81
//
82
// Clock and reset
83
//
84
input                           clk;
85
input                           rst;
86
 
87
//
88
// Write i/f
89
//
90
input                           cy_we_i;
91
output                          cy_we_o;
92
input                           supv;
93
input                           wb_freeze;
94
input   [aw-1:0]         addrw;
95
input   [dw-1:0]         dataw;
96
input                           we;
97
input                           flushpipe;
98
 
99
//
100
// Read i/f
101
//
102
input                           id_freeze;
103
input   [aw-1:0]         addra;
104
input   [aw-1:0]         addrb;
105
output  [dw-1:0]         dataa;
106
output  [dw-1:0]         datab;
107
input                           rda;
108
input                           rdb;
109
 
110
//
111
// SPR access for debugging purposes
112
//
113
input                           spr_cs;
114
input                           spr_write;
115
input   [31:0]                   spr_addr;
116
input   [31:0]                   spr_dat_i;
117
output  [31:0]                   spr_dat_o;
118
input                           du_read;
119 483 julius
 
120
`ifdef OR1200_RAM_PARITY
121
output                          p_err;
122
wire [1:0]                       p_err_wire;
123
reg                             ena_r, enb_r;
124 350 julius
 
125 483 julius
`endif
126
 
127
 
128 350 julius
//
129
// Internal wires and regs
130
//
131
wire    [dw-1:0]         from_rfa;
132
wire    [dw-1:0]         from_rfb;
133
wire    [aw-1:0]         rf_addra;
134
wire    [aw-1:0]         rf_addrw;
135
wire    [dw-1:0]         rf_dataw;
136
wire                            rf_we;
137
wire                            spr_valid;
138
wire                            rf_ena;
139
wire                            rf_enb;
140
reg                             rf_we_allow;
141
 
142
   // Logic to restore output on RFA after debug unit has read out via SPR if.
143
   // Problem was that the incorrect output would be on RFA after debug unit
144
   // had read out  - this is bad if that output is relied upon by execute
145
   // stage for next instruction. We simply save the last address for rf A and
146
   // and re-read it whenever the SPR select goes low, so we must remember
147
   // the last address and generate a signal for falling edge of SPR cs.
148
   // -- Julius
149
 
150
   // Detect falling edge of SPR select 
151
   reg                          spr_du_cs;
152
   wire                         spr_cs_fe;
153
   // Track RF A's address each time it's enabled
154
   reg  [aw-1:0]         addra_last;
155
 
156
 
157
   always @(posedge clk)
158
     if (rf_ena & !(spr_cs_fe | (du_read & spr_cs)))
159
       addra_last <= addra;
160
 
161
   always @(posedge clk)
162
     spr_du_cs <= spr_cs & du_read;
163
 
164
   assign spr_cs_fe = spr_du_cs & !(spr_cs & du_read);
165
 
166
//
167
// SPR access is valid when spr_cs is asserted and
168
// SPR address matches GPR addresses
169
//
170
assign spr_valid = spr_cs & (spr_addr[10:5] == `OR1200_SPR_RF);
171
 
172
//
173
// SPR data output is always from RF A
174
//
175
assign spr_dat_o = from_rfa;
176
 
177
//
178
// Operand A comes from RF or from saved A register
179
//
180
assign dataa = from_rfa;
181
 
182
//
183
// Operand B comes from RF or from saved B register
184
//
185
assign datab = from_rfb;
186
 
187
//
188
// RF A read address is either from SPRS or normal from CPU control
189
//
190
assign rf_addra = (spr_valid & !spr_write) ? spr_addr[4:0] :
191
                  spr_cs_fe ? addra_last : addra;
192
 
193
//
194
// RF write address is either from SPRS or normal from CPU control
195
//
196 483 julius
assign rf_addrw = rst ? 0 : (spr_valid & spr_write) ? spr_addr[4:0] : addrw;
197 350 julius
 
198
//
199
// RF write data is either from SPRS or normal from CPU datapath
200
//
201 483 julius
assign rf_dataw = rst ? 0 : (spr_valid & spr_write) ? spr_dat_i : dataw;
202 350 julius
 
203
//
204
// RF write enable is either from SPRS or normal from CPU control
205
//
206 358 julius
always @(`OR1200_RST_EVENT rst or posedge clk)
207
        if (rst == `OR1200_RST_VALUE)
208 350 julius
                rf_we_allow <=  1'b1;
209
        else if (~wb_freeze)
210
                rf_we_allow <=  ~flushpipe;
211
 
212 483 julius
assign rf_we = rst ? 1 : ((spr_valid & spr_write) | (we & ~wb_freeze)) &
213
               rf_we_allow;
214
 
215 350 julius
assign cy_we_o = cy_we_i && ~wb_freeze && rf_we_allow;
216
 
217
//
218
// CS RF A asserted when instruction reads operand A and ID stage
219
// is not stalled
220
//
221 483 julius
assign rf_ena = (rda & ~id_freeze) | (spr_valid & !spr_write) | spr_cs_fe;
222 350 julius
 
223
//
224
// CS RF B asserted when instruction reads operand B and ID stage
225
// is not stalled
226
//
227
assign rf_enb = rdb & ~id_freeze;
228
 
229 483 julius
`ifdef OR1200_RAM_PARITY
230
   always @(posedge clk)
231
     if (rst) begin
232
        ena_r <= 0;
233
        enb_r <= 0;
234
     end
235
     else if (p_err) begin
236
        ena_r <= 0;
237
        enb_r <= 0;
238
     end
239
     else begin
240
        ena_r <= rf_ena;
241
        enb_r <= rf_enb;
242
     end
243
 
244
 
245
   assign p_err = (p_err_wire[0] & ena_r) | (p_err_wire[1] & enb_r);
246
 
247
`endif
248
 
249 350 julius
`ifdef OR1200_RFRAM_TWOPORT
250
 
251
//
252
// Instantiation of register file two-port RAM A
253
//
254
or1200_tpram_32x32 rf_a(
255
        // Port A
256
        .clk_a(clk),
257
        .rst_a(rst),
258
        .ce_a(rf_ena),
259
        .we_a(1'b0),
260
        .oe_a(1'b1),
261
        .addr_a(rf_addra),
262
        .di_a(32'h0000_0000),
263
        .do_a(from_rfa),
264
 
265
        // Port B
266
        .clk_b(clk),
267
        .rst_b(rst),
268
        .ce_b(rf_we),
269
        .we_b(rf_we),
270
        .oe_b(1'b0),
271
        .addr_b(rf_addrw),
272
        .di_b(rf_dataw),
273
        .do_b()
274
);
275
 
276
//
277
// Instantiation of register file two-port RAM B
278
//
279
or1200_tpram_32x32 rf_b(
280
        // Port A
281
        .clk_a(clk),
282
        .rst_a(rst),
283
        .ce_a(rf_enb),
284
        .we_a(1'b0),
285
        .oe_a(1'b1),
286
        .addr_a(addrb),
287
        .di_a(32'h0000_0000),
288
        .do_a(from_rfb),
289
 
290
        // Port B
291
        .clk_b(clk),
292
        .rst_b(rst),
293
        .ce_b(rf_we),
294
        .we_b(rf_we),
295
        .oe_b(1'b0),
296
        .addr_b(rf_addrw),
297
        .di_b(rf_dataw),
298
        .do_b()
299
);
300
 
301 483 julius
 `ifdef OR1200_RAM_PARITY
302
   assign p_err_wire = 0;
303
 `endif
304
 
305
 
306 350 julius
`else
307
 
308 483 julius
 `ifdef OR1200_RFRAM_DUALPORT
309
 
310
   //
311
   // Instantiation of register file two-port RAM A
312
   //
313 350 julius
   or1200_dpram #
314
     (
315
      .aw(5),
316
      .dw(32)
317
      )
318
   rf_a
319
     (
320 483 julius
      .rst(rst),
321 350 julius
      // Port A
322 483 julius
      .clk_a(clk),
323 350 julius
      .ce_a(rf_ena),
324
      .addr_a(rf_addra),
325
      .do_a(from_rfa),
326
 
327
      // Port B
328
      .clk_b(clk),
329
      .ce_b(rf_we),
330
      .we_b(rf_we),
331
      .addr_b(rf_addrw),
332
      .di_b(rf_dataw)
333 482 julius
 
334 483 julius
  `ifdef OR1200_RAM_PARITY
335
      , .p_err(p_err_wire[0])
336
  `endif
337 350 julius
      );
338
 
339
   //
340
   // Instantiation of register file two-port RAM B
341
   //
342
   or1200_dpram #
343
     (
344
      .aw(5),
345
      .dw(32)
346
      )
347
   rf_b
348
     (
349 483 julius
      .rst(rst),
350 350 julius
      // Port A
351
      .clk_a(clk),
352
      .ce_a(rf_enb),
353
      .addr_a(addrb),
354
      .do_a(from_rfb),
355
 
356
      // Port B
357
      .clk_b(clk),
358
      .ce_b(rf_we),
359
      .we_b(rf_we),
360
      .addr_b(rf_addrw),
361
      .di_b(rf_dataw)
362 482 julius
 
363 483 julius
  `ifdef OR1200_RAM_PARITY
364
      , .p_err(p_err_wire[1])
365
  `endif
366
 
367
      );
368
 
369 350 julius
`else
370
 
371
`ifdef OR1200_RFRAM_GENERIC
372
 
373
//
374
// Instantiation of generic (flip-flop based) register file
375
//
376
or1200_rfram_generic rf_a(
377
        // Clock and reset
378
        .clk(clk),
379
        .rst(rst),
380
 
381
        // Port A
382
        .ce_a(rf_ena),
383
        .addr_a(rf_addra),
384
        .do_a(from_rfa),
385
 
386
        // Port B
387
        .ce_b(rf_enb),
388
        .addr_b(addrb),
389
        .do_b(from_rfb),
390
 
391
        // Port W
392
        .ce_w(rf_we),
393
        .we_w(rf_we),
394
        .addr_w(rf_addrw),
395
        .di_w(rf_dataw)
396
);
397
 
398 483 julius
 `ifdef OR1200_RAM_PARITY
399
   assign p_err_wire = 0;
400
 `endif
401
 
402 350 julius
`else
403
 
404
//
405
// RFRAM type not specified
406
//
407
initial begin
408
        $display("Define RFRAM type.");
409
        $finish;
410
end
411
 
412
`endif
413
`endif
414
`endif
415
 
416
endmodule

powered by: WebSVN 2.1.0

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