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

Subversion Repositories m32632

[/] [m32632/] [trunk/] [rtl/] [CACHE_LOGIK.v] - Blame information for rev 47

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

Line No. Rev Author Line
1 29 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 9 ns32kum
//
3
// This file is part of the M32632 project
4
// http://opencores.org/project,m32632
5
//
6 23 ns32kum
//      Filename:       CACHE_LOGIK.v
7 29 ns32kum
//  Version:    3.0
8
//      History:        2.0 of 11 August 2016
9
//                              1.1 bug fix of 7 October 2015
10 23 ns32kum
//                              1.0 first release of 30 Mai 2015
11 29 ns32kum
//      Date:           2 December 2018
12 9 ns32kum
//
13 29 ns32kum
// Copyright (C) 2018 Udo Moeller
14 9 ns32kum
// 
15
// This source file may be used and distributed without 
16
// restriction provided that this copyright statement is not 
17
// removed from the file and that any derivative work contains 
18
// the original copyright notice and the associated disclaimer.
19
// 
20
// This source file is free software; you can redistribute it 
21
// and/or modify it under the terms of the GNU Lesser General 
22
// Public License as published by the Free Software Foundation;
23
// either version 2.1 of the License, or (at your option) any 
24
// later version. 
25
// 
26
// This source is distributed in the hope that it will be 
27
// useful, but WITHOUT ANY WARRANTY; without even the implied 
28
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
29
// PURPOSE. See the GNU Lesser General Public License for more 
30
// details. 
31
// 
32
// You should have received a copy of the GNU Lesser General 
33
// Public License along with this source; if not, download it 
34
// from http://www.opencores.org/lgpl.shtml 
35
// 
36 29 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
37 9 ns32kum
//
38
//      Modules contained in this file:
39 29 ns32kum
//      1. WRPORT               Write Port
40
//      2. NEU_VALID    Cache Valid RAM
41
//      3. DEBUG_AE     Debug unit for address compare in data cache
42
//      4. MMU_UP               MMU memory update and initalization controller
43
//      5. DCA_CONTROL  Data cache valid memory update and initalization controller
44
//      6. MMU_MATCH    MMU virtual address match detector
45
//      7. CA_MATCH             Cache tag match detector
46
//      8. FILTCMP              Address Filter and Comparator
47
//      9. DCACHE_SM    Data cache state machine
48 9 ns32kum
//
49 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
50 9 ns32kum
 
51 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
52 9 ns32kum
//
53 29 ns32kum
//      1. WRPORT       Write Port
54 9 ns32kum
//
55 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
56 29 ns32kum
module WRPORT ( WRITE, DRAM_Q, WRDATA, ENBYTE, VADDR, DADDR, WDAT, CAP_Q, ENB );
57
 
58
        input                   WRITE;
59
        input  [127:0]   DRAM_Q;
60
        input   [31:0]   WRDATA;
61
        input    [3:0]   ENBYTE;
62
        input    [3:2]  VADDR;
63
        input    [3:2]  DADDR;
64
 
65
        output [127:0]   WDAT;
66
 
67
        output  reg     [31:0]   CAP_Q;
68
        output  reg     [15:0]   ENB;
69
 
70
        assign WDAT = WRITE ? {WRDATA,WRDATA,WRDATA,WRDATA} : DRAM_Q;
71
 
72
        always @(DADDR or DRAM_Q)
73
          case (DADDR)
74
            2'b00 : CAP_Q = DRAM_Q[31:0];
75
                2'b01 : CAP_Q = DRAM_Q[63:32];
76
                2'b10 : CAP_Q = DRAM_Q[95:64];
77
                2'b11 : CAP_Q = DRAM_Q[127:96];
78
          endcase
79
 
80
        always @(WRITE or VADDR or ENBYTE)
81
          case ({WRITE,VADDR})
82
             3'b100 : ENB = {4'd0  ,4'd0  ,4'd0  ,ENBYTE};
83
             3'b101 : ENB = {4'd0  ,4'd0  ,ENBYTE,4'd0  };
84
             3'b110 : ENB = {4'd0  ,ENBYTE,4'd0  ,4'd0  };
85
             3'b111 : ENB = {ENBYTE,4'd0  ,4'd0  ,4'd0  };
86
                default : ENB = 16'hFFFF;
87
          endcase
88
 
89
endmodule
90
 
91
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
92
//
93
//      2. NEU_VALID    Cache Valid RAM
94
//
95
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
96 23 ns32kum
module NEU_VALID ( BCLK, VALIN, WADR, WREN, RADR, VALOUT );
97
 
98
        input                   BCLK;
99
        input   [23:0]   VALIN;
100
        input    [4:0]   WADR;
101
        input                   WREN;
102
        input    [4:0]   RADR;
103
 
104
        output  [23:0]   VALOUT;
105
 
106
        reg             [23:0]   cvalid [0:31];   // Valid bits for Data Set 0 and 1 : 32 entries of 24 bits
107
        reg             [23:0]   ramout;
108
        reg             [23:0]   valhold;
109
        reg                             gleich;
110
 
111
        always @(posedge BCLK) ramout <= cvalid[RADR];
112
        always @(posedge BCLK) if (WREN) cvalid[WADR] <= VALIN;
113
 
114
        always @(posedge BCLK) valhold <= VALIN;
115
        always @(posedge BCLK) gleich  <= WREN & (RADR == WADR);
116
 
117
        assign VALOUT = gleich ? valhold : ramout;
118
 
119
endmodule
120
 
121
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
122
//
123 29 ns32kum
//      3. DEBUG_AE     Debug unit for address compare in data cache
124 23 ns32kum
//
125
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
126 9 ns32kum
module DEBUG_AE ( DBG_IN, READ, WRITE, USER, VIRTUELL, ACC_OK, VADR_R, MMU_Q, ENBYTE, DBG_HIT );
127
 
128
        input   [40:2]  DBG_IN;
129
 
130
        input                   READ,WRITE;
131
        input                   USER;
132
        input                   VIRTUELL;
133
        input                   ACC_OK;
134
        input   [31:2]  VADR_R;
135
        input   [19:0]   MMU_Q;
136
        input    [3:0]   ENBYTE;
137
 
138
        output                  DBG_HIT;
139
 
140
        wire                    sd,ud,crd,cwr,vnp;
141
        wire                    make;
142
        wire                    virt_adr,real_adr,page_adr;
143
        wire                    byte_en;
144
 
145
        assign sd  = DBG_IN[40];
