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

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [rtl/] [peripherals/] [zipmmu.v] - Blame information for rev 201

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

Line No. Rev Author Line
1 201 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    zipmmu.v
4
//
5
// Project:     Zip CPU backend for the GNU Compiler Collection
6
//
7
// Purpose:     To provide a "bump-in-the-line" wishbone memory management
8
//              unit, that is configured from one wishbone bus and modifies a
9
//      separate wishbone bus.  Both busses will not be active at the same time.
10
//
11
//      The idea is that the CPU can use one portion of its peripheral 
12
//      system memory space to configure the MMU, and another portion of its
13
//      memory space to access the MMU.  Even more, configuring the MMU is to
14
//      be done when the CPU is in supervisor mode.  This means that all
15
//      high-memory, system-peripheral accesses will be enabled *only* when
16
//      the CPU is in supervisor mode.
17
//
18
//      There is a very specific reason for this design choice: by designing
19
//      the MMU in this fashion, the MMU may then be inluded (or not) at the
20
//      discretion of the individual assembling the ZipSystem (or equivalent)
21
//      module.
22
//
23
// Design Goals:
24
//
25
//      Since we're trying to design this for disadvantaged, limited CPUs,
26
//      we should be able to offer such CPUs only as much MMU as they want.
27
//      Therefore, it should be possible to scale the MMU up and/or down in
28
//      LUT space.
29
//
30
// Memory space:
31
//      1. On access via the memory bus, the MMU should provide for a speed
32
//              going through it such that any access is delayed by only one
33
//              clock cycle.  Further, multiple accesses to the same page
34
//              should not take any longer than the one cycle delay.  Accesses
35
//              to other pages should take a minimum number of clocks.
36
//              Accesses from one page to the next, such as from one page to 
37
//              the next subsequent one, should cost no delays.
38
//
39
//      2. One independent control word to set the current context
40
//
41
//        - When context = 0, virtual page = physical page, page table is an
42
//              unused pass through.
43
//        - When context != 0, MMU translation is active anytime the GIE is
44
//              set.  Pages must match context, as well as virtual address.
45
//
46
//        - Contains 4 RdOnly bits indicating the log address size for the
47
//              machine, offset by 17.  Thus, the build will have an address
48
//              bus of width (lgpage+17), or a memory space of (2^(lgpage+17)).
49
//              Under this formula, the number of valid address bits can range
50
//              from 17 to 32.
51
//        -  Contains 4 RdOnly bits indicating log_2 TLB table size. 
52
//              Size is given by (2^(lgsize)).  I'm considering sizes of 6,7&8
53
//        -  Contains 4 RdOnly bits indicating the log page size, offset by
54
//              eight.  Page sizes are therefore given by (2^(lgpage+8)), and
55
//              the smallest page size is 256 words.
56
//        - Contains 4 RdOnly bits indicating the log context size, offset by 1.
57
//              The number of bits in the context word therefore run from 1 to
58
//              (lgcontext+1)-1, supporting between (2^1)-1=3 and
59
//              (2^16)-1 = 65535 contexts.  (The zero context is not being
60
//              counted here, as it is special.)
61
//
62
//      +------+------+------+------+--------------------+
63
//      |      |      |      |      |                    |
64
//      |  4b  |  4b  |  4b  |  4b  |       16-bit       |
65
//      | LGADR| LGTBL|LGPGSZ|LGCTXT|    Context word    |
66
//      |      |      |      |      |                    |
67
//      +------+------+------+------+--------------------+
68
//
69
//      Supervisor *cannot* have page table entries, since there are no
70
//      interrupts (page faults) allowed in supervisor context.
71
//
72
//      To be valid, 
73
//        Context Size (1..16), NFlags (    4) < Page Size (8-23 bits)
74
//        Page size (8-23 bits)                > NFlags bits (4)
75
//
76
//      Small page sizes, then, mean fewer contexts are possible
77
//
78
//      3. One status word, which contains the address that failed and some
79
//              flags:
80
//
81
//      Top Virtual address bits indicate which page ... caused  a problem. 
82
//              These will be the top N bits of the word, where N is the size
83
//              of the virtual address bits.  (Bits are cleared upon any write.)
84
//
85
//      Flags: (Up to 12 bits, all zeros means no fault.  Bits are cleared upon
86
//              write)
87
//              - 4: Multiple page table matches
88
//              - 2: Attempt to write a read-only page
89
//              - 1: Page not found
90
//      
91
//      3. Two words per active page table entry, accessed through two bus
92
//              addresses.  This word contains:
93
//
94
//        16-bits       Page context
95
//        20-bits       Virtual address
96
//        20-bits       Physical address
97
//                              A physical address of all ones means that the
98
//                              page does not exist, and any attempt to access
99
//                              the virtual address associated with this page
100
//                              should fault.
101
//
102
//      Flags:
103
//         1-bit        Read-only / ~written (user set/read/written)
104
//                              If set, this page will cause a fault on any
105
//                              attempt to write this memory.
106
//         1-bit        Accessed
107
//                              This an be used to implement a least-recently
108
//                              used measure.  The hardware will set this value
109
//                              when the page is accessed.  The user can also
110
//                              set or clear this at will.
111
//         1-bit        Cacheable
112
//                              This is not a hardware page, but a memory page.
113
//                              Therefore, the values within this page may be
114
//                              cached.
115
//         1-bit        This context
116
//                              This is a read-only bit, indicating that the
117
//                              context register of this address matches the
118
//                              context register in the control word.
119
//
120
//              (Loaded flag    Not necessary, just map the physical page to 0)
121
//
122
//      We could equivalently do a 16-bit V&P addresses, for a 28-bit total
123
//      address space, if we didn't want to support the entire 32-bit space.
124
//
125
//
126
//      4. Can read/write this word in two parts:
127
//
128
//              (20-bit Virtual )(8-bits lower context)(4-bit flags), and 
129
//              (20-bit Physical)(8-bits upper context)(4-bit flags)
130
//
131
//              Actual bit lengths will vary as the MMU configuration changes,
132
//              however the flags will always be the low order four bits,
133
//              and the virtual/physical address flags will always consume
134
//              32 bits minus the page table size.  The context bits will
135
//              always be split into upper and lower context bits.  If there
136
//              are more context bits than can fit in the space, then the
137
//              upper bits of the context field will be filled with zeros.
138
//
139
//              On any write, the context bits will be set from the context
140
//              bits in the control register.
141
//
142
//      +----+----+-----+----+----+----+----+--+--+--+--+
143
//      |                         | Lower 8b| R| A| C| T|
144
//      |  20-bit Virtual page ID | Context | O| C| C| H|
145
//      |(top 20 bits of the addr)|   ID    | n| C| H| S|
146
//      |                         |         | W| S| E| P|
147
//      +----+----+-----+----+----+----+----+--+--+--+--+
148
//
149
//      +----+----+-----+----+----+----+----+--+--+--+--+
150
//      |                         | Upper 8b| R| A| C| T|
151
//      |  20-bit Physical pg ID  | Context | O| C| C| H|
152
//      |(top 20 bits of the      |   ID    | n| C| H| S|
153
//      |    physical address     |         | W| S| E| P|
154
//      +----+----+-----+----+----+----+----+--+--+--+--+
155
//
156
//      5. PF Cache--handles words in both physical and virtual
157
//      - On any pf-read, the MMU returns the current pagetable/TBL mapping
158
//              This consists of [Context,Va,Pa].
159
//      - The PF cache stores this with the address tag.  (If the PF is reading,
160
//              the VP should match, only the physical page ID needs to be
161
//              sored ...)
162
//      - At the end of any cache line read, the page table/TBL mapping address
163
//              will have long been available, the "Valid" bit will be turned
164
//              on and associated with the physical mapping.
165
//      - On any data-write (pf doesn't write), MMU sends [Context,Va,Pa]
166
//              TLB mapping to the pf-cache.  
167
//      - If the write matches any physical PF-cache addresses (???), the
168
//              pfcache declares that address line invalid, and just plain
169
//              clears the valid bit for that page.
170
//
171
//      Since the cache lines sizes are smaller than the page table sizes,
172
//      failure to match the address means ... what?
173
//
174
//
175
//      6. Normal operation and timing:
176
//        - One clock lost if still on the same page as last time, or in the
177
//              supervisor (physical pages only) context ...
178
//        - Two clocks (1-more delay) if opening a new page.
179
//              (1-clock to look up the entry--comparing against all entries,
180
//              1-clock to read it, next clock the access goes forward.)
181
//        - No more than two stalls for any access, pipelineable.  Thus, once
182
//              you've stalled by both clocks, you'll not stall again during
183
//              any pipeline operation.
184
//
185
//
186
//
187
// Creator:     Dan Gisselquist, Ph.D.
188
//              Gisselquist Technology, LLC
189
//
190
////////////////////////////////////////////////////////////////////////////////
191
//
192
// Copyright (C) 2016-2017, Gisselquist Technology, LLC
193
//
194
// This program is free software (firmware): you can redistribute it and/or
195
// modify it under the terms of  the GNU General Public License as published
196
// by the Free Software Foundation, either version 3 of the License, or (at
197
// your option) any later version.
198
//
199
// This program is distributed in the hope that it will be useful, but WITHOUT
200
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
201
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
202
// for more details.
203
//
204
// You should have received a copy of the GNU General Public License along
205
// with this program.  (It's in the $(ROOT)/doc directory.  Run make with no
206
// target there if the PDF file isn't present.)  If not, see
207
// <http://www.gnu.org/licenses/> for a copy.
208
//
209
// License:     GPL, v3, as defined and found on www.gnu.org,
210
//              http://www.gnu.org/licenses/gpl.html
211
//
212
//
213
////////////////////////////////////////////////////////////////////////////////
214
module zipmmu(i_clk, i_reset, i_ctrl_cyc_stb, i_wbm_cyc, i_wbm_stb, i_wb_we,
215
                        i_wb_addr, i_wb_data,
216
                o_cyc, o_stb, o_we, o_addr, o_data,
217
                        i_stall, i_ack, i_err, i_data,
218
                        o_rtn_stall, o_rtn_ack, o_rtn_err,
219
                                o_rtn_miss, o_rtn_data,
220
                pf_return_stb, pf_return_we,
221
                                pf_return_p, pf_return_v,
222
                                pf_return_cachable);
