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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.5/] [rtl/] [w11a/] [pdp11_cache.vhd] - Blame information for rev 25

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

Line No. Rev Author Line
1 2 wfjm
-- $Id: pdp11_cache.vhd 314 2010-07-09 17:38:41Z mueller $
2
--
3
-- Copyright 2008- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4
--
5
-- This program is free software; you may redistribute and/or modify it under
6
-- the terms of the GNU General Public License as published by the Free
7
-- Software Foundation, either version 2, or at your option any later version.
8
--
9
-- This program is distributed in the hope that it will be useful, but
10
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
11
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
-- for complete details.
13
-- 
14
------------------------------------------------------------------------------
15
-- Module Name:    pdp11_cache - syn
16
-- Description:    pdp11: cache
17
--
18
-- Dependencies:   memlib/ram_2swsr_rfirst_gen
19
-- Test bench:     -
20
-- Target Devices: generic
21
-- Tool versions:  xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25
22
-- Revision History: 
23
-- Date         Rev Version  Comment
24
-- 2008-02-23   118   1.0.2  ce cache in s_idle to avoid U's in sim
25
--                           factor invariants out of if's; fix tag rmiss logic
26
-- 2008-02-17   117   1.0.1  use em_(mreq|sres) interface; use req,we for mem
27
--                           recode, ghdl doesn't like partial vector port maps
28
-- 2008-02-16   116   1.0    Initial version 
29
------------------------------------------------------------------------------
30
 
31
library ieee;
32
use ieee.std_logic_1164.all;
33
use ieee.std_logic_arith.all;
34
 
35
use work.slvtypes.all;
36
use work.memlib.all;
37
use work.pdp11.all;
38
 
39
entity pdp11_cache is                   -- cache
40
  port (
41
    CLK : in slbit;                     -- clock
42
    GRESET : in slbit;                  -- global reset
43
    EM_MREQ : in em_mreq_type;          -- em request
44
    EM_SRES : out em_sres_type;         -- em response
45
    FMISS : in slbit;                   -- force miss
46
    CHIT : out slbit;                   -- cache hit flag
47
    MEM_REQ : out slbit;                -- memory: request
48
    MEM_WE : out slbit;                 -- memory: write enable
49
    MEM_BUSY : in slbit;                -- memory: controller busy
50
    MEM_ACK_R : in slbit;               -- memory: acknowledge read
51
    MEM_ADDR : out slv20;               -- memory: address
52
    MEM_BE : out slv4;                  -- memory: byte enable
53
    MEM_DI : out slv32;                 -- memory: data in  (memory view)
54
    MEM_DO : in slv32                   -- memory: data out (memory view)
55
  );
56
end pdp11_cache;
57
 
58
 
59
architecture syn of pdp11_cache is
60
 
61
  type state_type is (
62
    s_idle,                             -- s_idle: wait for req
63
    s_read,                             -- s_read: read cycle
64
    s_rmiss,                            -- s_rmiss: read miss
65
    s_write                             -- s_write: write cycle
66
  );
67
 
68
  type regs_type is record
69
    state : state_type;                 -- state
70
    addr_w : slbit;                     -- address - word select
71
    addr_l : slv11;                     -- address - cache line address
72
    addr_t : slv9;                      -- address - cache tag part
73
    be : slv4;                          -- byte enables (at 4 byte level)
74
    di : slv16;                         -- data
75
  end record regs_type;
76
 
77
  constant regs_init : regs_type := (
78
    s_idle,                             -- state
79
    '0',                                -- addr_w
80
    (others=>'0'),                      -- addr_l
81
    (others=>'0'),                      -- addr_t
82
    (others=>'0'),                      -- be
83
    (others=>'0')                       -- di
84
  );
85
 
86
  signal R_REGS : regs_type := regs_init;  -- state registers
87
  signal N_REGS : regs_type := regs_init;  -- next value state regs
88
 
89
  signal CMEM_TAG_CEA  : slbit := '0';
90
  signal CMEM_TAG_CEB  : slbit := '0';
91
  signal CMEM_TAG_WEA  : slbit := '0';
92
  signal CMEM_TAG_WEB  : slbit := '0';
93
  signal CMEM_TAG_DIB  : slv9  := (others=>'0');
94
  signal CMEM_TAG_DOA  : slv9  := (others=>'0');
