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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.74/] [rtl/] [w11a/] [pdp11_vmbox.vhd] - Blame information for rev 38

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 37 wfjm
-- $Id: pdp11_vmbox.vhd 784 2016-07-09 22:17:01Z mueller $
2 2 wfjm
--
3 36 wfjm
-- Copyright 2006-2016 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_vmbox - syn
16
-- Description:    pdp11: virtual memory
17
--
18
-- Dependencies:   pdp11_mmu
19
--                 pdp11_ubmap
20
--                 ibus/ib_sres_or_4
21
--                 ibus/ib_sres_or_2
22 8 wfjm
--                 ibus/ib_sel
23 2 wfjm
--
24
-- Test bench:     tb/tb_pdp11_core (implicit)
25
-- Target Devices: generic
26 36 wfjm
-- Tool versions:  ise 8.2-14.7; viv 2014.4-2016.1; ghdl 0.18-0.33
27 8 wfjm
--
28 2 wfjm
-- Revision History: 
29
-- Date         Rev Version  Comment
30 37 wfjm
-- 2016-05-22   767   1.6.6  don't init N_REGS (vivado fix for fsm inference)
31 34 wfjm
-- 2015-07-03   697   1.6.5  much wider DM_STAT_VM
32 30 wfjm
-- 2015-04-04   662   1.6.4  atowidth now 6 (was 5) to support ibdr_rprm reset
33 13 wfjm
-- 2011-11-18   427   1.6.3  now numeric_std clean
34 8 wfjm
-- 2010-10-23   335   1.6.2  add r.paddr_iopage, use ib_sel
35
-- 2010-10-22   334   1.6.1  deassert ibus be's at end-cycle; fix rmw logic
36
-- 2010-10-17   333   1.6    implement ibus V2 interface
37 2 wfjm
-- 2010-06-27   310   1.5    redo ibus driver logic, now ibus driven from flops
38
-- 2010-06-20   307   1.4.2  rename cpacc to cacc in vm_cntl_type, mmu_cntl_type
39
-- 2010-06-18   306   1.4.1  for cpacc: set cacc in ib_mreq, forward racc,be
40
--                           from CP_ADDR; now all ibr handling via vmbox
41
-- 2010-06-13   305   1.4    rename CPADDR -> CP_ADDR
42
-- 2009-06-01   221   1.3.8  add dip signal in ib_mreq (set in s_ib)
43
-- 2009-05-30   220   1.3.7  final removal of snoopers (were already commented)
44
-- 2009-05-01   211   1.3.6  BUGFIX: add 177776 stack protect (SCCE)
45
-- 2008-08-22   161   1.3.5  rename pdp11_ibres_ -> ib_sres_, ubf_ -> ibf_
46
-- 2008-04-25   138   1.3.4  add BRESET port, clear stklim with BRESET
47
-- 2008-04-20   137   1.3.3  add DM_STAT_VM port
48
-- 2008-03-19   127   1.3.2  ignore ack state when waiting on a busy IB in s_ib
49
-- 2008-03-02   121   1.3.1  remove snoopers
50
-- 2008-02-24   119   1.3    revamp paddr generation; add _ubmap
51
-- 2008-02-23   118   1.2.1  use sys_conf_mem_losize
52
-- 2008-02-17   117   1.2    use em_(mreq|sres) interface for external memory
53
-- 2008-01-26   114   1.1.4  rename 'ubus' to 'ib' (proper name of intbus now)
54
-- 2008-01-05   110   1.1.3  update snooper.
55
--                           rename IB_MREQ(ena->req) SRES(sel->ack, hold->busy)
56
-- 2008-01-01   109   1.1.2  Use IB_SRES_(CPU|EXT); use r./n. coding style, move
57
--                           all status into regs_type. add intbus HOLD support.
58
-- 2007-12-30   108   1.1.1  use ubf_byte[01]
59
-- 2007-12-30   107   1.1    Use IB_MREQ/IB_SRES interface now; remove DMA port
60
-- 2007-09-16    83   1.0.2  Use ram_1swsr_wfirst_gen, not ram_2swsr_wfirst_gen
61
--                           2nd port was unused, connected ADDR caused slow net
62
-- 2007-06-14    56   1.0.1  Use slvtypes.all
63
-- 2007-05-12    26   1.0    Initial version 
64
------------------------------------------------------------------------------
65
 
