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

Subversion Repositories or1k

[/] [or1k/] [branches/] [mp3_stable/] [or1200/] [rtl/] [verilog/] [dc.v] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 218 lampret
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  OR1200's Data Cache top level                               ////
4
////                                                              ////
5
////  This file is part of the OpenRISC 1200 project              ////
6
////  http://www.opencores.org/cores/or1k/                        ////
7
////                                                              ////
8
////  Description                                                 ////
9
////  Instantiation of all DC blocks.                             ////
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
// CVS Revision History
45
//
46
// $Log: not supported by cvs2svn $
47
// Revision 1.9  2001/10/14 13:12:09  lampret
48
// MP3 version.
49
//
50
// Revision 1.1.1.1  2001/10/06 10:18:35  igorm
51
// no message
52
//
53
// Revision 1.4  2001/08/13 03:36:20  lampret
54
// Added cfg regs. Moved all defines into one defines.v file. More cleanup.
55
//
56
// Revision 1.3  2001/08/09 13:39:33  lampret
57
// Major clean-up.
58
//
59
// Revision 1.2  2001/07/22 03:31:53  lampret
60
// Fixed RAM's oen bug. Cache bypass under development.
61
//
62
// Revision 1.1  2001/07/20 00:46:03  lampret
63
// Development version of RTL. Libraries are missing.
64
//
65
//
66
 
67
// synopsys translate_off
68
`include "timescale.v"
69
// synopsys translate_on
70
`include "defines.v"
71
 
72
//
73
// Data cache
74
//
75
 
76
module dc(
77
        // Rst, clk and clock control
78
        clk, rst, clkdiv_by_2,
79
 
80
        // External i/f
81
        dcbiu_rdy, dcbiu_datain, dcbiu_dataout, dcbiu_addr, dcbiu_read, dcbiu_write, dcbiu_sel,
82
 
83
        // Internal i/f
84
        dc_en, dclsu_addr, dclsu_lsuop, dclsu_datain, dclsu_dataout, dclsu_stall, dclsu_unstall,
85
 
86
        // SPRs
87
        spr_cs, spr_write, spr_dat_i
88
);
89
 
90
parameter dw = `OPERAND_WIDTH;
91
 
92
//
93
// I/O
94
//
95
 
96
//
97
// Clock and reset
98
//
99
input                           clk;
100
input                           rst;
101
input                           clkdiv_by_2;
102
 
103
//
104
// External I/F
105
//
106
input                           dcbiu_rdy;
107
input   [dw-1:0]         dcbiu_datain;
108
output  [31:0]                   dcbiu_addr;
109
output                          dcbiu_read;
110
output                          dcbiu_write;
111
output  [3:0]                    dcbiu_sel;
112
 
113
//
114
// Internal I/F
115
//
116
input                           dc_en;
117
input   [31:0]                   dclsu_addr;
118
input   [`LSUOP_WIDTH-1:0]       dclsu_lsuop;
119
input   [dw-1:0]         dclsu_datain;
120
output  [dw-1:0]         dclsu_dataout;
121
output  [dw-1:0]         dcbiu_dataout;
122
output                          dclsu_stall;
123
output                          dclsu_unstall;
124
 
125
//
126
// SPR access
127
//
128
input                           spr_cs;
129
input                           spr_write;
130
input   [31:0]                   spr_dat_i;
131
 