223
        parameter       ADDRESS_WIDTH=28, LGTBL=6, PLGPGSZ=12, PLGCTXT=16, DW=32;
224
        localparam      // And for our derived parameters (don't set these ...)
225
                        // AW is just shorthand for the name ADDRESS_WIDTH
226
                        AW = ADDRESS_WIDTH,
227
                        // Page sizes must allow for a minimum of one context
228
                        // bit per page, plus four flag bits, hence the minimum
229
                        // number of bits for an address within a page is 5
230
                        LGPGSZ=(PLGPGSZ < 5)? 5:PLGPGSZ,
231
                        // The number of context bits is twice the number of
232
                        // bits left over from DW after removing the LGPGSZ
233
                        // and flags bits.
234
                        LGCTXT=(((DW-LGPGSZ-4)<<1)<PLGCTXT)?
235
                                ((DW-LGPGSZ-4)<<1):PLGCTXT,
236
                        // LGLCTX is the number of context bits in the low word
237
                        LGLCTX=((LGPGSZ-4)<LGCTXT)?(LGPGSZ-4):LGCTXT,
238
                        // LGHCTX is the number of context bits in the high word
239
                        LGHCTX= (LGCTXT-LGLCTX),
240
                        VAW=(DW-LGPGSZ), //  Virtual address width