146
        assign ud  = DBG_IN[39];
147
        assign crd = DBG_IN[38];
148
        assign cwr = DBG_IN[37];
149
        assign vnp = DBG_IN[36];
150
 
151
        assign make =  ((ud & USER) | (sd & ~USER))             // compare USER or SUPERVISOR
152
                                 & (VIRTUELL == vnp)                            // compare real or virtual address
153
                                 & ((cwr & WRITE) | (crd & READ));      // compare READ or WRITE
154
 
155
        assign virt_adr = (MMU_Q                 == DBG_IN[31:12]);
156
        assign real_adr = (VADR_R[31:12] == DBG_IN[31:12]);
157
        assign page_adr = (VADR_R[11:2]  == DBG_IN[11:2]);
158
 
159
        assign byte_en  = |(ENBYTE & DBG_IN[35:32]);
160
 
161
        assign DBG_HIT  =  ACC_OK               // all valid
162
                                         & make                 // selection is valid
163
                                         & (VIRTUELL ? virt_adr : real_adr)     & page_adr      // address
164
                                         & byte_en;             // Byte Enable
165
 
166
endmodule
167
 
168 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
169 9 ns32kum
//
170 29 ns32kum
//      4. MMU_UP               MMU memory update and initalization controller
171 9 ns32kum
//
172 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
173 9 ns32kum
module MMU_UP ( BCLK, BRESET, NEW_PTB, PTB1, IVAR, WR_MRAM, VADR, VADR_R, MVALID, UPDATE,
174
                                WE_MV, WADR_MV, RADR_MV, DAT_MV, NEW_PTB_RUN );
175
 
176
        input                   BCLK;
177
        input                   BRESET;
178
        input                   NEW_PTB;        // the MMU memory is cleared. Pulse of one BCLK cycle, Op-Dec is waiting
179
        input                   PTB1;           // which one
180
        input                   IVAR;
181
        input                   WR_MRAM;        // BCLK : update MRAM and MMU_VAL
182
        input  [19:16]  VADR,VADR_R;    // For update
183
        input   [31:0]   MVALID,UPDATE;
184
 
185
        output                  WE_MV;          // Write Enable MMU Valid
186
        output   [3:0]   WADR_MV,RADR_MV;
187
        output  [31:0]   DAT_MV;
188
        output                  NEW_PTB_RUN;
189
 
190
        reg                             neue_ptb,wr_flag,old_rst,run_over;
191
        reg              [3:0]   count;
192
 
193
        wire    [15:0]   new_val;
194
 
195
        assign WE_MV   = wr_flag | WR_MRAM | IVAR;      // write on falling edge BCLK
196
        assign RADR_MV = run_over ? count : VADR;