132
//
133
// Internal wires and regs
134
//
135
wire                            tag_v;
136
wire    [18:0]                   tag;
137
wire    [dw-1:0]         to_dcram;
138
wire    [dw-1:0]         from_dcram;
139
wire    [dw-1:0]         to_mem2reg;
140
wire    [31:0]                   saved_addr;
141
wire                            refill;
142
wire    [3:0]                    dcram_we;
143
wire                            dctag_we;
144
wire    [dw-1:0]         lsu_datain_memaligned;
145
wire    [31:0]                   dc_addr;
146
wire                            refill_first;
147
wire                            refill_prepare;
148
wire                            refill_start;
149
wire                            refill_rest;
150
wire    [`LSUOP_WIDTH-1:0]       dcfsm_lsuop;
151
wire                            dcfsm_read;
152
wire                            dcfsm_write;
153
wire    [1:0]                    mem2reg_addr;
154
reg                             hit;
155
reg     [1:0]                    valid_div;
156
reg     [3:0]                    dcbiu_sel;
157
reg     [1:0]                    bypass_wait;
158
wire                            queue;
159
wire                            cntrbusy;
160
wire                            dcbiu_valid;
161
wire    [12:4]                  dctag_addr;
162
wire                            dctag_en;
163
wire                            dctag_v;
164
wire                            dc_inv;
165
 
166
//
167
// Simple assignments
168
//
169
assign dcbiu_addr = dc_addr;
170
assign dclsu_unstall = dcbiu_rdy;
171
assign dc_inv = spr_cs & spr_write;
172
assign dctag_we = refill | dc_inv;
173
assign dctag_addr = dc_inv ? spr_dat_i[12:4] : dc_addr[12:4];
174
assign dctag_en = dc_inv | dc_en;
175
assign dctag_v = ~dc_inv;
176
 
177
//
178
// Data to BIU is from DCRAM when DC is enabled or from LSU when
179
// DC is disabled
180
//
181
assign dcbiu_dataout = (dc_en) ? from_dcram : lsu_datain_memaligned;
182
 
183
//
184
// Bypases of the DC when DC is disabled
185
//
186
assign dcfsm_lsuop = (dc_en) ? dclsu_lsuop : `LSUOP_NOP;
187
assign dcbiu_read = (dc_en) ? dcfsm_read : ((|dclsu_lsuop) && ~dclsu_lsuop[3]);
188
assign dcbiu_write = (dc_en) ? dcfsm_write : ((|dclsu_lsuop) && dclsu_lsuop[3]);
189
always @(dc_en or dclsu_lsuop or dclsu_addr)
190
        casex({dc_en, dclsu_lsuop, dclsu_addr[1:0]})
191
                {1'b0, `LSUOP_SB, 2'b00} : dcbiu_sel = 4'b1000;
192
                {1'b0, `LSUOP_SB, 2'b01} : dcbiu_sel = 4'b0100;
193
                {1'b0, `LSUOP_SB, 2'b10} : dcbiu_sel = 4'b0010;
194
                {1'b0, `LSUOP_SB, 2'b11} : dcbiu_sel = 4'b0001;
195
                {1'b0, `LSUOP_SH, 2'b00} : dcbiu_sel = 4'b1100;
196
                {1'b0, `LSUOP_SH, 2'b10} : dcbiu_sel = 4'b0011;
197
                {1'b0, `LSUOP_SW, 2'b00} : dcbiu_sel = 4'b1111;
198
                {1'b0, `LSUOP_LBZ, 2'b00}, {1'b0, `LSUOP_LBS, 2'b00} : dcbiu_sel = 4'b1000;
199
                {1'b0, `LSUOP_LBZ, 2'b01}, {1'b0, `LSUOP_LBS, 2'b01} : dcbiu_sel = 4'b0100;
200
                {1'b0, `LSUOP_LBZ, 2'b10}, {1'b0, `LSUOP_LBS, 2'b10} : dcbiu_sel = 4'b0010;
201
                {1'b0, `LSUOP_LBZ, 2'b11}, {1'b0, `LSUOP_LBS, 2'b11} : dcbiu_sel = 4'b0001;
202
                {1'b0, `LSUOP_LHZ, 2'b00}, {1'b0, `LSUOP_LHS, 2'b00} : dcbiu_sel = 4'b1100;
203
                {1'b0, `LSUOP_LHZ, 2'b10}, {1'b0, `LSUOP_LHS, 2'b10} : dcbiu_sel = 4'b0011;
204
                {1'b0, `LSUOP_LWZ, 2'b00}, {1'b0, `LSUOP_LWS, 2'b00} : dcbiu_sel = 4'b1111;
205
                7'b1xxxxxx : dcbiu_sel = 4'b1111;
206
                default : dcbiu_sel = 4'b0000;
207
        endcase
208
 
209
assign mem2reg_addr = (dc_en) ? saved_addr[1:0] : dclsu_addr[1:0];
210
 
211
//
212
// Wait for DC bypass access
213
//
214
always @(posedge rst or posedge clk)
215
        if (rst)
216
                bypass_wait <= #1 2'b00;
217
        else if (dcbiu_valid)
218
                bypass_wait <= #1 2'b00;
219
        else if (dcbiu_read | dcbiu_write)
220
                bypass_wait <= #1 {bypass_wait[0], 1'b1};
221
        else
222
                bypass_wait <= #1 2'b00;
223
 
224
//
225
// Queue
226
//
227
assign queue = (refill && (|dcfsm_lsuop) && !refill_first && !refill_rest) ? 1'b1 : 1'b0;
228
 
229
//
230
// DC/LSU stall
231
//
232
//assign dclsu_stall = refill_start | (refill_first & ~dcbiu_valid)| refill_rest | queue | cntrbusy | (~dc_en & bypass_wait[1] & ~dcbiu_valid);
233
assign dclsu_stall = refill_start | (refill_first & ~dcbiu_valid)| refill_rest | queue | cntrbusy | (~dc_en & (dcbiu_read | dcbiu_write) & ~dcbiu_rdy);
234
 
235
//
236
// Select between claddr generated by DC FSM and addr[3:2] generated by LSU
237
//
238
assign dc_addr = (refill == 1'b1) ? saved_addr : dclsu_addr;
239
 
240
//
241
// Select between input data generated by LSU or by BIU
242
//
243
assign to_dcram = (refill == 1'b1) ? dcbiu_datain : lsu_datain_memaligned;
244
 
245
//
246
// Select between data generated by DCRAM or passed by BIU
247
//
248
assign to_mem2reg = (refill_first == 1'b1) | (~dc_en) ? dcbiu_datain : from_dcram;
249
 
250
//
251
// Tag comparison
252
//
253
always @(tag or saved_addr or tag_v) begin
254
        if ((tag == saved_addr[31:13]) && tag_v)
255
                hit = 1'b1;
256
        else
257
                hit = 1'b0;
258
end
259
 
260
//
261
// Valid_div counts RISC clock cycles by modulo 4
262
//
263
always @(posedge clk or posedge rst)
264
        if (rst)
265
                valid_div <= #1 2'b0;
266
        else
267
                valid_div <= #1 valid_div + 'd1;
268
 
269
//
270
// dcbiu_valid is one RISC clock cycle long dcbiu_rdy.
271
// dcbiu_rdy is two or four RISC clock cycles long because memory
272
// controller works at 1/2 or 1/4 of RISC clock freq (at 1/2 if
273
// clkdiv_by_2 is asserted).
274
//
275
assign dcbiu_valid = dcbiu_rdy & (valid_div[1] | clkdiv_by_2) & valid_div[0];
276
 
277
//
278
// Generate refill_start that signals to frz_logic a cache linefill is about to begin
279
//
280
assign refill_start = (refill_prepare & ~hit) ? 1'b1 : 1'b0;
281
 
282
//
283
// Instantiation of DC Finite State Machine
284
//
285
dc_fsm dc_fsm(
286
        .clk(clk),
287
        .rst(rst),
288
        .lsu_op(dcfsm_lsuop),
289
        .miss(~hit),
290
        .biudata_valid(dcbiu_valid),
291
        .start_addr(dclsu_addr),
292
        .saved_addr(saved_addr),
293
        .refill(refill),
294
        .refill_first(refill_first),
295
        .refill_prepare(refill_prepare),
296
        .dcram_we(dcram_we),
297
        .biu_read(dcfsm_read),
298
        .biu_write(dcfsm_write),
299
        .refill_rest(refill_rest),
300
        .cntrbusy(cntrbusy)
301
);
302
 
303
//
304
// Instantiation of Regfile-to-memory aligner
305
//
306
reg2mem reg2mem(
307
        .addr(dc_addr[1:0]),
308
        .lsu_op(dclsu_lsuop),
309
        .regdata(dclsu_datain),
310
        .memdata(lsu_datain_memaligned)
311
);
312
 
313
//
314
// Instantiation of DC main memory
315
//
316
dc_ram dc_ram(
317
        .clk(clk),
318
        .rst(rst),
319
        .addr(dc_addr[12:2]),
320
        .en(dc_en),
321
        .we(dcram_we),
322
        .datain(to_dcram),
323
        .dataout(from_dcram)
324
);
325
 
326
//
327
// Instantiation of DC TAG memory
328
//
329
dc_tag dc_tag(
330
        .clk(clk),
331
        .rst(rst),
332
        .addr(dctag_addr),
333
        .en(dctag_en),
334
        .we(dctag_we),
335
        .datain({dc_addr[31:13], dctag_v}),
336
        .tag_v(tag_v),
337
        .tag(tag)
338
);
339
 
340
//
341
// Instatiation of Memory-to-regfile aligner
342
//
343
mem2reg mem2reg(
344
        .addr(mem2reg_addr[1:0]),
345
        .lsu_op(dclsu_lsuop),
346
        .memdata(to_mem2reg),
347
        .regdata(dclsu_dataout)
348
);
349
 
350
endmodule

powered by: WebSVN 2.1.0

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