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

Subversion Repositories m32632

[/] [m32632/] [trunk/] [rtl/] [ICACHE_SM.v] - Blame information for rev 23

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

Line No. Rev Author Line
1 9 ns32kum
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2
//
3
// This file is part of the M32632 project
4
// http://opencores.org/project,m32632
5
//
6 23 ns32kum
//      Filename:       ICACHE_SM.v
7
//      Version:        2.0
8
//      History:        1.0 first release of 30 Mai 2015
9
//      Date:           14 August 2016
10 9 ns32kum
//
11 23 ns32kum
// Copyright (C) 2016 Udo Moeller
12 9 ns32kum
// 
13
// This source file may be used and distributed without 
14
// restriction provided that this copyright statement is not 
15
// removed from the file and that any derivative work contains 
16
// the original copyright notice and the associated disclaimer.
17
// 
18
// This source file is free software; you can redistribute it 
19
// and/or modify it under the terms of the GNU Lesser General 
20
// Public License as published by the Free Software Foundation;
21
// either version 2.1 of the License, or (at your option) any 
22
// later version. 
23
// 
24
// This source is distributed in the hope that it will be 
25
// useful, but WITHOUT ANY WARRANTY; without even the implied 
26
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
27
// PURPOSE. See the GNU Lesser General Public License for more 
28
// details. 
29
// 
30
// You should have received a copy of the GNU Lesser General 
31
// Public License along with this source; if not, download it 
32
// from http://www.opencores.org/lgpl.shtml 
33
// 
34
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
35
//
36
//      Modules contained in this file:
37
//      1. KOLDETECT    Collision Detection Unit
38
//      2. ICACHE_SM    Instruction Cache State Machine
39
//
40 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
41 9 ns32kum
 
42 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
43 9 ns32kum
//
44
//      1. KOLDETECT    Collision Detection Unit
45
//
46 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
47
module KOLDETECT ( BCLK, BRESET, DRAM_WR, CVALID, ADDR, TAG0, TAG1 , CFG , C_VALID, READ_I, ACC_OK, HOLD, KDET, INVAL_A, ENA_HK,
48 9 ns32kum
                                   NEWCVAL, KOLLISION, STOP_ICRD, RUN_ICRD, KILL, KILLADR, ICTODC, STOP_CINV );
49
 
50
        input                   BCLK;
51
        input                   BRESET;
52
        input                   DRAM_WR;
53
        input   [23:0]   CVALID;         // Data from master Valid RAM
54
        input   [27:4]  ADDR;
55
        input  [27:12]  TAG0,TAG1;
56
        input    [1:0]   CFG;
57
        input   [23:0]   C_VALID;        // Data from secondary Valid RAM
58
        input                   READ_I;
59
        input                   ACC_OK;
60
        input                   HOLD;           // active low
61
        input                   KDET;
62
        input                   INVAL_A;        // Cache Invalidate All
63
        input                   ENA_HK;         // Enable HOLD and Kohaerenz
64
 
65
        output  [23:0]   NEWCVAL;
66
        output                  KOLLISION;
67
        output                  STOP_ICRD;
68
        output                  RUN_ICRD;
69
        output                  KILL;
70
        output  [11:7]  KILLADR;
71
        output   [2:0]   ICTODC;
72
        output                  STOP_CINV;
73
 
74
        reg             [27:4]  addr_r;
75 23 ns32kum
        reg              [7:0]   clear;
76 9 ns32kum
        reg                             do_koll;
77
        reg              [2:0]   counter;
78
        reg              [1:0]   wpointer,rpointer;
79
        reg             [35:0]   adrfifo;
80
        reg              [8:0]   fifo_q,fifo_c;
81
        reg              [1:0]   state;
82
        reg                             pipe;
83
        reg                             do_kill;
84
        reg                             dma;
85
 
86
        wire    [7:0]    set_0,set_1;
87
        wire                    match_0,match_1;
88
        wire                    valid_0,valid_1;
89
        wire                    found_0,found_1;
90
        wire                    kolli,dma_kolli;
91
        wire                    last_match;
92
        wire                    wr_entry;
93
        wire    [23:0]   cdaten;
94
        wire     [8:0]   kaddr;
95
        wire     [7:0]   new_0,new_1;
96
        wire                    dma_mode,ic_dma;
97
        wire                    free,ende;
98
        wire                    init_b;
99
 
100 11 ns32kum
        always @(posedge BCLK) do_koll <= DRAM_WR & CFG[0];      // one cycle pulse, without Cache Enable no collision