197
        assign WADR_MV = wr_flag ? (count - 4'b0001) : VADR_R;
198 11 ns32kum
        assign DAT_MV  = wr_flag ? {MVALID[31:16],new_val} : UPDATE;    // Only the matching entries are cleared : PTB0/PTB1
199 9 ns32kum
 
200
        // [31:16] Address-Space memory, [15:0] Valid memory
201 11 ns32kum
        assign new_val = neue_ptb ? (PTB1 ? (MVALID[15:0] & ~MVALID[31:16]) : (MVALID[15:0] & MVALID[31:16])) : 16'h0;
202 9 ns32kum
 
203
        always @(posedge BCLK or negedge BRESET)
204
                if (!BRESET) neue_ptb <= 1'b0;
205
                        else neue_ptb <= NEW_PTB | (neue_ptb & run_over);
206
 
207
        always @(posedge BCLK) old_rst <= BRESET;       // after Reset all will be set to 0 
208
 
209
        always @(posedge BCLK) run_over <= ((~old_rst | NEW_PTB) | (run_over & (count != 4'hF))) & BRESET;
210
 
211
        always @(posedge BCLK) count <= run_over ? count + 4'h1 : 4'h0;
212
 
213
        always @(posedge BCLK) wr_flag <= run_over;
214
 
215
        assign NEW_PTB_RUN = wr_flag;   // Info to Op-Dec
216
 
217
endmodule
218
 
219 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
220 9 ns32kum
//
221 29 ns32kum
//      5. DCA_CONTROL  Data cache valid memory update and initalization controller
222 9 ns32kum
//
223 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
224 29 ns32kum
module DCA_CONTROL ( BCLK, BRESET, CUPDATE, DRAM_ACC, CA_SET, HIT_ALL, VADR_R, UPDATE, INVAL_A, WRITE, MDONE, USE_CA,
225
                                         INHIBIT, KILL, WRCRAM0, WRCRAM1, WE_CV, WADR_CV, DAT_CV, INIT_CA_RUN, WRSET0, WRSET1 );
226 9 ns32kum
 
227
        input                   BCLK;
228
        input                   BRESET;
229
        input                   CUPDATE;        // State CUPDATE : Cache is filled from DRAM
230
        input                   DRAM_ACC;
231
        input                   CA_SET;
232
        input                   HIT_ALL;        // a complete cache hit !
233
        input   [11:7]  VADR_R;
234
        input   [23:0]   UPDATE;
235
        input                   INVAL_A;
236
        input                   WRITE;
237 29 ns32kum
        input                   MDONE;          // Signal from DRAM : Access Done
238
        input                   USE_CA;         // Signal use cache
239
        input                   INHIBIT;        // Signal cache inhibit  - no write in cache
240 9 ns32kum
        input                   KILL;           // valid Ram must be updated because of collision ... or CINV
241
 
242
        output                  WRCRAM0,WRCRAM1;
243
        output                  WE_CV;
244
        output   [4:0]   WADR_CV;
245
        output  [23:0]   DAT_CV;
246
        output                  INIT_CA_RUN;
247
        output                  WRSET0,WRSET1;
248
 
249
        reg              [1:0]   state;
250
        reg              [4:0]   acount;
251
        reg                             ca_set_d;
252
 
253
        wire                    countf;
254
 
255 23 ns32kum
        always @(posedge BCLK) if (DRAM_ACC) ca_set_d <= CA_SET;        // Store for whole access
256
 
257 9 ns32kum
        // physical address is stored in TAG-RAM
258
 
259 29 ns32kum
        assign WRCRAM0 = (CUPDATE & ~INHIBIT) & ~ca_set_d;
260
        assign WRCRAM1 = (CUPDATE & ~INHIBIT) &  ca_set_d;
261 9 ns32kum
 
262
        // Load Valid RAM :
263
 
264 29 ns32kum
        assign WE_CV   = state[1] | HIT_ALL | (CUPDATE & ~INHIBIT) | KILL; // Hit All for "Last" Update
265 9 ns32kum
        assign WADR_CV = state[1] ? acount : VADR_R;
266
        assign DAT_CV  = state[1] ? 24'h0 : UPDATE;
267
 
268
        // Clear of Cache-Valid RAMs : 32 clocks of BCLK
269
 
270
        assign countf = (acount == 5'h1F);
271
 
272
        always @(posedge BCLK)
273
                casex ({BRESET,INVAL_A,countf,state[1:0]})
274
                  5'b0xx_xx : state <= 2'b01;
275
                  5'b1xx_01 : state <= 2'b10;           // start counter
276
                  5'b10x_00 : state <= 2'b00;           // wait ...
277
                  5'b11x_00 : state <= 2'b10;
278
                  5'b1x0_10 : state <= 2'b10;
279
                  5'b1x1_10 : state <= 2'b00;
280
                  default   : state <= 2'b0;
281
                endcase
282
 
283
        always @(posedge BCLK) if (!state[1]) acount <= 5'h0; else acount <= acount + 5'h01;
284
 
285
        assign INIT_CA_RUN = state[1];
286
 
287
        // WRITE Control in data RAMs
288 29 ns32kum
        assign WRSET0 = ( ~CA_SET & WRITE & HIT_ALL) | (MDONE & USE_CA & ~ca_set_d);
289
        assign WRSET1 = (  CA_SET & WRITE & HIT_ALL) | (MDONE & USE_CA &  ca_set_d);
290 9 ns32kum
 
291
endmodule
292
 
293 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
294 9 ns32kum
//
295 29 ns32kum
//      6. MMU_MATCH    MMU virtual address match detector
296 9 ns32kum
//
297 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
298 9 ns32kum
module MMU_MATCH ( USER, READ, WRITE, RMW, MCR_FLAGS, MVALID, VADR_R, MMU_VA, IVAR,
299
                                   VIRTUELL, MMU_HIT , UPDATE, PROT_ERROR, CI, SEL_PTB1 );
300
 
301
        input                   USER;
302
        input                   READ;
303
        input                   WRITE;
304
        input                   RMW;
305
        input    [2:0]   MCR_FLAGS;
306
        input   [31:0]   MVALID;
307
        input  [31:12]  VADR_R;
308
        input  [31:16]  MMU_VA;
309
        input    [1:0]   IVAR;   // Invalidate Entry
310
 
311
        output                  VIRTUELL;       // only for Adress-Mux
312
        output                  MMU_HIT;
313
        output  [31:0]   UPDATE;
314
        output  reg             PROT_ERROR;     // if valid must suppress write in Write Buffer and cache
315
        output                  CI,SEL_PTB1;
316
 
317
        reg             [15:0]   maske;
318
 
319
        wire                    adr_space,as_sorte,match,alles_ok;
320
        wire    [15:0]   val_bits,as_bits;
321
        wire                    ena_prot;
322
        wire                    zugriff;
323
 
324
        assign zugriff = READ | WRITE;
325
 
326
        always @(VADR_R)
327
                case (VADR_R[15:12])
328
                  4'h0 : maske = 16'h0001;
329
                  4'h1 : maske = 16'h0002;
330
                  4'h2 : maske = 16'h0004;
331
                  4'h3 : maske = 16'h0008;
332
                  4'h4 : maske = 16'h0010;
333
                  4'h5 : maske = 16'h0020;
334
                  4'h6 : maske = 16'h0040;
335
                  4'h7 : maske = 16'h0080;
336
                  4'h8 : maske = 16'h0100;
337
                  4'h9 : maske = 16'h0200;
338
                  4'hA : maske = 16'h0400;
339
                  4'hB : maske = 16'h0800;
340
                  4'hC : maske = 16'h1000;
341
                  4'hD : maske = 16'h2000;
342
                  4'hE : maske = 16'h4000;
343
                  4'hF : maske = 16'h8000;
344
                endcase
345
 
346
        assign VIRTUELL = USER ? MCR_FLAGS[0] : MCR_FLAGS[1];
347
 
348 11 ns32kum
        assign adr_space = IVAR[1] ? IVAR[0] : (MCR_FLAGS[2] & USER);    // adr_space = IVARx ? 1 or 0 : DualSpace & TU
349 9 ns32kum
 
350
        assign as_sorte = ((MVALID[31:16] & maske) != 16'h0);
351
 
352 11 ns32kum
        assign match = (VADR_R[31:20] == MMU_VA[31:20]) & (adr_space == as_sorte) & ((MVALID[15:0] & maske) != 16'h0000);
353 9 ns32kum
 
354 11 ns32kum
        assign alles_ok = match & ( ~WRITE | MMU_VA[17] ) & ~PROT_ERROR;        // Modified - Flag : reload the PTE
355 9 ns32kum
 
356 23 ns32kum
        // if MMU_HIT = 0 then there is no Write-Buffer access and no update of cache !
357 9 ns32kum
        assign MMU_HIT = zugriff ? ( VIRTUELL ? alles_ok : 1'b1 ) : 1'b0 ;      // MMU off : then always HIT
358
 
359
        assign val_bits = IVAR[1] ? (MVALID[15:0] & (match ? ~maske : 16'hFFFF)) : (MVALID[15:0] | maske);
360 11 ns32kum
        assign as_bits  = IVAR[1] ? MVALID[31:16] : (adr_space ? (MVALID[31:16] | maske) : (MVALID[31:16] & ~maske));
361 9 ns32kum
 
362
        assign UPDATE = {as_bits,val_bits};
363
 
364
        assign ena_prot = zugriff & VIRTUELL & match;
365
 
366
        // A Protection error must suppress write in WB and cache
367
        always @(ena_prot or MMU_VA or USER or WRITE or RMW)
368
                case ({ena_prot,MMU_VA[19:18]})
369
                   3'b100 : PROT_ERROR = USER | WRITE | RMW;    // Only Supervisor READ
370
                   3'b101 : PROT_ERROR = USER;                                  // no USER access
371
                   3'b110 : PROT_ERROR = USER & (WRITE | RMW);  // USER only READ
372
                  default : PROT_ERROR = 1'b0;
373
                endcase
374
 
375
        assign CI = VIRTUELL & MMU_VA[16];
376
        assign SEL_PTB1 = adr_space;            // For PTE update
377
 
378
endmodule
379
 
380 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
381 9 ns32kum
//
382 29 ns32kum
//      7. CA_MATCH             Cache tag match detector
383 9 ns32kum
//
384 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
385 23 ns32kum
module CA_MATCH ( CVALID, DRAMSZ, ADDR, TAG0, TAG1, CFG, WRITE, MMU_HIT, CI, INVAL_L, KDET, ENDRAM, DC_ILO,
386 9 ns32kum
                                  CA_HIT, CA_SET, UPDATE, IO_SPACE, USE_CA, WB_ACC, KILL );
387
 
388
        input   [23:0]   CVALID;
389 23 ns32kum
        input    [2:0]   DRAMSZ;
390
        input   [31:4]  ADDR;
391 29 ns32kum
        input  [28:12]  TAG0,TAG1;
392 9 ns32kum
        input    [1:0]   CFG;    // LDC , DC
393
        input                   WRITE;
394
        input                   MMU_HIT;
395
        input                   CI;
396
        input                   INVAL_L;        // invalid cache line
397
        input                   KDET;
398
        input                   ENDRAM;
399
        input                   DC_ILO;         // CBITI/SBITI special case
400
 
401
        output                  CA_HIT;
402
        output                  CA_SET; // if no Hit then says SET where to store
403
        output  [23:0]   UPDATE; // Update Information for CVALID memory 
404
        output                  IO_SPACE;
405
        output                  USE_CA;
406
        output                  WB_ACC;
407
        output                  KILL;
408
 
409
        reg              [7:0]   maske;
410 29 ns32kum
        reg                             acc_dram;
411 9 ns32kum
 
412
        wire                    match_0,match_1;
413
        wire                    valid_0,valid_1;
414
        wire                    select;
415
        wire                    clear;
416
        wire     [7:0]   update_0,update_1,lastinfo;
417 29 ns32kum
        wire                    sel_dram;
418 9 ns32kum
 
419
        always @(ADDR)
420
                case (ADDR[6:4])
421
                  3'h0 : maske = 8'h01;
422
                  3'h1 : maske = 8'h02;
423
                  3'h2 : maske = 8'h04;
424
                  3'h3 : maske = 8'h08;
425
                  3'h4 : maske = 8'h10;
426
                  3'h5 : maske = 8'h20;
427
                  3'h6 : maske = 8'h40;
428
                  3'h7 : maske = 8'h80;
429
                endcase
430
 
431
        assign valid_0 = (( CVALID[7:0] & maske) != 8'h00);
432
        assign valid_1 = ((CVALID[15:8] & maske) != 8'h00);
433
 
434 29 ns32kum
        assign match_0 = ( TAG0 == ADDR[28:12] );       // 4KB
435
        assign match_1 = ( TAG1 == ADDR[28:12] );       // 4KB
436 9 ns32kum
 
437 29 ns32kum
        assign CA_HIT = ((valid_0 & match_0) | (valid_1 & match_1)) & ~DC_ILO & CFG[0] & (sel_dram | KDET);
438 9 ns32kum
 
439
        // which SET is written in cache miss ? If both are valid the last used is not taken
440 11 ns32kum
        assign select = (valid_1 & valid_0) ? ~((CVALID[23:16] & maske) != 8'h00) : valid_0;    // Last-used field = CVALID[23:16]
441 9 ns32kum
 
442
        assign CA_SET = CA_HIT ? (valid_1 & match_1) : select;
443
 
444
        assign clear = INVAL_L | KDET;  // INVAL_L is from CINV
445
 
446
        assign update_0 = CA_SET ? CVALID[7:0] : (clear ? (CVALID[7:0] & ~maske) : (CVALID[7:0] | maske));
447 11 ns32kum
        assign update_1 = CA_SET ? (clear ? (CVALID[15:8] & ~maske) : (CVALID[15:8] | maske)) : CVALID[15:8];
448 9 ns32kum
 
449 11 ns32kum
        assign lastinfo = CA_HIT ? (CA_SET ? (CVALID[23:16] | maske) : (CVALID[23:16] & ~maske)) : CVALID[23:16];
450 9 ns32kum
 
451
        assign UPDATE = {lastinfo,update_1,update_0};
452
 
453
        assign KILL = clear & CA_HIT & ~CFG[1];         // only if cache is not locked
454
 
455 29 ns32kum
        always @(DRAMSZ or ADDR)        // Size of DRAM
456
                case (DRAMSZ)
457
                  3'b000 : acc_dram = (ADDR[28:23] == 6'd0);    //   8 MB 32016 Second Processor
458
                  3'b001 : acc_dram = (ADDR[28:24] == 5'd0);    //  16 MB
459
                  3'b010 : acc_dram = (ADDR[28:25] == 4'd0);    //  32 MB
460
                  3'b011 : acc_dram = (ADDR[28:26] == 3'd0);    //  64 MB
461
                  3'b100 : acc_dram = (ADDR[28:27] == 2'd0);    // 128 MB
462
                  3'b101 : acc_dram = ~ADDR[28];                                // 256 MB
463
                  3'b110 : acc_dram =   1'b1;                                   // 512 MB
464
                  3'b111 : acc_dram = ~(ADDR[28:27] == 2'b10);  // 256 MB NetBSD + 128 MB
465 23 ns32kum
                endcase
466
 
467 29 ns32kum
        assign sel_dram =  (ADDR[31:29] == 3'd0) & acc_dram & ENDRAM;
468 9 ns32kum
        assign IO_SPACE = ~sel_dram;                                    // not DRAM or DRAM ist off
469 23 ns32kum
 
470 9 ns32kum
        assign USE_CA   = ~CI & ~DC_ILO & CFG[0] & ~CFG[1];      // CI ? ILO ? Cache on ? Locked Cache ? 
471
        assign WB_ACC   = WRITE & MMU_HIT & sel_dram;
472
 
473
endmodule
474
 
475 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
476 9 ns32kum
//
477 29 ns32kum
//      8. FILTCMP              Address Filter and Comparator
478 9 ns32kum
//
479 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
480 23 ns32kum
module FILTCMP ( DRAMSZ, RADR, DRAM_A, ADR_EQU, TAGDAT );
481
 
482
        input    [2:0]   DRAMSZ;
483 29 ns32kum
        input   [28:4]  RADR,DRAM_A;
484 23 ns32kum
 
485
        output                  ADR_EQU;
486 29 ns32kum
        output reg      [28:12] TAGDAT;
487 23 ns32kum
 
488 29 ns32kum
        reg        [28:23]      adram;
489 23 ns32kum
 
490
        always @(DRAMSZ or RADR)
491
                casex (DRAMSZ)
492 29 ns32kum
                  3'b000 : TAGDAT = {6'd0,RADR[22:12]}; //   8 MB
493
                  3'b001 : TAGDAT = {5'd0,RADR[23:12]}; //  16 MB
494
                  3'b010 : TAGDAT = {4'd0,RADR[24:12]}; //  32 MB
495
                  3'b011 : TAGDAT = {3'd0,RADR[25:12]}; //  64 MB
496
                  3'b100 : TAGDAT = {2'd0,RADR[26:12]}; // 128 MB
497
                  3'b101 : TAGDAT = {1'b0,RADR[27:12]}; // 256 MB
498
                  3'b11x : TAGDAT =       RADR[28:12] ; // 512 MB
499 23 ns32kum
                endcase
500
 
501
        always @(DRAMSZ or DRAM_A)      // The address comparator is only used in the data cache.
502
                casex (DRAMSZ)
503 29 ns32kum
                  3'b000 : adram =  6'd0;                                       //   8 MB
504
                  3'b001 : adram = {5'd0,DRAM_A[23]};           //  16 MB
505
                  3'b010 : adram = {4'd0,DRAM_A[24:23]};        //  32 MB