241
                        PAW=(AW-LGPGSZ), // Physical address width
242
                        TBL_BITS = LGTBL,       // Bits necessary to addr tbl
243
                        TBL_SIZE=(1<<TBL_BITS);// Number of table entries
244
        input                   i_clk, i_reset;
245
        //
246
        input                   i_ctrl_cyc_stb;
247
        //
248
        input                   i_wbm_cyc, i_wbm_stb;
249
        //
250
        input                   i_wb_we;
251
        input   [(DW-1):0]       i_wb_addr;
252
        input   [(DW-1):0]       i_wb_data;
253
        //
254
        // Here's where we drive the slave side of the bus
255
        output  reg                     o_cyc;
256
        output  wire                    o_stb, o_we;
257
        output  reg     [(AW-1):0]       o_addr;
258
        output  reg     [(DW-1):0]       o_data;
259
        // and get our return information from driving the slave ...
260
        input                           i_stall, i_ack, i_err;
261
        input           [(DW-1):0]       i_data;
262
        //
263
        // Here's where we return information on either our slave/control bus
264
        // or the memory bus we are controlled from.  Note that we share these
265
        // wires ...
266
        output  wire            o_rtn_stall;
267
        output  reg             o_rtn_ack;
268
        output  wire            o_rtn_err, o_rtn_miss;
