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

Subversion Repositories claw

[/] [claw/] [trunk/] [or1200_cpu/] [or1200_rf.v] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 conte
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  OR1200's register file inside CPU                           ////
4
////                                                              ////
5
////  This file is part of the OpenRISC 1200 project              ////
6
////  http://www.opencores.org/cores/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
////  Modified by:                                                ////
17
////      - Balaji V. Iyer, bviyer@ncsu.edu                       ////
18
////  Advisor:                                                    ////
19
////      - Dr. Tom Conte                                         ////
20
////                                                              ////
21
////                                                              ////
22
//////////////////////////////////////////////////////////////////////
23
////                                                              ////
24
//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
25
////                                                              ////
26
//// This source file may be used and distributed without         ////
27
//// restriction provided that this copyright statement is not    ////
28
//// removed from the file and that any derivative work contains  ////
29
//// the original copyright notice and the associated disclaimer. ////
30
////                                                              ////
31
//// This source file is free software; you can redistribute it   ////
32
//// and/or modify it under the terms of the GNU Lesser General   ////
33
//// Public License as published by the Free Software Foundation; ////
34
//// either version 2.1 of the License, or (at your option) any   ////
35
//// later version.                                               ////
36
////                                                              ////
37
//// This source is distributed in the hope that it will be       ////
38
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
39
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
40
//// PURPOSE.  See the GNU Lesser General Public License for more ////
41
//// details.                                                     ////
42
////                                                              ////
43
//// You should have received a copy of the GNU Lesser General    ////
44
//// Public License along with this source; if not, download it   ////
45
//// from http://www.opencores.org/lgpl.shtml                     ////
46
////                                                              ////
47
//////////////////////////////////////////////////////////////////////
48
//
49
// CVS Revision History
50
//
51
// $Log: not supported by cvs2svn $
52
// Revision 1.3  2003/04/07 01:21:56  lampret
53
// RFRAM type always need to be defined.
54
//
55
// Revision 1.2  2002/06/08 16:19:09  lampret
56
// Added generic flip-flop based memory macro instantiation.
57
//
58
// Revision 1.1  2002/01/03 08:16:15  lampret
59
// New prefixes for RTL files, prefixed module names. Updated cache controllers and MMUs.
60
//
61
// Revision 1.13  2001/11/20 18:46:15  simons
62
// Break point bug fixed
63
//
64
// Revision 1.12  2001/11/13 10:02:21  lampret
65
// Added 'setpc'. Renamed some signals (except_flushpipe into flushpipe etc)
66
//
67
// Revision 1.11  2001/11/12 01:45:40  lampret
68
// Moved flag bit into SR. Changed RF enable from constant enable to dynamic enable for read ports.
69
//
70
// Revision 1.10  2001/11/10 03:43:57  lampret
71
// Fixed exceptions.
72
//
73
// Revision 1.9  2001/10/21 17:57:16  lampret
74
// Removed params from generic_XX.v. Added translate_off/on in sprs.v and id.v. Removed spr_addr from dc.v and ic.v. Fixed CR+LF.
75
//
76
// Revision 1.8  2001/10/14 13:12:10  lampret
77
// MP3 version.
78
//
79
// Revision 1.1.1.1  2001/10/06 10:18:36  igorm
80
// no message
81
//
82
// Revision 1.3  2001/08/09 13:39:33  lampret
83
// Major clean-up.
84
//
85
// Revision 1.2  2001/07/22 03:31:54  lampret
86
// Fixed RAM's oen bug. Cache bypass under development.
87
//
88
// Revision 1.1  2001/07/20 00:46:21  lampret
89
// Development version of RTL. Libraries are missing.
90
//
91
//
92
 
93
// synopsys translate_off
94
`include "timescale.v"
95
// synopsys translate_on
96
`include "or1200_defines.v"
97
 
98
module or1200_rf(
99
        // Clock and reset
100
        clk, rst,
101
 
102
        // Write i/f
103
        supv, wb_freeze, addrw, dataw, addrw2, dataw2, we, we2, flushpipe,
104
 
105
        // Read i/f
106
        id_freeze, addra, addrb, dataa, datab, rda, rdb,
107
                   addra2,addrb2, dataa2, datab2, rda2, rdb2,
108
 
109
        // Debug
110
        spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o
111
);
112
 