506
                  3'b011 : adram = {3'd0,DRAM_A[25:23]};        //  64 MB
507
                  3'b100 : adram = {2'd0,DRAM_A[26:23]};        // 128 MB
508
                  3'b101 : adram = {1'd0,DRAM_A[27:23]};        // 256 MB
509
                  3'b11x : adram =       DRAM_A[28:23] ;        // 512 MB
510 23 ns32kum
                endcase
511
 
512
        assign ADR_EQU = {TAGDAT,RADR[11:4]} == {adram,DRAM_A[22:4]};
513
 
514
endmodule
515
 
516
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
517
//
518 29 ns32kum
//      9. DCACHE_SM    Data cache state machine
519 23 ns32kum
//
520
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
521 11 ns32kum
module DCACHE_SM ( BCLK, BRESET, IO_SPACE, MDONE, IO_READY, MMU_HIT, CA_HIT, READ, WRITE, ZTEST, RMW, CAPDAT, VADR_R, IC_VA,
522 23 ns32kum
                                   USE_CA, PTB_WR, PTB_SEL, SEL_PTB1, CPU_OUT, USER, PROT_ERROR, WB_ACC, ENWR, ADR_EQU, IC_PREQ, DMA_CHK, ICTODC,
523 12 ns32kum
                                   RWVAL, VIRTUELL, QWATWO,
524 11 ns32kum
                                   DRAM_ACC, DRAM_WR, IO_ACC, IO_RD, IO_WR, PTE_MUX, PD_MUX, PKEEP, PTE_ADR, PTE_DAT, HIT_ALL, ACC_OK,
525
                                   ABORT, PROTECT, IACC_STAT, ABO_LEVEL1, WR_MRAM, CUPDATE, AUX_DAT, NEW_PTB, PTB_ONE, MMU_DIN, IC_SIGS, KOMUX,
526 9 ns32kum
                                   KDET, DMA_MUX, HLDA, RWVFLAG, PTE_STAT );
