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

Subversion Repositories 8051

[/] [8051/] [trunk/] [rtl/] [verilog/] [oc8051_icache.v] - Blame information for rev 108

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

Line No. Rev Author Line
1 67 simont
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  8051 instruction cache                                      ////
4
////                                                              ////
5
////  This file is part of the 8051 cores project                 ////
6
////  http://www.opencores.org/cores/8051/                        ////
7
////                                                              ////
8
////  Description                                                 ////
9
////  8051 instruction cache                                      ////
10
////                                                              ////
11
////  To Do:                                                      ////
12
////    nothing                                                   ////
13
////                                                              ////
14
////  Author(s):                                                  ////
15
////      - Simon Teran, simont@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 62 simont
//
44
// CVS Revision History
45
//
46
// $Log: not supported by cvs2svn $
47 108 simont
// Revision 1.5  2003/04/02 11:22:15  simont
48
// fix bug.
49
//
50 94 simont
// Revision 1.4  2003/01/21 14:08:18  simont
51
// fix bugs
52
//
53 88 simont
// Revision 1.3  2003/01/13 14:14:41  simont
54
// replace some modules
55
//
56 82 simont
// Revision 1.2  2002/10/24 13:34:02  simont
57
// add parameters for instruction cache
58
//
59 67 simont
// Revision 1.1  2002/10/23 16:55:36  simont
60
// fix bugs in instruction interface
61 62 simont
//
62 67 simont
//
63 62 simont
 
