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

Subversion Repositories w11

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

powered by: WebSVN 2.1.0

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