527
 
528
        input                   BCLK;
529
        input                   BRESET;
530
        input                   IO_SPACE;
531
        input                   MDONE;          // Memory Done : feedback from DRAM Controller, BCLK aligned !
532
        input                   IO_READY;
533
        input                   MMU_HIT,CA_HIT;
534
        input                   READ,WRITE,ZTEST,RMW;
535
        input   [31:0]   CAPDAT;
536
        input  [31:12]  VADR_R,IC_VA;
537
        input                   USE_CA;
538
        input                   PTB_WR,PTB_SEL;
539
        input                   SEL_PTB1;
540 29 ns32kum
        input  [28:12]  CPU_OUT;        // used for PTB0/1
541 9 ns32kum
        input                   USER;
542
        input                   PROT_ERROR;
543
        input                   WB_ACC;
544
        input                   ENWR;           // Enable WRITE from DRAM
545
        input                   ADR_EQU;
546
        input                   IC_PREQ;
547 23 ns32kum
        input                   DMA_CHK;
548 9 ns32kum
        input    [3:0]   ICTODC;         // multiple signals from ICACHE, especially DMA
549
        input    [1:0]   RWVAL;          // RDVAL+WRVAL Operation
550
        input                   VIRTUELL;       // for RDVAL/WRVAL
551 12 ns32kum
        input                   QWATWO;
552 9 ns32kum
 
553
        output  reg             DRAM_ACC,DRAM_WR;
554
        output                  IO_ACC,IO_RD,IO_WR;
555
        output                  PTE_MUX,PD_MUX,PKEEP;
556 29 ns32kum
        output  [28:0]   PTE_ADR;
557 9 ns32kum
        output  [19:0]   PTE_DAT;
558
        output                  HIT_ALL;
559
        output                  ACC_OK;
560
        output                  ABORT,PROTECT;
561
        output   [3:1]  IACC_STAT;
562
        output                  ABO_LEVEL1;
563
        output                  WR_MRAM;
564
        output                  CUPDATE;
565
        output                  AUX_DAT;
566
        output  reg             NEW_PTB;
567
        output  reg             PTB_ONE;
568
        output  [23:0]   MMU_DIN;
569
        output   [1:0]   IC_SIGS;
570
        output                  KOMUX;
571
        output                  KDET;           // Signal for detection of collision
572
        output                  DMA_MUX;
573
        output                  HLDA;           // active low
574
        output                  RWVFLAG;        // RDVAL/WRVAL result
575
        output   [1:0]   PTE_STAT;
576
 
577
        reg                             IO_WR,IO_RD;
578
        reg              [1:0]   pl_dat;
579
        reg              [6:0]   new_state;
580
        reg                             mem_done;
581
        reg                             rd_done;
582
        reg              [2:0]   pstate;
583
        reg                             pte_run_wr;
584
        reg              [1:0]   prot_level1;
585
        reg                             card_flag;
586 29 ns32kum
        reg        [28:12]      ptb0,ptb1;
587 9 ns32kum
        reg                             write_ok;
588
        reg                             icp_acc;
589
        reg              [2:0]   ko_state;
590
        reg                             dma_run;
591
        reg                             dma_kdet;
592
        reg                             rwv_bit;
593
        reg                             prot_i;
594
        reg                             rd_rdy;
