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

Subversion Repositories w11

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

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

Line No. Rev Author Line
1 29 wfjm
-- $Id: pdp11_core_rbus.vhd 641 2015-02-01 22:12:15Z mueller $
2 2 wfjm
--
3 22 wfjm
-- Copyright 2007-2014 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 9 wfjm
-- Module Name:    pdp11_core_rbus - syn
16
-- Description:    pdp11: core to rbus interface
17 2 wfjm
--
18
-- Dependencies:   -
19 9 wfjm
-- Test bench:     tb/tb_rlink_tba_pdp11core
20 2 wfjm
--
21
-- Target Devices: generic
22 29 wfjm
-- Tool versions:  ise 8.2-14.7; viv 2014.4; ghdl 0.18-0.31
23 28 wfjm
--
24
-- Synthesized (xst):
25
-- Date         Rev  ise         Target      flop lutl lutm slic t peri
26
-- 2014-12-21   591 14.7  131013 xc6slx16-2    52  118    0   58 s  4.9
27
--
28 2 wfjm
-- Revision History: -
29
-- Date         Rev Version  Comment
30 28 wfjm
-- 2014-12-26   621   1.4    use full size 4k word ibus window
31
-- 2014-12-21   617   1.3.1  use separate RB_STAT bits for cmderr and cmdmerr
32 27 wfjm
-- 2014-09-05   591   1.3    use new rlink v4 iface and 4 bit STAT
33
-- 2014-08-15   583   1.2    rb_mreq addr now 16 bit
34 13 wfjm
-- 2011-11-18   427   1.1.1  now numeric_std clean
35 9 wfjm
-- 2010-12-29   351   1.1    renamed from pdp11_core_rri; ported to rbv3
36 8 wfjm
-- 2010-10-23   335   1.2.3  rename RRI_LAM->RB_LAM;
37 2 wfjm
-- 2010-06-20   308   1.2.2  use c_ibrb_ibf_ def's
38
-- 2010-06-18   306   1.2.1  rename RB_ADDR->RB_ADDR_CORE, add RB_ADDR_IBUS;
39
--                           add ibrb register and ibr window logic
40
-- 2010-06-13   305   1.2    add CP_ADDR in port; mostly rewritten for new
41
--                           rri <-> cp mapping
42
-- 2010-06-03   299   1.1.2  correct rbus init logic (use we, din, RB_ADDR)
43
-- 2010-05-02   287   1.1.1  rename RP_STAT->RB_STAT; remove unneeded unsigned()
44
-- 2010-05-01   285   1.1    port to rri V2 interface, add RB_ADDR generic;
45
--                           rename c_rp_addr_* -> c_rb_addr_*
46
-- 2008-05-03   143   1.0.8  rename _cpursta->_cpurust
47
-- 2008-04-27   140   1.0.7  use cpursta interface, remove cpufail
48
-- 2008-03-02   121   1.0.6  set RP_ERR when cmderr or cmdmerr status seen
49
-- 2008-02-24   119   1.0.5  support lah,rps,wps cp commands
50
-- 2008-01-20   113   1.0.4  use single LAM; change to RRI_LAM interface
51
-- 2007-10-12    88   1.0.3  avoid ieee.std_logic_unsigned, use cast to unsigned
52
-- 2007-08-16    74   1.0.2  add AP_LAM interface to pdp11_core_rri
53
-- 2007-08-12    73   1.0.1  use def's; add stat command; wait for step complete
54
-- 2007-07-08    65   1.0    Initial version 
55
------------------------------------------------------------------------------
56
--
57
-- rbus registers:
58
--
59 28 wfjm
--  Addr   Bits  Name        r/w/f  Function
60 2 wfjm
--
61 28 wfjm
-- 00000         conf        r/w/-  cpu configuration (e.g. cpu type)
62 2 wfjm
--                                   (currently unused, all bits MBZ)
63 28 wfjm
-- 00001         cntl        -/f/-  cpu control
64
--         3:00    func               function code
65 2 wfjm
--                                       0000: noop
66
--                                       0001: start
67
--                                       0010: stop
68
--                                       0011: continue
69
--                                       0100: step
70
--                                       1111: reset (soft)
71 28 wfjm
-- 00010         stat        r/-/-  cpu status
72
--         7:04    cpurust   r/-/-    cp_stat: cpurust
73
--            3    cpuhalt   r/-/-    cp_stat: cpuhalt
74
--            2    cpugo     r/-/-    cp_stat: cpugo
75
--            1    cmdmerr   r/-/-    cp_stat: cmdmerr
76
--            0    cmderr    r/-/-    cp_stat: cmderr
77
-- 00011         psw         r/w/-  processor status word access
78
-- 00100         al          r/w/-  address register, low
79
-- 00101         ah          r/w/-  address register, high
80
--            7    ubm       r/w/-    ubmap access
81
--            6    p22       r/w/-    22bit access
82
--         5:00    addr      r/w/-    addr(21:16)  
83
-- 00110         mem         r/w/-  memory access
84
-- 00111         memi        r/w/-  memory access, inc address
85
-- 01rrr         gpr[]       r/w/-  general purpose regs
86
-- 10000         membe       r/w/-  memory write byte enables
87
--            3    stick     r/w/-    sticky flag
88
--         1:00    be        r/w/-    byte enables
89 2 wfjm
--
90
 
