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

Subversion Repositories w11

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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