95
  signal CMEM_DAT_CEA  : slbit := '0';
96
  signal CMEM_DAT_CEB  : slbit := '0';
97
  signal CMEM_DAT_WEA  : slv4 := "0000";
98
  signal CMEM_DAT_WEB  : slv4 := "0000";
99
  signal CMEM_DIA_0    : slv9 := (others=>'0');
100
  signal CMEM_DIA_1    : slv9 := (others=>'0');
101
  signal CMEM_DIA_2    : slv9 := (others=>'0');
102
  signal CMEM_DIA_3    : slv9 := (others=>'0');
103
  signal CMEM_DIB_0    : slv9 := (others=>'0');
104
  signal CMEM_DIB_1    : slv9 := (others=>'0');
105
  signal CMEM_DIB_2    : slv9 := (others=>'0');
106
  signal CMEM_DIB_3    : slv9 := (others=>'0');
107
  signal CMEM_DOA_0    : slv9 := (others=>'0');
108
  signal CMEM_DOA_1    : slv9 := (others=>'0');
109
  signal CMEM_DOA_2    : slv9 := (others=>'0');
110
  signal CMEM_DOA_3    : slv9 := (others=>'0');
111
 
112
begin
113
 
114
  CMEM_TAG : ram_2swsr_rfirst_gen
115
    generic map (
116
      AWIDTH => 11,
117
      DWIDTH =>  9)
118
    port map (
119
      CLKA  => CLK,
120
      CLKB  => CLK,
121
      ENA   => CMEM_TAG_CEA,
122
      ENB   => CMEM_TAG_CEB,
123
      WEA   => CMEM_TAG_WEA,
124
      WEB   => CMEM_TAG_WEB,
125
      ADDRA => EM_MREQ.addr(12 downto 2),
126
      ADDRB => R_REGS.addr_l,
127
      DIA   => EM_MREQ.addr(21 downto 13),
128
      DIB   => CMEM_TAG_DIB,
129
      DOA   => CMEM_TAG_DOA,
130
      DOB   => open
131
      );
132
 
133
  CMEM_DAT0 : ram_2swsr_rfirst_gen
134
    generic map (
135
      AWIDTH => 11,
136
      DWIDTH =>  9)
137
    port map (
138
      CLKA  => CLK,
139
      CLKB  => CLK,
140
      ENA   => CMEM_DAT_CEA,
141
      ENB   => CMEM_DAT_CEB,
142
      WEA   => CMEM_DAT_WEA(0),
143
      WEB   => CMEM_DAT_WEB(0),
144
      ADDRA => EM_MREQ.addr(12 downto 2),
145
      ADDRB => R_REGS.addr_l,
146
      DIA   => CMEM_DIA_0,
147
      DIB   => CMEM_DIB_0,
148
      DOA   => CMEM_DOA_0,
149
      DOB   => open
150
      );
151
 
152
  CMEM_DAT1 : ram_2swsr_rfirst_gen
153
    generic map (
154
      AWIDTH => 11,
155
      DWIDTH =>  9)
156
    port map (
157
      CLKA  => CLK,
158
      CLKB  => CLK,
159
      ENA   => CMEM_DAT_CEA,
160
      ENB   => CMEM_DAT_CEB,
161
      WEA   => CMEM_DAT_WEA(1),
162
      WEB   => CMEM_DAT_WEB(1),
163
      ADDRA => EM_MREQ.addr(12 downto 2),
164
      ADDRB => R_REGS.addr_l,
165
      DIA   => CMEM_DIA_1,
166
      DIB   => CMEM_DIB_1,
167
      DOA   => CMEM_DOA_1,
168
      DOB   => open
169
      );
170
 
171
  CMEM_DAT2 : ram_2swsr_rfirst_gen
172
    generic map (
173
      AWIDTH => 11,
174
      DWIDTH =>  9)
175
    port map (
176
      CLKA  => CLK,
177
      CLKB  => CLK,
178
      ENA   => CMEM_DAT_CEA,
179
      ENB   => CMEM_DAT_CEB,
180
      WEA   => CMEM_DAT_WEA(2),
181
      WEB   => CMEM_DAT_WEB(2),
182
      ADDRA => EM_MREQ.addr(12 downto 2),
183
      ADDRB => R_REGS.addr_l,
184
      DIA   => CMEM_DIA_2,
185
      DIB   => CMEM_DIB_2,
186
      DOA   => CMEM_DOA_2,
187
      DOB   => open
188
      );