269
        output  [(DW-1):0]       o_rtn_data;
270
        // Finally, to allow the prefetch to snoop on the MMU conversion ...
271
        output  wire                    pf_return_stb, // snoop data is valid
272
                                        pf_return_we; // snoop data is chnging
273
        output  wire    [(PAW-1):0]      pf_return_p;
274
        output  wire    [(VAW-1):0]      pf_return_v;
275
        output  wire                    pf_return_cachable;
276
        //
277
        //
278
 
279
//
280
//
281
//
282
        reg     [3:1]                   tlb_flags       [0:(TBL_SIZE-1)];
283
        reg     [(LGCTXT-1):0]           tlb_cdata       [0:(TBL_SIZE-1)];
284
        reg     [(DW-LGPGSZ-1):0]        tlb_vdata       [0:(TBL_SIZE-1)];
285
        reg     [(AW-LGPGSZ-1):0]        tlb_pdata       [0:(TBL_SIZE-1)];
286
 
287
        wire    adr_control, adr_status, adr_vtable, adr_ptable;
288
        wire    wr_control, wr_status, wr_vtable, wr_ptable;
289
        wire    [(LGTBL-1):0]    wr_tlb_addr;
290
        assign  wr_tlb_addr= i_wb_addr[(LGTBL):1]; // Leave bottom for V/P
291
        assign  adr_control= (i_ctrl_cyc_stb)&&(~i_wb_addr[(LGTBL+1)])&&(~i_wb_addr[0]);
292
        assign  adr_status = (i_ctrl_cyc_stb)&&(~i_wb_addr[(LGTBL+1)])&&( i_wb_addr[0]);
293
        assign  adr_vtable = (i_ctrl_cyc_stb)&&( i_wb_addr[(LGTBL+1)])&&(~i_wb_addr[0]);
294
        assign  adr_ptable = (i_ctrl_cyc_stb)&&( i_wb_addr[(LGTBL+1)])&&( i_wb_addr[0]);
295
        assign  wr_control = (adr_control)&&(i_wb_we);
296
        assign  wr_status  = (adr_status )&&(i_wb_we);
297
        assign  wr_vtable  = (adr_vtable )&&(i_wb_we);
298
        assign  wr_ptable  = (adr_ptable )&&(i_wb_we);
299
 
300
        reg                     setup_ack, z_context, setup_this_page_flag;
301
        reg     [(DW-1):0]       setup_data;
302
        reg     [(LGCTXT-1):0]   r_context_word, setup_page;
303
        //
304
        wire    [31:0]           w_control_data,w_vtable_reg,w_ptable_reg;
305
        wire    [(LGCTXT-1):0]   w_ctable_reg;
306
        reg     [31:0]   status_word;
307
        //
308
        reg             rf_miss, rf_ropage, rf_table_err;
309
        wire    [31:0]   control_word;
310
        wire    [3:0]    lgaddr_bits, lgtblsz_bits, lgpagesz_bits,
311
                        lgcontext_bits;
312
 
313
        reg     [(AW-(LGPGSZ)):0]        r_mmu_err_vaddr;
314
        wire    [(DW-LGPGSZ):0]          w_mmu_err_vaddr;
315
        //
316
        reg                     r_pending, r_we, last_page_valid, last_ro, r_valid;
