Line 1... |
Line 1... |
-- $Id: pdp11_core_rbus.vhd 591 2014-09-06 17:45:38Z mueller $
|
-- $Id: pdp11_core_rbus.vhd 621 2014-12-26 21:20:05Z mueller $
|
--
|
--
|
-- Copyright 2007-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
-- Copyright 2007-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
--
|
--
|
-- This program is free software; you may redistribute and/or modify it under
|
-- This program is free software; you may redistribute and/or modify it under
|
-- the terms of the GNU General Public License as published by the Free
|
-- the terms of the GNU General Public License as published by the Free
|
Line 18... |
Line 18... |
-- Dependencies: -
|
-- Dependencies: -
|
-- Test bench: tb/tb_rlink_tba_pdp11core
|
-- Test bench: tb/tb_rlink_tba_pdp11core
|
--
|
--
|
-- Target Devices: generic
|
-- Target Devices: generic
|
-- Tool versions: xst 8.2-14.7; ghdl 0.18-0.31
|
-- Tool versions: xst 8.2-14.7; ghdl 0.18-0.31
|
|
--
|
|
-- Synthesized (xst):
|
|
-- Date Rev ise Target flop lutl lutm slic t peri
|
|
-- 2014-12-21 591 14.7 131013 xc6slx16-2 52 118 0 58 s 4.9
|
|
--
|
-- Revision History: -
|
-- Revision History: -
|
-- Date Rev Version Comment
|
-- Date Rev Version Comment
|
|
-- 2014-12-26 621 1.4 use full size 4k word ibus window
|
|
-- 2014-12-21 617 1.3.1 use separate RB_STAT bits for cmderr and cmdmerr
|
-- 2014-09-05 591 1.3 use new rlink v4 iface and 4 bit STAT
|
-- 2014-09-05 591 1.3 use new rlink v4 iface and 4 bit STAT
|
-- 2014-08-15 583 1.2 rb_mreq addr now 16 bit
|
-- 2014-08-15 583 1.2 rb_mreq addr now 16 bit
|
-- 2011-11-18 427 1.1.1 now numeric_std clean
|
-- 2011-11-18 427 1.1.1 now numeric_std clean
|
-- 2010-12-29 351 1.1 renamed from pdp11_core_rri; ported to rbv3
|
-- 2010-12-29 351 1.1 renamed from pdp11_core_rri; ported to rbv3
|
-- 2010-10-23 335 1.2.3 rename RRI_LAM->RB_LAM;
|
-- 2010-10-23 335 1.2.3 rename RRI_LAM->RB_LAM;
|
Line 47... |
Line 54... |
-- 2007-07-08 65 1.0 Initial version
|
-- 2007-07-08 65 1.0 Initial version
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
--
|
--
|
-- rbus registers:
|
-- rbus registers:
|
--
|
--
|
-- Address Bits Name r/w/i Function
|
-- Addr Bits Name r/w/f Function
|
--
|
--
|
-- bbb00000 conf r/w/- cpu configuration (e.g. cpu type)
|
-- 00000 conf r/w/- cpu configuration (e.g. cpu type)
|
-- (currently unused, all bits MBZ)
|
-- (currently unused, all bits MBZ)
|
-- bbb00001 cntl -/f/- cpu control
|
-- 00001 cntl -/f/- cpu control
|
-- 3:0 func function code
|
-- 3:00 func function code
|
-- 0000: noop
|
-- 0000: noop
|
-- 0001: start
|
-- 0001: start
|
-- 0010: stop
|
-- 0010: stop
|
-- 0011: continue
|
-- 0011: continue
|
-- 0100: step
|
-- 0100: step
|
-- 1111: reset (soft)
|
-- 1111: reset (soft)
|
-- bbb00010 stat r/-/- cpu status
|
-- 00010 stat r/-/- cpu status
|
-- 7:04 cpurust r/-/- cp_stat: cpurust
|
-- 7:04 cpurust r/-/- cp_stat: cpurust
|
-- 3 cpuhalt r/-/- cp_stat: cpuhalt
|
-- 3 cpuhalt r/-/- cp_stat: cpuhalt
|
-- 2 cpugo r/-/- cp_stat: cpugo
|
-- 2 cpugo r/-/- cp_stat: cpugo
|
-- 1 cmdmerr r/-/- cp_stat: cmdmerr
|
-- 1 cmdmerr r/-/- cp_stat: cmdmerr
|
-- 0 cmderr r/-/- cp_stat: cmderr
|
-- 0 cmderr r/-/- cp_stat: cmderr
|
-- bbb00011 psw r/w/- processor status word access
|
-- 00011 psw r/w/- processor status word access
|
-- bbb00100 al r/w/- address register, low
|
-- 00100 al r/w/- address register, low
|
-- bbb00101 ah r/w/- address register, high
|
-- 00101 ah r/w/- address register, high
|
-- 7 ubm r/w/- ubmap access
|
-- 7 ubm r/w/- ubmap access
|
-- 6 p22 r/w/- 22bit access
|
-- 6 p22 r/w/- 22bit access
|
-- 5: 0 addr r/w/- addr(21:16)
|
-- 5:00 addr r/w/- addr(21:16)
|
-- bbb00110 mem r/w/- memory access
|
-- 00110 mem r/w/- memory access
|
-- bbb00111 memi r/w/- memory access, inc address
|
-- 00111 memi r/w/- memory access, inc address
|
-- bbb01rrr gpr[] r/w/- general purpose regs
|
-- 01rrr gpr[] r/w/- general purpose regs
|
-- bbb10000 ibrb r/w/- ibr base address
|
-- 10000 membe r/w/- memory write byte enables
|
-- 12:06 base r/w/- ibr window base address
|
-- 3 stick r/w/- sticky flag
|
-- 1:00 we r/w/- byte enables (00 equivalent to 11)
|
-- 1:00 be r/w/- byte enables
|
-- www----- ibr[] r/w/- ibr window (32 words)
|
|
--
|
--
|
|
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
use ieee.numeric_std.all;
|
use ieee.numeric_std.all;
|
Line 92... |
Line 98... |
|
|
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
|
|
entity pdp11_core_rbus is -- core to rbus interface
|
entity pdp11_core_rbus is -- core to rbus interface
|
generic (
|
generic (
|
RB_ADDR_CORE : slv16 := slv(to_unsigned(2#0000000000000000#,16));
|
RB_ADDR_CORE : slv16 := slv(to_unsigned(16#0000#,16));
|
RB_ADDR_IBUS : slv16 := slv(to_unsigned(2#0000000010000000#,16)));
|
RB_ADDR_IBUS : slv16 := slv(to_unsigned(16#4000#,16)));
|
port (
|
port (
|
CLK : in slbit; -- clock
|
CLK : in slbit; -- clock
|
RESET : in slbit; -- reset
|
RESET : in slbit; -- reset
|
RB_MREQ : in rb_mreq_type; -- rbus: request
|
RB_MREQ : in rb_mreq_type; -- rbus: request
|
RB_SRES : out rb_sres_type; -- rbus: response
|
RB_SRES : out rb_sres_type; -- rbus: response
|
Line 129... |
Line 135... |
cpfunc : slv5; -- cp function
|
cpfunc : slv5; -- cp function
|
cpugo_1 : slbit; -- prev cycle cpugo
|
cpugo_1 : slbit; -- prev cycle cpugo
|
addr : slv22_1; -- address register
|
addr : slv22_1; -- address register
|
ena_22bit : slbit; -- 22bit enable
|
ena_22bit : slbit; -- 22bit enable
|
ena_ubmap : slbit; -- ubmap enable
|
ena_ubmap : slbit; -- ubmap enable
|
ibrbase : slv(c_ibrb_ibf_base); -- ibr base address
|
membe : slv2; -- memory write byte enables
|
ibrbe : slv2; -- ibr byte enables
|
membestick : slbit; -- memory write byte enables sticky
|
ibrberet : slv2; -- ibr byte enables (for readback)
|
|
doinc : slbit; -- at cmdack: do addr reg inc
|
doinc : slbit; -- at cmdack: do addr reg inc
|
waitstep : slbit; -- at cmdack: wait for cpu step complete
|
waitstep : slbit; -- at cmdack: wait for cpu step complete
|
end record regs_type;
|
end record regs_type;
|
|
|
constant regs_init : regs_type := (
|
constant regs_init : regs_type := (
|
Line 144... |
Line 149... |
'0', -- cpreq
|
'0', -- cpreq
|
(others=>'0'), -- cpfunc
|
(others=>'0'), -- cpfunc
|
'0', -- cpugo_1
|
'0', -- cpugo_1
|
(others=>'0'), -- addr
|
(others=>'0'), -- addr
|
'0','0', -- ena_22bit, ena_ubmap
|
'0','0', -- ena_22bit, ena_ubmap
|
(others=>'0'),"00","00", -- ibrbase, ibrbe, ibrberet
|
"11",'0', -- membe,membestick
|
'0','0' -- doinc, waitstep
|
'0','0' -- doinc, waitstep
|
);
|
);
|
|
|
signal R_REGS : regs_type := regs_init; -- state registers
|
signal R_REGS : regs_type := regs_init; -- state registers
|
signal N_REGS : regs_type := regs_init; -- next value state regs
|
signal N_REGS : regs_type := regs_init; -- next value state regs
|
Line 210... |
Line 215... |
n.rbselc := '0';
|
n.rbselc := '0';
|
if RB_MREQ.aval='1' then
|
if RB_MREQ.aval='1' then
|
if RB_MREQ.addr(15 downto 5)=RB_ADDR_CORE(15 downto 5) then
|
if RB_MREQ.addr(15 downto 5)=RB_ADDR_CORE(15 downto 5) then
|
n.rbselc := '1';
|
n.rbselc := '1';
|
end if;
|
end if;
|
if RB_MREQ.addr(15 downto 5)=RB_ADDR_IBUS(15 downto 5) then
|
if RB_MREQ.addr(15 downto 12)=RB_ADDR_IBUS(15 downto 12) then
|
n.rbseli := '1';
|
n.rbseli := '1';
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
if (r.rbselc='1' or r.rbseli='1') and irbena='1' then
|
if (r.rbselc='1' or r.rbseli='1') and irbena='1' then
|
Line 251... |
Line 256... |
if RB_MREQ.din(3 downto 0) = c_cpfunc_step(3 downto 0) then
|
if RB_MREQ.din(3 downto 0) = c_cpfunc_step(3 downto 0) then
|
n.waitstep := '1';
|
n.waitstep := '1';
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
when c_rbaddr_stat => -- stat -------------------------
|
when c_rbaddr_stat => -- stat ------------------
|
irb_dout(c_stat_rbf_cmderr) := CP_STAT.cmderr;
|
irb_dout(c_stat_rbf_cmderr) := CP_STAT.cmderr;
|
irb_dout(c_stat_rbf_cmdmerr) := CP_STAT.cmdmerr;
|
irb_dout(c_stat_rbf_cmdmerr) := CP_STAT.cmdmerr;
|
irb_dout(c_stat_rbf_cpugo) := CP_STAT.cpugo;
|
irb_dout(c_stat_rbf_cpugo) := CP_STAT.cpugo;
|
irb_dout(c_stat_rbf_cpuhalt) := CP_STAT.cpuhalt;
|
irb_dout(c_stat_rbf_cpuhalt) := CP_STAT.cpuhalt;
|
irb_dout(c_stat_rbf_cpurust) := CP_STAT.cpurust;
|
irb_dout(c_stat_rbf_cpurust) := CP_STAT.cpurust;
|
|
|
when c_rbaddr_psw => -- psw --------------------------
|
when c_rbaddr_psw => -- psw -------------------
|
if irbena = '1' then
|
if irbena = '1' then
|
n.cpfunc := c_cpfunc_rpsw;
|
n.cpfunc := c_cpfunc_rpsw;
|
n.cpfunc(0) := RB_MREQ.we;
|
n.cpfunc(0) := RB_MREQ.we;
|
icpreq := '1';
|
icpreq := '1';
|
end if;
|
end if;
|
|
|
when c_rbaddr_al => -- al ---------------------------
|
when c_rbaddr_al => -- al --------------------
|
irb_dout(c_al_rbf_addr) := r.addr(c_al_rbf_addr);
|
irb_dout(c_al_rbf_addr) := r.addr(c_al_rbf_addr);
|
if RB_MREQ.we = '1' then
|
if RB_MREQ.we = '1' then
|
n.addr := (others=>'0'); -- write to al clears ah !!
|
n.addr := (others=>'0'); -- write to al clears ah !!
|
n.ena_22bit := '0';
|
n.ena_22bit := '0';
|
n.ena_ubmap := '0';
|
n.ena_ubmap := '0';
|
n.addr(c_al_rbf_addr) := RB_MREQ.din(c_al_rbf_addr);
|
n.addr(c_al_rbf_addr) := RB_MREQ.din(c_al_rbf_addr);
|
end if;
|
end if;
|
|
|
when c_rbaddr_ah => -- ah ---------------------------
|
when c_rbaddr_ah => -- ah --------------------
|
irb_dout(c_ah_rbf_ena_ubmap) := r.ena_ubmap;
|
irb_dout(c_ah_rbf_ena_ubmap) := r.ena_ubmap;
|
irb_dout(c_ah_rbf_ena_22bit) := r.ena_22bit;
|
irb_dout(c_ah_rbf_ena_22bit) := r.ena_22bit;
|
irb_dout(c_ah_rbf_addr) := r.addr(21 downto 16);
|
irb_dout(c_ah_rbf_addr) := r.addr(21 downto 16);
|
if RB_MREQ.we = '1' then
|
if RB_MREQ.we = '1' then
|
n.addr(21 downto 16) := RB_MREQ.din(c_ah_rbf_addr);
|
n.addr(21 downto 16) := RB_MREQ.din(c_ah_rbf_addr);
|
n.ena_22bit := RB_MREQ.din(c_ah_rbf_ena_22bit);
|
n.ena_22bit := RB_MREQ.din(c_ah_rbf_ena_22bit);
|
n.ena_ubmap := RB_MREQ.din(c_ah_rbf_ena_ubmap);
|
n.ena_ubmap := RB_MREQ.din(c_ah_rbf_ena_ubmap);
|
end if;
|
end if;
|
|
|
when c_rbaddr_mem => -- mem -----------------
|
when c_rbaddr_mem => -- mem -------------------
|
if irbena = '1' then
|
if irbena = '1' then
|
n.cpfunc := c_cpfunc_rmem;
|
n.cpfunc := c_cpfunc_rmem;
|
n.cpfunc(0) := RB_MREQ.we;
|
n.cpfunc(0) := RB_MREQ.we;
|
icpreq := '1';
|
icpreq := '1';
|
end if;
|
end if;
|
|
|
when c_rbaddr_memi => -- memi ----------------
|
when c_rbaddr_memi => -- memi ------------------
|
if irbena = '1' then
|
if irbena = '1' then
|
n.cpfunc := c_cpfunc_rmem;
|
n.cpfunc := c_cpfunc_rmem;
|
n.cpfunc(0) := RB_MREQ.we;
|
n.cpfunc(0) := RB_MREQ.we;
|
n.doinc := '1';
|
n.doinc := '1';
|
icpreq := '1';
|
icpreq := '1';
|
end if;
|
end if;
|
|
|
when c_rbaddr_r0 | c_rbaddr_r1 |
|
when c_rbaddr_r0 | c_rbaddr_r1 |
|
c_rbaddr_r2 | c_rbaddr_r3 |
|
c_rbaddr_r2 | c_rbaddr_r3 |
|
c_rbaddr_r4 | c_rbaddr_r5 |
|
c_rbaddr_r4 | c_rbaddr_r5 |
|
c_rbaddr_sp | c_rbaddr_pc => -- r* ------------------
|
c_rbaddr_sp | c_rbaddr_pc => -- r* -----------------
|
if irbena = '1' then
|
if irbena = '1' then
|
n.cpfunc := c_cpfunc_rreg;
|
n.cpfunc := c_cpfunc_rreg;
|
n.cpfunc(0) := RB_MREQ.we;
|
n.cpfunc(0) := RB_MREQ.we;
|
icpreq := '1';
|
icpreq := '1';
|
end if;
|
end if;
|
|
|
when c_rbaddr_ibrb => -- ibrb ----------------
|
when c_rbaddr_membe => -- membe -----------------
|
irb_dout(c_ibrb_ibf_base) := r.ibrbase;
|
irb_dout(c_membe_rbf_be) := r.membe;
|
irb_dout(c_ibrb_ibf_be) := r.ibrberet;
|
irb_dout(c_membe_rbf_stick) := r.membestick;
|
if RB_MREQ.we = '1' then
|
if RB_MREQ.we = '1' then
|
n.ibrbase := RB_MREQ.din(c_ibrb_ibf_base);
|
n.membe := RB_MREQ.din(c_membe_rbf_be);
|
n.ibrberet := RB_MREQ.din(c_ibrb_ibf_be);
|
n.membestick := RB_MREQ.din(c_membe_rbf_stick);
|
if RB_MREQ.din(c_ibrb_ibf_be) = "00" then -- both be=0 ?
|
|
n.ibrbe := "11";
|
|
else -- otherwise take 2 LSB's
|
|
n.ibrbe := RB_MREQ.din(c_ibrb_ibf_be);
|
|
end if;
|
|
end if;
|
end if;
|
|
|
when others =>
|
when others =>
|
irb_ack := '0';
|
irb_ack := '0';
|
|
|
Line 339... |
Line 339... |
|
|
when s_cpwait => -- s_cpwait: wait for cp port ack ----
|
when s_cpwait => -- s_cpwait: wait for cp port ack ----
|
n.cpreq := '0'; -- cpreq only for 1 cycle
|
n.cpreq := '0'; -- cpreq only for 1 cycle
|
|
|
if (r.rbselc or r.rbseli)='0' or irbena='0' then -- rbus cycle abort
|
if (r.rbselc or r.rbseli)='0' or irbena='0' then -- rbus cycle abort
|
|
if r.cpfunc = c_cpfunc_wmem and -- if wmem command
|
|
r.membestick = '0' then -- and be's not sticky
|
|
n.membe := "11"; -- re-enable both bytes
|
|
end if;
|
n.state := s_idle; -- quit
|
n.state := s_idle; -- quit
|
else
|
else
|
irb_dout := CP_DOUT;
|
irb_dout := CP_DOUT;
|
irb_err := CP_STAT.cmderr or CP_STAT.cmdmerr;
|
irb_err := CP_STAT.cmderr or CP_STAT.cmdmerr;
|
if CP_STAT.cmdack = '1' then -- normal cycle end
|
if CP_STAT.cmdack = '1' then -- normal cycle end
|
|
if r.cpfunc = c_cpfunc_wmem and -- if wmem command
|
|
r.membestick = '0' then -- and be's not sticky
|
|
n.membe := "11"; -- re-enable both bytes
|
|
end if;
|
if r.doinc = '1' then
|
if r.doinc = '1' then
|
n.addr := slv(unsigned(r.addr) + 1);
|
n.addr := slv(unsigned(r.addr) + 1);
|
end if;
|
end if;
|
if r.waitstep = '1' then
|
if r.waitstep = '1' then
|
irb_busy := '1';
|
irb_busy := '1';
|
Line 373... |
Line 381... |
|
|
when others => null;
|
when others => null;
|
end case;
|
end case;
|
|
|
icpaddr := cp_addr_init;
|
icpaddr := cp_addr_init;
|
|
icpaddr.be := r.membe;
|
|
|
|
if r.rbseli = '0' then -- access via cp
|
icpaddr.addr := r.addr;
|
icpaddr.addr := r.addr;
|
icpaddr.racc := '0';
|
icpaddr.racc := '0';
|
icpaddr.be := "11";
|
|
icpaddr.ena_22bit := r.ena_22bit;
|
icpaddr.ena_22bit := r.ena_22bit;
|
icpaddr.ena_ubmap := r.ena_ubmap;
|
icpaddr.ena_ubmap := r.ena_ubmap;
|
|
else -- access via ibus window
|
if r.rbseli = '1' and irbena = '1' then
|
|
icpaddr.addr(15 downto 13) := "111";
|
icpaddr.addr(15 downto 13) := "111";
|
icpaddr.addr(c_ibrb_ibf_base) := r.ibrbase;
|
icpaddr.addr(12 downto 1) := RB_MREQ.addr(11 downto 0);
|
icpaddr.addr(5 downto 1) := RB_MREQ.addr(4 downto 0);
|
|
icpaddr.racc := '1';
|
icpaddr.racc := '1';
|
icpaddr.be := r.ibrbe;
|
|
icpaddr.ena_22bit := '0';
|
icpaddr.ena_22bit := '0';
|
icpaddr.ena_ubmap := '0';
|
icpaddr.ena_ubmap := '0';
|
end if;
|
end if;
|
|
|
n.cpugo_1 := CP_STAT.cpugo; -- delay cpugo
|
n.cpugo_1 := CP_STAT.cpugo; -- delay cpugo
|
Line 401... |
Line 408... |
RB_SRES.ack <= irb_ack;
|
RB_SRES.ack <= irb_ack;
|
RB_SRES.err <= irb_err;
|
RB_SRES.err <= irb_err;
|
RB_SRES.busy <= irb_busy;
|
RB_SRES.busy <= irb_busy;
|
RB_SRES.dout <= irb_dout;
|
RB_SRES.dout <= irb_dout;
|
|
|
RB_STAT(3) <= '0';
|
RB_STAT(3) <= CP_STAT.cmderr;
|
RB_STAT(2) <= CP_STAT.cmderr or CP_STAT.cmdmerr;
|
RB_STAT(2) <= CP_STAT.cmdmerr;
|
RB_STAT(1) <= CP_STAT.cpuhalt or CP_STAT.cpurust(CP_STAT.cpurust'left);
|
RB_STAT(1) <= CP_STAT.cpuhalt or CP_STAT.cpurust(CP_STAT.cpurust'left);
|
RB_STAT(0) <= CP_STAT.cpugo;
|
RB_STAT(0) <= CP_STAT.cpugo;
|
|
|
RB_LAM <= irb_lam;
|
RB_LAM <= irb_lam;
|
|
|