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

Subversion Repositories 8051

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

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

powered by: WebSVN 2.1.0

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