317
        reg     [(DW-1):0]       r_addr;
318
        reg     [(DW-1):0]       r_data;
319
        reg     [(PAW-1):0]      last_ppage;
320
        reg     [(VAW-1):0]      last_vpage;
321
        //
322
        wire    [(TBL_SIZE-1):0] r_tlb_match;
323
        reg     [(LGTBL-1):0]            s_tlb_addr;
324
        reg                             s_tlb_miss, s_tlb_hit, s_pending;
325
        //
326
        wire    ro_flag, simple_miss, ro_miss, table_err, cachable;
327
        reg     p_tlb_miss,p_tlb_err, pf_stb, pf_cachable;
328
        //
329
        reg     rtn_err;
330
 
331
 
332
        //////////////////////////////////////////
333
        //
334
        //
335
        // Step one -- handle the control bus--i_ctrl_cyc_stb
336
        //
337
        //
338
        //////////////////////////////////////////
339
        always @(posedge i_clk)
340
        begin
341
                // Write to the Translation lookaside buffer
342
                if (wr_vtable)
343
                        tlb_vdata[wr_tlb_addr]<=i_wb_data[(DW-1):LGPGSZ];
344
                if (wr_ptable)
345
                        tlb_pdata[wr_tlb_addr]<=i_wb_data[(AW-1):LGPGSZ];
346
                // Set the context register for the page
347
                if ((wr_vtable)||(wr_ptable))
348
                        tlb_flags[wr_tlb_addr] <= i_wb_data[3:1];
349
                // Otherwise, keep track of the accessed bit if we ever access this page
350
                else if ((!z_context)&&(r_pending)&&(s_tlb_hit)&&((!r_we)||(!ro_flag)))
351
                        tlb_flags[s_tlb_addr][2] <= 1'b1;
352
                if (wr_vtable)
353
                        tlb_cdata[wr_tlb_addr][((LGCTXT>=8)? 7:(LGCTXT-1)):0]
354
                                <= i_wb_data[((LGCTXT>=8)? 11:(4+LGCTXT-1)):4];
355
                if ((wr_ptable)&&(LGCTXT > 8))
356
                        tlb_cdata[wr_tlb_addr][(LGCTXT-1):8]
357
                                <= i_wb_data[(4+LGCTXT-8-1):4];
358
                setup_ack <= (i_ctrl_cyc_stb)&&(!i_reset);
359
        end
360
        // Writing to the control word
361
        initial z_context = 1'b1;
362
        initial r_context_word = 0;
363
        always @(posedge i_clk)
364
        if (wr_control)
365
                begin
366
                r_context_word <= i_wb_data[(LGCTXT-1):0];
