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

Subversion Repositories w11

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

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

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

powered by: WebSVN 2.1.0

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