189
 
190
  CMEM_DAT3 : ram_2swsr_rfirst_gen
191
    generic map (
192
      AWIDTH => 11,
193
      DWIDTH =>  9)
194
    port map (
195
      CLKA  => CLK,
196
      CLKB  => CLK,
197
      ENA   => CMEM_DAT_CEA,
198
      ENB   => CMEM_DAT_CEB,
199
      WEA   => CMEM_DAT_WEA(3),
200
      WEB   => CMEM_DAT_WEB(3),
201
      ADDRA => EM_MREQ.addr(12 downto 2),
202
      ADDRB => R_REGS.addr_l,
203
      DIA   => CMEM_DIA_3,
204
      DIB   => CMEM_DIB_3,
205
      DOA   => CMEM_DOA_3,
206
      DOB   => open
207
      );
208
 
209
  proc_regs: process (CLK)
210
  begin
211
 
212
    if CLK'event and CLK='1' then
213
      if GRESET = '1' then
214
        R_REGS <= regs_init;
215
      else
216
        R_REGS <= N_REGS;
217
      end if;
218
    end if;
219
 
220
  end process proc_regs;
221
 
222
  proc_next: process (R_REGS, EM_MREQ, FMISS,
223
                      CMEM_TAG_DOA,
224
                      CMEM_DOA_0, CMEM_DOA_1, CMEM_DOA_2, CMEM_DOA_3,
225
                      MEM_BUSY, MEM_ACK_R, MEM_DO)
226
 
227
    variable r : regs_type := regs_init;
228
    variable n : regs_type := regs_init;
229
 
230
    variable iaddr_w : slbit := '0';
231
    variable iaddr_l : slv11 := (others=>'0');
232
    variable iaddr_t : slv9  := (others=>'0');
233
 
234
    variable itagok : slbit := '0';
235
    variable ivalok : slbit := '0';
236
 
237
    variable icmem_tag_cea : slbit := '0';
238
    variable icmem_tag_ceb : slbit := '0';
239
    variable icmem_tag_wea : slbit := '0';
240
    variable icmem_tag_web : slbit := '0';
241
    variable icmem_tag_dib : slv9  := (others=>'0');
242
    variable icmem_dat_cea : slbit := '0';
243
    variable icmem_dat_ceb : slbit := '0';
244
    variable icmem_dat_wea : slv4  := "0000";
245
    variable icmem_dat_web : slv4  := "0000";
246
    variable icmem_val_doa : slv4  := "0000";
247
    variable icmem_dat_doa : slv32 := (others=>'0');
248
    variable icmem_val_dib : slv4  := "0000";
249
    variable icmem_dat_dib : slv32 := (others=>'0');
250
 
251
    variable iackr : slbit := '0';
252
    variable iackw : slbit := '0';
253
    variable ichit : slbit := '0';
254
    variable iosel : slv2  := "11";
255
 
256
    variable imem_reqr : slbit := '0';
257
    variable imem_reqw : slbit := '0';
258
    variable imem_be   : slv4  := "0000";
259
 
260
  begin
261
 
262
    r := R_REGS;
263
    n := R_REGS;
264
 
265
    iaddr_w := EM_MREQ.addr(1);                -- get word select
266
    iaddr_l := EM_MREQ.addr(12 downto 2);      -- get cache line addr
267
    iaddr_t := EM_MREQ.addr(21 downto 13);     -- get cache tag part
268
 
269
    icmem_tag_cea := '0';
270
    icmem_tag_ceb := '0';
271
    icmem_tag_wea := '0';
272
    icmem_tag_web := '0';
273
    icmem_tag_dib := r.addr_t;          -- default, local define whenver used
274
    icmem_dat_cea := '0';
275
    icmem_dat_ceb := '0';
276
    icmem_dat_wea := "0000";
277
    icmem_dat_web := "0000";
278
    icmem_val_dib := "0000";
279
    icmem_dat_dib := MEM_DO;            -- default, local define whenver used
280
 
281
    icmem_val_doa(0)            := CMEM_DOA_0(8);
282
    icmem_dat_doa( 7 downto  0) := CMEM_DOA_0(7 downto 0);