101 9 ns32kum
        always @(posedge BCLK) addr_r <= ADDR;
102
 
103
        // similar logic like in CA_MATCH
104
 
105
        assign set_0 = C_VALID[7:0];
106
        assign set_1 = C_VALID[15:8];
107
 
108
        assign valid_0 = set_0[addr_r[6:4]];
109
        assign valid_1 = set_1[addr_r[6:4]];
110
 
111
        assign match_0 = ( TAG0 == addr_r[27:12] );     // 4KB
112
        assign match_1 = ( TAG1 == addr_r[27:12] );     // 4KB
113
 
114
        assign found_0 = valid_0 & match_0;
115
        assign found_1 = valid_1 & match_1;
116
 
117
        assign kolli = (found_0 | found_1) & ~CFG[1] & do_koll; // Action only if ICACHE is not locked
118
 
119
        assign KOLLISION = (found_0 | found_1) & do_koll;       // to Statistik Modul, Register there
120
 
121
        assign dma_kolli = (found_0 | found_1) & ~CFG[1] & CFG[0];
122
 
123
        // the FIFO with 4 entries :
124
        assign init_b = CFG[0] & ~INVAL_A;       // initialise if CINV A too
125
 
126
        always @(posedge BCLK)
127
                if (!init_b) wpointer <= 2'b00;
128
                        else
