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

Subversion Repositories 8051

[/] [8051/] [tags/] [rel_12/] [rtl/] [verilog/] [oc8051_icache.v] - Blame information for rev 67

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

powered by: WebSVN 2.1.0

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