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

Subversion Repositories w11

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 13 wfjm
-- $Id: pdp11_mmu.vhd 427 2011-11-19 21:04:11Z mueller $
2 2 wfjm
--
3 13 wfjm
-- Copyright 2006-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_mmu - syn
16
-- Description:    pdp11: mmu - memory management unit
17
--
18
-- Dependencies:   pdp11_mmu_sadr
19
--                 pdp11_mmu_ssr12
20
--                 ibus/ib_sres_or_3
21 8 wfjm
--                 ibus/ib_sel
22 2 wfjm
--
23
-- Test bench:     tb/tb_pdp11_core (implicit)
24
-- Target Devices: generic
25 13 wfjm
-- Tool versions:  xst 8.2, 9.1, 9.2, 12.1, 13.1; ghdl 0.18-0.29
26 8 wfjm
--
27 2 wfjm
-- Revision History: 
28
-- Date         Rev Version  Comment
29 13 wfjm
-- 2011-11-18   427   1.4.2  now numeric_std clean
30 8 wfjm
-- 2010-10-23   335   1.4.1  use ib_sel
31
-- 2010-10-17   333   1.4    use ibus V2 interface
32 2 wfjm
-- 2010-06-20   307   1.3.7  rename cpacc to cacc in mmu_cntl_type
33
-- 2009-05-30   220   1.3.6  final removal of snoopers (were already commented)
34
-- 2009-05-09   213   1.3.5  BUGFIX: tie inst_compl permanentely '0'
35
--                           BUGFIX: set ssr0 trap_mmu even when traps disabled
36
-- 2008-08-22   161   1.3.4  rename pdp11_ibres_ -> ib_sres_, ubf_ -> ibf_
37
-- 2008-04-27   139   1.3.3  allow ssr1/2 tracing even with mmu_ena=0
38
-- 2008-04-25   138   1.3.2  add BRESET port, clear ssr0/3 with BRESET
39
-- 2008-03-02   121   1.3.1  remove snoopers
40
-- 2008-02-24   119   1.3    return always mapped address in PADDRH; remove
41
--                           cpacc handling; PADDR generation now on _vmbox
42
-- 2008-01-05   110   1.2.1  rename _mmu_regs -> _mmu_sadr
43
--                           rename IB_MREQ(ena->req) SRES(sel->ack, hold->busy)
44
-- 2008-01-01   109   1.2    use pdp11_mmu_regs (rather than _regset)
45
-- 2007-12-31   108   1.1.1  remove SADR memory address mux (-> _mmu_regfile)
46
-- 2007-12-30   107   1.1    use IB_MREQ/IB_SRES interface now
47
-- 2007-06-14    56   1.0.1  Use slvtypes.all
48
-- 2007-05-12    26   1.0    Initial version 
49
------------------------------------------------------------------------------
50
 
51
library ieee;
52
use ieee.std_logic_1164.all;
53 13 wfjm
use ieee.numeric_std.all;
54 2 wfjm
 
55
use work.slvtypes.all;
56
use work.iblib.all;
57
use work.pdp11.all;
58
 
59
-- ----------------------------------------------------------------------------
60
 
61
entity pdp11_mmu is                     -- mmu - memory management unit
62
  port (
63
    CLK : in slbit;                     -- clock
64
    CRESET : in slbit;                  -- console reset
65
    BRESET : in slbit;                  -- ibus reset
66
    CNTL : in mmu_cntl_type;            -- control port
67
    VADDR : in slv16;                   -- virtual address
68
    MONI : in mmu_moni_type;            -- monitor port
69
    STAT : out mmu_stat_type;           -- status port
70
    PADDRH : out slv16;                 -- physical address (upper 16 bit)
71
    IB_MREQ: in ib_mreq_type;           -- ibus request
72
    IB_SRES: out ib_sres_type           -- ibus response
73
  );
74
end pdp11_mmu;
75
 
76
architecture syn of pdp11_mmu is
77
 