283
    icmem_val_doa(1)            := CMEM_DOA_1(8);
284
    icmem_dat_doa(15 downto  8) := CMEM_DOA_1(7 downto 0);
285
    icmem_val_doa(2)            := CMEM_DOA_2(8);
286
    icmem_dat_doa(23 downto 16) := CMEM_DOA_2(7 downto 0);
287
    icmem_val_doa(3)            := CMEM_DOA_3(8);
288
    icmem_dat_doa(31 downto 24) := CMEM_DOA_3(7 downto 0);
289
 
290
    itagok := '0';
291
    if CMEM_TAG_DOA = r.addr_t then  -- cache tag hit
292
      itagok := '1';
293
    end if;
294
    ivalok := '0';
295
    if (icmem_val_doa and r.be) = r.be then
296
      ivalok := '1';
297
    end if;
298
 
299
    iackr := '0';
300
    iackw := '0';
301
    ichit := '0';
302
    iosel := "11";                      -- default to ext. mem data
303
                                        -- this prevents U's from cache bram's
304
                                        -- to propagate to dout in beginning...
305
 
306
    imem_reqr := '0';
307
    imem_reqw := '0';
308
    imem_be   := r.be;
309
 
310
    case r.state is
311
      when s_idle =>                    -- s_idle: wait for req
312
        n.addr_w := iaddr_w;              -- capture address: word select
313
        n.addr_l := iaddr_l;              -- capture address: cache line addr
314
        n.addr_t := iaddr_t;              -- capture address: cache tag part
315
        n.be     := "0000";
316
        icmem_tag_cea := '1';             -- access cache tag port A
317
        icmem_dat_cea := '1';             -- access cache data port A
318
        if iaddr_w = '0' then             -- capture byte enables at 4 byte lvl
319
          n.be(1 downto 0) := EM_MREQ.be;
320
        else
321
          n.be(3 downto 2) := EM_MREQ.be;
322
        end if;
323
        n.di     := EM_MREQ.din;          -- capture data
324
 
325
        if EM_MREQ.req = '1' then         -- if access requested
326
          if EM_MREQ.we = '0' then          -- if READ requested
327
            n.state := s_read;                -- next: read
328
 
329
          else                              -- if WRITE requested
330
            icmem_tag_wea := '1';             -- write tag
331
            icmem_dat_wea := n.be;            -- write cache data
332
            n.state := s_write;               -- next: write
333
          end if;
334
        end if;
335
 
336
      when s_read =>                    -- s_read: read cycle
337
        iosel := '0' & r.addr_w;          -- output select: cache
338
        imem_be := "1111";                -- mem read: all 4 bytes
339
        if EM_MREQ.cancel = '0' then
340
          if FMISS='0' and itagok='1' and ivalok='1' then -- read tag&val hit
341
            iackr := '1';                   -- signal read acknowledge
342
            ichit := '1';                   -- signal cache hit
343
            n.state := s_idle;              -- next: back to idle 
344
          else                            -- read miss
345
            if MEM_BUSY = '0' then          -- if mem not busy
346
              imem_reqr :='1';                -- request mem read
347
              n.state := s_rmiss;             -- next: rmiss, wait for mem data
348
            end if;
349
          end if;
350
        else
351
          n.state := s_idle;              -- next: back to idle 
352
        end if;
353
 
354
      when s_rmiss =>                   -- s_rmiss: read cycle
355
        iosel := '1' & r.addr_w;          -- output select: memory
356
        icmem_tag_web := '1';             -- cache update: write tag
357
        icmem_tag_dib := r.addr_t;        -- cache update: new tag
358
        icmem_val_dib := "1111";          -- cache update: all valid
359
        icmem_dat_dib := MEM_DO;          -- cache update: data from mem
360
        icmem_dat_web := "1111";          -- cache update: write all 4 bytes
361
        if MEM_ACK_R = '1' then           -- mem data valid
362
          iackr := '1';                     -- signal read acknowledge
363
          icmem_tag_ceb := '1';             -- access cache tag  port B
364
          icmem_dat_ceb := '1';             -- access cache data port B
365
          n.state := s_idle;                -- next: back to idle
366
        end if;
367
 
368
      when s_write =>                   -- s_write: write cycle
369
        icmem_tag_dib := CMEM_TAG_DOA;    -- cache restore: last state 