129
                                wpointer <= wpointer + {1'b0,wr_entry};
130
 
131
        always @(posedge BCLK)
132
                if (!init_b) rpointer <= 2'b00;
133
                        else
134
                                rpointer <= rpointer + {1'b0,do_kill};
135
 
136
        always @(posedge BCLK)
137
          begin
138
                if (wr_entry && (wpointer == 2'b00)) adrfifo[8:0]   <= {addr_r[11:4],found_1};
139
                if (wr_entry && (wpointer == 2'b01)) adrfifo[17:9]  <= {addr_r[11:4],found_1};
140
                if (wr_entry && (wpointer == 2'b10)) adrfifo[26:18] <= {addr_r[11:4],found_1};
141
                if (wr_entry && (wpointer == 2'b11)) adrfifo[35:27] <= {addr_r[11:4],found_1};
142
          end
143
 
144
        always @(adrfifo or rpointer)
145
                case (rpointer)
146
                  2'b00 : fifo_q = adrfifo[8:0];
147
                  2'b01 : fifo_q = adrfifo[17:9];
148
                  2'b10 : fifo_q = adrfifo[26:18];
149
                  2'b11 : fifo_q = adrfifo[35:27];
150
                endcase
151
 
152
        always @(adrfifo or wpointer)   // for Match of last entry use wpointer
153
                case (wpointer)
154
                  2'b01 : fifo_c = adrfifo[8:0];
155
                  2'b10 : fifo_c = adrfifo[17:9];
156
                  2'b11 : fifo_c = adrfifo[26:18];
157
                  2'b00 : fifo_c = adrfifo[35:27];
158
                endcase
159
 
160
        // Control
161
 
162 11 ns32kum
        assign last_match = counter[2] & (fifo_c == {addr_r[11:4],found_1});    // if Match with last Entry no new Entry
163 9 ns32kum
 
164
        assign wr_entry = kolli & ~last_match;
165
 
166
        always @(posedge BCLK)
167
                casex ({init_b,wr_entry,do_kill,counter})
168
                  6'b0_xx_xxx : counter <= 3'b000;
169
                  6'b1_00_xxx : counter <= counter;
170
                  6'b1_11_xxx : counter <= counter;
171
                  6'b1_10_000 : counter <= 3'b100;
172 11 ns32kum
                  6'b1_10_1xx : counter <= (counter[1:0] == 2'b11) ? 3'b111 : {counter[2],(counter[1:0] + 2'b01)};        // Overflow avoid
173 9 ns32kum
                  6'b1_01_1xx : counter <= (counter[1:0] == 2'b00) ? 3'b000 : {counter[2],(counter[1:0] + 2'b11)};
174
                  default         : counter <= counter;
175
                endcase
176
 
177
        // DMA Access
178
        always @(posedge BCLK) dma <= ~HOLD;    // there is only one FF for this , from here to DCACHE
179
 
180
        // Controlling of ICACHE
181
 
182
        assign free = (~READ_I | ACC_OK) & ENA_HK;      // switch off if CINV
183
 
184
        always @(posedge BCLK)                                  //  state[1]  state[0]
185
                casex ({BRESET,dma,counter[2],free,ende,STOP_ICRD,dma_mode})
186
                  7'b0_xx_xx_xx : state <= 2'b00;
187
                  7'b1_00_xx_00 : state <= 2'b00;
188
                  7'b1_01_1x_00 : state <= 2'b10;       // Start of DCACHE Kohaerenz
189
                  7'b1_1x_1x_00 : state <= 2'b11;       // Start of DMA
190
        //
191
                  7'b1_xx_x0_10 : state <= 2'b10;       // without "ende" it stays as is
192
                  7'b1_0x_x1_10 : state <= 2'b00;       // DMA is not active
193
                  7'b1_1x_x1_10 : state <= 2'b11;       // to DMA !
194
        //
195
                  7'b1_00_xx_11 : state <= 2'b00;
196
                  7'b1_01_xx_11 : state <= 2'b10;
197
                  7'b1_1x_xx_11 : state <= 2'b11;
198
                  default               : state <= 2'b00;
199
                endcase
200
 
201
        assign STOP_ICRD = state[1];    // used for Multiplexer
202
        assign dma_mode  = state[0];     // internal Multiplexer
203
 
204
        assign STOP_CINV = state[1] & ~ENA_HK;  // stops CINV if DMA access or Kohaerenz access
205
 
206
        assign ende = (counter[1:0] == 2'b00) & do_kill;
207
 
208
        assign ic_dma = STOP_ICRD & dma_mode;   // Signal to DCACHE that ICACHE has stoped
209
 
210
        always @(posedge BCLK) pipe <= STOP_ICRD;
211
 
212
        assign RUN_ICRD = ~(STOP_ICRD | pipe);  // Release for IC_READ
213
 
214 11 ns32kum
        always @(posedge BCLK) do_kill <= STOP_ICRD & ~dma_mode & ~do_kill;     // Write pulse in Cache Valid RAM, 1 cycle on, 1 cycle off
215 9 ns32kum
 
216
        assign KILL = do_kill | (KDET & dma_kolli);
217
 
218
        // Valid Daten prepare : different sources for DMA and DCACHE Kohaerenz
219
 
220
        assign cdaten = dma_mode ? C_VALID : CVALID;
221
        assign kaddr  = dma_mode ? {addr_r[11:4],found_1} : fifo_q;
222
 
223
        assign KILLADR = kaddr[8:4];
224
 
225
        always @(kaddr)
226
                case (kaddr[3:1])
227
                  3'h0 : clear = 8'hFE;
228
                  3'h1 : clear = 8'hFD;
229
                  3'h2 : clear = 8'hFB;
230
                  3'h3 : clear = 8'hF7;
231
                  3'h4 : clear = 8'hEF;
232
                  3'h5 : clear = 8'hDF;
233
                  3'h6 : clear = 8'hBF;
234
                  3'h7 : clear = 8'h7F;
235
                endcase
236
 
237
        assign new_0 = kaddr[0] ? cdaten[7:0] : (cdaten[7:0] & clear);
238
        assign new_1 = kaddr[0] ? (cdaten[15:8] & clear) : cdaten[15:8];
239
 
240
        assign NEWCVAL = {cdaten[23:16],new_1,new_0};
241
 
242
        // multiple signals are needed in DCACHE :
243
        assign ICTODC = {dma,ic_dma,~(counter[2:1] == 2'b11)};
244
 
245
endmodule
246
 
247 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
248 9 ns32kum
//
249
//      2. ICACHE_SM    Instruction Cache State Machine
250
//
251 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
252 9 ns32kum
module ICACHE_SM ( BCLK, BRESET, IO_SPACE, MDONE, IO_READY, MMU_HIT, CA_HIT, READ, PTE_ACC,
253
                                   USE_CA, PTB_WR, PTB_SEL, USER, PROT_ERROR,
254
                                   DRAM_ACC, IO_RD, IO_ACC, IC_PREQ, ACC_OK, HIT_ALL, CUPDATE, AUX_DAT, NEW_PTB, PTB_ONE );
255
 
256
        input                   BCLK;
257
        input                   BRESET;
258
        input                   IO_SPACE;
259
        input                   MDONE;          // Memory Done : Feedback from DRAM Controller, BCLK aligned
260
        input                   IO_READY;
261
        input                   MMU_HIT,CA_HIT;
262
        input                   READ;
263
        input                   PTE_ACC;
264
        input                   USE_CA;
265
        input                   PTB_WR,PTB_SEL;
266
        input                   USER;
267
        input                   PROT_ERROR;
268
 
269
        output  reg             DRAM_ACC,IO_RD;
270
        output                  IO_ACC;
271
        output                  IC_PREQ;
272
        output                  ACC_OK;
273
        output                  HIT_ALL;
274
        output                  CUPDATE;
275
        output                  AUX_DAT;
276
        output  reg             NEW_PTB,PTB_ONE;
277
 
278
        reg              [3:0]   new_state;
279
        reg                             rd_done;
280
        reg                             card_flag;
281
        reg                             rd_rdy;
282
 
283
        wire                    io_busy;
284
        wire                    dram_go;
285
        wire                    rd_ende;
286
        wire                    do_ca_rd;
287
 
288
// Cycle :                      /-\_/-\_/-\_/-\_/-\_/-\_/-\_/-\_/-\_/-\_
289
// Access :                     _/-----------------------------------\__
290
// State Machine :  ____/----------------------------\______
291
//                                                      Busy status ...
292
 
293
        assign rd_ende = CA_HIT | rd_rdy;       // CA_HIT only if Cache activ !
294
 
295
        always @(        READ           // only READ , global control
296
                          or PROT_ERROR // is not allowed !
297
                        //
298
                          or IO_SPACE   // indicates access in the IO_WELT
299
                          or io_busy    // is already active ?
300
                        //
301
                          or MMU_HIT    // Hit in the MMU , now only a READ can be active
302
                          or rd_ende    // Cache Hit
303
                          or DRAM_ACC   // DRAM Access running
304
                        //
305
                          or PTE_ACC )  // PTE Access running
306
                        //                                #_#                      #_#                                          #_#
307
                casex ({READ,PROT_ERROR,IO_SPACE,io_busy,MMU_HIT,rd_ende,DRAM_ACC,PTE_ACC})
308
                // MMU Miss : PTE load from memory 
309
                  8'b10_xx_0xx_0 : new_state = 4'b0100; // start PTE access
310
                // IO-Address selected : external access starts if not already BUSY
311
                  8'b10_10_1xx_x : new_state = 4'b0001;
312
                // DRAM Access : Cache Miss at READ
313
                  8'b10_0x_100_x : new_state = 4'b1010; // can start directly
314
                  default                : new_state = 4'b0;
315
                endcase
316
 
317
        assign IO_ACC   = new_state[0];  // to load the Register for Data and Addr
318
        assign dram_go  = new_state[1];
319
        assign IC_PREQ  = new_state[2]; // MMU to DCACHE !
320
        assign do_ca_rd = new_state[3];
321
 
322
        assign HIT_ALL = MMU_HIT & CA_HIT;      // for Update "Last-Set" , MMU_HIT contains ZUGRIFF
323
 
324
        always @(posedge BCLK or negedge BRESET)
325
                if (!BRESET) card_flag <= 1'b0;
326
                        else card_flag <= (do_ca_rd & ~rd_rdy) | (card_flag & ~MDONE);
327
 
328
        assign CUPDATE = card_flag & USE_CA & MDONE;    // USE_CA = ~CI & ~LDC;
329
 
330
        always @(posedge BCLK) rd_rdy <= card_flag & MDONE;
331
 
332 11 ns32kum
        // The cache RAM can not provide fast enough the data after an Update. In this case a secondary data path is activated
333 9 ns32kum
        assign AUX_DAT = rd_rdy;
334
 
335
        // DRAM Interface :
336
 
337
        always @(posedge BCLK) if (dram_go) DRAM_ACC <= 1'b1;
338
                                                         else
339
                                                                DRAM_ACC <= DRAM_ACC & ~MDONE & BRESET;
340
        // IO Interface :
341
 
342
        always @(posedge BCLK)
343
          begin
344
                if (IO_ACC) IO_RD <= READ;  else IO_RD <= IO_RD & ~IO_READY & BRESET;
345
          end
346
 
347 11 ns32kum
        assign io_busy = IO_RD | rd_done;       // access is gone in next clock cycle, therefore blocked with "rd_done"
348 9 ns32kum
 
349 11 ns32kum
        always @(posedge BCLK) rd_done <= READ & IO_READY;      // For READ one clock later for data to come through
350 9 ns32kum
 
351
        // global feedback to opcode fetch unit : you can continue
352
 
353
        assign ACC_OK = IO_SPACE ? rd_done : (READ & MMU_HIT & rd_ende);
354
 
355
        // PTB1 und PTB0
356
 
357
        always @(posedge BCLK) NEW_PTB <= PTB_WR;                       // to MMU Update Block
358
        always @(posedge BCLK) if (PTB_WR) PTB_ONE <= PTB_SEL;
359
 
360
endmodule

powered by: WebSVN 2.1.0

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