595
 
596 29 ns32kum
        wire   [28:12]  ptb10;
597 9 ns32kum
        wire   [31:12]  virtual_adr;
598
        wire                    io_busy;
599
        wire                    dram_go;
600
        wire                    pte_sel;
601
        wire                    pte_acc;
602
        wire                    do_ca_rd,pte_go,do_ic_p;
603
        wire                    valid,valid_a,refer,modi;
604
        wire                    level1,level2;
605
        wire                    rd_level2;
606
        wire                    wr_req;
607
        wire                    wr_dram;
608
        wire                    wr_icmram;
609
        wire                    rd_ende;
610
        wire                    pte_dat_8;
611
        wire                    pte_wr_sig;
612
        wire                    run_dc;
613
        wire                    kostart;
614
        wire                    dma;
615
        wire                    dma_go;
616
        wire                    zugriff;
617
        wire                    mmu_hit_i;
618
        wire                    do_zt;
619
        wire                    zt_ok;
620
        wire     [1:0]   acc_level;
621
        wire                    user_ptw,wr_ptw;
622
        wire                    pte_puls;
623
 
624
        // if USER not virtual then ZTEST is quickly done
625
        assign zugriff = READ | WRITE | (ZTEST & VIRTUELL);
626
        assign mmu_hit_i = MMU_HIT & ~ZTEST;
627
 
628
        // WB_ACC is a successful WRITE access, ICTODC[0] is coherent Logik release : >=3 entries in FIFO
629 11 ns32kum
        assign wr_req = WB_ACC & ((ENWR & ICTODC[0]) | (DRAM_WR & ADR_EQU));     // release done by DRAM signal ENWR
630 9 ns32kum
 
631
        assign rd_ende = CA_HIT | rd_rdy;       // CA_HIT only when Cache activ !
632
 
633
        always @(        zugriff        // READ or WRITE or ZTEST , global control
634
                          or PROT_ERROR // must not be
635
                        //
636
                          or IO_SPACE   // access of IO world
637
                          or io_busy    // is access already running ?
638
                        //
639
                          or mmu_hit_i  // Hit in MMU , now only a READ can happen
640
                          or READ
641
                          or wr_req
642
                          or rd_ende    // Cache Hit
643
                        //
644
                          or DRAM_ACC   // DRAM Access : shows an active state
645
                          or pte_acc    // PTE access is running
646
                        //
647
                          or IC_PREQ    // PTE Request from ICACHE
648
                        //
649
                          or dma                // DMA Request
650
                          or dma_run )  // DMA running
651
                        //                                       #_#                      #_#                                               #_#                                     #_#
652 11 ns32kum
                casex ({zugriff,PROT_ERROR,IO_SPACE,io_busy,mmu_hit_i,READ,wr_req,rd_ende,DRAM_ACC,pte_acc,IC_PREQ,dma,dma_run})
653 9 ns32kum
                // MMU Miss : PTE load from memory , valid too if WRITE and M=0
654
                  13'b10_xx_0xxx_x0_x_x0 : new_state = 7'b0001010;      // start PTE access
655
                // IO-Address selected : external access starts if not busy because of WRITE
656
                  13'b10_10_1xxx_x0_x_x0 : new_state = 7'b0000001;
657
                // DRAM access : Cache Miss at READ : 
658
                  13'b10_0x_1100_00_x_x0 : new_state = 7'b0010010;
659
                // DRAM access : WRITE
660
                  13'b10_0x_101x_x0_x_x0 : new_state = 7'b0000100;
661
                // PTE Request ICACHE , IO access with WRITE is stored - parallel DRAM access possible
662 23 ns32kum
                  13'b0x_xx_xxxx_x0_1_x0 : new_state = 7'b0101010;      // no access
663 11 ns32kum
                  13'b10_0x_1101_x0_1_x0 : new_state = 7'b0101010;      // if successful READ a PTE access can happen in parallel
664 9 ns32kum
                // DMA access. Attention : no IO-Write access in background and no ICACHE PTE access !
665 23 ns32kum
                  13'b0x_x0_xxxx_x0_0_10 : new_state = 7'b1000000;      // DMA access is started
666 9 ns32kum
                  default                                : new_state = 7'b0;
667
                endcase
668
 
669
        assign IO_ACC   = new_state[0];  // to load registers for data, addr und BE, signal one pulse
670
        assign dram_go  = new_state[1] | rd_level2 ;
671
        assign wr_dram  = new_state[2]; // pulse only
672
        assign pte_go   = new_state[3];
673
        assign do_ca_rd = new_state[4];
674
        assign do_ic_p  = new_state[5];
675
        assign dma_go   = new_state[6];
676
 
677
        // ZTEST logic is for the special case when a write access is crossing page boundaries
678
 
679
        assign do_zt = ZTEST & ~icp_acc;
680
 
681 11 ns32kum
        // 0 is pass , 1 is blocked. RWVAL[0] is 1 if WRVAL. Level 1 can only be blocked, otherwise ABORT or Level 2 is following.
682 29 ns32kum
        always @(posedge BCLK) if (mem_done) rwv_bit <= level2 ? ~(CAPDAT[2] & (~RWVAL[0] | CAPDAT[1])) : 1'b1;
683 9 ns32kum
 
684
        assign RWVFLAG = VIRTUELL & rwv_bit;
685
 
686 29 ns32kum
        assign zt_ok = mem_done & (RWVAL[1] ? (~CAPDAT[2] | (RWVAL[0] & ~CAPDAT[1]) | level2)    // Level 2 always ok
687
                                                                                : (CAPDAT[0] & ~prot_i & level2) );      // "normal" access
688 9 ns32kum
 
689
        // PTE access logic, normal state machine
690
        // Updates to the PTEs are normal WRITE request to DRAM, therefore no MDONE at Write
691
 
692
        assign modi  = ~CAPDAT[8] & WRITE & write_ok & ~icp_acc;        // is "1" if the Modified Bit must be set
693
        assign refer = CAPDAT[7] | do_zt;       // Assumption "R" Bit is set if RDVAL/WRVAL and page border test
694 29 ns32kum
        assign valid = (do_zt & RWVAL[1]) ? (CAPDAT[2] & (CAPDAT[1] | ~RWVAL[0]) & CAPDAT[0] & level1)
695
                                                                          : (CAPDAT[0] & ~prot_i);
696 9 ns32kum
 
697
        always @(posedge BCLK) mem_done <= MDONE & pte_acc;
698
 