78 13 wfjm
  constant ibaddr_ssr0 : slv16 := slv(to_unsigned(8#177572#,16));
79
  constant ibaddr_ssr3 : slv16 := slv(to_unsigned(8#172516#,16));
80 2 wfjm
 
81
  constant ssr0_ibf_abo_nonres : integer := 15;
82
  constant ssr0_ibf_abo_length : integer := 14;
83
  constant ssr0_ibf_abo_rdonly : integer := 13;
84
  constant ssr0_ibf_trap_mmu : integer := 12;
85
  constant ssr0_ibf_ena_trap : integer := 9;
86
  constant ssr0_ibf_inst_compl : integer := 7;
87
  subtype  ssr0_ibf_seg_mode is integer range 6 downto 5;
88
  constant ssr0_ibf_dspace : integer := 4;
89
  subtype  ssr0_ibf_seg_num is integer range 3 downto 1;
90
  constant ssr0_ibf_ena_mmu : integer := 0;
91
 
92
  constant ssr3_ibf_ena_ubmap : integer := 5;
93
  constant ssr3_ibf_ena_22bit : integer := 4;
94
  constant ssr3_ibf_dspace_km : integer := 2;
95
  constant ssr3_ibf_dspace_sm : integer := 1;
96
  constant ssr3_ibf_dspace_um : integer := 0;
97
 
98
  signal IBSEL_SSR0 : slbit := '0';     -- ibus select SSR0
99
  signal IBSEL_SSR3 : slbit := '0';     -- ibus select SSR3
100
 
101
  signal R_SSR0 : mmu_ssr0_type := mmu_ssr0_init;
102
  signal N_SSR0 : mmu_ssr0_type := mmu_ssr0_init;
103
 
104
  signal R_SSR3 : mmu_ssr3_type := mmu_ssr3_init;
105
 
106
  signal ASN : slv4 := "0000";          -- augmented segment number (1+3 bit)
107
  signal AIB_WE : slbit := '0';         -- update AIB
108
  signal AIB_SETA : slbit := '0';       -- set A bit in access information bits
109
  signal AIB_SETW : slbit := '0';       -- set W bit in access information bits
110
 
111
  signal TRACE : slbit := '0';          -- enable tracing in ssr1/2
112
  signal DSPACE : slbit := '0';         -- use dspace
113
 
114
  signal IB_SRES_SADR  : ib_sres_type := ib_sres_init;
115
  signal IB_SRES_SSR12 : ib_sres_type := ib_sres_init;
116
  signal IB_SRES_SSR03 : ib_sres_type := ib_sres_init;
117
 
118
  signal SARSDR : sarsdr_type := sarsdr_init;
119
 
120
begin
121
 
122
  SADR : pdp11_mmu_sadr port map (
123
    CLK      => CLK,
124
    MODE     => CNTL.mode,
125
    ASN      => ASN,
126
    AIB_WE   => AIB_WE,
127
    AIB_SETA => AIB_SETA,
128
    AIB_SETW => AIB_SETW,
129
    SARSDR   => SARSDR,
130
    IB_MREQ  => IB_MREQ,
131
    IB_SRES  => IB_SRES_SADR);
132
 
133
  SSR12 : pdp11_mmu_ssr12 port map (
134
    CLK     => CLK,
135
    CRESET  => CRESET,
136
    TRACE   => TRACE,
137
    MONI    => MONI,
138
    IB_MREQ => IB_MREQ,
139
    IB_SRES => IB_SRES_SSR12);
140
 
141 8 wfjm
  SRES_OR : ib_sres_or_3
142 2 wfjm
    port map (
143
      IB_SRES_1  => IB_SRES_SADR,
144
      IB_SRES_2  => IB_SRES_SSR12,
145
      IB_SRES_3  => IB_SRES_SSR03,
146
      IB_SRES_OR => IB_SRES);
147
 
148 8 wfjm
  SEL_SSR0 : ib_sel
149
    generic map (
150
      IB_ADDR => ibaddr_ssr0)
151
    port map (
152
      CLK     => CLK,
153
      IB_MREQ => IB_MREQ,
154
      SEL     => IBSEL_SSR0
155
    );
156
  SEL_SSR3 : ib_sel
157
    generic map (
158
      IB_ADDR => ibaddr_ssr3)
159
    port map (
160
      CLK     => CLK,
161
      IB_MREQ => IB_MREQ,
162
      SEL     => IBSEL_SSR3
163
    );
164 2 wfjm
 
165 8 wfjm
  proc_ibres : process (IBSEL_SSR0, IBSEL_SSR3, IB_MREQ, R_SSR0, R_SSR3)
166 2 wfjm
 
167
    variable ssr0out : slv16 := (others=>'0');
168
    variable ssr3out : slv16 := (others=>'0');
169
 
170
  begin
171
 
172
    ssr0out := (others=>'0');
173
    if IBSEL_SSR0 = '1' then
174
      ssr0out(ssr0_ibf_abo_nonres) := R_SSR0.abo_nonres;
175
      ssr0out(ssr0_ibf_abo_length) := R_SSR0.abo_length;
176
      ssr0out(ssr0_ibf_abo_rdonly) := R_SSR0.abo_rdonly;
177
      ssr0out(ssr0_ibf_trap_mmu)   := R_SSR0.trap_mmu;
178
      ssr0out(ssr0_ibf_ena_trap)   := R_SSR0.ena_trap;
179
      ssr0out(ssr0_ibf_inst_compl) := R_SSR0.inst_compl;
180
      ssr0out(ssr0_ibf_seg_mode)   := R_SSR0.seg_mode;
181
      ssr0out(ssr0_ibf_dspace)     := R_SSR0.dspace;
182
      ssr0out(ssr0_ibf_seg_num)    := R_SSR0.seg_num;
183
      ssr0out(ssr0_ibf_ena_mmu)    := R_SSR0.ena_mmu;
184
    end if;
185
 
186
    ssr3out := (others=>'0');
187
    if IBSEL_SSR3 = '1' then
188
      ssr3out(ssr3_ibf_ena_ubmap) := R_SSR3.ena_ubmap;
189
      ssr3out(ssr3_ibf_ena_22bit) := R_SSR3.ena_22bit;
190
      ssr3out(ssr3_ibf_dspace_km) := R_SSR3.dspace_km;
191
      ssr3out(ssr3_ibf_dspace_sm) := R_SSR3.dspace_sm;
192
      ssr3out(ssr3_ibf_dspace_um) := R_SSR3.dspace_um;
193
    end if;
194
 
195
    IB_SRES_SSR03.dout <= ssr0out or ssr3out;
196 8 wfjm
    IB_SRES_SSR03.ack  <= (IBSEL_SSR0 or IBSEL_SSR3) and
197
                          (IB_MREQ.re or IB_MREQ.we); -- ack all
198
    IB_SRES_SSR03.busy <= '0';
199 2 wfjm
 
200 8 wfjm
  end process proc_ibres;
201 2 wfjm
 
202
  proc_ssr0 : process (CLK)
203
  begin
204 13 wfjm
    if rising_edge(CLK) then
205 2 wfjm
      if BRESET = '1' then
206
        R_SSR0 <= mmu_ssr0_init;
207
      else
208
        R_SSR0 <= N_SSR0;
209
      end if;
210
    end if;
211
  end process proc_ssr0;
212
 
213
  proc_ssr3 : process (CLK)
214
  begin
215 13 wfjm
    if rising_edge(CLK) then
216 2 wfjm
      if BRESET = '1' then
217
        R_SSR3 <= mmu_ssr3_init;
218 8 wfjm
      elsif IBSEL_SSR3='1' and IB_MREQ.we='1' then
219 2 wfjm
        if IB_MREQ.be0 = '1' then
220
          R_SSR3.ena_ubmap <= IB_MREQ.din(ssr3_ibf_ena_ubmap);
221
          R_SSR3.ena_22bit <= IB_MREQ.din(ssr3_ibf_ena_22bit);
222
          R_SSR3.dspace_km <= IB_MREQ.din(ssr3_ibf_dspace_km);
223
          R_SSR3.dspace_sm <= IB_MREQ.din(ssr3_ibf_dspace_sm);
224
          R_SSR3.dspace_um <= IB_MREQ.din(ssr3_ibf_dspace_um);
225
        end if;
226
      end if;
227
    end if;
228
  end process proc_ssr3;
229
 
230
  proc_paddr : process (R_SSR0, R_SSR3, CNTL, SARSDR, VADDR)
231
 
232
    variable ipaddrh : slv16 := (others=>'0');
233
    variable dspace_ok : slbit := '0';
234
    variable dspace_en : slbit := '0';
235
    variable asf : slv3 := (others=>'0'); -- va: active segment field
236
    variable bn : slv7 := (others=>'0');  -- va: block number
237
    variable iasn : slv4 := (others=>'0');-- augmented segment number
238
 
239
  begin
240
 
241
    asf := VADDR(15 downto 13);
242
    bn := VADDR(12 downto 6);
243
 
244
    dspace_en := '0';
245
    case CNTL.mode is
246
      when "00" => dspace_en := R_SSR3.dspace_km;
247
      when "01" => dspace_en := R_SSR3.dspace_sm;
248
      when "11" => dspace_en := R_SSR3.dspace_um;
249
      when others => null;
250
    end case;
251
    dspace_ok := CNTL.dspace and dspace_en;
252
 
253
    iasn(3) := dspace_ok;
254
    iasn(2 downto 0) := asf;
255
 
256 13 wfjm
    ipaddrh := slv(unsigned("000000000"&bn) + unsigned(SARSDR.saf));
257 2 wfjm
 
258
    DSPACE <= dspace_ok;
259
    ASN    <= iasn;
260
    PADDRH <= ipaddrh;
261
 
262
  end process proc_paddr;
263
 
264
  proc_nssr0 : process (R_SSR0, R_SSR3, IB_MREQ, IBSEL_SSR0, DSPACE,
265
                        CNTL, MONI, SARSDR, VADDR)
266
 
267
    variable nssr0 : mmu_ssr0_type := mmu_ssr0_init;
268
    variable asf : slv3 := (others=>'0');
269
    variable bn : slv7 := (others=>'0');
270
    variable abo_nonres : slbit := '0';
271
    variable abo_length : slbit := '0';
272
    variable abo_rdonly : slbit := '0';
273
    variable ssr_freeze : slbit := '0';
274
    variable doabort : slbit := '0';
275
    variable dotrap : slbit := '0';
276
    variable dotrace : slbit := '0';
277
 
278
  begin
279
 
280
    nssr0 := R_SSR0;
281
 
282
    AIB_WE   <= '0';
283
    AIB_SETA <= '0';
284
    AIB_SETW <= '0';
285
 
286
    ssr_freeze := R_SSR0.abo_nonres or R_SSR0.abo_length or R_SSR0.abo_rdonly;
287
    dotrace := not(CNTL.cacc or ssr_freeze);
288
 
289
    asf := VADDR(15 downto 13);
290
    bn := VADDR(12 downto 6);
291
 
292
    abo_nonres := '0';
293
    abo_length := '0';
294
    abo_rdonly := '0';
295
    doabort := '0';
296
    dotrap := '0';
297
 
298
    if SARSDR.ed = '0' then             -- ed=0: upward expansion
299
      if unsigned(bn) > unsigned(SARSDR.slf) then
300
        abo_length := '1';
301
      end if;
302
    else                                -- ed=0: downward expansion
303
      if unsigned(bn) < unsigned(SARSDR.slf) then
304
        abo_length := '1';
305
      end if;
306
    end if;
307
 
308
    case SARSDR.acf is                  -- evaluate accecc control field
309
 
310
      when "000" =>                     -- segment non-resident
311
        abo_nonres := '1';
312
 
313
      when "001" =>                     -- read-only; trap on read
314
        if CNTL.wacc='1' or CNTL.macc='1' then
315
          abo_rdonly := '1';
316
        end if;
317
        dotrap := '1';
318
 
319
      when "010" =>                     -- read-only
320
        if CNTL.wacc='1'  or CNTL.macc='1' then
321
          abo_rdonly := '1';
322
        end if;
323
 
324
      when "100" =>                     -- read/write; trap on read&write
325
        dotrap := '1';
326
 
327
      when "101" =>                     -- read/write; trap on write
328
        dotrap := CNTL.wacc or CNTL.macc;
329
 
330
      when "110" => null;               -- read/write;
331
 
332
      when others =>                    -- unused codes: abort access
333
        abo_nonres := '1';
334
    end case;
335
 
336 8 wfjm
    if IBSEL_SSR0='1' and IB_MREQ.we='1' then
337 2 wfjm
 
338
      if IB_MREQ.be1 = '1' then
339
        nssr0.abo_nonres := IB_MREQ.din(ssr0_ibf_abo_nonres);
340
        nssr0.abo_length := IB_MREQ.din(ssr0_ibf_abo_length);
341
        nssr0.abo_rdonly := IB_MREQ.din(ssr0_ibf_abo_rdonly);
342
        nssr0.trap_mmu   := IB_MREQ.din(ssr0_ibf_trap_mmu);
343
        nssr0.ena_trap   := IB_MREQ.din(ssr0_ibf_ena_trap);
344
      end if;
345
      if IB_MREQ.be0 = '1' then
346
        nssr0.ena_mmu := IB_MREQ.din(ssr0_ibf_ena_mmu);
347
      end if;
348
 
349
    elsif nssr0.ena_mmu='1' and CNTL.cacc='0' then
350
 
351
      if dotrace = '1' then
352
        if MONI.istart = '1' then
353
          nssr0.inst_compl := '0';
354
        elsif MONI.idone = '1' then
355
          nssr0.inst_compl := '0';      -- disable instr.compl logic 
356
        end if;
357
      end if;
358
 
359
      if CNTL.req = '1' then
360
        AIB_WE <= '1';
361
        if ssr_freeze = '0' then
362
          nssr0.abo_nonres := abo_nonres;
363
          nssr0.abo_length := abo_length;
364
          nssr0.abo_rdonly := abo_rdonly;
365
        end if;
366
        doabort := abo_nonres or abo_length or abo_rdonly;
367
 
368
        if doabort = '0' then
369
          AIB_SETA <= '1';
370
          AIB_SETW <= CNTL.wacc or CNTL.macc;
371
        end if;
372
 
373
        if ssr_freeze = '0' then
374
          nssr0.dspace   := DSPACE;
375
          nssr0.seg_num  := asf;
376
          nssr0.seg_mode := CNTL.mode;
377
        end if;
378
      end if;
379
    end if;
380
 
381
    if CNTL.req='1' and R_SSR0.ena_mmu='1' and CNTL.cacc='0' and
382
       dotrap='1' then
383
      nssr0.trap_mmu := '1';
384
    end if;
385
 
386
    nssr0.trace_prev := dotrace;
387
 
388
    if MONI.trace_prev = '0' then
389
      TRACE <= dotrace;
390
    else
391
      TRACE <= R_SSR0.trace_prev;
392
    end if;
393
 
394
    N_SSR0 <= nssr0;
395
 
396
    if R_SSR0.ena_mmu='1' and CNTL.cacc='0' then
397
      STAT.vaok <= not doabort;
398
    else
399
      STAT.vaok <= '1';
400
    end if;
401
 
402
    if R_SSR0.ena_mmu='1' and CNTL.cacc='0' and doabort='0' and
403
       R_SSR0.ena_trap='1' and R_SSR0.trap_mmu='0' and dotrap='1' then
404
      STAT.trap <= '1';
405
    else
406
      STAT.trap <= '0';
407
    end if;
408
 
409
    STAT.ena_mmu   <= R_SSR0.ena_mmu;
410
    STAT.ena_22bit <= R_SSR3.ena_22bit;
411
    STAT.ena_ubmap <= R_SSR3.ena_ubmap;
412
 
413
  end process proc_nssr0;
414
 
415
end syn;

powered by: WebSVN 2.1.0

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