113
parameter dw = 32; //`OR1200_OPERAND_WIDTH;
114
parameter aw = 5; // `OR1200_REGFILE_ADDR_WIDTH;
115
 
116
//
117
// I/O
118
//
119
 
120
//
121
// Clock and reset
122
//
123
input                           clk;
124
input                           rst;
125
 
126
//
127
// Write i/f
128
//
129
input                           supv;
130
input                           wb_freeze;
131
input   [aw-1:0]         addrw;
132
input   [dw-1:0]         dataw;
133
input                           we;
134
input                           flushpipe;
135
 
136
 
137
 
138
// bviyer: replicated the write port to two. One problem here we can face is that
139
// if two insturctions write the same register then we will have some biggie
140
// problems...but this is something that the compiler should take care of it. 
141
input [aw-1:0]                   addrw2;
142
input [dw-1:0]                   dataw2;
143
input                           we2;
144
//
145
// Read i/f
146
//
147
input                           id_freeze;
148
input   [aw-1:0]         addra;
149
input   [aw-1:0]         addrb;
150
output  [dw-1:0]         dataa;
151
output  [dw-1:0]         datab;
152
input                           rda;
153
input                           rdb;
154
 
155
// bviyer: replicated the address and output ports to hold two values to the register file.
156
 
157
input [aw-1:0]                   addra2;
158
input [aw-1:0]                   addrb2;
159
output [dw-1:0]                  dataa2;
160
output [dw-1:0]                  datab2;
161
input                           rda2;
162
input                           rdb2;
163
 
164
 
165
 
166
//
167
// SPR access for debugging purposes
168
//
169
input                           spr_cs;
170
input                           spr_write;
171
input   [31:0]                   spr_addr;
172
input   [31:0]                   spr_dat_i;
173
output  [31:0]                   spr_dat_o;
174
 
175
//
176
// Internal wires and regs
177
//
178
wire    [dw-1:0]         from_rfa;
179
wire    [dw-1:0]         from_rfb;
180
reg     [dw:0]                   dataa_saved;
181
reg     [dw:0]                   datab_saved;
182
wire    [aw-1:0]         rf_addra;
183
wire    [aw-1:0]         rf_addrw;
184
wire    [dw-1:0]         rf_dataw;
185
wire                            rf_we;
186
wire                            spr_valid;
187
wire                            rf_ena;
188
wire                            rf_enb;
189
reg                             rf_we_allow;
190
 
191
// bviyer: replicating the temporary registers and wires to hold the temporary values
192
 
193
wire    [dw-1:0]         from_rfa2;
194
wire    [dw-1:0]         from_rfb2;
195
reg     [dw:0]                   dataa_saved2;
196
reg     [dw:0]                   datab_saved2;
197
wire    [aw-1:0]         rf_addra2;
198
wire    [aw-1:0]         rf_addrw2;
199
wire    [dw-1:0]         rf_dataw2;
200
wire                            rf_we2;
201
wire                            rf_ena2;
202
wire                            rf_enb2;
203
reg                             rf_we_allow2;
204
 
205
 