699
        always @(posedge BCLK or negedge BRESET)
700
                if (!BRESET) pstate <= 3'h0;
701
                  else
702
                        casex ({pte_go,mem_done,valid,refer,modi,pte_run_wr,pstate})
703
                          9'b0x_xxxx_000 : pstate <= 3'd0;      // nothing to do
704
                          9'b1x_xxxx_000 : pstate <= 3'd4;      // start
705
                          9'bx0_xxxx_100 : pstate <= 3'd4;      // wait for Level 1
706
                          9'bx1_0xxx_100 : pstate <= 3'd0;      // THAT'S ABORT ! 
707
                          9'bx1_11xx_100 : pstate <= 3'd6;      // PTE Level 1 was referenced , next is Level 2
708
                          9'bx1_10xx_100 : pstate <= 3'd5;      // for writing of modified Level 1 : R=1
709
                          9'bxx_xxx0_101 : pstate <= 3'd5;      // write must wait
710
                          9'bxx_xxx1_101 : pstate <= 3'd6;      // one wait cycle
711
                          9'bx0_xxxx_110 : pstate <= 3'd6;      // wait for Level 2
712
                          9'bx1_0xxx_110 : pstate <= 3'd0;      // THAT'S ABORT !
713
                          9'bx1_10xx_110 : pstate <= 3'd7;      // Update neccesary : R=0
714
                          9'bx1_110x_110 : pstate <= 3'd0;      // all ok - end
715
                          9'bx1_111x_110 : pstate <= 3'd7;      // Update neccesary : M=0
716
                          9'bxx_xxx0_111 : pstate <= 3'd7;      // write must wait
717
                          9'bxx_xxx1_111 : pstate <= 3'd0;      // continues to end of DRAM write
718
                          default            : pstate <= 3'd0;
719
                        endcase
720
 
721
        assign pte_acc =  pstate[2];
722
        assign level1  = ~pstate[1];
723
        assign level2  =  pstate[1];
724
 
725 29 ns32kum
        assign valid_a = (ZTEST & RWVAL[1]) ? (CAPDAT[2] & (CAPDAT[1] | ~RWVAL[0]) & ~CAPDAT[0] & level1)
726
                                                                                : ~CAPDAT[0];    // not do_zt because of icp_acc in ABORT
727 9 ns32kum
 
728
        assign ABORT   =   mem_done & valid_a & ~icp_acc;
729 11 ns32kum
        assign PROTECT = ((mem_done & prot_i  & ~icp_acc) | PROT_ERROR) & ~(ZTEST & RWVAL[1]);  // no Protection-Error at RDVAL/WRVAL
730 9 ns32kum
 
731 29 ns32kum
        assign IACC_STAT[1] = mem_done & ~CAPDAT[0] & icp_acc;
732 9 ns32kum
        assign IACC_STAT[2] = level1;
733
        assign IACC_STAT[3] = mem_done & prot_i & icp_acc;
734
 
735
        assign ABO_LEVEL1 = level1;     // is stored in case of ABORT in ADDR_UNIT
736
 
737
        assign rd_level2 = (pstate == 3'd5) | (mem_done & (pstate == 3'd4) & refer & valid);
738
 
