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 170

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

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

powered by: WebSVN 2.1.0

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