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 166

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 166 lampret
// Revision 1.1  2001/07/20 00:46:03  lampret
48
// Development version of RTL. Libraries are missing.
49 161 lampret
//
50 166 lampret
//
51 161 lampret
 
52
`include "general.h"
53
 
54
// Data cache
55
 
56
module dc(clk, rst, clkdiv_by_2, dcbiu_rdy, dclsu_addr, dclsu_lsuop, dclsu_datain, dcbiu_datain,
57 166 lampret
        dclsu_dataout, dcbiu_dataout, dcbiu_addr, dcbiu_read, dcbiu_write, dclsu_stall, dcbiu_sel,
58 161 lampret
        tp2w, tp3w, tpdw
59
);
60
 
61
parameter dw = `OPERAND_WIDTH;
62
 
63
input clk;
64
input rst;
65
input clkdiv_by_2;
66
input dcbiu_rdy;
67
input [31:0] dclsu_addr;
68
input [`LSUOP_WIDTH-1:0] dclsu_lsuop;
69
input [dw-1:0] dclsu_datain;
70
input [dw-1:0] dcbiu_datain;
71
 
72
output [dw-1:0] dclsu_dataout;
73
output [dw-1:0] dcbiu_dataout;
74
output [31:0] dcbiu_addr;
75
output dcbiu_read;
76
output dcbiu_write;
77
output dclsu_stall;
78 166 lampret
output [3:0] dcbiu_sel;
79 161 lampret
 
80
input [`TP2W_WIDTH-1:0] tp2w;
81
input [`TP3W_WIDTH-1:0] tp3w;
82
input [31:0] tpdw;
83
 
84
wire [18:0] tag;
85
wire [dw-1:0] to_dcram;
86
wire [dw-1:0] from_dcram;
87
wire [dw-1:0] to_mem2reg;
88
wire [31:0] saved_addr;
89
wire refill;
90
wire [3:0] dcram_we;
91
wire dctag_we;
92
wire [dw-1:0] lsu_datain_memaligned;
93
wire [31:0] dc_addr;
94
wire refill_first;
95
wire refill_prepare;
96
wire refill_start;
97
wire refill_rest;
98 166 lampret
wire [`LSUOP_WIDTH-1:0] dcfsm_lsuop;
99
wire dcfsm_read;
100
wire dcfsm_write;
101
wire dc_en;
102
wire [1:0] mem2reg_addr;
103 161 lampret
 
104
reg hit;
105
reg [1:0] valid_div;
106 166 lampret
reg [3:0] dcbiu_sel;
107
reg [1:0] bypass_wait;
108 161 lampret
 
109
wire queue;
110
wire cntrbusy;
111
wire dcbiu_valid;
112
 
113
assign dcbiu_addr = dc_addr;
114
assign dctag_we = refill;
115 166 lampret
assign dcbiu_dataout = (dc_en) ? from_dcram : lsu_datain_memaligned;
116 161 lampret
 
117 166 lampret
// Bypases of DC
118
assign dc_en = 1'b0;
119
assign dcfsm_lsuop = (dc_en) ? dclsu_lsuop : `LSUOP_NOP;
120
assign dcbiu_read = (dc_en) ? dcfsm_read : (dclsu_lsuop && ~dclsu_lsuop[3]);
121
assign dcbiu_write = (dc_en) ? dcfsm_write : (dclsu_lsuop && dclsu_lsuop[3]);
122
always @(dc_en or dclsu_lsuop or dclsu_addr)
123
        casex({dc_en, dclsu_lsuop, dclsu_addr[1:0]})
124
                {1'b0, `LSUOP_SB, 2'b00} : dcbiu_sel <= #1 4'b1000;
125
                {1'b0, `LSUOP_SB, 2'b01} : dcbiu_sel <= #1 4'b0100;
126
                {1'b0, `LSUOP_SB, 2'b10} : dcbiu_sel <= #1 4'b0010;
127
                {1'b0, `LSUOP_SB, 2'b11} : dcbiu_sel <= #1 4'b0001;
128
                {1'b0, `LSUOP_SH, 2'b00} : dcbiu_sel <= #1 4'b1100;
129
                {1'b0, `LSUOP_SH, 2'b10} : dcbiu_sel <= #1 4'b0011;
130
                {1'b0, `LSUOP_SW, 2'b00} : dcbiu_sel <= #1 4'b1111;
131
                {1'b0, `LSUOP_LBZ, 2'b00}, {1'b0, `LSUOP_LBS, 2'b00} : dcbiu_sel <= #1 4'b1000;
132
                {1'b0, `LSUOP_LBZ, 2'b01}, {1'b0, `LSUOP_LBS, 2'b01} : dcbiu_sel <= #1 4'b0100;
133
                {1'b0, `LSUOP_LBZ, 2'b10}, {1'b0, `LSUOP_LBS, 2'b10} : dcbiu_sel <= #1 4'b0010;
134
                {1'b0, `LSUOP_LBZ, 2'b11}, {1'b0, `LSUOP_LBS, 2'b11} : dcbiu_sel <= #1 4'b0001;
135
                {1'b0, `LSUOP_LHZ, 2'b00}, {1'b0, `LSUOP_LHS, 2'b00} : dcbiu_sel <= #1 4'b1100;
136
                {1'b0, `LSUOP_LHZ, 2'b10}, {1'b0, `LSUOP_LHS, 2'b10} : dcbiu_sel <= #1 4'b0011;
137
                {1'b0, `LSUOP_LWZ, 2'b00}, {1'b0, `LSUOP_LWS, 2'b00} : dcbiu_sel <= #1 4'b1111;