739
        assign WR_MRAM   = mem_done &  (pstate == 3'd6) & valid & ~icp_acc & ~ZTEST;
740
        assign wr_icmram = mem_done &  (pstate == 3'd6) & valid &  icp_acc;
741
 
742
        // Signals to the Instruction Cache
743
        // pte_acc combined with icp_acc for STATISTIK.
744
        assign IC_SIGS = {(pte_acc & icp_acc),wr_icmram};
745
 
746
        assign PTE_MUX = pte_go | (pte_acc & ~pstate[1]);
747
 
748
        assign pte_puls = mem_done & pte_acc & ~pstate[1];
749
        assign PTE_STAT = {(pte_puls & icp_acc),(pte_puls & ~icp_acc)}; // only for statistic
750
 
751 11 ns32kum
        assign PD_MUX =  ((pstate == 3'd4) & mem_done & valid & ~refer)         // switch data-MUX, write level 1 too
752 9 ns32kum
                                   | ((pstate == 3'd6) & mem_done & valid & (~refer | modi))    // write level 2
753
                                   | (((pstate == 3'd5) | (pstate == 3'd7)) & ~pte_run_wr);
754
 
755
        assign pte_wr_sig = ENWR & PD_MUX;
756
 
757
        always @(posedge BCLK) pte_run_wr <= pte_wr_sig;        // Ok-Signal for pstate State-machine
758
 
759
        assign PKEEP = (pstate == 3'd6) | ((pstate == 3'd7) & ~pte_run_wr);     // keep the DRAM address
760
 
761 11 ns32kum
        // If there is a PTE still in the data cache it must be deleted. If MMU Bits are set by the pte engine a following
762 9 ns32kum
        // READ would deliver wrong data if cache hit. Therefore access of the Tags.
763
        always @(posedge BCLK or negedge BRESET)
764
                if (!BRESET) ko_state <= 3'b000;
765
                  else
766
                        casex ({kostart,ko_state})
767
                          4'b0_000 : ko_state <= 3'b000;
768
                          4'b1_000 : ko_state <= 3'b110;
769
                          4'bx_110 : ko_state <= 3'b111;
770
                          4'bx_111 : ko_state <= 3'b100;
771
                          4'bx_100 : ko_state <= 3'b000;
772
                          default  : ko_state <= 3'b000;
773
                        endcase
774
 
775
        assign kostart = pte_go | rd_level2;
776
 
777 12 ns32kum
        // ko_state[2] suppresses ACC_OK at READ
778
        assign run_dc = (~ko_state[2] | QWATWO) & ~dma_run;     // Bugfix of 7.10.2015
779
        assign KOMUX  =   ko_state[1]                   |  DMA_MUX;
780
        assign KDET   =   ko_state[0]                    |  dma_kdet;
781 9 ns32kum
 
782 11 ns32kum
        assign HIT_ALL = MMU_HIT & CA_HIT & run_dc & ~pte_acc;  // for Update "Last-Set" , MMU_HIT contains ZUGRIFF
783 9 ns32kum
 
784
        always @(posedge BCLK or negedge BRESET)
785
                if (!BRESET) card_flag <= 1'b0;
786
                        else card_flag <= (do_ca_rd & ~rd_rdy) | (card_flag & ~MDONE);
787
 
788
        assign CUPDATE = card_flag & USE_CA & MDONE;
789
 
790
        always @(posedge BCLK) rd_rdy <= card_flag & MDONE;
791
 
792 11 ns32kum
        // The cache RAM can not provide fast enough the data after an Update. In this case a secondary data path is activated
793 9 ns32kum
        assign AUX_DAT = rd_rdy;
794
 
795
        // DRAM interface :
796
 
797
        always @(posedge BCLK)                          DRAM_WR  <= wr_dram | pte_wr_sig; // pulse
798
        always @(posedge BCLK) if (dram_go) DRAM_ACC <= 1'b1;
799
                                                         else
800
                                                                DRAM_ACC <= DRAM_ACC & ~MDONE & BRESET;
801
        // IO interface :
802
 
803
        always @(posedge BCLK)
804
          begin
805
                if (IO_ACC) IO_RD <= READ;  else IO_RD <= IO_RD & ~IO_READY & BRESET;
806
                if (IO_ACC) IO_WR <= WRITE; else IO_WR <= IO_WR & ~IO_READY & BRESET;
807
          end
808
 
809 11 ns32kum
        assign io_busy = IO_RD | IO_WR | rd_done;       // access is gone in next clock cycle, therefore blocked with "rd_done"
810 9 ns32kum
 
811 11 ns32kum
        always @(posedge BCLK) rd_done <= IO_RD & IO_READY;     // For READ one clock later for data to come through
812 9 ns32kum
 
813
        assign dma = ICTODC[2]; // external request HOLD after FF in ICACHE
814
 
815 11 ns32kum
        always @(posedge BCLK) dma_run <= (dma_go | (dma_run & dma)) & BRESET;  // stops the data access until HOLD becomes inactive
816 9 ns32kum
 
817
        assign HLDA = ~(ICTODC[1] & dma_run);   // Signal for system that the CPU has stopped accesses
818
 
819 23 ns32kum
        always @(posedge BCLK) dma_kdet <= DMA_CHK;
820
        assign DMA_MUX = DMA_CHK | dma_kdet;
821 9 ns32kum
 
822
        // global feedback to ADDR_UNIT, early feedback to Op-Dec : you can continue
823
 
824
        assign ACC_OK = ZTEST ? (~VIRTUELL | zt_ok)
825 11 ns32kum
                                                  : (IO_SPACE ? ((IO_ACC & WRITE) | rd_done) : (wr_dram | (READ & MMU_HIT & rd_ende & run_dc)) );
826 9 ns32kum
 
827
        // PTB1 and PTB0
828
 
829 29 ns32kum
        always @(posedge BCLK) if (PTB_WR && !PTB_SEL) ptb0 <= CPU_OUT;
830
        always @(posedge BCLK) if (PTB_WR &&  PTB_SEL) ptb1 <= CPU_OUT;
831 9 ns32kum
 
832
        always @(posedge BCLK) NEW_PTB <= PTB_WR;                       // to MMU Update Block
833
        always @(posedge BCLK) if (PTB_WR) PTB_ONE <= PTB_SEL;
834
 
835
        assign ptb10 = SEL_PTB1 ? ptb1 : ptb0;
836
 
837
        // Address multiplex between ICACHE=1 and DCACHE=0 :
838
        always @(posedge BCLK) if (pte_go) icp_acc <= do_ic_p;
839
 
840
        assign pte_sel = pte_go ? do_ic_p : icp_acc;
841
 
842
        assign virtual_adr = pte_sel ? IC_VA : VADR_R;
843
 
844
        // The 2 Address-LSB's : no full access : USE_CA = 0    
845 29 ns32kum
        assign PTE_ADR = rd_level2 ? {CAPDAT[28:12],virtual_adr[21:12],2'b00} : {ptb10,virtual_adr[31:22],2'b00};
846 9 ns32kum
 
847
        // PTE_DAT[8] is used for update of MMU_RAM.
848
        assign pte_dat_8 = (level2 & WRITE & write_ok & ~icp_acc) | CAPDAT[8];
849 29 ns32kum
        assign PTE_DAT = {4'h3,CAPDAT[15:9],pte_dat_8,1'b1,CAPDAT[6:0]}; // the top 4 bits are Byte-Enable
850 9 ns32kum
 
851
        // The data for the MMU-RAM : 24 Bits , [6]=Cache Inhibit
852
        assign MMU_DIN = {pl_dat,pte_dat_8,CAPDAT[6],CAPDAT[31:12]};
853
 
854
        // Protection field
855
 
856 29 ns32kum
        always @(posedge BCLK) if (mem_done && (pstate[2:0] == 3'd4)) prot_level1 <= CAPDAT[2:1];
857 9 ns32kum
 
858 29 ns32kum
        always @(prot_level1 or CAPDAT)
859
                casex ({prot_level1,CAPDAT[2]})
860
                  3'b11_x : pl_dat = CAPDAT[2:1];
861 9 ns32kum
                  3'b10_1 : pl_dat = 2'b10;
862 29 ns32kum
                  3'b10_0 : pl_dat = CAPDAT[2:1];
863 9 ns32kum
                  3'b01_1 : pl_dat = 2'b01;
864 29 ns32kum
                  3'b01_0 : pl_dat = CAPDAT[2:1];
865 9 ns32kum
                  3'b00_x : pl_dat = 2'b00;
866
                endcase
867
 
868 11 ns32kum
        always @(USER or pl_dat)        // is used if no PTE update is neccesary for M-Bit if writing is not allowed
869 9 ns32kum
                casex ({USER,pl_dat})
870
                  3'b1_11 : write_ok = 1'b1;
871
                  3'b0_1x : write_ok = 1'b1;
872
                  3'b0_01 : write_ok = 1'b1;
873
                  default : write_ok = 1'b0;
874
                endcase
875
 
876 29 ns32kum
        assign acc_level = level2 ? pl_dat : CAPDAT[2:1];
877 9 ns32kum
        assign user_ptw = icp_acc ? ICTODC[3] : USER;
878
        assign wr_ptw = ~icp_acc & (WRITE | RMW | (ZTEST & ~RWVAL[1])); // only data cache can write
879
 
880
        always @(acc_level or user_ptw or wr_ptw)
881
                case (acc_level)
882
                        2'b00 : prot_i = user_ptw | wr_ptw;
883
                        2'b01 : prot_i = user_ptw;
884
                        2'b10 : prot_i = user_ptw & wr_ptw;
885
                        2'b11 : prot_i = 1'b0;
886
                endcase
887
 
888
endmodule
889
 

powered by: WebSVN 2.1.0

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