1
0
mirror of https://github.com/wfjm/w11.git synced 2026-01-12 00:43:01 +00:00

lp11_buf: output buffered; add tbench

- ib_rlim_{gen,slv}: new modules for implementation of rate limiters
- ibdr_lp11_buf: new LP11 interface with fifo buffering
- ibdr_maxisys: add ib_rlim_gen, ibdr_lp11_buf
- tbench/test_lp11_all.tcl: tbench for lp11 and lp11_buf
- Rw11CntlLP11: handles now also buffered lp11
This commit is contained in:
wfjm 2019-03-23 08:20:25 +01:00
parent a49f628920
commit f9faf937b1
21 changed files with 1449 additions and 67 deletions

View File

@ -27,11 +27,14 @@ The full set of tests is only run for tagged releases.
- new components
- fifo_simple_dram: simple fifo with CE/WE interface, dram based
- ibd_ibtst: ibus tester device
- ib_rlim_{gen,slv}: new modules for implementation of rate limiters
- ibdr_lp11_buf: new LP11 interface with fifo buffering
- simclkv: test bench clock generator with variable period
- new verification codes
- tbench/w11a_ibtst/*: tbench for ibd_ibtst
- tbench/w11a_ibmon/*: tbench for ibd_ibmon
- test_w11a_sdreg.tcl: tbench for sdreg
- w11a_ibtst/*: tbench for ibd_ibtst
- w11a_ibmon/*: tbench for ibd_ibmon
- w11a/test_w11a_sdreg.tcl: tbench for sdreg
- test_lp11_all.tcl: tbench for lp11 and lp11_buf
### Changes
- tools changes
@ -51,10 +54,13 @@ The full set of tests is only run for tagged releases.
- ibdr_lp11: move valid bit to msb of buf (for ibdr_lp11_buf compatibility)
- sys_w11a_s3: set BTOWIDTH 7 (was 6, must be > vmbox atowidth (6))
- pdp11_sys70: instantiate ibd_ibtst (when sys_conf_ibtst = true)
- ibdr_maxisys,sys_conf ready for buffered DL,PC,LP and dz11,ibtst
- ibdr_maxisys,sys_conf ready for buffered DL,PC and dz11
- use type code instead of boolean for sys_conf_ibd_{dl11,lp11,pc11}
- add sys_conf_ibtst (enabled in all systems)
- add sys_conf_ibd_dz11 (enabled in all systems)
- add ib_rlim_gen to support rate limiters
- instantiate ibd_ibtst
- instantiate ibdr_lp11_buf
### Bug Fixes
- backend code: some getters crashed with `SIGSEGV`, see

View File

@ -7,7 +7,23 @@ This file descibes general issues.
The case id indicates the release when the issue was first recognized.
### V0.50-8 {[issue #21](https://github.com/wfjm/w11/issues/21)} --RK11,RL11: no proper NXM check in 18bit systems
### V0.50-1 {[issue #23](https://github.com/wfjm/w11/issues/23)} -- CPU: several deficits in trap logic
The current w11a implementation has several deficits in the handling of
traps and interrupts which lead to non-conforming behavior when multiple
trap, fault and interrupt conditions occur simultaneously, for example
- bad stack frame when `IOT` trigger stack violation (TCK-003)
- bad stack frame when interrupt triggers stack violation (TCK-004)
- no yellow stack abort when `jsr` triggers a stack violation (TCK-006)
- no odd address trap when `EMT` is executed with odd `SP` (TCK-007)
- no yellow stack abort for `mov (sp),(sp)` (TCK-028)
These situations never occur during the execution of operation systems, and
in case they do, the operating system will crash anyway. Thus there is no
impact in normal usage, but diagnostics programs do complain. Will be fixed
in an upcoming release.
### V0.50-8 {[issue #21](https://github.com/wfjm/w11/issues/21)} -- RK11,RL11: no proper NXM check in 18bit systems
No `NXM` error is generated when a UNIBUS device DMA transfer reaches the top
of memory in 18 bit addressing. Seen originally for RK11, but RL11 and DEUNA

View File

@ -0,0 +1,5 @@
# libs
../vlib/slvtypes.vhd
iblib.vhd
# design
ib_rlim_gen.vhd

109
rtl/ibus/ib_rlim_gen.vhd Normal file
View File

@ -0,0 +1,109 @@
-- $Id: ib_rlim_gen.vhd 1123 2019-03-17 17:55:12Z mueller $
--
-- Copyright 2019- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- 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
-- Software Foundation, either version 3, or (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-- for complete details.
--
------------------------------------------------------------------------------
-- Module Name: ib_rlim_gen - syn
-- Description: ibus rate limter - master
--
-- Dependencies: -
-- Test bench: -
-- Target Devices: generic
-- Tool versions: ise 14.7; viv 2017.2; ghdl 0.35
--
-- Revision History:
-- Date Rev Version Comment
-- 2019-03-17 1123 1.0 Initial version
-- 2019-03-15 1122 0.1 First draft
--
-- Notes:
-- cev scale rate in slv
-- (0) 1: 1 8 usec 125.0 kHz
-- (1) 1: 2 16 usec 62.5 kHz
-- (2) 1: 4 32 usec 31.2 kHz
-- (3) 1: 8 64 usec 15.6 kHz
-- (4) 1: 32 256 usec 3.9 kHz
-- (5) 1: 64 512 usec 2.0 kHz
-- (6) 1:128 1024 usec 1.0 kHz
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.slvtypes.all;
-- ----------------------------------------------------------------------------
entity ib_rlim_gen is -- ibus rate limter - master
port (
CLK : in slbit; -- clock
CE_USEC : in slbit; -- usec pulse
RESET : in slbit; -- system reset
RLIM_CEV : out slv7 -- clock enable vector
);
end ib_rlim_gen;
architecture syn of ib_rlim_gen is
type regs_type is record -- state registers
cnt : slv7; -- usec counter
cev : slv6; -- ce vector
end record regs_type;
constant regs_init : regs_type := (
(others=>'0'), -- cnt
(others=>'0') -- cev
);
signal R_REGS : regs_type := regs_init;
signal N_REGS : regs_type := regs_init;
begin
proc_regs: process (CLK)
begin
if rising_edge(CLK) then
if RESET = '1' then
R_REGS <= regs_init;
else
R_REGS <= N_REGS;
end if;
end if;
end process proc_regs;
proc_next : process (R_REGS, CE_USEC)
variable r : regs_type := regs_init;
variable n : regs_type := regs_init;
begin
r := R_REGS;
n := R_REGS;
n.cev := (others=>'0');
if CE_USEC = '1' then
n.cnt := slv(unsigned(r.cnt) + 1);
if r.cnt(0 downto 0) = "1" then n.cev(0) := '1'; end if; -- 1: 2
if r.cnt(1 downto 0) = "11" then n.cev(1) := '1'; end if; -- 1: 4
if r.cnt(2 downto 0) = "111" then n.cev(2) := '1'; end if; -- 1: 8
if r.cnt(4 downto 0) = "11111" then n.cev(3) := '1'; end if; -- 1: 32
if r.cnt(5 downto 0) = "111111" then n.cev(4) := '1'; end if; -- 1: 64
if r.cnt(6 downto 0) = "1111111" then n.cev(5) := '1'; end if; -- 1:128
end if;
N_REGS <= n;
RLIM_CEV(6 downto 1) <= r.cev;
RLIM_CEV(0) <= CE_USEC;
end process proc_next;
end syn;

View File

@ -0,0 +1,5 @@
# libs
../vlib/slvtypes.vhd
iblib.vhd
# design
ib_rlim_slv.vhd

135
rtl/ibus/ib_rlim_slv.vhd Normal file
View File

@ -0,0 +1,135 @@
-- $Id: ib_rlim_slv.vhd 1123 2019-03-17 17:55:12Z mueller $
--
-- Copyright 2019- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- 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
-- Software Foundation, either version 3, or (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-- for complete details.
--
------------------------------------------------------------------------------
-- Module Name: ib_rlim_slv - syn
-- Description: ibus rate limter - slave
--
-- Dependencies: -
-- Test bench: -
-- Target Devices: generic
-- Tool versions: ise 14.7; viv 2017.2; ghdl 0.35
--
-- Revision History:
-- Date Rev Version Comment
-- 2019-03-17 1123 1.0 Initial version
-- 2019-03-15 1122 0.1 First draft
--
-- Notes:
-- sel ce-scale rate in slv
-- 0 - 7 cycles
-- 1 1: 1 8 usec 125.0 kHz
-- 2 1: 2 16 usec 62.5 kHz
-- 3 1: 4 32 usec 31.2 kHz
-- 4 1: 8 64 usec 15.6 kHz
-- 5 1: 16 256 usec 3.9 kHz
-- 6 1: 32 512 usec 2.0 kHz
-- 7 1: 64 1024 usec 1.0 kHz
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.slvtypes.all;
-- ----------------------------------------------------------------------------
entity ib_rlim_slv is -- ibus rate limter - slave
port (
CLK : in slbit; -- clock
RESET : in slbit; -- system reset
RLIM_CEV : in slv7; -- clock enable vector
SEL : in slv3; -- rlim select
START : in slbit; -- start timer
STOP : in slbit; -- stop timer
DONE : out slbit; -- 1 cycle pulse when expired
BUSY : out slbit -- timer running
);
end ib_rlim_slv;
architecture syn of ib_rlim_slv is
type regs_type is record -- state registers
cnt : slv3; -- counter
busy : slbit; -- busy
end record regs_type;
constant regs_init : regs_type := (
(others=>'0'), -- cnt
'0' -- busy
);
signal R_REGS : regs_type := regs_init;
signal N_REGS : regs_type := regs_init;
begin
proc_regs: process (CLK)
begin
if rising_edge(CLK) then
if RESET = '1' then
R_REGS <= regs_init;
else
R_REGS <= N_REGS;
end if;
end if;
end process proc_regs;
proc_next : process (R_REGS, RLIM_CEV, SEL, START, STOP)
variable r : regs_type := regs_init;
variable n : regs_type := regs_init;
variable idone : slbit := '0';
variable ice : slbit := '0';
begin
r := R_REGS;
n := R_REGS;
ice := '0';
case SEL is
when "000" => ice := '1'; -- every cycle
when "001" => ice := RLIM_CEV(0); -- every CE_USEC
when "010" => ice := RLIM_CEV(1); -- every 2nd CE_USEC
when "011" => ice := RLIM_CEV(2); -- every 4th CE_USEC
when "100" => ice := RLIM_CEV(3); -- every 8th CE_USEC
when "101" => ice := RLIM_CEV(4); -- every 32nd CE_USEC
when "110" => ice := RLIM_CEV(5); -- every 64th CE_USEC
when "111" => ice := RLIM_CEV(6); -- every 128th CE_USEC
when others => null;
end case;
idone := '0';
if STOP = '1' then
n.busy := '0';
idone := r.busy;
elsif START = '1' then
n.busy := '1';
n.cnt := "000";
elsif r.busy = '1' then
if ice = '1' then
n.cnt := slv(unsigned(r.cnt) + 1);
if r.cnt = "111" then
n.busy := '0';
idone := '1';
end if;
end if;
end if;
N_REGS <= n;
DONE <= idone;
BUSY <= r.busy;
end process proc_next;
end syn;

View File

@ -1,6 +1,6 @@
-- $Id: ibdlib.vhd 1111 2019-02-10 16:13:55Z mueller $
-- $Id: ibdlib.vhd 1123 2019-03-17 17:55:12Z mueller $
--
-- Copyright 2008-2018 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
-- Copyright 2008-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- 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
@ -19,6 +19,7 @@
-- Tool versions: ise 8.2-14.7; viv 2014.4-2018.3; ghdl 0.18-0.35
-- Revision History:
-- Date Rev Version Comment
-- 2019-03-09 1121 1.3.3 add ibdr_lp11_buf
-- 2018-10-13 1055 1.3.2 update ibdr_maxisys (add IDEC port)
-- 2018-09-08 1043 1.3.1 update ibd_kw11p
-- 2017-01-29 847 1.3.1 add ibdr_deuna
@ -266,6 +267,23 @@ component ibdr_lp11 is -- ibus dev(rem): LP11
);
end component;
component ibdr_lp11_buf is -- ibus dev(rem): LP11
-- fixed address: 177514
generic (
AWIDTH : natural := 5); -- fifo address width
port (
CLK : in slbit; -- clock
RESET : in slbit; -- system reset
BRESET : in slbit; -- ibus reset
RLIM_CEV : in slv7; -- clock enable vector
RB_LAM : out slbit; -- remote attention
IB_MREQ : in ib_mreq_type; -- ibus request
IB_SRES : out ib_sres_type; -- ibus response
EI_REQ : out slbit; -- interrupt request
EI_ACK : in slbit -- interrupt acknowledge
);
end component;
component ibdr_sdreg is -- ibus dev(rem): Switch/Display regs
-- fixed address: 177570
port (

View File

@ -0,0 +1,9 @@
# libs
../vlib/slvtypes.vhd
../vlib/memlib/memlib.vhd
iblib.vhd
# components
../vlib/memlib/fifo_simple_dram.vbom
ib_rlim_slv.vbom
# design
ibdr_lp11_buf.vhd

300
rtl/ibus/ibdr_lp11_buf.vhd Normal file
View File

@ -0,0 +1,300 @@
-- $Id: ibdr_lp11_buf.vhd 1123 2019-03-17 17:55:12Z mueller $
--
-- Copyright 2019- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- 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
-- Software Foundation, either version 3, or (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-- for complete details.
--
------------------------------------------------------------------------------
-- Module Name: ibdr_lp11_buf - syn
-- Description: ibus dev(rem): LP11
--
-- Dependencies: fifo_simple_dram
-- ib_rlim_slv
-- Test bench: -
-- Target Devices: generic
-- Tool versions: ise 8.2-14.7; viv 2017.2-2018.3; ghdl 0.35
--
-- Revision History:
-- Date Rev Version Comment
-- 2019-03-17 1123 1.0 Initial version
-- 2019-03-10 1121 0.1 First draft (derived from ibdr_lp11)
------------------------------------------------------------------------------
--
-- Notes:
-- - the ERR bit is just a status flag
-- - no hardware interlock (DONE forced 0 when ERR=1), like in simh
-- - also no interrupt when ERR goes 1, like in simh
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.slvtypes.all;
use work.memlib.all;
use work.iblib.all;
-- ----------------------------------------------------------------------------
entity ibdr_lp11_buf is -- ibus dev(rem): LP11
-- fixed address: 177514
generic (
AWIDTH : natural := 5); -- fifo address width
port (
CLK : in slbit; -- clock
RESET : in slbit; -- system reset
BRESET : in slbit; -- ibus reset
RLIM_CEV : in slv7; -- clock enable vector
RB_LAM : out slbit; -- remote attention
IB_MREQ : in ib_mreq_type; -- ibus request
IB_SRES : out ib_sres_type; -- ibus response
EI_REQ : out slbit; -- interrupt request
EI_ACK : in slbit -- interrupt acknowledge
);
end ibdr_lp11_buf;
architecture syn of ibdr_lp11_buf is
constant ibaddr_lp11 : slv16 := slv(to_unsigned(8#177514#,16));
constant ibaddr_csr : slv1 := "0"; -- csr address offset
constant ibaddr_buf : slv1 := "1"; -- buf address offset
constant csr_ibf_err : integer := 15;
subtype csr_ibf_rlim is integer range 14 downto 12;
subtype csr_ibf_type is integer range 10 downto 8;
constant csr_ibf_done : integer := 7;
constant csr_ibf_ie : integer := 6;
constant buf_ibf_val : integer := 15;
subtype buf_ibf_size is integer range AWIDTH-1+8 downto 8;
subtype buf_ibf_data is integer range 6 downto 0;
type regs_type is record -- state registers
ibsel : slbit; -- ibus select
err : slbit; -- csr: error flag
rlim : slv3; -- csr: rate limit
done : slbit; -- csr: done flag
ie : slbit; -- csr: interrupt enable
intreq : slbit; -- interrupt request
end record regs_type;
constant regs_init : regs_type := (
'0', -- ibsel
'1', -- err !! is set !!
"000", -- rlim
'1', -- done !! is set !!
'0', -- ie
'0' -- intreq
);
signal R_REGS : regs_type := regs_init;
signal N_REGS : regs_type := regs_init;
signal PBUF_CE : slbit := '0';
signal PBUF_WE : slbit := '0';
signal PBUF_DO : slv7 := (others=>'0');
signal PBUF_RESET : slbit := '0';
signal PBUF_EMPTY : slbit := '0';
signal PBUF_FULL : slbit := '0';
signal PBUF_SIZE : slv(AWIDTH-1 downto 0) := (others=>'0');
signal RLIM_START : slbit := '0';
signal RLIM_BUSY : slbit := '0';
begin
assert AWIDTH>=4 and AWIDTH<=7
report "assert(AWIDTH>=4 and AWIDTH<=7): unsupported AWIDTH"
severity failure;
PBUF : fifo_simple_dram
generic map (
AWIDTH => AWIDTH,
DWIDTH => 7)
port map (
CLK => CLK,
RESET => PBUF_RESET,
CE => PBUF_CE,
WE => PBUF_WE,
DI => IB_MREQ.din(buf_ibf_data),
DO => PBUF_DO,
EMPTY => PBUF_EMPTY,
FULL => PBUF_FULL,
SIZE => PBUF_SIZE
);
RLIM : ib_rlim_slv
port map (
CLK => CLK,
RESET => RESET,
RLIM_CEV => RLIM_CEV,
SEL => R_REGS.rlim,
START => RLIM_START,
STOP => BRESET,
DONE => open,
BUSY => RLIM_BUSY
);
proc_regs: process (CLK)
begin
if rising_edge(CLK) then
if BRESET = '1' then -- BRESET is 1 for system and ibus reset
R_REGS <= regs_init;
if RESET = '0' then -- if RESET=0 we do just an ibus reset
R_REGS.err <= N_REGS.err; -- keep ERR flag
R_REGS.rlim <= N_REGS.rlim; -- keep RLIM flag
end if;
else
R_REGS <= N_REGS;
end if;
end if;
end process proc_regs;
proc_next : process (R_REGS, IB_MREQ, EI_ACK, RESET, BRESET,
PBUF_DO, PBUF_EMPTY, PBUF_FULL, PBUF_SIZE, RLIM_BUSY)
variable r : regs_type := regs_init;
variable n : regs_type := regs_init;
variable idout : slv16 := (others=>'0');
variable ibreq : slbit := '0';
variable iback : slbit := '0';
variable ibrd : slbit := '0';
variable ibw0 : slbit := '0';
variable ibw1 : slbit := '0';
variable ilam : slbit := '0';
variable ipbufce : slbit := '0';
variable ipbufwe : slbit := '0';
variable irlimsta : slbit := '0';
begin
r := R_REGS;
n := R_REGS;
idout := (others=>'0');
ibreq := IB_MREQ.re or IB_MREQ.we;
iback := r.ibsel and ibreq;
ibrd := IB_MREQ.re;
ibw0 := IB_MREQ.we and IB_MREQ.be0;
ibw1 := IB_MREQ.we and IB_MREQ.be1;
ilam := '0';
ipbufce := '0';
ipbufwe := '0';
irlimsta := '0';
-- ibus address decoder
n.ibsel := '0';
if IB_MREQ.aval='1' and
IB_MREQ.addr(12 downto 2)=ibaddr_lp11(12 downto 2) then
n.ibsel := '1';
end if;
-- ibus transactions
if r.ibsel = '1' then
case IB_MREQ.addr(1 downto 1) is
when ibaddr_csr => -- CSR -- control status -------------
idout(csr_ibf_err) := r.err;
if IB_MREQ.racc = '1' then
idout(csr_ibf_type) := slv(to_unsigned(AWIDTH,3));
end if;
idout(csr_ibf_done) := r.done;
idout(csr_ibf_ie) := r.ie;
if IB_MREQ.racc = '0' then -- cpu
if ibw0 = '1' then
n.ie := IB_MREQ.din(csr_ibf_ie);
if IB_MREQ.din(csr_ibf_ie) = '1' then
if r.done='1' and r.ie='0' then -- ie set while done=1
n.intreq := '1'; -- request interrupt
end if;
else
n.intreq := '0';
end if;
end if;
else -- rri
idout(csr_ibf_rlim) := r.rlim;
if ibw1 = '1' then
n.err := IB_MREQ.din(csr_ibf_err);
n.rlim := IB_MREQ.din(csr_ibf_rlim);
if IB_MREQ.din(csr_ibf_err) = '1' then
n.done := '1';
n.intreq := '0'; -- clear irupt (like simh!)
end if;
end if;
end if;
when ibaddr_buf => -- BUF -- data buffer ----------------
if IB_MREQ.racc = '0' then -- cpu
if ibw0 = '1' then
irlimsta := '1'; -- in all cases start timer
if r.done = '1' then -- ignore buf write when done=0
if r.err = '0' then -- if online (handle via rbus)
if PBUF_FULL = '0' then -- fifo not full
ipbufce := '1'; -- write to fifo
ipbufwe := '1';
if PBUF_EMPTY = '1' then -- first write to empty fifo
ilam := '1'; -- request attention
end if;
end if; -- PBUF_FULL = '0'
else -- if offline (discard locally)
null;
end if; -- r.err = '0'
end if; -- r.done = '1'
end if; -- ibw0 = '1'
else -- rri
idout(buf_ibf_val) := not PBUF_EMPTY;
idout(buf_ibf_size) := PBUF_SIZE;
idout(buf_ibf_data) := PBUF_DO;
if ibrd = '1' then
if PBUF_EMPTY = '0' then -- fifo not empty
ipbufce := '1'; -- read from fifo
ipbufwe := '0';
else -- read from empty fifo
iback := '0'; -- signal nak
end if;
end if;
end if;
when others => null;
end case;
end if;
-- other state changes
if EI_ACK = '1' then
n.intreq := '0';
end if;
if (RLIM_BUSY or PBUF_FULL) ='1' then -- busy or fifo full
n.done := '0'; -- clear done
n.intreq := '0'; -- clear interrupt
else -- not busy and fifo not full
n.done := '1'; -- set done
if r.done='0' and -- done going 0->1
r.err='0' and r.ie='1' then -- and err=0 and interrupt enabled
n.intreq := '1'; -- request interrupt
end if;
end if;
N_REGS <= n;
PBUF_RESET <= RESET or BRESET or r.err;
PBUF_CE <= ipbufce;
PBUF_WE <= ipbufwe;
RLIM_START <= irlimsta;
IB_SRES.dout <= idout;
IB_SRES.ack <= iback;
IB_SRES.busy <= '0';
RB_LAM <= ilam;
EI_REQ <= r.intreq;
end process proc_next;
end syn;

View File

@ -4,6 +4,7 @@ iblib.vhd
ibdlib.vhd
${sys_conf := sys_conf.vhd}
# components
ib_rlim_gen.vbom
ibd_iist.vbom
ibd_kw11l.vbom
ibd_kw11p.vbom
@ -15,6 +16,7 @@ ibdr_tm11.vbom
ibdr_dl11.vbom
ibdr_pc11.vbom
ibdr_lp11.vbom
ibdr_lp11_buf.vbom
ibdr_sdreg.vbom
ib_sres_or_4.vbom
ib_sres_or_3.vbom

View File

@ -1,4 +1,4 @@
-- $Id: ibdr_maxisys.vhd 1111 2019-02-10 16:13:55Z mueller $
-- $Id: ibdr_maxisys.vhd 1123 2019-03-17 17:55:12Z mueller $
--
-- Copyright 2009-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
@ -15,7 +15,8 @@
-- Module Name: ibdr_maxisys - syn
-- Description: ibus(rem) devices for full system
--
-- Dependencies: ibd_iist
-- Dependencies: ib_rlim_gen
-- ibd_iist
-- ibd_kw11l
-- ibd_kw11p
-- ibdr_deuna
@ -26,6 +27,7 @@
-- ibdr_dl11
-- ibdr_pc11
-- ibdr_lp11
-- ibdr_lp11_buf
-- ibdr_sdreg
-- ib_sres_or_4
-- ib_sres_or_3
@ -49,6 +51,8 @@
--
-- Revision History:
-- Date Rev Version Comment
-- 2019-03-17 1123 1.6.2 add ib_rlim_gen, use with ibdr_lp11_buf
-- 2019-03-09 1121 1.6.1 add ibdr_lp11_buf
-- 2019-02-10 1111 1.6 use typ for DL,PC,LP
-- 2019-01-29 1108 1.5.1 move IIST signals into generate
-- 2018-10-13 1055 1.5 add IDEC port, connect to EXTEVT of KW11P
@ -226,9 +230,19 @@ architecture syn of ibdr_maxisys is
signal EI_ACK_PC11PTR : slbit := '0';
signal EI_ACK_PC11PTP : slbit := '0';
signal EI_ACK_LP11 : slbit := '0';
signal RLIM_CEV : slv7 := (others=>'0');
begin
RLIM : ib_rlim_gen
port map (
CLK => CLK,
CE_USEC => CE_USEC,
RESET => '0',
RLIM_CEV => RLIM_CEV
);
IIST: if sys_conf_ibd_iist generate
signal IIST_BUS : iist_bus_type := iist_bus_init;
signal IIST_OUT_0 : iist_line_type := iist_line_init;
@ -415,7 +429,7 @@ begin
);
end generate PC11;
LP11: if sys_conf_ibd_lp11 >= 0 generate
LP11: if sys_conf_ibd_lp11 = 0 generate
begin
LPA : ibdr_lp11
port map (
@ -430,6 +444,24 @@ begin
);
end generate LP11;
LP11BUF: if sys_conf_ibd_lp11 > 0 generate
begin
LPA : ibdr_lp11_buf
generic map (
AWIDTH => sys_conf_ibd_lp11)
port map (
CLK => CLK,
RESET => RESET,
BRESET => BRESET,
RLIM_CEV => RLIM_CEV,
RB_LAM => RB_LAM_LP11,
IB_MREQ => IB_MREQ,
IB_SRES => IB_SRES_LP11,
EI_REQ => EI_REQ_LP11,
EI_ACK => EI_ACK_LP11
);
end generate LP11BUF;
SDREG : ibdr_sdreg
port map (
CLK => CLK,

View File

@ -1,4 +1,4 @@
-- $Id: iblib.vhd 1111 2019-02-10 16:13:55Z mueller $
-- $Id: iblib.vhd 1123 2019-03-17 17:55:12Z mueller $
--
-- Copyright 2008-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
@ -19,6 +19,7 @@
-- Tool versions: ise 8.1-14.7; viv 2014.4-2018.3; ghdl 0.18-0.35
-- Revision History:
-- Date Rev Version Comment
-- 2019-03-17 1123 2.2.2 add ib_rlim_gen,ib_rlim_slv
-- 2019-02-10 1111 2.2.1 add ibd_ibtst
-- 2017-01-28 846 2.2 add ib_intmap24
-- 2016-05-28 770 2.1.1 use type natural for vec,pri fields of intmap_type
@ -177,6 +178,28 @@ component ibd_ibtst is -- ibus dev(rem): ibus tester
);
end component;
component ib_rlim_gen is -- ibus rate limter - master
port (
CLK : in slbit; -- clock
CE_USEC : in slbit; -- usec pulse
RESET : in slbit; -- system reset
RLIM_CEV : out slv7 -- clock enable vector
);
end component;
component ib_rlim_slv is -- ibus rate limter - slave
port (
CLK : in slbit; -- clock
RESET : in slbit; -- system reset
RLIM_CEV : in slv7; -- clock enable vector
SEL : in slv3; -- rlim select
START : in slbit; -- start timer
STOP : in slbit; -- stop timer
DONE : out slbit; -- 1 cycle pulse when expired
BUSY : out slbit -- timer running
);
end component;
--
-- components for use in test benches (not synthesizable)
--

View File

@ -1,4 +1,4 @@
-- $Id: sys_w11a_n3.vhd 1116 2019-03-03 08:24:07Z mueller $
-- $Id: sys_w11a_n3.vhd 1123 2019-03-17 17:55:12Z mueller $
--
-- Copyright 2011-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
@ -34,6 +34,7 @@
--
-- Synthesized (xst):
-- Date Rev ise Target flop lutl lutm slic t peri
-- 2019-03-17 1123 14.7 131013 xc6slx16-2 3059 5722 212 2041 ok: +lpbuf 89%
-- 2019-03-02 1116 14.7 131013 xc6slx16-2 3048 5741 212 2030 ok: +ibtst 89%
-- 2019-01-27 1108 14.7 131013 xc6slx16-2 2979 5542 201 2018 ok: -iist 88%
-- 2018-10-13 1055 14.7 131013 xc6slx16-2 3057 5822 201 2064 ok: +dmpcnt 90%

View File

@ -1,4 +1,4 @@
-- $Id: sys_w11a_n4.vhd 1116 2019-03-03 08:24:07Z mueller $
-- $Id: sys_w11a_n4.vhd 1123 2019-03-17 17:55:12Z mueller $
--
-- Copyright 2013-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
@ -35,6 +35,7 @@
--
-- Synthesized:
-- Date Rev viv Target flop lutl lutm bram slic MHz
-- 2019-03-17 1123 2017.2 xc7a100t-1 3231 6403 212 17.0 2053 80 +lpbuf
-- 2019-03-02 1116 2017.2 xc7a100t-1 3200 6317 198 17.0 2032 80 +ibtst
-- 2019-02-02 1108 2018.3 xc7a100t-1 3165 6497 182 17.0 2054 80
-- 2019-02-02 1108 2017.2 xc7a100t-1 3146 6227 182 17.0 1982 80

View File

@ -1,4 +1,4 @@
// $Id: Rw11CntlLP11.cpp 1114 2019-02-23 18:01:55Z mueller $
// $Id: Rw11CntlLP11.cpp 1123 2019-03-17 17:55:12Z mueller $
//
// Copyright 2013-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
@ -13,6 +13,7 @@
//
// Revision History:
// Date Rev Version Comment
// 2019-03-17 1123 1.3 add lp11_buf readout
// 2019-02-23 1114 1.2.6 use std::bind instead of lambda
// 2018-12-15 1082 1.2.5 use lambda instead of boost::bind
// 2018-12-09 1080 1.2.4 use HasVirt()
@ -26,7 +27,6 @@
// ---------------------------------------------------------------------------
/*!
\file
\brief Implemenation of Rw11CntlLP11.
*/
@ -65,7 +65,13 @@ const bool Rw11CntlLP11::kProbeInt;
const bool Rw11CntlLP11::kProbeRem;
const uint16_t Rw11CntlLP11::kCSR_M_ERROR;
const uint16_t Rw11CntlLP11::kCSR_V_RLIM;
const uint16_t Rw11CntlLP11::kCSR_B_RLIM;
const uint16_t Rw11CntlLP11::kCSR_V_TYPE;
const uint16_t Rw11CntlLP11::kCSR_B_TYPE;
const uint16_t Rw11CntlLP11::kBUF_M_VAL;
const uint16_t Rw11CntlLP11::kBUF_V_SIZE;
const uint16_t Rw11CntlLP11::kBUF_B_SIZE;
const uint16_t Rw11CntlLP11::kBUF_M_BUF;
//------------------------------------------+-----------------------------------
@ -73,10 +79,20 @@ const uint16_t Rw11CntlLP11::kBUF_M_BUF;
Rw11CntlLP11::Rw11CntlLP11()
: Rw11CntlBase<Rw11UnitLP11,1>("lp11"),
fPC_buf(0)
fPC_buf(0),
fRlim(0),
fItype(0),
fFsize(0),
fRblkSize(4)
{
// must be here because Units have a back-ptr (not available at Rw11CntlBase)
fspUnit[0].reset(new Rw11UnitLP11(this, 0)); // single unit controller
fStats.Define(kStatNQue , "NQue" , "rblk queued");
fStats.Define(kStatNNull , "NNull" , "null char send");
fStats.Define(kStatNChar , "NChar" , "char send (non-null)");
fStats.Define(kStatNLine , "NLine" , "lines send");
fStats.Define(kStatNPage , "NPage" , "pages send");
}
//------------------------------------------+-----------------------------------
@ -108,11 +124,21 @@ void Rw11CntlLP11::Start()
Cpu().AllIAddrMapInsert(Name()+".csr", Base() + kCSR);
Cpu().AllIAddrMapInsert(Name()+".buf", Base() + kBUF);
// detect device type
fItype = (fProbe.DataRem()>>kCSR_V_TYPE) & kCSR_B_TYPE;
fFsize = (1<<fItype) - 1;
// setup primary info clist
fPrimClist.Clear();
fPrimClist.AddAttn();
fPC_buf = Cpu().AddRibr(fPrimClist, fBase+kBUF);
if (!Buffered()) {
fPC_buf = Cpu().AddRibr(fPrimClist, fBase+kBUF);
} else {
fPC_buf = Cpu().AddRbibr(fPrimClist, fBase+kBUF, fRblkSize);
fPrimClist[fPC_buf].SetExpectStatus(0, RlinkCommand::kStat_M_RbTout |
RlinkCommand::kStat_M_RbNak);
}
// add attn handler
Server().AddAttnHandler(bind(&Rw11CntlLP11::AttnHandler, this, _1),
uint16_t(1)<<fLam, this);
@ -134,12 +160,31 @@ void Rw11CntlLP11::UnitSetup(size_t ind)
//------------------------------------------+-----------------------------------
//! FIXME_docs
void Rw11CntlLP11::SetRlim(uint16_t rlim)
{
if (rlim > kCSR_B_RLIM)
throw Rexception("Rw11CntlLP11::SetRlim","Bad args: rlim too large");
fRlim = rlim;
Rw11UnitLP11& unit = *fspUnit[0];
SetOnline(unit.HasVirt());
return;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
void Rw11CntlLP11::Dump(std::ostream& os, int ind, const char* text,
int detail) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11CntlLP11 @ " << this << endl;
os << bl << " fPC_buf: " << fPC_buf << endl;
os << bl << " fRlim: " << RosPrintf(fRlim,"d",3) << endl;
os << bl << " fItype: " << RosPrintf(fItype,"d",3) << endl;
os << bl << " fFsize: " << RosPrintf(fFsize,"d",3) << endl;
os << bl << " fRblkSize: " << RosPrintf(fRblkSize,"d",3) << endl;
Rw11CntlBase<Rw11UnitLP11,1>::Dump(os, ind, " ^", detail);
return;
@ -153,38 +198,12 @@ int Rw11CntlLP11::AttnHandler(RlinkServer::AttnArgs& args)
fStats.Inc(kStatNAttnHdl);
Server().GetAttnInfo(args, fPrimClist);
uint16_t buf = fPrimClist[fPC_buf].Data();
bool val = buf & kBUF_M_VAL;
uint8_t ochr = buf & kBUF_M_BUF;
if (fTraceLevel>0) {
RlogMsg lmsg(LogFile());
lmsg << "-I " << Name() << ":"
<< " buf=" << RosPrintBvi(buf,8)
<< " val=" << val;
if (val) {
lmsg << " char=";
if (ochr>=040 && ochr<0177) {
lmsg << "'" << char(ochr) << "'";
} else {
lmsg << RosPrintBvi(ochr,8);
}
}
if (!Buffered()) { // un-buffered iface -------------
ProcessChar(fPrimClist[fPC_buf].Data());
} else { // buffered iface ----------------
ProcessCmd(fPrimClist[fPC_buf], true);
}
if (val) {
RerrMsg emsg;
bool rc = fspUnit[0]->VirtWrite(&ochr, 1, emsg);
if (!rc) {
RlogMsg lmsg(LogFile());
lmsg << emsg;
SetOnline(false);
}
if (ochr == 014) { // ^L = FF = FormFeed seen ?
rc = fspUnit[0]->VirtFlush(emsg);
}
}
return 0;
}
@ -194,11 +213,107 @@ int Rw11CntlLP11::AttnHandler(RlinkServer::AttnArgs& args)
void Rw11CntlLP11::SetOnline(bool online)
{
Rw11Cpu& cpu = Cpu();
uint16_t csr = online ? 0 : kCSR_M_ERROR;
uint16_t csr = (online ? 0 : kCSR_M_ERROR) | // err field
((fRlim & kCSR_B_RLIM) << kCSR_V_RLIM); // rlim field
RlinkCommandList clist;
cpu.AddWibr(clist, fBase+kCSR, csr);
Server().Exec(clist);
return;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
void Rw11CntlLP11::ProcessChar(uint16_t buf)
{
bool val = buf & kBUF_M_VAL;
uint16_t size = (buf>>kBUF_V_SIZE) & kBUF_B_SIZE;
uint8_t ochr = buf & kBUF_M_BUF;
if (fTraceLevel>0) {
RlogMsg lmsg(LogFile());
lmsg << "-I " << Name() << ":"
<< " buf=" << RosPrintBvi(buf,8)
<< " val=" << val;
if (Buffered()) lmsg << " size=" << RosPrintf(size,"d",3);
if (val) {
lmsg << " char=";
if (ochr>=040 && ochr<0177) {
lmsg << "'" << char(ochr) << "'";
} else {
lmsg << RosPrintBvi(ochr,8);
}
}
}
if (val) { // valid chars
if (ochr == 0) { // count NULL char
fStats.Inc(kStatNNull);
} else { // forward only non-NULL char
fStats.Inc(kStatNChar);
RerrMsg emsg;
bool rc = fspUnit[0]->VirtWrite(&ochr, 1, emsg);
if (!rc) {
RlogMsg lmsg(LogFile());
lmsg << emsg;
SetOnline(false);
}
if (ochr == '\f') { // ^L = FF = FormFeed seen ?
fStats.Inc(kStatNPage);
rc = fspUnit[0]->VirtFlush(emsg);
} else if (ochr == '\n') { // ^J = LF = LineFeed seen ?
fStats.Inc(kStatNLine);
}
}
}
return;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
void Rw11CntlLP11::ProcessCmd(const RlinkCommand& cmd, bool prim)
{
const uint16_t* pbuf = cmd.BlockPointer();
size_t done = cmd.BlockDone();
for (size_t i=0; i < done; i++) {
ProcessChar(pbuf[i]);
}
// determine next chunk size from fifo 'size' field of first item
uint16_t buf = pbuf[0];
uint16_t size = (buf>>kBUF_V_SIZE) & kBUF_B_SIZE;
fRblkSize = size; // use last size
if (fRblkSize < 4) fRblkSize = 4;
if (fRblkSize > fFsize) fRblkSize = fFsize;
// check whether last entry emptied fifo -> check whether 'size=1'
buf = pbuf[done-1];
size = (buf>>kBUF_V_SIZE) & kBUF_B_SIZE;
if (size > 1) { // fifo not emptied, continue
fStats.Inc(kStatNQue);
Server().QueueAction(bind(&Rw11CntlLP11::RcvHandler, this));
}
// re-sizing the prim rblk invalidates pbuf -> so must be done last
if (prim) { // if primary list
fPrimClist[fPC_buf].SetBlockRead(fRblkSize); // setup size for next attn
}
return;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
int Rw11CntlLP11::RcvHandler()
{
RlinkCommandList clist;
Cpu().AddRbibr(clist, fBase+kBUF, fRblkSize);
clist[0].SetExpectStatus(0, RlinkCommand::kStat_M_RbTout |
RlinkCommand::kStat_M_RbNak);
Server().Exec(clist);
ProcessCmd(clist[0], false);
return 0;
}
} // end namespace Retro

View File

@ -1,6 +1,6 @@
// $Id: Rw11CntlLP11.hpp 983 2018-01-02 20:35:59Z mueller $
// $Id: Rw11CntlLP11.hpp 1123 2019-03-17 17:55:12Z mueller $
//
// Copyright 2013-2017 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
// Copyright 2013-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// 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
@ -11,8 +11,9 @@
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for complete details.
//
// Revision History:
// Revision History:
// Date Rev Version Comment
// 2019-03-17 1123 1.2 buf.val in msb; add lp11_buf readout
// 2017-04-02 865 1.1.1 Dump(): add detail arg
// 2014-12-29 623 1.1 adopt to Rlink V4 attn logic
// 2013-05-01 513 1.0 Initial version
@ -20,7 +21,6 @@
/*!
\file
\brief Declaration of class Rw11CntlLP11.
*/
@ -44,6 +44,13 @@ namespace Retro {
virtual void UnitSetup(size_t ind);
void SetRlim(uint16_t rlim);
uint16_t Rlim() const;
uint16_t Itype() const;
bool Buffered() const;
uint16_t FifoSize() const;
virtual void Dump(std::ostream& os, int ind=0, const char* text=0,
int detail=0) const;
@ -58,20 +65,44 @@ namespace Retro {
static const bool kProbeInt = true; //!< probe int active
static const bool kProbeRem = true; //!< probr rem active
static const uint16_t kCSR_M_ERROR = kWBit15;
static const uint16_t kBUF_M_VAL = kWBit08;
static const uint16_t kBUF_M_BUF = 0177;
static const uint16_t kCSR_M_ERROR = kWBit15; //!< csr.err mask
static const uint16_t kCSR_V_RLIM = 12; //!< csr.rlim shift
static const uint16_t kCSR_B_RLIM = 007; //!< csr.rlim bit mask
static const uint16_t kCSR_V_TYPE = 8; //!< csr.type shift
static const uint16_t kCSR_B_TYPE = 0007; //!< csr.type bit mask
static const uint16_t kBUF_M_VAL = kWBit15; //!< buf.val mask
static const uint16_t kBUF_V_SIZE = 8; //!< buf.size shift
static const uint16_t kBUF_B_SIZE = 0177; //!< buf.size bit mask
static const uint16_t kBUF_M_BUF = 0177; //!< buf data mask
// statistics counter indices
enum stats {
kStatNQue= Rw11Cntl::kDimStat, //!< queue rblk
kStatNNull, //!< send null char
kStatNChar, //!< send char
kStatNLine, //!< send lines
kStatNPage, //!< send pages
kDimStat
};
protected:
int AttnHandler(RlinkServer::AttnArgs& args);
void SetOnline(bool online);
void ProcessChar(uint16_t buf);
void ProcessCmd(const RlinkCommand& cmd, bool prim);
int RcvHandler();
protected:
size_t fPC_buf; //!< PrimClist: buf index
uint16_t fRlim; //!< interrupt rate limit
uint16_t fItype; //!< interface type
uint16_t fFsize; //!< fifo size
uint16_t fRblkSize; //!< rblk chunk size
};
} // end namespace Retro
//#include "Rw11CntlLP11.ipp"
#include "Rw11CntlLP11.ipp"
#endif

View File

@ -0,0 +1,59 @@
// $Id: Rw11CntlLP11.ipp 1123 2019-03-17 17:55:12Z mueller $
//
// Copyright 2019- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// 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
// Software Foundation, either version 3, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for complete details.
//
// Revision History:
// Date Rev Version Comment
// 2019-03-17 1123 1.0 Initial version
// ---------------------------------------------------------------------------
/*!
\brief Implemenation (inline) of Rw11CntlLP11.
*/
// all method definitions in namespace Retro
namespace Retro {
//------------------------------------------+-----------------------------------
//! FIXME_docs
inline uint16_t Rw11CntlLP11::Rlim() const
{
return fRlim;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
inline uint16_t Rw11CntlLP11::Itype() const
{
return fItype;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
inline bool Rw11CntlLP11::Buffered() const
{
return fFsize > 0;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
inline uint16_t Rw11CntlLP11::FifoSize() const
{
return fFsize;
}
} // end namespace Retro

View File

@ -1,6 +1,6 @@
// $Id: RtclRw11CntlLP11.cpp 983 2018-01-02 20:35:59Z mueller $
// $Id: RtclRw11CntlLP11.cpp 1123 2019-03-17 17:55:12Z mueller $
//
// Copyright 2013-2017 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
// Copyright 2013-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// 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
@ -13,12 +13,12 @@
//
// Revision History:
// Date Rev Version Comment
// 2019-03-17 1123 1.2 add getters& setters for lp11_buf readout
// 2017-04-16 878 1.1 add class in ctor;derive from RtclRw11CntlStreamBase
// 2013-05-01 513 1.0 Initial version
// ---------------------------------------------------------------------------
/*!
\file
\brief Implemenation of RtclRw11CntlLP11.
*/
@ -28,6 +28,7 @@
#include "RtclRw11UnitLP11.hpp"
using namespace std;
using namespace std::placeholders;
/*!
\class Retro::RtclRw11CntlLP11
@ -42,7 +43,15 @@ namespace Retro {
RtclRw11CntlLP11::RtclRw11CntlLP11()
: RtclRw11CntlStreamBase<Rw11CntlLP11>("Rw11CntlLP11","stream")
{}
{
Rw11CntlLP11* pobj = &Obj();
fGets.Add<uint16_t> ("rlim", bind(&Rw11CntlLP11::Rlim, pobj));
fGets.Add<uint16_t> ("itype", bind(&Rw11CntlLP11::Itype, pobj));
fGets.Add<bool> ("buffered", bind(&Rw11CntlLP11::Buffered, pobj));
fGets.Add<uint16_t> ("fifosize", bind(&Rw11CntlLP11::FifoSize, pobj));
fSets.Add<uint16_t> ("rlim", bind(&Rw11CntlLP11::SetRlim,pobj, _1));
}
//------------------------------------------+-----------------------------------
//! Destructor

View File

@ -1,7 +1,8 @@
# $Id: dev_all.dat 848 2017-02-04 14:55:30Z mueller $
# $Id: dev_all.dat 1120 2019-03-09 18:19:31Z mueller $
#
## steering file for all devices tests
#
test_lp11_all.tcl
@rhrp/rhrp_all.dat
@tm11/tm11_all.dat
@deuna/deuna_all.dat

View File

@ -0,0 +1,494 @@
# $Id: test_lp11_all.tcl 1123 2019-03-17 17:55:12Z mueller $
#
# Copyright 2019- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
# License disclaimer see License.txt in $RETROBASE directory
#
# Revision History:
# Date Rev Version Comment
# 2019-03-17 1123 1.0 Initial version
# 2019-03-11 1121 0.1 First draft
#
# Test register response
# A: register basics
# ----------------------------------------------------------------------------
rlc log "test_lp11_all: test lp11 response -----------------------------------"
package require ibd_lp11
if {![ibd_lp11::setup]} {
rlc log " test_lp11_all-W: device not found, test aborted"
return
}
rlc set statmask $rw11::STAT_DEFMASK
rlc set statvalue 0
set attnlp [expr {1<<$ibd_lp11::ANUM}]
set attncpu [expr {1<<$rw11::ANUM}]
# -- Section A ---------------------------------------------------------------
rlc log " A1: test csr response -------------------------------------"
rlc log " A1.1: csr err, done --------------------------------"
# breset & rem ERR=0 --> test DONE=1,IE=0
# rem ERR=1 --> test ERR=1,DONE=1,IE=0 (DONE not rem writable)
# loc ERR=0 --> test ERR=1,DONE=1,IE=0 (ERR not loc writable)
# rem ERR=0 --> test ERR=0,DONE=1,IE=0
set rcsrmask [regbld ibd_lp11::RCSR err done ie]
$cpu cp \
-breset \
-wibr lpa.csr 0x0 \
-ribr lpa.csr lprcsr -edata [regbld ibd_lp11::RCSR done] $rcsrmask \
-rma lpa.csr -edata [regbld ibd_lp11::CSR done] \
-wibr lpa.csr [regbld ibd_lp11::CSR err] \
-ribr lpa.csr -edata [regbld ibd_lp11::RCSR err done] $rcsrmask \
-rma lpa.csr -edata [regbld ibd_lp11::CSR err done] \
-wma lpa.csr 0x0 \
-rma lpa.csr -edata [regbld ibd_lp11::CSR err done] \
-wibr lpa.csr 0x0 \
-ribr lpa.csr -edata [regbld ibd_lp11::RCSR done] $rcsrmask \
-rma lpa.csr lpcsr -edata [regbld ibd_lp11::CSR done]
# remember 'type' retrieved from csr for later tests
set type [regget ibd_lp11::RCSR(type) $lprcsr]
rlc log " A1.2: csr ie ---------------------------------------"
# loc IE=1 --> seen on loc and rem
# rem IE=0 --> stays, IE not rem writable
# loc IE=0 --> seen on loc and rem
$cpu cp \
-wma lpa.csr [regbld ibd_lp11::CSR ie] \
-rma lpa.csr -edata [regbld ibd_lp11::CSR ie done] \
-ribr lpa.csr -edata [regbld ibd_lp11::CSR ie done] $rcsrmask\
-wibr lpa.csr 0x0 \
-rma lpa.csr -edata [regbld ibd_lp11::CSR ie done] \
-ribr lpa.csr -edata [regbld ibd_lp11::CSR ie done] $rcsrmask\
-wma lpa.csr 0x0 \
-rma lpa.csr -edata [regbld ibd_lp11::CSR done] \
-ribr lpa.csr -edata [regbld ibd_lp11::CSR done] $rcsrmask
if {$type > 0} { # if buffered test rlim
rlc log " A1.3: csr rlim -------------------------------------"
# rem write rlim --> seen rem, not loc
# loc write rlim --> stays, rlim not loc writable
set rcsrmaskbuf [regbld ibd_lp11::RCSR err {rlim -1} done ie]
$cpu cp \
-wibr lpa.csr [regbld ibd_lp11::RCSR {rlim 1}] \
-ribr lpa.csr -edata [regbld ibd_lp11::RCSR {rlim 1} done] $rcsrmaskbuf \
-rma lpa.csr -edata [regbld ibd_lp11::CSR done] \
-wibr lpa.csr [regbld ibd_lp11::RCSR {rlim 7}] \
-ribr lpa.csr -edata [regbld ibd_lp11::RCSR {rlim 7} done] $rcsrmaskbuf \
-wma lpa.csr 0x0 \
-ribr lpa.csr -edata [regbld ibd_lp11::RCSR {rlim 7} done] $rcsrmaskbuf \
-wibr lpa.csr [regbld ibd_lp11::RCSR {rlim 0}] \
-ribr lpa.csr -edata [regbld ibd_lp11::RCSR {rlim 0} done] $rcsrmaskbuf
}
if {$type == 0} { # unbuffered --------------------------
rlc log " A2: test data response (unbuffered) -----------------------"
rlc log " A2.1: loc write, rem read --------------------------"
# loc wr buf --> test DONE=0
# loc rd buf --> test DONE=0 (loc read is noop); test attn send
# rem wr buf --> test DONE=1
$cpu cp \
-wma lpa.buf 0107 \
-rma lpa.csr -edata [regbld ibd_lp11::CSR] \
-rma lpa.buf \
-rma lpa.csr -edata [regbld ibd_lp11::CSR] \
-ribr lpa.buf -edata [regbld ibd_lp11::RBUF val {size 1} {data 0107} ] \
-rma lpa.csr -edata [regbld ibd_lp11::CSR done]
# expect and harvest attn (drop other attn potentially triggered by breset)
rlc wtlam 1.
rlc exec -attn -edata $attnlp $attnlp
rlc log " A2.2: csr.err=1, no attn, DONE=1, no val data ------"
$cpu cp \
-wibr lpa.csr [regbld ibd_lp11::CSR err] \
-rma lpa.csr -edata [regbld ibd_lp11::CSR err done] \
-wma lpa.buf 031 \
-rma lpa.csr -edata [regbld ibd_lp11::CSR err done] \
-wibr lpa.csr 0x0 \
-rma lpa.csr -edata [regbld ibd_lp11::CSR done] \
-ribr lpa.buf -edata [regbld ibd_lp11::RBUF {size 0} {data 031} ]
# test that no attn send
rlc exec -attn -edata 0x0
rlc log " A2.3: 7 bit data; done set on breset ---------------"
$cpu cp \
-wma lpa.buf 0370 \
-ribr lpa.buf -edata [regbld ibd_lp11::RBUF val {size 1} {data 0170} ] \
-wma lpa.buf 040 \
-rma lpa.csr -edata [regbld ibd_lp11::CSR] \
-breset \
-rma lpa.csr -edata [regbld ibd_lp11::CSR done]
# harvest breset/creset triggered attn's
rlc exec -attn
rlc wtlam 0.
rlc log " A2.4: loc write, csr.err sets DONE, date invalid ---"
$cpu cp \
-wma lpa.buf 032 \
-rma lpa.csr -edata [regbld ibd_lp11::CSR] \
-wibr lpa.csr [regbld ibd_lp11::CSR err] \
-wibr lpa.csr 0x0 \
-rma lpa.csr -edata [regbld ibd_lp11::CSR done] \
-ribr lpa.buf -edata [regbld ibd_lp11::RBUF {size 0} {data 032} ]
# expect and harvest attn
rlc wtlam 1.
rlc exec -attn -edata $attnlp
} else { # buffered ---------------------------
set fsize [expr {(1<<$type)-1}]
rlc log " A2: test data response (basic fifo; AWIDTH=$type) --------"
rlc log " A2.1: loc write, rem read --------------------------"
# loc wr buf --> test DONE=1
# loc rd buf --> test DONE=1 (loc read is noop); test attn send
# loc wr buf --> test DONE=1
# loc wr buf --> test DONE=1
# rem wr buf --> test VAL=1,SIZE=3
# rem wr buf --> test VAL=1,SIZE=2
# rem wr buf --> test VAL=1,SIZE=1
$cpu cp \
-wma lpa.buf 031 \
-rma lpa.csr -edata [regbld ibd_lp11::CSR done] \
-rma lpa.buf \
-wma lpa.buf 032 \
-rma lpa.csr -edata [regbld ibd_lp11::CSR done] \
-wma lpa.buf 033 \
-rma lpa.csr -edata [regbld ibd_lp11::CSR done] \
-ribr lpa.buf -edata [regbldkv ibd_lp11::RBUF val 1 size 3 data 031] \
-ribr lpa.buf -edata [regbldkv ibd_lp11::RBUF val 1 size 2 data 032] \
-ribr lpa.buf -edata [regbldkv ibd_lp11::RBUF val 1 size 1 data 033] \
-rma lpa.csr -edata [regbld ibd_lp11::CSR done]
# expect and harvest attn (drop other attn potentially triggered by breset)
rlc wtlam 1.
rlc exec -attn -edata $attnlp $attnlp
rlc log " A2.2: csr.err=1, loc write not stored, no attn -----"
$cpu cp \
-wibr lpa.csr [regbld ibd_lp11::CSR err] \
-wma lpa.buf 034 \
-wibr lpa.csr 0x0 \
-ribr lpa.buf -estaterr
# test that no attn send
rlc exec -attn -edata 0x0
rlc log " A2.3: loc write, rem blk read abort; 7 bit data ----"
# loc wr two char; rem blk rd three char --> expect 2 and error
# test 7 bit data path trunctation
$cpu cp \
-wma lpa.buf 0340 \
-wma lpa.buf 0037 \
-rbibr lpa.buf 4 -estaterr -edone 2 -edata \
[list [regbldkv ibd_lp11::RBUF val 1 size 2 data 0140] \
[regbldkv ibd_lp11::RBUF val 1 size 1 data 0037] ]
# expect and harvest attn
rlc wtlam 1.
rlc exec -attn -edata $attnlp
rlc log " A2.4: loc write, breset clears fifo ----------------"
$cpu cp \
-wma lpa.buf 041 \
-wma lpa.buf 042 \
-breset \
-rbibr lpa.buf 3 -estaterr -edone 0
# expect and harvest attn (drop other attn potentially triggered by breset)
rlc wtlam 1.
rlc exec -attn -edata $attnlp $attnlp
rlc log " A2.5: loc write, csr.err clears fifo ---------------"
$cpu cp \
-wma lpa.buf 043 \
-wma lpa.buf 044 \
-wibr lpa.csr [regbld ibd_lp11::CSR err] \
-wibr lpa.csr 0x0 \
-rbibr lpa.buf 3 -estaterr -edone 0
# expect and harvest attn (drop other attn potentially triggered by breset)
rlc wtlam 1.
rlc exec -attn -edata $attnlp $attnlp
rlc log " A3: test fifo logic (csr.done and attn) ------------------"
rlc log " A3.1: 1st loc write, get attn ----------------------"
# 1 loc wr -> get attn (1 in fifo; DONE=1)
$cpu cp \
-wma lpa.buf 051 \
-rma lpa.csr -edata [regbld ibd_lp11::CSR done]
# expect and harvest attn
rlc wtlam 1.
rlc exec -attn -edata $attnlp
rlc log " A3.2: 2nd loc write, no attn -----------------------"
# 1 loc wr -> no attn (2 in fifo)
$cpu cp \
-wma lpa.buf 052 \
-rma lpa.csr -edata [regbld ibd_lp11::CSR done]
rlc exec -attn -edata 0x0
rlc log " A3.3: write/read to non-empty fifo -> no attn ------"
# 1 rem rd (1 in fifo; DONE=1)
# 1 loc wr -> no attn (2 in fifo; DONE=1)
# 1 rem rd (1 in fifo; DONE=1)
$cpu cp \
-ribr lpa.buf -edata [regbldkv ibd_lp11::RBUF val 1 size 2 data 051] \
-wma lpa.buf 053 \
-rma lpa.csr -edata [regbld ibd_lp11::CSR done]
rlc exec -attn -edata 0x0
$cpu cp \
-ribr lpa.buf -edata [regbldkv ibd_lp11::RBUF val 1 size 2 data 052] \
-rma lpa.csr -edata [regbld ibd_lp11::CSR done]
rlc log " A3.4: fill fifo, DONE 1->0 on $fsize char -------------"
# x = fsize in following
# x-2 loc wr (x-1 in fifo; DONE=1)
# 1 rem rd (x-2 in fifo; DONE=1)
# 1 rem rd (x-3 in fifo; DONE=1)
$cpu ldasm -lst lst -sym sym {
.include |lib/vec_cpucatch.mac|
. = 1000 ; data area
stack:
;
start: mov r2,(r0)
sob r1,start
halt
stop:
}
# specify ps in asmrun to use -start (and avoid a creset!!)
set fs0 $fsize
set fs1 [expr {$fsize-1}]
set fs2 [expr {$fsize-2}]
set fs4 [expr {$fsize-4}]
rw11::asmrun $cpu sym r0 [$cpu imap lpa.buf] \
r1 $fs2 \
r2 066 \
ps [regbld rw11::PSW {cmode k} {pri 7}]
rw11::asmwait $cpu sym
rw11::asmtreg $cpu r1 0
$cpu cp \
-rma lpa.csr -edata [regbld ibd_lp11::CSR done] \
-ribr lpa.buf -edata [regbldkv ibd_lp11::RBUF val 1 size $fs1 data 053] \
-ribr lpa.buf -edata [regbldkv ibd_lp11::RBUF val 1 size $fs2 data 066] \
-rma lpa.csr -edata [regbld ibd_lp11::CSR done]
# 1 loc wr -> (x-2 in fifo; DONE=1)
# 1 loc wr -> (x-1 in fifo; DONE=1)
# 1 loc wr -> (x in fifo; DONE=0)
# 1 loc wr -> (x in fifo; DONE=0) (overfill !!)
$cpu cp \
-wma lpa.buf 066 \
-rma lpa.csr -edata [regbld ibd_lp11::CSR done] \
-wma lpa.buf 066 \
-rma lpa.csr -edata [regbld ibd_lp11::CSR done] \
-wma lpa.buf 066 \
-rma lpa.csr -edata [regbld ibd_lp11::CSR] \
-wma lpa.buf 066 \
-rma lpa.csr -edata [regbld ibd_lp11::CSR]
rlc log " A3.5: partial fifo read, DONE goes 1 ---------------"
# 1 rem rd -> (x-1 in fifo; DONE=1)
# 1 rem rd -> (x-2 in fifo; DONE=1)
$cpu cp \
-ribr lpa.buf -edata [regbldkv ibd_lp11::RBUF val 1 size $fs0 data 066] \
-rma lpa.csr -edata [regbld ibd_lp11::CSR done] \
-ribr lpa.buf -edata [regbldkv ibd_lp11::RBUF val 1 size $fs1 data 066] \
-rma lpa.csr -edata [regbld ibd_lp11::CSR done]
rlc log " A3.6: full fifo read -------------------------------"
# x-4 rem rd -> ( 2 in fifo; DONE=1)
# 1 rem rd -> ( 1 in fifo; DONE=1)
# 1 rem rd -> ( 0 in fifo; DONE=1)
# 1 rem rd -> error
set edata {}
for {set i 0} { $i < $fs4 } {incr i} {
lappend edata [regbldkv ibd_lp11::RBUF val 1 size [expr {$fs2-$i}] data 066]
}
$cpu cp \
-rbibr lpa.buf $fs4 -edata $edata \
-ribr lpa.buf -edata [regbldkv ibd_lp11::RBUF val 1 size 2 data 066] \
-rma lpa.csr -edata [regbld ibd_lp11::CSR done] \
-ribr lpa.buf -edata [regbldkv ibd_lp11::RBUF val 1 size 1 data 066] \
-rma lpa.csr -edata [regbld ibd_lp11::CSR done] \
-ribr lpa.buf -estaterr
rlc log " A3.7: BRESET on full fifo sets DONE=1 --------------"
# 1 loc wr -> get attn (1 in fifo; DONE=1)
$cpu cp \
-wma lpa.buf 067 \
-rma lpa.csr -edata [regbld ibd_lp11::CSR done]
# expect and harvest attn
rlc wtlam 1.
rlc exec -attn -edata $attnlp
# x loc wr (x in fifo; DONE=0)
rw11::asmrun $cpu sym r0 [$cpu imap lpa.buf] \
r1 $fs0 \
r2 067 \
ps [regbld rw11::PSW {cmode k} {pri 7}]
rw11::asmwait $cpu sym
rw11::asmtreg $cpu r1 0
# breset -> DONE=1
# 1 rem rd -> error
$cpu cp \
-rma lpa.csr -edata [regbld ibd_lp11::CSR] \
-breset \
-rma lpa.csr -edata [regbld ibd_lp11::CSR done] \
-ribr lpa.buf -estaterr
}
# harvest triggered attn's
rlc exec -attn
rlc wtlam 0.
# -- Section B ---------------------------------------------------------------
rlc log " B1: test csr.ie and basic interrupt response --------------"
# load test code
$cpu ldasm -lst lst -sym sym {
.include |lib/defs_cpu.mac|
.include |lib/defs_lp.mac|
. = va.lp ; setup LP11 interrupt vector
.word vh.lp
.word cp.pr7
;
. = 1000 ; data area
stack:
;
; use in following mov to psw instead of spl to allow immediate interrupt
;
start: spl 7 ;;; lock-out interrupts
mov #lp.ie,@#lp.csr ;;; enable lp interrupts
mov #cp.pr6,@#cp.psw ;;; allow pri=7
mov #cp.pr5,@#cp.psw ;;; allow pri=6
mov #cp.pr4,@#cp.psw ;;; allow pri=5
mov #cp.pr3,@#cp.psw ;;; allow pri=4
mov #cp.pr2,@#cp.psw ;;; allow pri=3
mov #cp.pr1,@#cp.psw ;;; allow pri=2
mov #cp.pr0,@#cp.psw ;;; allow pri=1
halt ;;;
;
vh.lp: halt
stop:
}
# check that interrupt done, and pushed psw has pri=3 (device is pri=4)
rw11::asmrun $cpu sym
rw11::asmwait $cpu sym
rw11::asmtreg $cpu sp [expr {$sym(stack)-4}]
rw11::asmtmem $cpu [expr {$sym(stack)-2}] [list [regbld rw11::PSW {pri 3}]]
rlc log " B2: test csr.ie and cpu write -> rri read -----------------"
# load test code
$cpu ldasm -lst lst -sym sym {
.include |lib/defs_cpu.mac|
.include |lib/defs_lp.mac|
;
.include |lib/vec_cpucatch.mac|
.include |lib/vec_devcatch.mac|
;
. = v..lp ; setup LP11 interrupt vector
.word vh.lp
.word cp.pr7
;
. = 1000 ; data area
stack:
;
start: ; call with r0=<count_of_chars>
spl 7
mov #lp.ie,@#lp.csr ; enable interrupt
clr r1 ; clear out char
spl 0
1$: wait ; wait for interrupt
br 1$ ; forever
;
vh.lp: movb r1,@#lp.buf ; write char
dec r0 ; all done ?
beq 1$ ; if eq yes, quit
incb r1
bicb #200,r1
tstb @#lp.csr ; done set ?
bmi vh.lp ; if mi yes, loop
rti ; otherwise exit interrupt
;
1$: halt
stop:
}
set nchar 4
set charcur 0
set charseen 0
set haltseen 0
if {$type == 0} { # unbuffered --------------------------
rw11::asmrun $cpu sym r0 $nchar
while {1} {
if {[rlc wtlam 1.] >= 1.} { break }
rlc exec -attn attnpat
if {$attnpat & $attncpu} { # cpu attn
set haltseen 1
}
if {$attnpat & $attnlp} { # lp attn
$cpu cp \
-ribr lpa.buf -edata [regbldkv ibd_lp11::RBUF val 1 size 1 data $charcur]
set charcur [expr { ($charcur+1) & 0177 }]
incr charseen
}
if {$charseen == $nchar && $haltseen} { break }
}
} else { # buffered -----------------------------
# setup char count as about 1.25 of fifo size
# AWIDTH 4 15+ 3 = 18
# AWIDTH 5 31+ 7 = 38
# AWIDTH 6 63+15 = 78
# AWIDTH 7 127+31 = 158
set nchar [expr {$fsize + ($fsize>>2)}]
set rsize [expr {$fsize>>2}]
set fstatmsk [regbld rw11::STAT cmderr rbtout rbnak]; # don't check err !!
# try this to verify rlim logic --> quite a slow down !!
# $cpu cp -wibr lpa.csr [regbld ibd_lp11::RCSR {rlim 1}]
rw11::asmrun $cpu sym r0 $nchar
while (1) {
if {[rlc wtlam 10.] >= 10.} { break }
rlc exec -attn attnpat
if {$attnpat & $attncpu} { # cpu attn
set haltseen 1
}
if {$attnpat & $attnlp} { # lp attn
while (1) {
$cpu cp \
-rbibr lpa.buf $rsize fdata -estat 0x0 $fstatmsk
for {set i 0} { $i < [llength $fdata] } {incr i} {
set rbuf [lindex $fdata $i]
set val [regget ibd_lp11::RBUF(val) $rbuf]
set size [regget ibd_lp11::RBUF(size) $rbuf]
set data [regget ibd_lp11::RBUF(data) $rbuf]
if {$val != 1 || $data != $charcur} {
rlc log "FAIL: bad data: val: $val; data: $data, exp: $charcur"
rlc errcnt -inc
}
if {$i == 0} { set rsize $size }
set charcur [expr { ($charcur+1) & 0177 }]
incr charseen
}
if {$size <= 1} {
rlc log " rbibr chain ends with size=1 after $charseen"
break;
}
}
}
if {$charseen == $nchar && $haltseen} { break }
}
}
$cpu cp -rpc -edata $sym(stop); # check proper stop pc
if {$haltseen == 0} { $cpu cp -creset }; # kill rouge code
# harvest any dangling attn
rlc exec -attn
rlc wtlam 0.

View File

@ -1,6 +1,6 @@
# $Id: util.tcl 985 2018-01-03 08:59:40Z mueller $
# $Id: util.tcl 1123 2019-03-17 17:55:12Z mueller $
#
# Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
# Copyright 2015-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
#
# 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
@ -13,6 +13,8 @@
#
# Revision History:
# Date Rev Version Comment
# 2019-03-17 1123 1.1.1 add print formats for RBUF; add RCSR.rlim
# 2019-03-09 1120 1.1 add setup proc; add regdsc for RCSR,RBUF
# 2015-12-26 719 1.0 Initial version
#
@ -27,10 +29,19 @@ namespace eval ibd_lp11 {
# setup register descriptions for ibd_lp11 ---------------------------------
#
regdsc CSR {err 15} {done 7} {ie 6}
regdsc CSR {err 15} {done 7} {ie 6}
regdsc RCSR {err 15} {rlim 14 3} {type 10 3} {done 7} {ie 6}
regdsc RBUF {val 15} {size 14 7 "d"} {data 6 7 "o"}
rw11util::regmap_add ibd_lp11 lp?.rcsr {?? CSR}
rw11util::regmap_add ibd_lp11 lp?.csr {l? CSR r? RCSR}
rw11util::regmap_add ibd_lp11 lp?.buf {r? RBUF}
variable ANUM 8
#
# setup: create controller with default attributes -------------------------
#
proc setup {{cpu "cpu0"}} {
return [rw11::setup_cntl $cpu "lp11" "lpa"]
}
}