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

Subversion Repositories next186_soc_pc

[/] [next186_soc_pc/] [trunk/] [HW/] [cache_controller.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ndumitrach
//////////////////////////////////////////////////////////////////////////////////
2
//
3
// This file is part of the Next186 Soc PC project
4
// http://opencores.org/project,next186
5
//
6
// Filename: cache_controller.v
7
// Description: Part of the Next186 SoC PC project, cache controller
8
// Version 1.0
9
// Creation date: Jan2012
10
//
11
// Author: Nicolae Dumitrache 
12
// e-mail: ndumitrache@opencores.org
13
//
14
/////////////////////////////////////////////////////////////////////////////////
15
// 
16
// Copyright (C) 2012 Nicolae Dumitrache
17
// 
18
// This source file may be used and distributed without 
19
// restriction provided that this copyright statement is not 
20
// removed from the file and that any derivative work contains 
21
// the original copyright notice and the associated disclaimer.
22
// 
23
// This source file is free software; you can redistribute it 
24
// and/or modify it under the terms of the GNU Lesser General 
25
// Public License as published by the Free Software Foundation;
26
// either version 2.1 of the License, or (at your option) any 
27
// later version. 
28
// 
29
// This source is distributed in the hope that it will be 
30
// useful, but WITHOUT ANY WARRANTY; without even the implied 
31
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
32
// PURPOSE. See the GNU Lesser General Public License for more 
33
// details. 
34
// 
35
// You should have received a copy of the GNU Lesser General 
36
// Public License along with this source; if not, download it 
37
// from http://www.opencores.org/lgpl.shtml 
38
// 
39
///////////////////////////////////////////////////////////////////////////////////
40
// Additional Comments: 
41
//
42
// 8 lines of 256bytes each
43
// preloaded with bootstrap code (last 4 lines)
44
//////////////////////////////////////////////////////////////////////////////////
45
 
46
`timescale 1ns / 1ps
47
 
48
 
49
module cache_controller(
50
    input [19:0] addr,
51
    output [31:0] dout,
52
         input [31:0]din,
53
         input clk,     // 3xCLK
54
         input mreq,
55
         input wr,
56
         input [3:0]wmask,
57
         output ce,     // clock enable for CPU
58
         input [31:0]ddr_din,
59
         output [31:0]ddr_dout,
60
         input ddr_clk,
61
         input cache_write_data, // 1 when data must be written to cache, on posedge ddr_clk
62
         input [5:0]lowaddr,
63
         output reg ddr_rd = 0,
64
         output reg ddr_wr = 0,
65
         output reg [11:0] waddr
66
    );
67
 
68
        wire [7:0]fit;
69
        wire [7:0]free;
70
        reg [15:0]cache0 = 16'h0000; // 8'b:addr, 3'b:count, 1'b:dirty
71
        reg [15:0]cache1 = 16'h0012; // 8'b:addr, 3'b:count, 1'b:dirty
72
        reg [15:0]cache2 = 16'h0024; // 8'b:addr, 3'b:count, 1'b:dirty
73
        reg [15:0]cache3 = 16'h0036; // 8'b:addr, 3'b:count, 1'b:dirty
74
        reg [15:0]cache4 = 16'hffc9; // 8'b:addr, 3'b:count, 1'b:dirty
75
        reg [15:0]cache5 = 16'hffdb; // 8'b:addr, 3'b:count, 1'b:dirty
76
        reg [15:0]cache6 = 16'hffed; // 8'b:addr, 3'b:count, 1'b:dirty
77
        reg [15:0]cache7 = 16'hffff; // 8'b:addr, 3'b:count, 1'b:dirty
78
 
79
        reg dirty;
80
        reg [2:0]STATE = 0;
81
        reg ps_lowaddr5 = 0;
82
        reg s_lowaddr5 = 0;
83
 
84
        assign fit[0] = cache0[15:4] == addr[19:8];
85
        assign fit[1] = cache1[15:4] == addr[19:8];
86
        assign fit[2] = cache2[15:4] == addr[19:8];
87
        assign fit[3] = cache3[15:4] == addr[19:8];
88
        assign fit[4] = cache4[15:4] == addr[19:8];
89
        assign fit[5] = cache5[15:4] == addr[19:8];
90
        assign fit[6] = cache6[15:4] == addr[19:8];
91
        assign fit[7] = cache7[15:4] == addr[19:8];
92
 
93
        assign free[0] = cache0[3:1] == 3'b000;
94
   assign free[1] = cache1[3:1] == 3'b000;
95
   assign free[2] = cache2[3:1] == 3'b000;
96
   assign free[3] = cache3[3:1] == 3'b000;
97
   assign free[4] = cache4[3:1] == 3'b000;
98
   assign free[5] = cache5[3:1] == 3'b000;
99
   assign free[6] = cache6[3:1] == 3'b000;
100
   assign free[7] = cache7[3:1] == 3'b000;
101
 
102
        wire hit = |fit;
103
        wire st0 = STATE == 0;
104
        assign ce = st0 && (~mreq || hit);
105
 
106
        wire [2:0]blk =  {fit[4] | fit[5] | fit[6] | fit[7], fit[2] | fit[3] | fit[6] | fit[7], fit[1] | fit[3] | fit[5] | fit[7]};
107
        wire [2:0]fblk = {free[4] | free[5] | free[6] | free[7], free[2] | free[3] | free[6] | free[7], free[1] | free[3] | free[5] | free[7]};
108
        wire [2:0]csblk = ({3{fit[0]}} & cache0[3:1]) | ({3{fit[1]}} & cache1[3:1]) |
109
                                                        ({3{fit[2]}} & cache2[3:1]) | ({3{fit[3]}} & cache3[3:1]) |
110
                                                        ({3{fit[4]}} & cache4[3:1]) | ({3{fit[5]}} & cache5[3:1]) |
111
                                                        ({3{fit[6]}} & cache6[3:1]) | ({3{fit[7]}} & cache7[3:1]);
112
 
113
        cache cache_mem (
114
          .clka(ddr_clk), // input clka
115
          .wea({4{cache_write_data}}), // input [3 : 0] wea
116
          .addra({blk, lowaddr}), // input [8 : 0] addra
117
          .dina(ddr_din), // input [31 : 0] dina
118
          .douta(ddr_dout), // output [31 : 0] douta
119
          .clkb(clk), // input clkb
120
          .enb(mreq & hit & st0),
121
          .web(wmask), // input [3 : 0] web
122
          .addrb({blk, addr[7:2]}), // input [8 : 0] addrb
123
          .dinb(din), // input [31 : 0] dinb
124
          .doutb(dout) // output [31 : 0] doutb
125
        );
126
 
127
 
128
        always @(cache0, cache1, cache2, cache3, cache4, cache5, cache6, cache7) begin
129
                dirty = 1'bx;
130
                case(1)
131
                        free[0]: begin dirty = cache0[0]; end
132
                        free[1]:        begin dirty = cache1[0]; end
133
                        free[2]:        begin dirty = cache2[0]; end
134
                        free[3]:        begin dirty = cache3[0]; end
135
                        free[4]:        begin dirty = cache4[0]; end
136
                        free[5]:        begin dirty = cache5[0]; end
137
                        free[6]:        begin dirty = cache6[0]; end
138
                        free[7]:        begin dirty = cache7[0]; end
139
                endcase
140
        end
141
 
142
 
143
        always @(posedge clk) begin
144
                ps_lowaddr5 <= lowaddr[5];
145
                s_lowaddr5 <= ps_lowaddr5;
146
 
147
                case(STATE)
148
                        3'b000: begin
149
                                if(mreq) begin
150
                                        if(hit) begin   // cache hit
151
                                                cache0[3:1] <= fit[0] ? 3'b111 : cache0[3:1] - (cache0[3:1] > csblk);
152
                                                cache1[3:1] <= fit[1] ? 3'b111 : cache1[3:1] - (cache1[3:1] > csblk);
153
                                                cache2[3:1] <= fit[2] ? 3'b111 : cache2[3:1] - (cache2[3:1] > csblk);
154
                                                cache3[3:1] <= fit[3] ? 3'b111 : cache3[3:1] - (cache3[3:1] > csblk);
155
                                                cache4[3:1] <= fit[4] ? 3'b111 : cache4[3:1] - (cache4[3:1] > csblk);
156
                                                cache5[3:1] <= fit[5] ? 3'b111 : cache5[3:1] - (cache5[3:1] > csblk);
157
                                                cache6[3:1] <= fit[6] ? 3'b111 : cache6[3:1] - (cache6[3:1] > csblk);
158
                                                cache7[3:1] <= fit[7] ? 3'b111 : cache7[3:1] - (cache7[3:1] > csblk);
159
                                        end else begin  // cache miss
160
                                                case(fblk)      // free block
161
                                                        0:       begin waddr <= cache0[15:4]; cache0[15:4] <= addr[19:8]; end
162
                                                        1:      begin waddr <= cache1[15:4]; cache1[15:4] <= addr[19:8]; end
163
                                                        2:      begin waddr <= cache2[15:4]; cache2[15:4] <= addr[19:8]; end
164
                                                        3:      begin waddr <= cache3[15:4]; cache3[15:4] <= addr[19:8]; end
165
                                                        4:      begin waddr <= cache4[15:4]; cache4[15:4] <= addr[19:8]; end
166
                                                        5:      begin waddr <= cache5[15:4]; cache5[15:4] <= addr[19:8]; end
167
                                                        6:      begin waddr <= cache6[15:4]; cache6[15:4] <= addr[19:8]; end
168
                                                        7:      begin waddr <= cache7[15:4]; cache7[15:4] <= addr[19:8]; end
169
                                                endcase
170
                                                ddr_rd <= ~dirty;
171
                                                ddr_wr <= dirty;
172
                                                STATE <= dirty ? 3'b011 : 3'b100;
173
                                        end
174
                                        if(hit) case(1) // free or hit block
175
                                                fit[0]: cache0[0] <= (cache0[0] | wr);
176
                                                fit[1]: cache1[0] <= (cache1[0] | wr);
177
                                                fit[2]: cache2[0] <= (cache2[0] | wr);
178
                                                fit[3]: cache3[0] <= (cache3[0] | wr);
179
                                                fit[4]: cache4[0] <= (cache4[0] | wr);
180
                                                fit[5]: cache5[0] <= (cache5[0] | wr);
181
                                                fit[6]: cache6[0] <= (cache6[0] | wr);
182
                                                fit[7]: cache7[0] <= (cache7[0] | wr);
183
                                        endcase else case(1)
184
                                                free[0]: cache0[0] <= 0;
185
                                                free[1]: cache1[0] <= 0;
186
                                                free[2]: cache2[0] <= 0;
187
                                                free[3]: cache3[0] <= 0;
188
                                                free[4]: cache4[0] <= 0;
189
                                                free[5]: cache5[0] <= 0;
190
                                                free[6]: cache6[0] <= 0;
191
                                                free[7]: cache7[0] <= 0;
192
                                        endcase
193
                                end
194
                        end
195
                        3'b011: begin   // write cache to ddr
196
                                ddr_rd <= 1'b1;
197
                                if(s_lowaddr5) begin
198
                                        ddr_wr <= 1'b0;
199
                                        STATE <= 3'b111;
200
                                end
201
                        end
202
                        3'b111: begin // read cache from ddr
203
                                if(~s_lowaddr5) STATE <= 3'b100;
204
                        end
205
                        3'b100: begin
206
                                if(s_lowaddr5) STATE <= 3'b101;
207
                        end
208
                        3'b101: begin
209
                                ddr_rd <= 1'b0;
210
                                if(~s_lowaddr5) STATE <= 3'b000;
211
                        end
212
                endcase
213
        end
214
 
215
endmodule
216
 
217
module seg_map(
218
         input CLK,
219
         input [3:0]addr,
220
         output [9:0]rdata,
221
         input [9:0]wdata,
222
         input [3:0]addr1,
223
         output [9:0]data1,
224
         input WE
225
    );
226
 
227
 RAM16X1D #(.INIT(16'haaaa) ) RAM16X1D_inst0
228
 (
229
      .DPO(data1[0]),     // Read-only 1-bit data output for DPRA
230
      .SPO(rdata[0]),     // Rw/ 1-bit data output for A0-A3
231
      .A0(addr[0]),       // Rw/ address[0] input bit
232
      .A1(addr[1]),       // Rw/ address[1] input bit
233
      .A2(addr[2]),       // Rw/ address[2] input bit
234
      .A3(addr[3]),       // Rw/ address[3] input bit
235
      .D(wdata[0]),         // Write 1-bit data input
236
      .DPRA0(addr1[0]), // Read address[0] input bit
237
      .DPRA1(addr1[1]), // Read address[1] input bit
238
      .DPRA2(addr1[2]), // Read address[2] input bit
239
      .DPRA3(addr1[3]), // Read address[3] input bit
240
      .WCLK(CLK),   // Write clock input
241
      .WE(WE)        // Write enable input
242
   );
243
 
244
 RAM16X1D #(.INIT(16'hcccc) ) RAM16X1D_inst1
245
 (
246
      .DPO(data1[1]),     // Read-only 1-bit data output for DPRA
247
      .SPO(rdata[1]),     // Rw/ 1-bit data output for A0-A3
248
      .A0(addr[0]),       // Rw/ address[0] input bit
249
      .A1(addr[1]),       // Rw/ address[1] input bit
250
      .A2(addr[2]),       // Rw/ address[2] input bit
251
      .A3(addr[3]),       // Rw/ address[3] input bit
252
      .D(wdata[1]),         // Write 1-bit data input
253
      .DPRA0(addr1[0]), // Read address[0] input bit
254
      .DPRA1(addr1[1]), // Read address[1] input bit
255
      .DPRA2(addr1[2]), // Read address[2] input bit
256
      .DPRA3(addr1[3]), // Read address[3] input bit
257
      .WCLK(CLK),   // Write clock input
258
      .WE(WE)        // Write enable input
259
   );
260
 
261
 RAM16X1D #(.INIT(16'hf0f0) ) RAM16X1D_inst2
262
 (
263
      .DPO(data1[2]),     // Read-only 1-bit data output for DPRA
264
      .SPO(rdata[2]),     // Rw/ 1-bit data output for A0-A3
265
      .A0(addr[0]),       // Rw/ address[0] input bit
266
      .A1(addr[1]),       // Rw/ address[1] input bit
267
      .A2(addr[2]),       // Rw/ address[2] input bit
268
      .A3(addr[3]),       // Rw/ address[3] input bit
269
      .D(wdata[2]),         // Write 1-bit data input
270
      .DPRA0(addr1[0]), // Read address[0] input bit
271
      .DPRA1(addr1[1]), // Read address[1] input bit
272
      .DPRA2(addr1[2]), // Read address[2] input bit
273
      .DPRA3(addr1[3]), // Read address[3] input bit
274
      .WCLK(CLK),   // Write clock input
275
      .WE(WE)        // Write enable input
276
   );
277
 
278
 RAM16X1D #(.INIT(16'hff00) ) RAM16X1D_inst3
279
 (
280
      .DPO(data1[3]),     // Read-only 1-bit data output for DPRA
281
      .SPO(rdata[3]),     // Rw/ 1-bit data output for A0-A3
282
      .A0(addr[0]),       // Rw/ address[0] input bit
283
      .A1(addr[1]),       // Rw/ address[1] input bit
284
      .A2(addr[2]),       // Rw/ address[2] input bit
285
      .A3(addr[3]),       // Rw/ address[3] input bit
286
      .D(wdata[3]),         // Write 1-bit data input
287
      .DPRA0(addr1[0]), // Read address[0] input bit
288
      .DPRA1(addr1[1]), // Read address[1] input bit
289
      .DPRA2(addr1[2]), // Read address[2] input bit
290
      .DPRA3(addr1[3]), // Read address[3] input bit
291
      .WCLK(CLK),   // Write clock input
292
      .WE(WE)        // Write enable input
293
   );
294
 
295
 
296
 RAM16X1D #(.INIT(16'h0000) ) RAM16X1D_inst4
297
 (
298
      .DPO(data1[4]),     // Read-only 1-bit data output for DPRA
299
      .SPO(rdata[4]),     // Rw/ 1-bit data output for A0-A3
300
      .A0(addr[0]),       // Rw/ address[0] input bit
301
      .A1(addr[1]),       // Rw/ address[1] input bit
302
      .A2(addr[2]),       // Rw/ address[2] input bit
303
      .A3(addr[3]),       // Rw/ address[3] input bit
304
      .D(wdata[4]),         // Write 1-bit data input
305
      .DPRA0(addr1[0]), // Read address[0] input bit
306
      .DPRA1(addr1[1]), // Read address[1] input bit
307
      .DPRA2(addr1[2]), // Read address[2] input bit
308
      .DPRA3(addr1[3]), // Read address[3] input bit
309
      .WCLK(CLK),   // Write clock input
310
      .WE(WE)        // Write enable input
311
   );
312
 
313
 RAM16X1D #(.INIT(16'h0000) ) RAM16X1D_inst5
314
 (
315
      .DPO(data1[5]),     // Read-only 1-bit data output for DPRA
316
      .SPO(rdata[5]),     // Rw/ 1-bit data output for A0-A3
317
      .A0(addr[0]),       // Rw/ address[0] input bit
318
      .A1(addr[1]),       // Rw/ address[1] input bit
319
      .A2(addr[2]),       // Rw/ address[2] input bit
320
      .A3(addr[3]),       // Rw/ address[3] input bit
321
      .D(wdata[5]),         // Write 1-bit data input
322
      .DPRA0(addr1[0]), // Read address[0] input bit
323
      .DPRA1(addr1[1]), // Read address[1] input bit
324
      .DPRA2(addr1[2]), // Read address[2] input bit
325
      .DPRA3(addr1[3]), // Read address[3] input bit
326
      .WCLK(CLK),   // Write clock input
327
      .WE(WE)        // Write enable input
328
   );
329
 
330
 RAM16X1D #(.INIT(16'h0000) ) RAM16X1D_inst6
331
 (
332
      .DPO(data1[6]),     // Read-only 1-bit data output for DPRA
333
      .SPO(rdata[6]),     // Rw/ 1-bit data output for A0-A3
334
      .A0(addr[0]),       // Rw/ address[0] input bit
335
      .A1(addr[1]),       // Rw/ address[1] input bit
336
      .A2(addr[2]),       // Rw/ address[2] input bit
337
      .A3(addr[3]),       // Rw/ address[3] input bit
338
      .D(wdata[6]),         // Write 1-bit data input
339
      .DPRA0(addr1[0]), // Read address[0] input bit
340
      .DPRA1(addr1[1]), // Read address[1] input bit
341
      .DPRA2(addr1[2]), // Read address[2] input bit
342
      .DPRA3(addr1[3]), // Read address[3] input bit
343
      .WCLK(CLK),   // Write clock input
344
      .WE(WE)        // Write enable input
345
   );
346
 
347
 RAM16X1D #(.INIT(16'h0000) ) RAM16X1D_inst7
348
 (
349
      .DPO(data1[7]),     // Read-only 1-bit data output for DPRA
350
      .SPO(rdata[7]),     // Rw/ 1-bit data output for A0-A3
351
      .A0(addr[0]),       // Rw/ address[0] input bit
352
      .A1(addr[1]),       // Rw/ address[1] input bit
353
      .A2(addr[2]),       // Rw/ address[2] input bit
354
      .A3(addr[3]),       // Rw/ address[3] input bit
355
      .D(wdata[7]),         // Write 1-bit data input
356
      .DPRA0(addr1[0]), // Read address[0] input bit
357
      .DPRA1(addr1[1]), // Read address[1] input bit
358
      .DPRA2(addr1[2]), // Read address[2] input bit
359
      .DPRA3(addr1[3]), // Read address[3] input bit
360
      .WCLK(CLK),   // Write clock input
361
      .WE(WE)        // Write enable input
362
   );
363
 
364
 RAM16X1D #(.INIT(16'h0000) ) RAM16X1D_inst8
365
 (
366
      .DPO(data1[8]),     // Read-only 1-bit data output for DPRA
367
      .SPO(rdata[8]),     // Rw/ 1-bit data output for A0-A3
368
      .A0(addr[0]),       // Rw/ address[0] input bit
369
      .A1(addr[1]),       // Rw/ address[1] input bit
370
      .A2(addr[2]),       // Rw/ address[2] input bit
371
      .A3(addr[3]),       // Rw/ address[3] input bit
372
      .D(wdata[8]),         // Write 1-bit data input
373
      .DPRA0(addr1[0]), // Read address[0] input bit
374
      .DPRA1(addr1[1]), // Read address[1] input bit
375
      .DPRA2(addr1[2]), // Read address[2] input bit
376
      .DPRA3(addr1[3]), // Read address[3] input bit
377
      .WCLK(CLK),   // Write clock input
378
      .WE(WE)        // Write enable input
379
   );
380
 
381
 RAM16X1D #(.INIT(16'h0000) ) RAM16X1D_inst9
382
 (
383
      .DPO(data1[9]),     // Read-only 1-bit data output for DPRA
384
      .SPO(rdata[9]),     // Rw/ 1-bit data output for A0-A3
385
      .A0(addr[0]),       // Rw/ address[0] input bit
386
      .A1(addr[1]),       // Rw/ address[1] input bit
387
      .A2(addr[2]),       // Rw/ address[2] input bit
388
      .A3(addr[3]),       // Rw/ address[3] input bit
389
      .D(wdata[9]),         // Write 1-bit data input
390
      .DPRA0(addr1[0]), // Read address[0] input bit
391
      .DPRA1(addr1[1]), // Read address[1] input bit
392
      .DPRA2(addr1[2]), // Read address[2] input bit
393
      .DPRA3(addr1[3]), // Read address[3] input bit
394
      .WCLK(CLK),   // Write clock input
395
      .WE(WE)        // Write enable input
396
   );
397
endmodule

powered by: WebSVN 2.1.0

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