367
                z_context      <= (i_wb_data[(LGCTXT-1):0] == {(LGCTXT){1'b0}});
368
                end
369
        // Status words cannot be written to
370
 
371
        /* verilator lint_off WIDTH */
372
        assign  w_control_data[31:28] = AW-17;
373
        assign  w_control_data[27:24] = LGTBL;
374
        assign  w_control_data[23:20] = LGPGSZ-8;
375
        assign  w_control_data[19:16] = LGCTXT-1;
376
        /* verilator lint_on WIDTH */
377
        assign  w_control_data[15: 0] = {{(16-LGCTXT){1'b0}}, r_context_word};
378
        //
379
        assign  w_vtable_reg[(DW-1):LGPGSZ] = tlb_vdata[wr_tlb_addr];
380
        assign  w_vtable_reg[(LGPGSZ-1):(LGLCTX+4-1)] = 0;
381
        assign  w_vtable_reg[(LGLCTX+4-1):4] = { tlb_cdata[wr_tlb_addr][(LGLCTX-1):0] };
382
        assign  w_vtable_reg[ 3:0]  = { tlb_flags[wr_tlb_addr], 1'b0 };
383
        //
384
        assign  w_ptable_reg[(DW-1):LGPGSZ] = { {(DW-AW){1'b0}},
385
                                        tlb_pdata[wr_tlb_addr] };
386
        assign  w_ptable_reg[LGPGSZ:(4+LGHCTX)] = 0;
387
        assign  w_ptable_reg[ 3:0]  = { tlb_flags[wr_tlb_addr], 1'b0 };
388
        assign  w_ctable_reg = tlb_cdata[wr_tlb_addr];
389
        //
390
        generate
391
                if (4+LGHCTX-1>4)
392
                        assign  w_ptable_reg[(4+LGHCTX-1):4] =  {
393
                                tlb_cdata[wr_tlb_addr][(LGCTXT-1):LGLCTX] };
394
        endgenerate
395
 
396
        // Now, reading from the bus
397
        always @(posedge i_clk)
398
                setup_page <= w_ctable_reg;
399
        always @(posedge i_clk)
400
                setup_this_page_flag <= (i_ctrl_cyc_stb)&&(i_wb_addr[LGTBL+1]);
401
        always @(posedge i_clk)
402
                case({i_wb_addr[LGTBL+1],i_wb_addr[0]})
403
                2'b00: setup_data <= w_control_data;
404
                2'b01: setup_data <= status_word;
405
                2'b10: setup_data <= w_vtable_reg;
406
                2'b11: setup_data <= w_ptable_reg;
407
                endcase
408
 
409
 
410
 
411
        //////////////////////////////////////////
412
        //
413
        //
414
        // Step two -- handle the page lookup on the master bus
415
        //
416
        //
417
        //////////////////////////////////////////
418
        assign w_mmu_err_vaddr = { {(DW-AW){1'b0}}, r_mmu_err_vaddr };
419
 
420
        //
421
        //
422
        // First clock, and the r_ register, copies the bus data from the bus.
423
        // While this increases the bus latency, it also gives us a moment to
424
        // work.
425
        //
426
        //
427
        initial r_pending = 1'b0;
428
        initial r_valid   = 1'b0;
429
        always @(posedge i_clk)
430
        begin
431
                if (!o_rtn_stall)
432
                begin
433
                        r_pending <= i_wbm_stb;
434
                        r_we      <= i_wb_we;
435
                        r_addr    <= i_wb_addr;
436
                        r_data    <= i_wb_data;
437
                        r_valid   <= (i_wbm_stb)&&((z_context)||((last_page_valid)
438
                                        &&(i_wb_addr[(DW-1):LGPGSZ] == last_vpage)
439
                                        &&((!last_ro)||(!i_wb_we))));
440
                        s_pending <= 1'b0;
441
                end else begin
442
                        r_valid <= (r_valid)||((last_page_valid)
443
                                        &&(r_addr[(DW-1):LGPGSZ] == last_vpage)
444
                                        &&((!last_ro)||(!r_we)));
445
                        r_pending<= (r_pending)&&(i_wbm_cyc);
446
                        s_pending <= r_pending;
447
                end
448
 
449
                if (i_reset)
450
                        r_pending <= 1'b0;
451
        end
452
        // Second clock: know which buffer entry this belong in.
453
        // If we don't already know, then the pipeline must be stalled for a
454
        // while ...
455
        genvar k, s;
456
        generate
457
        for(k=0; k<TBL_BITS; k = k + 1)
458
                assign r_tlb_match[k] =
459
                        // Virtual address must match
460
                        ((tlb_vdata[k] == r_addr[(DW-1):LGPGSZ])
461
                        // Context must match as well
462
                                &&(tlb_cdata[k] == r_context_word));
463
        endgenerate
464
 
465
        initial s_tlb_miss = 1'b0;
466
        initial s_tlb_hit  = 1'b0;
467
        generate
468
        always @(posedge i_clk)
469
        begin // valid when s_ becomes valid
470
                s_tlb_addr <= {(LGTBL){1'b0}};
471
                for(k=0; k<TBL_SIZE; k=k+1)
472
                        for(s=0; s<LGTBL; s=s+1)
473
                                if (((k&(1<<s))!=0)&&(r_tlb_match[k]))
474
                                        s_tlb_addr[s] <= 1'b1;
475
                s_tlb_miss <= (r_pending)&&(r_tlb_match[(TBL_BITS-1):0] == 0);
476
                s_tlb_hit <= 1'b0;
477
                for(k=0; k<TBL_SIZE; k=k+1)
478
                        if (r_tlb_match == (1<<k))
479
                                s_tlb_hit <= (r_pending);
480
        end endgenerate
481
 
482
 
483
        // Third clock: Read from the address the virtual table offset,
484
        // whether read-only, etc.
485
        assign  ro_flag     = tlb_flags[s_tlb_addr][3];
486
        assign  simple_miss = (s_pending)&&(s_tlb_miss);
487
        assign  ro_miss     = (s_pending)&&(s_tlb_hit)&&(r_we)&&(ro_flag);
488
        assign  table_err   = (s_pending)&&(!s_tlb_miss)&&(!s_tlb_hit);
489
        assign  cachable    = tlb_flags[s_tlb_addr][1];
490
        // assign       tlb_access_flag    = tlb_flags[s_tlb_addr][2];
491
        initial pf_stb = 1'b0;
492
        initial p_tlb_err  = 1'b0;
493
        initial p_tlb_miss = 1'b0;
494
        always @(posedge i_clk)
495
        begin
496
                p_tlb_miss <= (simple_miss)||(ro_miss);
497
                p_tlb_err  <= (s_pending)&&((!s_tlb_miss)&&(!s_tlb_hit));
498
 
499
                pf_cachable <= cachable;
500
                if ((!z_context)&&(r_pending))
501
                begin
502
                        last_ppage <= tlb_pdata[s_tlb_addr];
503
                        last_vpage <= tlb_vdata[s_tlb_addr];
504
                        last_ro    <= ro_flag;
505
                        pf_stb <= 1'b1;
506
                end else
507
                        pf_stb <= 1'b0;
508
                if ((table_err)||(ro_miss)||(simple_miss))
509
                        status_word <= { r_addr[(DW-1):LGPGSZ],
510
                                {(LGPGSZ-3){1'b0}},
511
                                (table_err), (ro_miss), (simple_miss) };
512
 
513
                if (wr_control)
514
                        last_page_valid <= (last_page_valid)
515
                          &&(r_context_word == i_wb_data[(LGCTXT-1):0]);
516
                else if ((r_pending)&&(!z_context))
517
                        last_page_valid <= (s_tlb_hit)&&(!ro_miss);
518
 
519
                if (i_reset)
520
                        last_page_valid <= 1'b0;
521
        end
522
 
523
        initial rtn_err = 1'b0;
524
        always @(posedge i_clk)
525
        begin
526
                o_cyc <=  (!i_reset)&&(i_wbm_cyc);
527
 
528
                o_rtn_ack  <= (!i_reset)&&((setup_ack)||(i_wbm_cyc)&&(i_ack));
529
                o_rtn_data <= (setup_ack) ? setup_data : i_data;
530
                if (setup_this_page_flag)
531
                        o_rtn_data[0] <= ((setup_page == r_context_word)? 1'b1:1'b0);
532
                rtn_err  <= (!i_reset)&&(i_wbm_cyc)&&(i_err);
533
        end
534
        assign  o_stb = (r_valid);
535
        assign  o_we  =  (r_we);
536
        assign  o_rtn_stall = (i_wbm_cyc)&&(((r_pending)&&(!r_valid))||(i_stall));
537
        assign  o_rtn_miss  = p_tlb_miss;
538
        assign  o_rtn_err   = (rtn_err)||(p_tlb_err);
539
 
540
        assign  o_addr[(AW-1):0] = {(z_context)?
541
                                r_addr[(AW-1):LGPGSZ] : last_ppage,
542
                        r_addr[(LGPGSZ-1):0]};
543
        assign  o_data = r_data;
544
 
545
        //
546
        // Bus snooping returns ...
547
        //
548
        assign  pf_return_stb = pf_stb;
549
        assign  pf_return_we = r_we;
550
        assign  pf_return_p  = last_ppage;
551
        assign  pf_return_v  = last_vpage;
552
        assign  pf_return_cachable = pf_cachable;
553
 
554
endmodule

powered by: WebSVN 2.1.0

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