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

Subversion Repositories w11

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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