64
// synopsys translate_off
65
`include "oc8051_timescale.v"
66
// synopsys translate_on
67
 
68
 
69
module oc8051_icache (rst, clk, adr_i, dat_o,stb_i, ack_o, cyc_i,
70
        dat_i, cyc_o, adr_o, ack_i, stb_o);
71
//
72
// rst           (in)  reset - pin
73
// clk           (in)  clock - pini
74
input rst, clk;
75
 
76
//
77
// interface to oc8051 cpu
78
//
79
// adr_i    (in)  address
80
// dat_o    (out) data output
81
// stb_i    (in)  strobe
82
// ack_o    (out) acknowledge
83
// cyc_i    (in)  cycle
84
input stb_i, cyc_i;
85
input [15:0] adr_i;
86
output ack_o;
87
output [31:0] dat_o;
88
reg [31:0] dat_o;
89
 
90
//
91
// interface to instruction rom
92
//
93
// adr_o    (out) address
94
// dat_i    (in)  data input
95
// stb_o    (out) strobe
96
// ack_i    (in) acknowledge
97
// cyc_o    (out)  cycle
98
input ack_i;
99
input [31:0] dat_i;
100
output stb_o, cyc_o;
101
output [15:0] adr_o;
102 67 simont
//reg [15:0] adr_o;
103 62 simont
reg stb_o, cyc_o;
104
 
105 67 simont
parameter ADR_WIDTH = 6; // cache address wihth
106
parameter LINE_WIDTH = 2; // line address width (2 => 4x32)
107
parameter BL_WIDTH = ADR_WIDTH - LINE_WIDTH; // block address width
108
parameter BL_NUM = 15; // number of blocks (2^BL_WIDTH-1)
109
parameter CACHE_RAM = 64; // cache ram x 32 (2^ADR_WIDTH)
110
 
111 62 simont
//
112
// internal buffers adn wires
113
//
114 67 simont
// con_buf control buffer, contains upper addresses [15:ADDR_WIDTH1] in cache
115
reg [13-ADR_WIDTH:0] con_buf [BL_NUM:0];
116 88 simont
// valid[x]=1 if block x is valid;
117
reg [BL_NUM:0] valid;
118 62 simont
// con0, con2 contain temporal control information of current address and corrent address+2
119 67 simont
// part of con_buf memory
120 108 simont
reg [13-ADR_WIDTH:0] con0, con2;
121 67 simont
//current upper address,
122
reg [13-ADR_WIDTH:0] cadr0, cadr2;
123 62 simont
reg stb_b;
124 67 simont
// byte_select in 32 bit line (adr_i[1:0])
125 62 simont
reg [1:0] byte_sel;
126 67 simont
// read cycle
127
reg [LINE_WIDTH-1:0] cyc;
128
// data input from cache ram
129 62 simont
reg [31:0] data1_i;
130 67 simont
// temporaly data from ram
131 62 simont
reg [15:0] tmp_data1;
132
reg wr1, wr1_t, stb_it;
133
 
134 108 simont
////////////////
135
 
136
reg vaild_h, vaild_l;
137
 
138
 
139 62 simont
wire [31:0] data0, data1_o;
140
wire cy, cy1;
141 67 simont
wire [BL_WIDTH-1:0] adr_i2;
142 62 simont
wire hit, hit_l, hit_h;
143 67 simont
wire [ADR_WIDTH-1:0] adr_r, addr1;
144
reg [ADR_WIDTH-1:0] adr_w;
145 62 simont
reg [15:0] mis_adr;
146
wire [15:0] data1;
147 67 simont
wire [LINE_WIDTH-1:0] adr_r1;
148 62 simont
 
149 67 simont
 
150
assign cy = &adr_i[LINE_WIDTH+1:1];
151
assign {cy1, adr_i2} = {1'b0, adr_i[ADR_WIDTH+1:LINE_WIDTH+2]}+cy;
152 108 simont
assign hit_l = (con0==cadr0) & vaild_l;
153
assign hit_h = (con2==cadr2) & vaild_h;
154 62 simont
assign hit = hit_l && hit_h;
155
 
156 67 simont
assign adr_r = adr_i[ADR_WIDTH+1:2] + adr_i[1];
157 62 simont
assign addr1 = wr1 ? adr_w : adr_r;
158 67 simont
assign adr_r1 = adr_r[LINE_WIDTH-1:0] + 2'b01;
159 62 simont
assign ack_o = hit && stb_it;
160
 
161
assign data1 = wr1_t ? tmp_data1 : data1_o[31:16];
162
 
163 67 simont
assign adr_o = {mis_adr[15:LINE_WIDTH+2], cyc, 2'b00};
164
 
165
 
166 108 simont
 
167 67 simont
oc8051_cache_ram oc8051_cache_ram1(.clk(clk), .rst(rst), .addr0(adr_i[ADR_WIDTH+1:2]),
168
       .addr1(addr1), .data0(data0), .data1_o(data1_o), .data1_i(data1_i),
169 62 simont
       .wr1(wr1));
170
 
171 67 simont
defparam oc8051_cache_ram1.ADR_WIDTH = ADR_WIDTH;
172
defparam oc8051_cache_ram1.CACHE_RAM = CACHE_RAM;
173
 
174 108 simont
 
175
 
176
/*
177
generic_dpram #(ADR_WIDTH, 32) oc8051_cache_ram1(
178
        .rclk  ( clk                  ),
179
        .rrst  ( rst                  ),
180
        .rce   ( 1'b1                 ),
181
        .oe    ( 1'b1                 ),
182
        .raddr ( adr_i[ADR_WIDTH+1:2] ),
183
        .do    ( data0                ),
184
 
185
        .wclk  ( clk                  ),
186
        .wrst  ( rst                  ),
187
        .wce   ( 1'b1                 ),
188
        .we    ( wr1                  ),
189
        .waddr ( addr1                ),
190
        .di    ( data1_i              )
191
);
192
*/
193
 
194
 
195
 
196
 
197 62 simont
always @(stb_b or data0 or data1 or byte_sel)
198
begin
199
  if (stb_b) begin
200
    case (byte_sel)
201 88 simont
      2'b00  : dat_o = data0;
202
      2'b01  : dat_o = {data0[23:0], data1[15:8]};
203
      2'b10  : dat_o = {data0[15:0], data1};
204
      default: dat_o = {data0[ 7:0], data1, 8'h00};
205 62 simont
    endcase
206 67 simont
  end else begin
207 62 simont
    dat_o = 32'h0;
208
  end
209
end
210
 
211
always @(posedge clk or posedge rst)
212
begin
213 88 simont
  if (rst)
214
    begin
215
        con0 <= #1 9'h0;
216
        con2 <= #1 9'h0;
217 108 simont
        vaild_h <= #1 1'b0;
218
        vaild_l <= #1 1'b0;
219 88 simont
    end
220
  else
221
    begin
222 108 simont
        con0 <= #1 {con_buf[adr_i[ADR_WIDTH+1:LINE_WIDTH+2]]};
223
        con2 <= #1 {con_buf[adr_i2]};
224
        vaild_l <= #1 valid[adr_i[ADR_WIDTH+1:LINE_WIDTH+2]];
225
        vaild_h <= #1 valid[adr_i2];
226 88 simont
    end
227 62 simont
end
228
 
229
always @(posedge clk or posedge rst)
230
begin
231
  if (rst) begin
232
    cadr0 <= #1 8'h00;
233
    cadr2 <= #1 8'h00;
234
  end else begin
235 67 simont
    cadr0 <= #1 adr_i[15:ADR_WIDTH+2];
236
    cadr2 <= #1 adr_i[15:ADR_WIDTH+2]+ cy1;
237 62 simont
  end
238
end
239
 
240
always @(posedge clk or posedge rst)
241
begin
242
  if (rst) begin
243
    stb_b <= #1 1'b0;
244 67 simont
    byte_sel <= #1 2'b00;
245 62 simont
  end else begin
246
    stb_b <= #1 stb_i;
247
    byte_sel <= #1 adr_i[1:0];
248
  end
249
end
250
 
251
always @(posedge clk or posedge rst)
252
begin
253 88 simont
  if (rst)
254
    begin
255
        cyc    <= #1 2'b00;
256
        cyc_o  <= #1 1'b0;
257
        stb_o  <= #1 1'b0;
258
        data1_i<= #1 32'h0;
259
        wr1    <= #1 1'b0;
260
        adr_w  <= #1 6'h0;
261
        valid  <= #1 16'h0;
262 108 simont
    end
263 88 simont
  else if (stb_b && !hit && !stb_o && !wr1)
264
    begin
265
        cyc     <= #1 2'b00;
266
        cyc_o   <= #1 1'b1;
267
        stb_o   <= #1 1'b1;
268
        data1_i <= #1 32'h0;
269
        wr1     <= #1 1'b0;
270
    end
271
  else if (stb_o && ack_i)
272
    begin
273
        data1_i<= #1 dat_i;
274
        wr1    <= #1 1'b1;
275
        adr_w  <= #1 adr_o[ADR_WIDTH+1:2];
276
 
277
        if (&cyc)
278
          begin
279
              cyc   <= #1 2'b00;
280
              cyc_o <= #1 1'b0;
281
              stb_o <= #1 1'b0;
282
              valid[mis_adr[ADR_WIDTH+1:LINE_WIDTH+2]] <= #1 1'b1;
283
          end
284
        else
285
          begin
286
              cyc   <= #1 cyc + 1'b1;
287
              cyc_o <= #1 1'b1;
288
              stb_o <= #1 1'b1;
289 108 simont
              valid[mis_adr[ADR_WIDTH+1:LINE_WIDTH+2]] <= #1 1'b0;
290 88 simont
          end
291 67 simont
    end
292 88 simont
  else
293 62 simont
    wr1 <= #1 1'b0;
294
end
295
 
296 88 simont
//rih
297
always @(posedge clk)
298 94 simont
  if ( ~(stb_b && !hit && !stb_o && !wr1) & (stb_o && ack_i && cyc) )
299 88 simont
    con_buf[mis_adr[ADR_WIDTH+1:LINE_WIDTH+2]] <= #1 mis_adr[15:ADR_WIDTH+2];
300
 
301
 
302 62 simont
always @(posedge clk or posedge rst)
303
begin
304
  if (rst)
305 88 simont
    mis_adr <= #1 1'b0;
306 62 simont
  else if (!hit_l)
307
    mis_adr <= #1 adr_i;
308
  else if (!hit_h)
309 67 simont
    mis_adr <= #1 adr_i+'d2;
310
end
311 62 simont
 
312
always @(posedge clk or posedge rst)
313
begin
314
  if (rst)
315 88 simont
    tmp_data1 <= #1 1'b0;
316 62 simont
  else if (!hit_h && wr1 && (cyc==adr_r1))
317
    tmp_data1 <= #1 dat_i[31:16];
318
  else if (!hit_l && hit_h && wr1)
319
    tmp_data1 <= #1 data1_o[31:16];
320 67 simont
end
321 62 simont
 
322
always @(posedge clk or posedge rst)
323
begin
324
  if (rst) begin
325
    wr1_t <= #1 1'b0;
326
    stb_it <= #1 1'b0;
327
  end else begin
328
    wr1_t <= #1 wr1;
329 67 simont
    stb_it <= #1 stb_i;
330 62 simont
  end
331
end
332
 
333
endmodule
334 88 simont
 

powered by: WebSVN 2.1.0

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