206
//
207
// SPR access is valid when spr_cs is asserted and
208
// SPR address matches GPR addresses
209
//
210
assign spr_valid = spr_cs & (spr_addr[10:5] == `OR1200_SPR_RF);
211
 
212
//
213
// SPR data output is always from RF A
214
//
215
// bviyer: one thing I am assuming is that teh data to be written to the
216
// special purpose register will never be put in the 2nd slot of the VLIW
217
assign spr_dat_o = from_rfa;
218
 
219
//
220
// Operand A comes from RF or from saved A register
221
//
222
assign dataa = (dataa_saved[32]) ? dataa_saved[31:0] : from_rfa;
223
assign dataa2 = (dataa_saved2[32]) ? dataa_saved2[31:0] : from_rfa2;
224
 
225
//
226
// Operand B comes from RF or from saved B register
227
//
228
assign datab = (datab_saved[32]) ? datab_saved[31:0] : from_rfb;
229
assign datab2 = (datab_saved2[32]) ? datab_saved2[31:0] : from_rfb2;
230
 
231
//
232
// RF A read address is either from SPRS or normal from CPU control
233
//
234
assign rf_addra = (spr_valid & !spr_write) ? spr_addr[4:0] : addra;
235
assign rf_addra2 = (spr_valid & !spr_write) ? spr_addr[4:0] : addra2;
236
 
237
//
238
// RF write address is either from SPRS or normal from CPU control
239
//
240
assign rf_addrw = (spr_valid & spr_write) ? spr_addr[4:0] : addrw;
241
assign rf_addrw2 = (spr_valid & spr_write) ? spr_addr[4:0] : addrw2;
242
 
243
//
244
// RF write data is either from SPRS or normal from CPU datapath
245
//
246
assign rf_dataw = (spr_valid & spr_write) ? spr_dat_i : dataw;
247
 
248
// bviyer
249
assign rf_dataw2 = (spr_valid & spr_write) ? spr_dat_i : dataw2;
250
 
251
//
252
// RF write enable is either from SPRS or normal from CPU control
253
//
254
always @(posedge rst or posedge clk)
255
        if (rst)
256
                rf_we_allow <=  1'b1;
257
        else if (~wb_freeze)
258
                rf_we_allow <=  ~flushpipe;
259
 
260
assign rf_we = ((spr_valid & spr_write) | (we & ~wb_freeze)) & rf_we_allow & (supv | (|rf_addrw));
261
 
262
// bviyer
263
assign rf_we2 = ((spr_valid & spr_write) | (we2 & ~wb_freeze)) & rf_we_allow & (supv | (|rf_addrw2));
264
 
265
//
266
// CS RF A asserted when instruction reads operand A and ID stage
267
// is not stalled
268
//
269
assign rf_ena = rda & ~id_freeze | spr_valid;   // probably works with fixed binutils
270
// assign rf_ena = 1'b1;                        // does not work with single-stepping
271
//assign rf_ena = ~id_freeze | spr_valid;       // works with broken binutils 
272
 
273
 
274
// bviyer
275
assign rf_ena2 = rda2 & ~id_freeze | spr_valid;
276
//
277
// CS RF B asserted when instruction reads operand B and ID stage
278
// is not stalled
279
//
280
assign rf_enb = rdb & ~id_freeze | spr_valid;
281
 
282
// bviyer
283
assign rf_enb2 = rdb2 & ~id_freeze | spr_valid;
284
// assign rf_enb = 1'b1;
285
//assign rf_enb = ~id_freeze | spr_valid;       // works with broken binutils 
286
 
287
//
288
// Stores operand from RF_A into temp reg when pipeline is frozen
289
//
290
always @(posedge clk or posedge rst)
291
        if (rst) begin
292
                dataa_saved <=  33'b0;
293
        end
294
        else if (id_freeze & !dataa_saved[32]) begin
295
                dataa_saved <=  {1'b1, from_rfa};
296
        end
297
        else if (!id_freeze)
298
                dataa_saved <=  33'b0;
299
 
300
//
301
// Stores operand from RF_B into temp reg when pipeline is frozen
302
//
303
always @(posedge clk or posedge rst)
304
        if (rst) begin
305
                datab_saved <=  33'b0;
306
        end
307
        else if (id_freeze & !datab_saved[32]) begin
308
                datab_saved <=  {1'b1, from_rfb};
309
        end
310
        else if (!id_freeze)
311
                datab_saved <=  33'b0;
312
 
313
 
314
 
315
//
316
// Stores operand from RF_A into temp reg when pipeline is frozen
317
//
318
always @(posedge clk or posedge rst)
319
        if (rst) begin
320
                dataa_saved2 <=  33'b0;
321
        end
322
        else if (id_freeze & !dataa_saved[32]) begin
323
                dataa_saved2 <=  {1'b1, from_rfa2};
324
        end
325
        else if (!id_freeze)
326
                dataa_saved2 <=  33'b0;
327
 
328
//
329
// Stores operand from RF_B into temp reg when pipeline is frozen
330
//
331
always @(posedge clk or posedge rst)
332
        if (rst) begin
333
                datab_saved2 <=  33'b0;
334
        end
335
        else if (id_freeze & !datab_saved[32]) begin
336
                datab_saved2 <=  {1'b1, from_rfb2};
337
        end
338
        else if (!id_freeze)
339
                datab_saved2 <=  33'b0;
340
 
341
 
342
`ifdef OR1200_RFRAM_TWOPORT
343
 
344
//
345
// Instantiation of register file two-port RAM A
346
//
347
or1200_tpram_32x32 rf_a(
348
        // Port A
349
        .clk_a(clk),
350
        .rst_a(rst),
351
        .ce_a(rf_ena),
352
        .we_a(1'b0),
353
        .oe_a(1'b1),
354
        .addr_a(rf_addra),
355
        .di_a(32'h0000_0000),
356
        .do_a(from_rfa),
357
 
358
        // Port B
359
        .clk_b(clk),
360
        .rst_b(rst),
361
        .ce_b(rf_we),
362
        .we_b(rf_we),
363
        .oe_b(1'b0),
364
        .addr_b(rf_addrw),
365
        .di_b(rf_dataw),
366
        .do_b()
367
);
368
 
369
//
370
// Instantiation of register file two-port RAM B
371
//
372
or1200_tpram_32x32 rf_b(
373
        // Port A
374
        .clk_a(clk),
375
        .rst_a(rst),
376
        .ce_a(rf_enb),
377
        .we_a(1'b0),
378
        .oe_a(1'b1),
379
        .addr_a(addrb),
380
        .di_a(32'h0000_0000),
381
        .do_a(from_rfb),
382
 
383
        // Port B
384
        .clk_b(clk),
385
        .rst_b(rst),
386
        .ce_b(rf_we),
387
        .we_b(rf_we),
388
        .oe_b(1'b0),
389
        .addr_b(rf_addrw),
390
        .di_b(rf_dataw),
391
        .do_b()
392
);
393
 
394
//
395
// Instantiation of register file two-port RAM A
396
//
397
or1200_tpram_32x32 rf_a2(
398
        // Port A
399
        .clk_a(clk),
400
        .rst_a(rst),
401
        .ce_a(rf_ena2),
402
        .we_a(1'b0),
403
        .oe_a(1'b1),
404
        .addr_a(rf_addra2),
405
        .di_a(32'h0000_0000),
406
        .do_a(from_rfa2),
407
 
408
        // Port B
409
        .clk_b(clk),
410
        .rst_b(rst),
411
        .ce_b(rf_we2),
412
        .we_b(rf_we2),
413
        .oe_b(1'b0),
414
        .addr_b(rf_addrw2),
415
        .di_b(rf_dataw2),
416
        .do_b()
417
);
418
 
419
//
420
// Instantiation of register file two-port RAM B
421
//
422
or1200_tpram_32x32 rf_b2(
423
        // Port A
424
        .clk_a(clk),
425
        .rst_a(rst),
426
        .ce_a(rf_enb2),
427
        .we_a(1'b0),
428
        .oe_a(1'b1),
429
        .addr_a(addrb2),
430
        .di_a(32'h0000_0000),
431
        .do_a(from_rfb2),
432
 
433
        // Port B
434
        .clk_b(clk),
435
        .rst_b(rst),
436
        .ce_b(rf_we2),
437
        .we_b(rf_we2),
438
        .oe_b(1'b0),
439
        .addr_b(rf_addrw2),
440
        .di_b(rf_dataw2),
441
        .do_b()
442
);
443
 
444
`else
445
 
446
`ifdef OR1200_RFRAM_DUALPORT
447
 
448
//
449
// Instantiation of register file two-port RAM A
450
//
451
or1200_dpram_32x32 rf_a(
452
        // Port A
453
        .clk_a(clk),
454
        .rst_a(rst),
455
        .ce_a(rf_ena),
456
        .oe_a(1'b1),
457
        .addr_a(rf_addra),
458
        .do_a(from_rfa),
459
 
460
        // Port B
461
        .clk_b(clk),
462
        .rst_b(rst),
463
        .ce_b(rf_we),
464
        .we_b(rf_we),
465
        .addr_b(rf_addrw),
466
        .di_b(rf_dataw)
467
);
468
 
469
//
470
// Instantiation of register file two-port RAM B
471
//
472
or1200_dpram_32x32 rf_b(
473
        // Port A
474
        .clk_a(clk),
475
        .rst_a(rst),
476
        .ce_a(rf_enb),
477
        .oe_a(1'b1),
478
        .addr_a(addrb),
479
        .do_a(from_rfb),
480
 
481
        // Port B
482
        .clk_b(clk),
483
        .rst_b(rst),
484
        .ce_b(rf_we),
485
        .we_b(rf_we),
486
        .addr_b(rf_addrw),
487
        .di_b(rf_dataw)
488
);
489
 
490
 
491
 
492
// bviyer: I guess the way the implemented the register is by using ram, so what
493
// I m doing is that I am replicating the ram pieces to hold additional read and writes
494
//
495
// Instantiation of register file two-port RAM A
496
//
497
or1200_dpram_32x32 rf_a2(
498
        // Port A
499
        .clk_a(clk),
500
        .rst_a(rst),
501
        .ce_a(rf_ena2),
502
        .oe_a(1'b1),
503
        .addr_a(rf_addra2),
504
        .do_a(from_rfa2),
505
 
506
        // Port B
507
        .clk_b(clk),
508
        .rst_b(rst),
509
        .ce_b(rf_we2),
510
        .we_b(rf_we2),
511
        .addr_b(rf_addrw2),
512
        .di_b(rf_dataw2)
513
);
514
 
515
//
516
// Instantiation of register file two-port RAM B
517
//
518
or1200_dpram_32x32 rf_b2(
519
        // Port A
520
        .clk_a(clk),
521
        .rst_a(rst),
522
        .ce_a(rf_enb2),
523
        .oe_a(1'b1),
524
        .addr_a(addrb2),
525
        .do_a(from_rfb2),
526
 
527
        // Port B
528
        .clk_b(clk),
529
        .rst_b(rst),
530
        .ce_b(rf_we2),
531
        .we_b(rf_we2),
532
        .addr_b(rf_addrw2),
533
        .di_b(rf_dataw2)
534
);
535
 
536
`else
537
 
538
`ifdef OR1200_RFRAM_GENERIC
539
 
540
 
541
//
542
// Instantiation of generic (flip-flop based) register file
543
//
544
or1200_rfram_generic rf_a(
545
        // Clock and reset
546
        .clk(clk),
547
        .rst(rst),
548
 
549
        // Port A
550
        .ce_a(rf_ena),
551
        .addr_a(addra),
552
        .do_a(from_rfa),
553
 
554
        // Port B
555
        .ce_b(rf_enb),
556
        .addr_b(rf_addrb),
557
        .do_b(from_rfb),
558
 
559
        // Port W
560
        .ce_w(rf_we),
561
        .we_w(rf_we),
562
        .addr_w(rf_addrw),
563
        .di_w(rf_dataw)
564
);
565
 
566
or1200_rfram_generic rf_a2(
567
        // Clock and reset
568
        .clk(clk),
569
        .rst(rst),
570
 
571
        // Port A
572
        .ce_a(rf_ena2),
573
        .addr_a(addra2),
574
        .do_a(from_rfa2),
575
 
576
        // Port B
577
        .ce_b(rf_enb2),
578
        .addr_b(rf_addrb2),
579
        .do_b(from_rfb2),
580
 
581
        // Port W
582
        .ce_w(rf_we2),
583
        .we_w(rf_we2),
584
        .addr_w(rf_addrw2),
585
        .di_w(rf_dataw2)
586
);
587
 
588
`else
589
 
590
//
591
// RFRAM type not specified
592
//
593
initial begin
594
        $display("Define RFRAM type.");
595
        $finish;
596
end
597
 
598
`endif
599
`endif
600
`endif
601
 
602
endmodule
603
 
604
/* WHY WHY WHY!!
605
`else
606
 
607
`ifdef OR1200_RFRAM_GENERIC
608
 
609
//
610
// Instantiation of generic (flip-flop based) register file
611
//
612
or1200_rfram_generic rf_a(
613
        // Clock and reset
614
        .clk(clk),
615
        .rst(rst),
616
 
617
        // Port A
618
        .ce_a(rf_ena),
619
        .addr_a(rf_addra),
620
        .do_a(from_rfa),
621
 
622
        // Port B
623
        .ce_b(rf_enb),
624
        .addr_b(addrb),
625
        .do_b(from_rfb),
626
 
627
        // Port W
628
        .ce_w(rf_we),
629
        .we_w(rf_we),
630
        .addr_w(rf_addrw),
631
        .di_w(rf_dataw)
632
);
633
 
634
`else
635
 
636
//
637
// RFRAM type not specified
638
//
639
initial begin
640
        $display("Define RFRAM type.");
641
        $finish;
642
end
643
 
644
`endif
645
`endif
646
`endif
647
 
648
endmodule
649
*/

powered by: WebSVN 2.1.0

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