370
        icmem_dat_dib := icmem_dat_doa;   -- cache restore: last state 
371
        if EM_MREQ.cancel = '0' then      -- request ok
372
          if MEM_BUSY = '0' then            -- if mem not busy
373
            if itagok = '0' then              -- if write tag miss
374
              icmem_dat_ceb := '1';             -- access cache (invalidate)
375
              icmem_dat_web := not r.be;        -- write missed bytes
376
              icmem_val_dib := "0000";          -- invalidate missed bytes
377
            end if;
378
            imem_reqw := '1';                 -- write back to main memory
379
            iackw := '1';                     -- and done
380
            n.state := s_idle;                -- next: back to idle
381
          end if;
382
 
383
        else                              -- request canceled -> restore
384
          icmem_tag_ceb := '1';             -- access cache line
385
          icmem_tag_web := '1';             -- write tag
386
          icmem_dat_ceb := '1';             -- access cache line
387
          icmem_dat_web := "1111";          -- restore cache line
388
          icmem_val_dib := icmem_val_doa;   -- cache restore: last state 
389
          n.state := s_idle;                -- next: back to idle          
390
        end if;
391
 
392
      when others => null;
393
    end case;
394
 
395
    N_REGS <= n;
396
 
397
    CMEM_TAG_CEA <= icmem_tag_cea;
398
    CMEM_TAG_CEB <= icmem_tag_ceb;
399
    CMEM_TAG_WEA <= icmem_tag_wea;
400
    CMEM_TAG_WEB <= icmem_tag_web;
401
    CMEM_TAG_DIB <= icmem_tag_dib;
402
    CMEM_DAT_CEA <= icmem_dat_cea;
403
    CMEM_DAT_CEB <= icmem_dat_ceb;
404
    CMEM_DAT_WEA <= icmem_dat_wea;
405
    CMEM_DAT_WEB <= icmem_dat_web;
406
 
407
    CMEM_DIA_0(8)          <= '1';
408
    CMEM_DIA_0(7 downto 0) <= EM_MREQ.din( 7 downto 0);
409
    CMEM_DIA_1(8)          <= '1';
410
    CMEM_DIA_1(7 downto 0) <= EM_MREQ.din(15 downto 8);
411
    CMEM_DIA_2(8)          <= '1';
412
    CMEM_DIA_2(7 downto 0) <= EM_MREQ.din( 7 downto 0);
413
    CMEM_DIA_3(8)          <= '1';
414
    CMEM_DIA_3(7 downto 0) <= EM_MREQ.din(15 downto 8);
415
 
416
    CMEM_DIB_0(8)          <= icmem_val_dib(0);
417
    CMEM_DIB_0(7 downto 0) <= icmem_dat_dib(7 downto 0);
418
    CMEM_DIB_1(8)          <= icmem_val_dib(1);
419
    CMEM_DIB_1(7 downto 0) <= icmem_dat_dib(15 downto 8);
420
    CMEM_DIB_2(8)          <= icmem_val_dib(2);
421
    CMEM_DIB_2(7 downto 0) <= icmem_dat_dib(23 downto 16);
422
    CMEM_DIB_3(8)          <= icmem_val_dib(3);
423
    CMEM_DIB_3(7 downto 0) <= icmem_dat_dib(31 downto 24);
424
 
425
    EM_SRES <= em_sres_init;
426
    EM_SRES.ack_r <= iackr;
427
    EM_SRES.ack_w <= iackw;
428
    case iosel is
429
      when "00" => EM_SRES.dout <= icmem_dat_doa(15 downto  0);
430
      when "01" => EM_SRES.dout <= icmem_dat_doa(31 downto 16);
431
      when "10" => EM_SRES.dout <= MEM_DO(15 downto  0);
432
      when "11" => EM_SRES.dout <= MEM_DO(31 downto 16);
433
      when others => null;
434
    end case;
435
 
436
    CHIT  <= ichit;
437
 
438
    MEM_REQ  <= imem_reqr or imem_reqw;
439
    MEM_WE   <= imem_reqw;
440
    MEM_ADDR <= r.addr_t & r.addr_l;
441
    MEM_BE   <= imem_be;
442
    MEM_DI   <= r.di & r.di;
443
 
444
  end process proc_next;
445
 
446
end syn;

powered by: WebSVN 2.1.0

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