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

Subversion Repositories m32632

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

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

powered by: WebSVN 2.1.0

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