66
library ieee;
67
use ieee.std_logic_1164.all;
68 13 wfjm
use ieee.numeric_std.all;
69 2 wfjm
 
70
use work.slvtypes.all;
71
use work.iblib.all;
72
use work.pdp11.all;
73
use work.sys_conf.all;
74
 
75
-- ----------------------------------------------------------------------------
76
 
77
entity pdp11_vmbox is                   -- virtual memory
78
  port (
79
    CLK : in slbit;                     -- clock
80 30 wfjm
    GRESET : in slbit;                  -- general reset
81
    CRESET : in slbit;                  -- cpu reset
82
    BRESET : in slbit;                  -- bus reset
83 2 wfjm
    CP_ADDR : in cp_addr_type;          -- console port address
84
    VM_CNTL : in vm_cntl_type;          -- vm control port
85
    VM_ADDR : in slv16;                 -- vm address
86
    VM_DIN : in slv16;                  -- vm data in
87
    VM_STAT : out vm_stat_type;         -- vm status port
88
    VM_DOUT : out slv16;                -- vm data out
89
    EM_MREQ : out em_mreq_type;         -- external memory: request
90
    EM_SRES : in em_sres_type;          -- external memory: response
91
    MMU_MONI : in mmu_moni_type;        -- mmu monitor port
92
    IB_MREQ_M : out ib_mreq_type;       -- ibus request  (master)
93
    IB_SRES_CPU : in ib_sres_type;      -- ibus response (CPU registers)
94
    IB_SRES_EXT : in ib_sres_type;      -- ibus response (external devices)
95
    DM_STAT_VM : out dm_stat_vm_type    -- debug and monitor status
96
  );
97
end pdp11_vmbox;
98
 
99
architecture syn of pdp11_vmbox is
100
 