91
library ieee;
92
use ieee.std_logic_1164.all;
93 13 wfjm
use ieee.numeric_std.all;
94 2 wfjm
 
95
use work.slvtypes.all;
96 9 wfjm
use work.rblib.all;
97 2 wfjm
use work.pdp11.all;
98
 
99
-- ----------------------------------------------------------------------------
100
 
101 9 wfjm
entity pdp11_core_rbus is               -- core to rbus interface
102 2 wfjm
  generic (
103 28 wfjm
    RB_ADDR_CORE : slv16 := slv(to_unsigned(16#0000#,16));
104
    RB_ADDR_IBUS : slv16 := slv(to_unsigned(16#4000#,16)));
105 2 wfjm
  port (
106
    CLK : in slbit;                     -- clock
107
    RESET : in slbit;                   -- reset
108
    RB_MREQ : in rb_mreq_type;          -- rbus: request
109
    RB_SRES : out rb_sres_type;         -- rbus: response
110 27 wfjm
    RB_STAT : out slv4;                 -- rbus: status flags
111 8 wfjm
    RB_LAM : out slbit;                 -- remote attention
112 2 wfjm
    CPU_RESET : out slbit;              -- cpu master reset
113
    CP_CNTL : out cp_cntl_type;         -- console control port
114
    CP_ADDR : out cp_addr_type;         -- console address port
115
    CP_DIN : out slv16;                 -- console data in
116
    CP_STAT : in cp_stat_type;          -- console status port
117
    CP_DOUT : in slv16                  -- console data out
118
  );
119 9 wfjm
end pdp11_core_rbus;
120 2 wfjm
 
121
 
122 9 wfjm
architecture syn of pdp11_core_rbus is
123 2 wfjm
 
124
  type state_type is (
125
    s_idle,                             -- s_idle: wait for rp access
126
    s_cpwait,                           -- s_cpwait: wait for cp port ack
127
    s_cpstep                            -- s_cpstep: wait for cpustep done
128
  );
129
 
130
  type regs_type is record
131
    state : state_type;                 -- state
132 9 wfjm
    rbselc : slbit;                     -- rbus select for core
133
    rbseli : slbit;                     -- rbus select for ibus
134 2 wfjm
    cpreq : slbit;                      -- cp request flag
135
    cpfunc : slv5;                      -- cp function
136
    cpugo_1 : slbit;                    -- prev cycle cpugo
137
    addr : slv22_1;                     -- address register
138
    ena_22bit : slbit;                  -- 22bit enable
139
    ena_ubmap : slbit;                  -- ubmap enable
140 28 wfjm
    membe : slv2;                       -- memory write byte enables
141
    membestick : slbit;                 -- memory write byte enables sticky
142 2 wfjm
    doinc : slbit;                      -- at cmdack: do addr reg inc
143
    waitstep : slbit;                   -- at cmdack: wait for cpu step complete
144
  end record regs_type;
145
 
146
  constant regs_init : regs_type := (
147
    s_idle,                             -- state
148 9 wfjm
    '0','0',                            -- rbselc,rbseli
149 2 wfjm
    '0',                                -- cpreq
150
    (others=>'0'),                      -- cpfunc
151
    '0',                                -- cpugo_1
152
    (others=>'0'),                      -- addr
153
    '0','0',                            -- ena_22bit, ena_ubmap
154 28 wfjm
    "11",'0',                           -- membe,membestick
155 2 wfjm
    '0','0'                             -- doinc, waitstep
156
  );
157
 
158
  signal R_REGS : regs_type := regs_init;  -- state registers
159
  signal N_REGS : regs_type := regs_init;  -- next value state regs
160
 
161
  begin
162
 
163
  proc_regs: process (CLK)
164
  begin
165
 
166 13 wfjm
    if rising_edge(CLK) then
167 2 wfjm
      if RESET = '1' then
168
        R_REGS <= regs_init;
169
      else
170
        R_REGS <= N_REGS;
171
      end if;
172
    end if;
173
 
174
  end process proc_regs;
175
 
176
  proc_next: process (R_REGS, RB_MREQ, CP_STAT, CP_DOUT)
177
 
178
    variable r : regs_type := regs_init;
179
    variable n : regs_type := regs_init;
180
 
181
    variable irb_ack  : slbit := '0';
182
    variable irb_busy : slbit := '0';
183
    variable irb_err  : slbit := '0';
184
    variable irb_dout : slv16 := (others=>'0');
185
    variable irb_lam  : slbit := '0';
186 9 wfjm
    variable irbena   : slbit := '0';
187 2 wfjm
 
188
    variable icpreq    : slbit := '0';
189
    variable icpureset : slbit := '0';
190
    variable icpaddr   : cp_addr_type := cp_addr_init;
191
 
192
  begin
193
 
194
    r := R_REGS;
195
    n := R_REGS;
196
 
197
    irb_ack  := '0';
198
    irb_busy := '0';
199
    irb_err  := '0';
200
    irb_dout := (others=>'0');
201
    irb_lam  := '0';
202 9 wfjm
 
203
    irbena  := RB_MREQ.re or RB_MREQ.we;
204
 
205 2 wfjm
    icpreq    := '0';
206
    icpureset := '0';
207
 
208 9 wfjm
    -- look for init's against the rbus base address, generate subsystem resets
209 27 wfjm
    if RB_MREQ.init='1' and RB_MREQ.addr=RB_ADDR_CORE then
210 9 wfjm
      icpureset := RB_MREQ.din(0);
211
    end if;
212
 
213
    -- rbus address decoder
214
    n.rbseli := '0';
215
    n.rbselc := '0';
216
    if RB_MREQ.aval='1' then
217 27 wfjm
      if RB_MREQ.addr(15 downto 5)=RB_ADDR_CORE(15 downto 5) then
218 9 wfjm
        n.rbselc := '1';
219 2 wfjm
      end if;
220 28 wfjm
      if RB_MREQ.addr(15 downto 12)=RB_ADDR_IBUS(15 downto 12) then
221 9 wfjm
        n.rbseli := '1';
222 2 wfjm
      end if;
223
    end if;
224
 
225 9 wfjm
    if (r.rbselc='1' or r.rbseli='1') and irbena='1' then
226
      irb_ack  := '1';                   -- ack all (maybe rejected later)
227
    end if;
228 2 wfjm
 
229
    case r.state is
230
 
231
      when s_idle =>                    -- s_idle: wait for rbus access ------
232
 
233
        n.doinc    := '0';
234
        n.waitstep := '0';
235
 
236 9 wfjm
        if r.rbseli = '1' then
237
          if irbena = '1' then
238
            n.cpfunc    := c_cpfunc_rmem;
239
            n.cpfunc(0) := RB_MREQ.we;
240
            icpreq := '1';
241
          end if;
242 2 wfjm
 
243 9 wfjm
        elsif r.rbselc = '1' then
244 2 wfjm
 
245
          case RB_MREQ.addr(4 downto 0) is
246
 
247
            when c_rbaddr_conf =>         -- conf -------------------------
248
              null;                         -- currently no action
249
 
250
            when c_rbaddr_cntl =>         -- cntl -------------------------
251 9 wfjm
              if irbena = '1' then
252
                n.cpfunc := RB_MREQ.din(n.cpfunc'range);
253
              end if;
254 2 wfjm
              if RB_MREQ.we = '1' then
255
                icpreq := '1';
256
                if RB_MREQ.din(3 downto 0) = c_cpfunc_step(3 downto 0) then
257
                  n.waitstep := '1';
258
                end if;
259
              end if;
260
 
261 28 wfjm
            when c_rbaddr_stat =>           -- stat ------------------
262 2 wfjm
              irb_dout(c_stat_rbf_cmderr)  := CP_STAT.cmderr;
263
              irb_dout(c_stat_rbf_cmdmerr) := CP_STAT.cmdmerr;
264
              irb_dout(c_stat_rbf_cpugo)   := CP_STAT.cpugo;
265
              irb_dout(c_stat_rbf_cpuhalt) := CP_STAT.cpuhalt;
266
              irb_dout(c_stat_rbf_cpurust) := CP_STAT.cpurust;
267
 
268 28 wfjm
            when c_rbaddr_psw  =>           -- psw -------------------
269 9 wfjm
              if irbena = '1' then
270
                n.cpfunc    := c_cpfunc_rpsw;
271
                n.cpfunc(0) := RB_MREQ.we;
272
                icpreq := '1';
273
              end if;
274 2 wfjm
 
275 28 wfjm
            when c_rbaddr_al   =>           -- al --------------------
276 2 wfjm
              irb_dout(c_al_rbf_addr) := r.addr(c_al_rbf_addr);
277
              if RB_MREQ.we = '1' then
278
                n.addr      := (others=>'0'); -- write to al clears ah !!
279
                n.ena_22bit := '0';
280
                n.ena_ubmap := '0';
281
                n.addr(c_al_rbf_addr) := RB_MREQ.din(c_al_rbf_addr);
282
              end if;
283
 
284 28 wfjm
            when c_rbaddr_ah   =>           -- ah --------------------
285 2 wfjm
              irb_dout(c_ah_rbf_ena_ubmap) := r.ena_ubmap;
286
              irb_dout(c_ah_rbf_ena_22bit) := r.ena_22bit;
287
              irb_dout(c_ah_rbf_addr)      := r.addr(21 downto 16);
288
              if RB_MREQ.we = '1' then
289
                n.addr(21 downto 16) := RB_MREQ.din(c_ah_rbf_addr);
290
                n.ena_22bit          := RB_MREQ.din(c_ah_rbf_ena_22bit);
291
                n.ena_ubmap          := RB_MREQ.din(c_ah_rbf_ena_ubmap);
292
              end if;
293
 
294 28 wfjm
            when c_rbaddr_mem  =>           -- mem -------------------
295 9 wfjm
              if irbena = '1' then
296
                n.cpfunc    := c_cpfunc_rmem;
297
                n.cpfunc(0) := RB_MREQ.we;
298
                icpreq   := '1';
299
              end if;
300
 
301 28 wfjm
            when c_rbaddr_memi  =>          -- memi ------------------
302 9 wfjm
              if irbena = '1' then
303
                n.cpfunc    := c_cpfunc_rmem;
304
                n.cpfunc(0) := RB_MREQ.we;
305
                n.doinc  := '1';
306
                icpreq   := '1';
307
              end if;
308 2 wfjm
 
309
            when c_rbaddr_r0 | c_rbaddr_r1 |
310
                 c_rbaddr_r2 | c_rbaddr_r3 |
311
                 c_rbaddr_r4 | c_rbaddr_r5 |
312 28 wfjm
                 c_rbaddr_sp | c_rbaddr_pc =>  -- r* -----------------
313 9 wfjm
              if irbena = '1' then
314
                n.cpfunc    := c_cpfunc_rreg;
315
                n.cpfunc(0) := RB_MREQ.we;
316
                icpreq   := '1';
317
              end if;
318
 
319 28 wfjm
            when c_rbaddr_membe  =>         -- membe -----------------
320
              irb_dout(c_membe_rbf_be)    := r.membe;
321
              irb_dout(c_membe_rbf_stick) := r.membestick;
322 2 wfjm
              if RB_MREQ.we = '1' then
323 28 wfjm
                n.membe      := RB_MREQ.din(c_membe_rbf_be);
324
                n.membestick := RB_MREQ.din(c_membe_rbf_stick);
325 2 wfjm
              end if;
326
 
327
            when others =>
328
              irb_ack := '0';
329
 
330
          end case;
331
 
332
        end if;
333
 
334
        if icpreq = '1' then
335
          irb_busy := '1';
336
          n.cpreq  := '1';
337
          n.state  := s_cpwait;
338
        end if;
339
 
340
      when s_cpwait =>                  -- s_cpwait: wait for cp port ack ----
341
        n.cpreq := '0';                   -- cpreq only for 1 cycle
342
 
343 9 wfjm
        if (r.rbselc or r.rbseli)='0' or irbena='0' then -- rbus cycle abort
344 28 wfjm
          if r.cpfunc = c_cpfunc_wmem and   -- if wmem command
345
               r.membestick = '0' then        --   and be's not sticky
346
            n.membe := "11";                  -- re-enable both bytes
347
          end if;
348 2 wfjm
          n.state := s_idle;              -- quit
349
        else
350
          irb_dout := CP_DOUT;
351 9 wfjm
          irb_err  := CP_STAT.cmderr or CP_STAT.cmdmerr;
352 2 wfjm
          if CP_STAT.cmdack = '1' then       -- normal cycle end
353 28 wfjm
            if r.cpfunc = c_cpfunc_wmem and   -- if wmem command
354
                 r.membestick = '0' then        --   and be's not sticky
355
              n.membe := "11";                  -- re-enable both bytes
356
            end if;
357 2 wfjm
            if r.doinc = '1' then
358 13 wfjm
              n.addr := slv(unsigned(r.addr) + 1);
359 2 wfjm
            end if;
360
            if r.waitstep = '1' then
361
              irb_busy := '1';
362
              n.state := s_cpstep;
363
            else
364
              n.state := s_idle;
365
            end if;
366
          else
367
            irb_busy := '1';
368
          end if;
369
        end if;
370
 
371
      when s_cpstep =>                  -- s_cpstep: wait for cpustep done ---
372 9 wfjm
        if r.rbselc='0' or irbena='0' then -- rbus cycle abort
373 2 wfjm
          n.state := s_idle;                -- quit
374
        else
375
          if CP_STAT.cpustep = '0' then      -- cpustep done
376
            n.state := s_idle;
377
          else
378
            irb_busy := '1';
379
          end if;
380
        end if;
381
 
382
      when others => null;
383
    end case;
384
 
385 28 wfjm
    icpaddr    := cp_addr_init;
386
    icpaddr.be := r.membe;
387 2 wfjm
 
388 28 wfjm
    if r.rbseli = '0' then              -- access via cp
389
      icpaddr.addr      := r.addr;
390
      icpaddr.racc      := '0';
391
      icpaddr.ena_22bit := r.ena_22bit;
392
      icpaddr.ena_ubmap := r.ena_ubmap;
393
    else                                -- access via ibus window
394
      icpaddr.addr(15 downto 13) := "111";
395
      icpaddr.addr(12 downto 1)  := RB_MREQ.addr(11 downto 0);
396 2 wfjm
      icpaddr.racc      := '1';
397
      icpaddr.ena_22bit := '0';
398
      icpaddr.ena_ubmap := '0';
399
    end if;
400
 
401
    n.cpugo_1 := CP_STAT.cpugo;         -- delay cpugo 
402
    if CP_STAT.cpugo='0' and r.cpugo_1='1' then  -- cpugo 1 -> 0 transition ?
403
      irb_lam := '1';
404
    end if;
405
 
406
    N_REGS <= n;
407
 
408
    RB_SRES.ack  <= irb_ack;
409
    RB_SRES.err  <= irb_err;
410
    RB_SRES.busy <= irb_busy;
411
    RB_SRES.dout <= irb_dout;
412
 
413 28 wfjm
    RB_STAT(3) <= CP_STAT.cmderr;
414
    RB_STAT(2) <= CP_STAT.cmdmerr;
415 27 wfjm
    RB_STAT(1) <= CP_STAT.cpuhalt or CP_STAT.cpurust(CP_STAT.cpurust'left);
416 2 wfjm
    RB_STAT(0) <= CP_STAT.cpugo;
417
 
418 8 wfjm
    RB_LAM     <= irb_lam;
419 2 wfjm
 
420
    CPU_RESET  <= icpureset;
421
 
422
    CP_CNTL.req  <= r.cpreq;
423
    CP_CNTL.func <= r.cpfunc;
424
    CP_CNTL.rnum <= RB_MREQ.addr(2 downto 0);
425
 
426
    CP_ADDR <= icpaddr;
427
    CP_DIN  <= RB_MREQ.din;
428
 
429
  end process proc_next;
430
 
431
end syn;

powered by: WebSVN 2.1.0

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