138
                7'b1xxxxxx : dcbiu_sel <= #1 4'b1111;
139
                default : dcbiu_sel <= #1 4'b0000;
140
        endcase
141 161 lampret
 
142 166 lampret
assign mem2reg_addr = (dc_en) ? saved_addr[1:0] : dclsu_addr[1:0];
143
 
144
// Wait for DC bypass acess
145
always @(posedge rst or posedge clk)
146
        if (rst)
147
                bypass_wait <= #1 2'b0;
148
        else if (dcbiu_valid)
149
                bypass_wait <= #1 2'b0;
150
        else if (dcbiu_read | dcbiu_write)
151
                bypass_wait <= #1 {bypass_wait, 1'b1};
152
        else
153
                bypass_wait <= #1 2'b00;
154
 
155
// assign dc_stall = dcfsm_read | dcfsm_write | refill_start;  // can't remember if it works
156
assign queue = (refill && dcfsm_lsuop && !refill_first & !refill_rest) ? 1'b1 : 1'b0;
157
 
158 161 lampret
// assign dclsu_stall = refill_start | (refill_first & ~dcbiu_valid)| refill_rest | queue;  // kind of working
159 166 lampret
assign dclsu_stall = refill_start | (refill_first & ~dcbiu_valid)| refill_rest | queue | cntrbusy | (~dc_en & bypass_wait[1] & ~dcbiu_valid);
160 161 lampret
 
161
// Select between claddr generated by DC FSM and addr[3:2] generated by LSU
162
assign dc_addr = (refill == 1'b1) ? saved_addr : dclsu_addr;
163
 
164
// Select between input data generated by LSU or by BIU
165
assign to_dcram = (refill == 1'b1) ? dcbiu_datain : lsu_datain_memaligned;
166
 
167
// Select between data generated by DCRAM or passed by BIU
168 166 lampret
assign to_mem2reg = (refill_first == 1'b1) | (~dc_en) ? dcbiu_datain : from_dcram;
169 161 lampret
 
170
// Tag comparison
171
always @(tag or saved_addr) begin
172
        if (tag == saved_addr[31:13])
173
                hit <= #1 1'b1;
174
        else
175
                hit <= #1 1'b0;
176
end
177
 
178
// Valid_div counts RISC clock cycles by modulo 4
179
always @(posedge clk or posedge rst)
180
        if (rst)
181
                valid_div <= #1 2'b0;
182
        else
183
                valid_div <= #1 valid_div + 'd1;
184
 
185
// dcbiu_valid is one RISC clock cycle long dcbiu_rdy.
186
// dcbiu_rdy is two or four RISC clock cycles long because memory
187
// controller works at 1/2 or 1/4 of RISC clock freq (at 1/2 if
188
// clkdiv_by_2 is asserted).
189
assign dcbiu_valid = dcbiu_rdy & (valid_div[1] | clkdiv_by_2) & valid_div[0];
190
 
191
// Generate refill_start that signals to frz_logic a cache linefill is about to begin
192
assign refill_start = (refill_prepare & ~hit) ? 1'b1 : 1'b0;
193
 
194
dtlb dtlb(
195
        .clk(clk),
196
        .rst(rst),
197
        .we(1'b0),
198
        .tlb_en(1'b1),
199
        .datain(dclsu_datain),
200
        .vaddr(saved_addr),
201
        .paddr(),
202
        .cache_en(),
203
        .tlb_miss(),
204
        .tp3w(tp3w),
205
        .tpdw(tpdw)
206
);
207
 
208
dc_fsm dc_fsm(
209
        .clk(clk),
210
        .rst(rst),
211 166 lampret
        .lsu_op(dcfsm_lsuop),
212 161 lampret
        .miss(~hit),
213
        .biudata_valid(dcbiu_valid),
214
        .start_addr(dclsu_addr),
215
        .saved_addr(saved_addr),
216
        .refill(refill),
217
        .refill_first(refill_first),
218
        .refill_prepare(refill_prepare),
219
        .dcram_we(dcram_we),
220 166 lampret
        .biu_read(dcfsm_read),
221
        .biu_write(dcfsm_write),
222 161 lampret
        .refill_rest(refill_rest),
223
        .cntrbusy(cntrbusy)
224
);
225
 
226
// Regfile-to-memory aligner
227
reg2mem reg2mem(
228
        .addr(dc_addr[1:0]),
229
        .lsu_op(dclsu_lsuop),
230
        .regdata(dclsu_datain),
231
        .memdata(lsu_datain_memaligned)
232
);
233
 
234
dc_ram dc_ram(
235
        .clk(clk),
236
        .addr(dc_addr[12:2]),
237
        .we(dcram_we),
238
        .datain(to_dcram),
239
        .dataout(from_dcram),
240
        .tp2w(tp2w),
241
        .tpdw(tpdw)
242
);
243
 
244
dc_tag dc_tag(
245
        .clk(clk),
246
        .addr(dc_addr[12:4]),
247
        .we(dctag_we),
248
        .datain(dc_addr[31:13]),
249
        .dataout(tag),
250
        .tp2w(tp2w),
251
        .tpdw(tpdw)
252
);
253
 
254
// Memory-to-regfile aligner
255
mem2reg mem2reg(
256 166 lampret
        .addr(mem2reg_addr[1:0]),
257 161 lampret
        .lsu_op(dclsu_lsuop),
258
        .memdata(to_mem2reg),
259
        .regdata(dclsu_dataout)
260
);
261
 
262
endmodule

powered by: WebSVN 2.1.0

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