101 13 wfjm
  constant ibaddr_slim : slv16 := slv(to_unsigned(8#177774#,16));
102 30 wfjm
  constant atowidth : natural := 6;     -- size of access timeout counter
103 2 wfjm
 
104
  type state_type is (
105
    s_idle,                             -- s_idle: wait for vm_cntl request
106
    s_mem_w,                            -- s_mem_w: check mmu, wait for memory
107
    s_ib_w,                             -- s_ib_w: wait for ibus
108
    s_ib_wend,                          -- s_ib_wend: ibus write completion
109
    s_ib_rend,                          -- s_ib_rend: ibus read completion
110
    s_idle_mw_ib,                       -- s_idle_mw_ib: wait macc write (ibus)
111
    s_idle_mw_mem,                      -- s_idle_mw_mem: wait macc write (mem)
112
    s_mem_mw_w,                         -- s_mem_mw_w: wait for memory (macc)
113
    s_fail,                             -- s_fail: vmbox fatal error catcher
114
    s_errrsv,                           -- s_errrsv: red stack violation
115
    s_errib                             -- s_errib: ibus error handler
116
  );
117
 
118
  type regs_type is record              -- state registers
119
    state : state_type;                 -- state
120
    wacc : slbit;                       -- write access
121
    macc : slbit;                       -- modify access (r-m-w sequence)
122
    cacc : slbit;                       -- console access
123
    bytop : slbit;                      -- byte operation
124
    kstack : slbit;                     -- access through kernel stack
125
    ysv : slbit;                        -- yellow stack violation detected
126
    vaok : slbit;                       -- virtual address valid (from MMU)
127
    trap_mmu : slbit;                   -- mmu trace trap requested
128
    mdin : slv16;                       -- data input (memory order)
129
    paddr : slv22;                      -- physical address register
130 8 wfjm
    paddr_iopage : slv9;                -- iopage base (upper 9 bits of paddr)
131 2 wfjm
    atocnt : slv(atowidth-1 downto 0);  -- access timeout counter
132 8 wfjm
    ibre : slbit;                       -- ibus re signal
133 2 wfjm
    ibwe : slbit;                       -- ibus we signal
134
    ibbe : slv2;                        -- ibus be0,be1 signals
135 8 wfjm
    ibrmw : slbit;                      -- ibus rmw signal
136 2 wfjm
    ibcacc : slbit;                     -- ibus cacc signal
137
    ibracc : slbit;                     -- ibus racc signal
138
    ibdout : slv16;                     -- ibus dout register
139
  end record regs_type;
140
 
141
  constant atocnt_init : slv(atowidth-1 downto 0) := (others=>'1');
142
  constant regs_init : regs_type := (
143
    s_idle,                             -- state
144
    '0','0','0','0',                    -- wacc,macc,cacc,bytop
145
    '0','0','0','0',                    -- kstack,ysv,vaok,trap_mmu
146
    (others=>'0'),                      -- mdin
147
    (others=>'0'),                      -- paddr
148 8 wfjm
    (others=>'0'),                      -- paddr_iopage
149 2 wfjm
    atocnt_init,                        -- atocnt
150 8 wfjm
    '0','0',"00",                       -- ibre,ibwe,ibbe
151
    '0','0','0',                        -- ibrmw,ibcacc,ibracc
152 2 wfjm
    (others=>'0')                       -- ibdout
153
  );
154
 
155
  signal R_REGS : regs_type := regs_init;
156 36 wfjm
  signal N_REGS : regs_type;            -- don't init (vivado fix for fsm infer)
157 2 wfjm
 
158
  signal R_SLIM : slv8 := (others=>'0');   -- stack limit register
159
 
160
  signal MMU_CNTL : mmu_cntl_type := mmu_cntl_init;
161
  signal MMU_STAT : mmu_stat_type := mmu_stat_init;
162
  signal PADDRH   : slv16 := (others=>'0');
163
 
164
  signal IBSEL_SLIM :slbit := '0';      -- select stack limit reg
165
  signal IB_SRES_SLIM  : ib_sres_type := ib_sres_init;
166
  signal IB_SRES_MMU   : ib_sres_type := ib_sres_init;
167
  signal IB_SRES_UBMAP : ib_sres_type := ib_sres_init;
168
 
169
  signal UBMAP_MREQ : slbit := '0';
170
  signal UBMAP_ADDR_PM : slv22_1 := (others=>'0');
171
 
172 34 wfjm
  signal VM_STAT_L : vm_stat_type := vm_stat_init; -- vm status    (local)
173
  signal VM_DOUT_L : slv16 := (others=>'0');       -- vm data out  (local)
174
 
175 2 wfjm
  signal IB_MREQ : ib_mreq_type := ib_mreq_init; -- ibus request  (local)
176
  signal IB_SRES : ib_sres_type := ib_sres_init; -- ibus response (local)
177
  signal IB_SRES_INT : ib_sres_type := ib_sres_init; -- ibus response (cpu)
178 34 wfjm
 
179
  signal EM_MREQ_L : em_mreq_type := em_mreq_init; -- ext mem: request (local)
180 2 wfjm
 
181
begin
182
 
183
  MMU : pdp11_mmu
184
    port map (
185
      CLK     => CLK,
186
      CRESET  => CRESET,
187
      BRESET  => BRESET,
188
      CNTL    => MMU_CNTL,
189
      VADDR   => VM_ADDR,
190
      MONI    => MMU_MONI,
191
      STAT    => MMU_STAT,
192
      PADDRH  => PADDRH,
193
      IB_MREQ => IB_MREQ,
194
      IB_SRES => IB_SRES_MMU
195
    );
196
 
197
  UBMAP : pdp11_ubmap
198
    port map (
199
      CLK     => CLK,
200
      MREQ    => UBMAP_MREQ,
201
      ADDR_UB => CP_ADDR.addr(17 downto 1),
202
      ADDR_PM => UBMAP_ADDR_PM,
203
      IB_MREQ => IB_MREQ,
204
      IB_SRES => IB_SRES_UBMAP
205
    );
206
 
207 8 wfjm
  SRES_OR_INT : ib_sres_or_4
208 2 wfjm
    port map (
209
      IB_SRES_1  => IB_SRES_CPU,
210
      IB_SRES_2  => IB_SRES_SLIM,
211
      IB_SRES_3  => IB_SRES_MMU,
212
      IB_SRES_4  => IB_SRES_UBMAP,
213
      IB_SRES_OR => IB_SRES_INT
214
    );
215
 
216 8 wfjm
  SRES_OR_ALL : ib_sres_or_2
217 2 wfjm
    port map (
218
      IB_SRES_1  => IB_SRES_INT,
219
      IB_SRES_2  => IB_SRES_EXT,
220
      IB_SRES_OR => IB_SRES
221
    );
222
 
223 8 wfjm
  SEL : ib_sel
224
    generic map (
225
      IB_ADDR => ibaddr_slim)
226
    port map (
227
      CLK     => CLK,
228
      IB_MREQ => IB_MREQ,
229
      SEL     => IBSEL_SLIM
230
    );
231 2 wfjm
 
232 8 wfjm
  proc_ibres : process (IBSEL_SLIM, IB_MREQ, R_SLIM)
233
    variable idout : slv16 := (others=>'0');
234 2 wfjm
  begin
235 8 wfjm
    idout := (others=>'0');
236 2 wfjm
    if IBSEL_SLIM = '1' then
237 8 wfjm
      idout(ibf_byte1) := R_SLIM;
238 2 wfjm
    end if;
239 8 wfjm
    IB_SRES_SLIM.dout <= idout;
240
    IB_SRES_SLIM.ack  <= IBSEL_SLIM and (IB_MREQ.re or IB_MREQ.we); -- ack all
241
    IB_SRES_SLIM.busy <= '0';
242
  end process proc_ibres;
243 2 wfjm
 
244
  proc_slim: process (CLK)
245
  begin
246 13 wfjm
    if rising_edge(CLK) then
247 2 wfjm
      if BRESET = '1' then
248
        R_SLIM <= (others=>'0');
249 8 wfjm
      elsif IBSEL_SLIM='1' and IB_MREQ.we='1' then
250 2 wfjm
        if IB_MREQ.be1 = '1' then
251
          R_SLIM <= IB_MREQ.din(ibf_byte1);
252
        end if;
253
      end if;
254
    end if;
255
  end process proc_slim;
256
 
257
  proc_regs: process (CLK)
258
  begin
259 13 wfjm
    if rising_edge(CLK) then
260 2 wfjm
      if GRESET = '1' then
261
        R_REGS <= regs_init;
262
     else
263
        R_REGS <= N_REGS;
264
      end if;
265
    end if;
266
  end process proc_regs;
267
 
268
  proc_next: process (R_REGS, R_SLIM, CP_ADDR, VM_CNTL, VM_DIN, VM_ADDR,
269
                      IB_SRES, UBMAP_ADDR_PM,
270
                      EM_SRES, MMU_STAT, PADDRH)
271
 
272
    variable r : regs_type := regs_init;
273
    variable n : regs_type := regs_init;
274
 
275
    variable ivm_stat : vm_stat_type := vm_stat_init;
276
    variable ivm_dout : slv16 := (others=>'0');
277
    variable iem_mreq : em_mreq_type := em_mreq_init;
278
    variable immu_cntl : mmu_cntl_type := mmu_cntl_init;
279 8 wfjm
 
280
    variable ipaddr        : slv22 := (others=>'0');
281
    variable ipaddr_iopage : slv9 := (others=>'0');
282
 
283
    variable iib_aval : slbit := '0';
284 2 wfjm
 
285
    variable ato_go : slbit := '0';
286
    variable ato_end : slbit := '0';
287
 
288
    variable is_stackyellow : slbit := '1'; -- VM_ADDR in yellow stack zone
289
    variable is_stackred : slbit := '1';    -- VM_ADDR in red stack zone
290
 
291
    variable iubmap_mreq : slbit := '0';
292
    variable paddr_mmu : slbit := '0';
293
    variable paddr_sel : slv2  := "00";
294
    constant c_paddr_sel_vmaddr : slv2 := "00";
295
    constant c_paddr_sel_rpaddr : slv2 := "01";
296
    constant c_paddr_sel_cacc   : slv2 := "10";
297
    constant c_paddr_sel_ubmap  : slv2 := "11";
298
 
299
 
300
  begin
301
 
302
    r := R_REGS;
303
    n := R_REGS;
304
 
305
    n.state := s_fail;
306
 
307
    ivm_stat  := vm_stat_init;
308
    ivm_dout  := EM_SRES.dout;
309
    immu_cntl := mmu_cntl_init;
310
 
311 8 wfjm
    iib_aval  := '0';
312
 
313 2 wfjm
    iem_mreq  := em_mreq_init;
314
    iem_mreq.din  := VM_DIN;
315
 
316
    if VM_CNTL.bytop = '0' then         -- if word access
317
      iem_mreq.be := "11";                -- both be's
318
    else
319
      if VM_ADDR(0) = '0' then            -- if low byte
320
        iem_mreq.be := "01";
321
      else                                -- if high byte
322
        iem_mreq.be := "10";
323
        iem_mreq.din(ibf_byte1) := VM_DIN(ibf_byte0);
324
      end if;
325
    end if;
326
 
327
    iubmap_mreq :='0';
328
 
329
    paddr_mmu := '1';                   -- ipaddr selector, used in s_idle
330
                                        -- and overwritten in s_idle_mw_mem
331
    paddr_sel := "00";
332
    if MMU_STAT.ena_mmu='0' or VM_CNTL.cacc='1' then
333
      paddr_mmu := '0';
334
      paddr_sel := c_paddr_sel_vmaddr;
335
      if VM_CNTL.cacc = '1' then
336
        if CP_ADDR.ena_ubmap='1' and MMU_STAT.ena_ubmap='1' then
337
          paddr_sel := c_paddr_sel_ubmap;
338
        else
339
          paddr_sel := c_paddr_sel_cacc;
340
        end if;
341
      end if;
342
    end if;
343
 
344 8 wfjm
    -- the iopage base is determined based on mmu regs and request type
345
    -- r.paddr_iopage is updated during s_idle. This way the iopage base
346
    -- address is determined in parallel to paddr and latched at end of s_idle.
347
    -- Note: is VM_CNTL.cacc here, the status in s_idle is relevant !
348
 
349
    ipaddr_iopage := "111111111";       -- iopage match pattern (for 22 bit)
350
    if VM_CNTL.cacc = '1' then
351 2 wfjm
      if CP_ADDR.ena_22bit = '0' then
352 8 wfjm
        ipaddr_iopage := "000000111";   -- 16 bit cacc
353 2 wfjm
      end if;
354
    else
355
      if MMU_STAT.ena_mmu = '0' then
356 8 wfjm
        ipaddr_iopage := "000000111";   -- 16 bit mode
357 2 wfjm
      else
358
        if MMU_STAT.ena_22bit = '0' then
359 8 wfjm
          ipaddr_iopage := "000011111"; -- 18 bit mode
360 2 wfjm
        end if;
361
      end if;
362
    end if;
363
 
364
    ato_go := '0';                      -- default: keep access timeout in reset
365
    ato_end := '0';
366
    if unsigned(r.atocnt) = 0 then      -- if access timeout count at zero
367
      ato_end := '1';                   -- signal expiration
368
    end if;
369
 
370
    is_stackyellow := '0';
371
    is_stackred := '0';
372
    if unsigned(VM_ADDR(15 downto 8)) <= unsigned(R_SLIM) then
373
      is_stackyellow := '1';
374
      if unsigned(VM_ADDR(7 downto 5)) /= 7 then  -- below 340
375
        is_stackred := '1';
376
      end if;
377
    end if;
378
 
379
    if VM_ADDR(15 downto 1) = "111111111111111" then  -- vaddr == 177776
380
      is_stackred := '1';
381
    end if;
382
 
383
    immu_cntl.wacc      := VM_CNTL.wacc;
384
    immu_cntl.macc      := VM_CNTL.macc;
385
    immu_cntl.cacc      := VM_CNTL.cacc;
386
    immu_cntl.dspace    := VM_CNTL.dspace;
387
    immu_cntl.mode      := VM_CNTL.mode;
388
    immu_cntl.trap_done := VM_CNTL.trap_done;
389
 
390
    case r.state is
391
      when s_idle =>                    -- s_idle: wait for vm_cntl request --
392
        n.state := s_idle;
393
        iubmap_mreq := '1';             -- activate ubmap always in s_idle
394
 
395
        if VM_CNTL.req = '1' then
396
          n.wacc   := VM_CNTL.wacc;
397
          n.macc   := VM_CNTL.macc;
398
          n.cacc   := VM_CNTL.cacc;
399
          n.bytop  := VM_CNTL.bytop;
400
          n.kstack := VM_CNTL.kstack;
401
          n.ysv    := '0';
402
          n.vaok   := MMU_STAT.vaok;
403
          n.trap_mmu := MMU_STAT.trap;
404
          n.mdin   := iem_mreq.din;
405
          -- n.paddr assignment handled separately in 'if state=s_idle' at the
406
          -- end. 
407
 
408
          immu_cntl.req := '1';
409
 
410
          if VM_CNTL.wacc='1' and VM_CNTL.macc='1' then
411
            n.state := s_fail;
412
 
413
          elsif VM_CNTL.kstack='1' and VM_CNTL.intrsv='0' and
414
                is_stackred='1' then
415
            n.state := s_errrsv;
416
 
417
          else
418
            iem_mreq.req := '1';
419
            iem_mreq.we  := VM_CNTL.wacc;
420
            if VM_CNTL.kstack='1'and VM_CNTL.intrsv='0'  then
421
              n.ysv := is_stackyellow;
422
            end if;
423
            n.state := s_mem_w;
424
          end if;
425
        end if;
426
 
427
      when s_mem_w =>                   -- s_mem_w: check mmu, wait for memory
428
 
429
        if r.bytop='0' and r.paddr(0)='1' then -- odd address ?
430
          ivm_stat.err := '1';
431
          ivm_stat.err_odd := '1';
432
          ivm_stat.err_rsv := r.kstack;      -- escalate to rsv if kstack
433
          iem_mreq.cancel  := '1';           -- cancel pending mem request
434
          n.state := s_idle;
435
 
436
        elsif r.vaok = '0' then          -- MMU abort ?
437
          ivm_stat.err := '1';
438
          ivm_stat.err_mmu := '1';
439
          ivm_stat.err_rsv := r.kstack;      -- escalate to rsv if kstack
440
          iem_mreq.cancel  := '1';           -- cancel pending mem request
441
          n.state := s_idle;
442
 
443
        else
444 8 wfjm
          if r.paddr(21 downto 13) = r.paddr_iopage then
445 2 wfjm
                                             -- I/O page decoded
446
            iem_mreq.cancel  := '1';         -- cancel pending mem request
447 8 wfjm
            iib_aval := '1';                 -- declare ibus addr valid
448
            n.ibre   := not r.wacc;
449 2 wfjm
            n.ibwe   := r.wacc;
450
            n.ibcacc := r.cacc;
451
            n.ibracc := r.cacc and CP_ADDR.racc;
452
            n.ibbe   := "11";
453
            if r.cacc = '1' then               -- console access ?
454
              n.ibbe   := CP_ADDR.be;
455
            else                               -- cpu access ?
456
              if r.bytop = '1' then
457
                if r.paddr(0) = '0' then
458
                  n.ibbe(1) := '0';
459
                else
460
                  n.ibbe(0) := '0';
461
                end if;
462
              end if;
463
            end if;
464 8 wfjm
            n.ibrmw  := r.macc;
465 2 wfjm
            n.state  := s_ib_w;
466
 
467
          else
468
            if unsigned(r.paddr(21 downto 6)) > sys_conf_mem_losize then
469
              ivm_stat.err := '1';
470
              ivm_stat.err_nxm := '1';
471
              ivm_stat.err_rsv := r.kstack;   -- escalate to rsv if kstack
472
              iem_mreq.cancel  := '1';        -- cancel pending mem request
473
              n.state := s_idle;
474
 
475
            else
476
 
477
              if EM_SRES.ack_r='1' or EM_SRES.ack_w='1' then
478
                ivm_stat.ack := '1';
479
                ivm_stat.trap_ysv := r.ysv;
480
                ivm_stat.trap_mmu := r.trap_mmu;
481
                if r.macc='1' and r.wacc='0' then
482
                  n.state := s_idle_mw_mem;
483
                else
484
                  n.state := s_idle;
485
                end if;
486
              else
487
                n.state := s_mem_w;     -- keep waiting
488
              end if;
489
 
490
            end if;
491
          end if;
492
        end if;
493
 
494
      when s_ib_w =>                    -- s_ib_w: wait for ibus -------------
495
        ato_go := '1';                    -- activate timeout counter
496
 
497 8 wfjm
        iib_aval := '1';                  -- declare ibus addr valid
498
 
499
        n.ibre   := '0';                  -- end cycle, unless busy seen
500
        n.ibwe   := '0';
501
        n.ibrmw  := '0';
502
        n.ibbe   := "00";
503
        n.ibcacc := '0';
504
        n.ibracc := '0';
505
 
506 2 wfjm
        if IB_SRES.ack='1' and IB_SRES.busy='0' then -- ibus cycle finished
507
          if r.wacc = '1' then
508
            n.state := s_ib_wend;
509
          else
510 8 wfjm
            if r.macc = '1' then          -- if first part of rmw
511
              n.ibrmw  := r.macc;           -- keep rmw 
512
              n.ibbe   := r.ibbe;           -- keep be's
513
              n.ibcacc := r.ibcacc;
514
              n.ibracc := r.ibracc;
515
            end if;
516 2 wfjm
            n.ibdout := IB_SRES.dout;
517
            n.state  := s_ib_rend;
518
          end if;
519
        elsif IB_SRES.busy='1' and ato_end='0' then
520 8 wfjm
          n.ibre   := r.ibre;             -- continue ibus cycle
521
          n.ibwe   := r.ibwe;
522
          n.ibrmw  := r.ibrmw;
523
          n.ibbe   := r.ibbe;
524
          n.ibcacc := r.ibcacc;
525
          n.ibracc := r.ibracc;
526 2 wfjm
          n.state := s_ib_w;
527
        else
528
          n.state := s_errib;
529
        end if;
530
 
531
      when s_ib_wend =>                 -- s_ib_wend: ibus write completion --
532
        ivm_stat.ack := '1';
533
        n.state := s_idle;
534
 
535
      when s_ib_rend =>                 -- s_ib_rend: ibus read completion ---
536
        ivm_stat.ack := '1';
537
        ivm_dout := r.ibdout;
538 8 wfjm
        if r.macc='1' then                -- first part of read-mod-write
539
          iib_aval := '1';                  -- keep ibus addr valid
540 2 wfjm
          n.state := s_idle_mw_ib;
541
        else
542
          n.state := s_idle;
543
        end if;
544
 
545
      when s_idle_mw_ib =>              -- s_idle_mw_ib: wait macc write (ibus)
546
        n.state := s_idle_mw_ib;
547 8 wfjm
        iib_aval := '1';                  -- keep ibus addr valid
548 2 wfjm
        if r.ibbe = "10" then
549
          iem_mreq.din(ibf_byte1) := VM_DIN(ibf_byte0);
550
        end if;
551
        if VM_CNTL.req = '1' then
552
          n.wacc  := VM_CNTL.wacc;
553
          n.macc  := VM_CNTL.macc;
554
          n.mdin  := iem_mreq.din;
555
          if VM_CNTL.wacc='0' or VM_CNTL.macc='0' then
556
            n.state := s_fail;
557
          else
558
            n.ibwe  := '1';                 -- Note: all other ibus drivers
559
                                            --   already set in 1st part
560
            n.state := s_ib_w;
561
          end if;
562
        end if;
563
 
564
      when s_idle_mw_mem =>             -- s_idle_mw_mem: wait macc write (mem)
565
        n.state := s_idle_mw_mem;
566
 
567
        paddr_mmu := '0';
568
        paddr_sel := c_paddr_sel_rpaddr;
569
 
570
        if VM_CNTL.bytop = '0' then     -- if word access
571
          iem_mreq.be := "11";            -- both be's
572
        else
573
          if r.paddr(0) = '0' then        -- if low byte
574
            iem_mreq.be := "01";
575
          else                            -- if high byte
576
            iem_mreq.be := "10";
577
            iem_mreq.din(ibf_byte1) := VM_DIN(ibf_byte0);
578
          end if;
579
        end if;
580
 
581
        if VM_CNTL.req = '1' then
582
          n.wacc  := VM_CNTL.wacc;
583
          n.macc  := VM_CNTL.macc;
584
          n.bytop := VM_CNTL.bytop;
585
          n.mdin  := iem_mreq.din;
586
 
587
          if VM_CNTL.wacc='0' or VM_CNTL.macc='0' then
588
            n.state := s_fail;
589
          else
590
            iem_mreq.req := '1';
591
            iem_mreq.we  := '1';
592
            n.state := s_mem_mw_w;
593
          end if;
594
        end if;
595
 
596
      when s_mem_mw_w =>                -- s_mem_mw_w: wait for memory (macc)
597
        if EM_SRES.ack_w = '1' then
598
          ivm_stat.ack := '1';
599
          n.state := s_idle;
600
        else
601
          n.state := s_mem_mw_w;        -- keep waiting
602
        end if;
603
 
604
      when s_fail =>                    -- s_fail: vmbox fatal error catcher
605
        ivm_stat.fail := '1';
606
        n.state := s_idle;
607
 
608
      when s_errrsv =>                  -- s_errrsv: red stack violation -----
609
        ivm_stat.err := '1';
610
        ivm_stat.err_rsv := '1';
611
        n.state := s_idle;
612
 
613
      when s_errib =>                   -- s_errib: ibus error handler -------
614
        ivm_stat.err := '1';
615
        ivm_stat.err_iobto := '1';
616
        ivm_stat.err_rsv := r.kstack;    -- escalate to rsv if kstack
617
        n.state := s_idle;
618
 
619
      when others => null;
620
    end case;
621
 
622
    if r.bytop='1' and r.paddr(0)='1' then
623
      ivm_dout(ibf_byte0) := ivm_dout(ibf_byte1);
624
    end if;
625
 
626
    if ato_go = '0' then                -- handle access timeout counter
627
      n.atocnt := atocnt_init;          -- if ato_go=0, keep in reset
628
    else
629 13 wfjm
      n.atocnt := slv(unsigned(r.atocnt) - 1);-- otherwise count down
630 2 wfjm
    end if;
631
 
632
    ipaddr := (others=>'0');
633
    if paddr_mmu = '1' then
634
      ipaddr( 5 downto 0) := VM_ADDR(5 downto 0);
635
      ipaddr(21 downto 6) := PADDRH;
636
      if MMU_STAT.ena_22bit = '0' then
637
        ipaddr(21 downto 18) := (others=>'0');
638
      end if;
639
    else
640
      case paddr_sel is
641
        when c_paddr_sel_vmaddr  =>
642
          ipaddr(15 downto 0) := VM_ADDR(15 downto 0);
643
        when c_paddr_sel_rpaddr =>
644
          ipaddr := r.paddr;
645
        when c_paddr_sel_cacc  =>
646
          ipaddr := CP_ADDR.addr & '0';
647
          if CP_ADDR.ena_22bit = '0' then
648
            ipaddr(21 downto 16) := (others=>'0');
649
          end if;
650
        when c_paddr_sel_ubmap  =>
651
          ipaddr := UBMAP_ADDR_PM & '0';
652
        when others => null;
653
      end case;
654
    end if;
655
 
656
    if r.state = s_idle then
657 8 wfjm
      n.paddr        := ipaddr;
658
      n.paddr_iopage := ipaddr_iopage;
659 2 wfjm
    end if;
660
 
661
    iem_mreq.addr := ipaddr(21 downto 1);
662
 
663
    N_REGS <= n;
664
 
665
    UBMAP_MREQ <= iubmap_mreq;
666
 
667 8 wfjm
    IB_MREQ.aval <= iib_aval;
668
    IB_MREQ.re   <= r.ibre;
669 2 wfjm
    IB_MREQ.we   <= r.ibwe;
670
    IB_MREQ.be0  <= r.ibbe(0);
671
    IB_MREQ.be1  <= r.ibbe(1);
672 8 wfjm
    IB_MREQ.rmw  <= r.ibrmw;
673 2 wfjm
    IB_MREQ.cacc <= r.ibcacc;
674
    IB_MREQ.racc <= r.ibracc;
675 8 wfjm
    IB_MREQ.addr <= r.paddr(12 downto 1);
676 2 wfjm
    IB_MREQ.din  <= r.mdin;
677
 
678 34 wfjm
    VM_STAT_L <= ivm_stat;
679
    VM_DOUT_L <= ivm_dout;
680
    MMU_CNTL  <= immu_cntl;
681 2 wfjm
 
682 34 wfjm
    EM_MREQ_L  <= iem_mreq;
683
 
684 2 wfjm
  end process proc_next;
685
 
686 34 wfjm
  VM_STAT   <= VM_STAT_L;
687
  VM_DOUT   <= VM_DOUT_L;
688 2 wfjm
  IB_MREQ_M <= IB_MREQ;                 -- external drive master port
689 34 wfjm
  EM_MREQ   <= EM_MREQ_L;
690
 
691
  DM_STAT_VM.vmcntl <= VM_CNTL;
692
  DM_STAT_VM.vmaddr <= VM_ADDR;
693
  DM_STAT_VM.vmdin  <= VM_DIN;
694
  DM_STAT_VM.vmstat <= VM_STAT_L;
695
  DM_STAT_VM.vmdout <= VM_DOUT_L;
696 2 wfjm
  DM_STAT_VM.ibmreq <= IB_MREQ;
697
  DM_STAT_VM.ibsres <= IB_SRES;
698 34 wfjm
  DM_STAT_VM.emmreq <= EM_MREQ_L;
699
  DM_STAT_VM.emsres <= EM_SRES;
700 2 wfjm
 
701
end syn;

powered by: WebSVN 2.1.0

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