1
0
mirror of https://github.com/wfjm/w11.git synced 2026-04-03 13:23:50 +00:00

add dz11 device

- ibus/ibdr_maxisys: instantiate ibdr_dz11
- ibus/ibdr_dz11: added, 8 line serial port multiplexer
This commit is contained in:
wfjm
2019-05-25 19:43:35 +02:00
parent 6594b3c90e
commit 334c7214be
6 changed files with 839 additions and 17 deletions

View File

@@ -24,10 +24,12 @@ The full set of tests is only run for tagged releases.
### Summary
- add m9312 boot prom emulation
- add dz11 8 line serial port multiplexer
### New features
- new components
- ibd_m9312: new boot prom emulation
- ibdr_dz11: 8 line serial port multiplexer
- new verification codes
- test_m9312_all.tcl: tbench for m9312
- new test and demonstration codes under tools/mcode

View File

@@ -1,4 +1,4 @@
-- $Id: ibdlib.vhd 1142 2019-04-28 19:27:57Z mueller $
-- $Id: ibdlib.vhd 1147 2019-05-11 07:08:40Z mueller $
--
-- Copyright 2008-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
@@ -209,11 +209,13 @@ end component;
component ibdr_dz11 is -- ibus dev(rem): DZ11
generic (
IB_ADDR : slv16 := ibaddr_dz11);
IB_ADDR : slv16 := ibaddr_dz11;
AWIDTH : natural := 5); -- fifo address width
port (
CLK : in slbit; -- clock
RESET : in slbit; -- system reset
BRESET : in slbit; -- ibus reset
RLIM_CEV : in slv8; -- 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

9
rtl/ibus/ibdr_dz11.vbom Normal file
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_dz11.vhd

782
rtl/ibus/ibdr_dz11.vhd Normal file
View File

@@ -0,0 +1,782 @@
-- $Id: ibdr_dz11.vhd 1150 2019-05-19 17:52:54Z 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_dz11 - syn
-- Description: ibus dev(rem): DZ11
--
-- Dependencies: fifo_simple_dram
-- ib_rlim_slv
-- Test bench: xxdp: zdzaj0
-- Target Devices: generic
-- Tool versions: ise 8.2-14.7; 2017.2; ghdl 0.35
--
-- Revision History:
-- Date Rev Version Comment
-- 2019-05-19 1150 1.0 Initial version
-- 2019-05-01 1144 0.1 First draft
------------------------------------------------------------------------------
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_dz11 is -- ibus dev(rem): DZ11
-- fixed address: 160100
generic (
IB_ADDR : slv16 := slv(to_unsigned(8#160100#,16));
AWIDTH : natural := 5); -- fifo address width
port (
CLK : in slbit; -- clock
RESET : in slbit; -- system reset
BRESET : in slbit; -- ibus reset
RLIM_CEV : in slv8; -- 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_RX : out slbit; -- interrupt request, receiver
EI_REQ_TX : out slbit; -- interrupt request, transmitter
EI_ACK_RX : in slbit; -- interrupt acknowledge, receiver
EI_ACK_TX : in slbit -- interrupt acknowledge, transmitter
);
end ibdr_dz11;
architecture syn of ibdr_dz11 is
-- loc view register naming, offsets and bit definitions
constant ibaddr_csr : slv2 := "00"; -- csr address offset
constant ibaddr_rbuf_lpr : slv2 := "01"; -- rbuf/lpr address offset
constant ibaddr_tcr : slv2 := "10"; -- tcr address offset
constant ibaddr_msr_tdr : slv2 := "11"; -- msr/tdr address offset
constant csr_ibf_trdy : integer := 15;
constant csr_ibf_tie : integer := 14;
constant csr_ibf_sa : integer := 13;
constant csr_ibf_sae : integer := 12;
subtype csr_ibf_tline is integer range 10 downto 8;
constant csr_ibf_rdone : integer := 7;
constant csr_ibf_rie : integer := 6;
constant csr_ibf_mse : integer := 5;
constant csr_ibf_clr : integer := 4;
constant csr_ibf_maint : integer := 3;
constant rbuf_ibf_val : integer := 15;
constant rbuf_ibf_ferr : integer := 13;
subtype rbuf_ibf_line is integer range 10 downto 8;
subtype rbuf_ibf_data is integer range 7 downto 0;
constant lpr_ibf_rxon : integer := 12;
subtype lpr_ibf_line is integer range 2 downto 0;
subtype tcr_ibf_dtr is integer range 15 downto 8;
subtype tcr_ibf_lena is integer range 7 downto 0;
subtype msr_ibf_co is integer range 15 downto 8;
subtype msr_ibf_ring is integer range 7 downto 0;
subtype tdr_ibf_brk is integer range 15 downto 8;
subtype tdr_ibf_tbuf is integer range 7 downto 0;
-- rem view register naming, offsets and bit definitions
constant ibaddr_cntl : slv2 := "00"; -- cntl address offset
constant ibaddr_stat : slv2 := "01"; -- stat address offset
constant ibaddr_fuse : slv2 := "10"; -- fuse address offset
constant ibaddr_fdat : slv2 := "11"; -- fdat address offset
-- rem-r view
subtype cntl_ibf_awdth is integer range 10 downto 8;
subtype cntl_ibf_ssel is integer range 4 downto 3; -- also wr
constant cntl_ibf_sam: integer := 7; -- also wr
constant cntl_ibf_mse : integer := 2;
constant cntl_ibf_maint : integer := 1;
-- rem-w view
subtype cntl_ibf_data is integer range 15 downto 8;
subtype cntl_ibf_rrlim is integer range 14 downto 12;
subtype cntl_ibf_trlim is integer range 10 downto 8;
constant cntl_ibf_rclr : integer := 6;
constant cntl_ibf_tclr : integer := 5;
-- cntl_ibf_ssel is integer range 4 downto 3;
subtype cntl_ibf_func is integer range 2 downto 0;
constant func_noop : slv3 := "000"; -- func: noop
constant func_sco : slv3 := "001"; -- func: set CO
constant func_sring : slv3 := "010"; -- func: set RING
constant func_srlim : slv3 := "011"; -- func: set RLIM
constant ssel_dtle : slv2 := "00"; -- ssel: get DTR and LENA
constant ssel_brrx : slv2 := "01"; -- ssel: get BRK and RXON
constant ssel_cori : slv2 := "10"; -- ssel: get CO and RING
constant ssel_rlcn : slv2 := "11"; -- ssel: get RLIM and CNTL
constant cal_dtr : slv3 := "000"; -- cal: DTR
constant cal_brk : slv3 := "001"; -- cal: BRK
constant cal_rxon : slv3 := "010"; -- cal: RXON
constant cal_csr : slv3 := "011"; -- cal: CSR
subtype sdlle_ibf_dtr is integer range 15 downto 8;
subtype sdlle_ibf_lena is integer range 7 downto 0;
subtype sbrrx_ibf_brk is integer range 15 downto 8;
subtype sbrrx_ibf_rxon is integer range 7 downto 0;
subtype scori_ibf_co is integer range 15 downto 8;
subtype scori_ibf_ring is integer range 7 downto 0;
subtype srlcn_ibf_rrlim is integer range 14 downto 12;
subtype srlcn_ibf_trlim is integer range 10 downto 8;
constant srlcn_ibf_rir : integer := 7;
constant srlcn_ibf_tir : integer := 6;
constant srlcn_ibf_mse : integer := 5;
constant srlcn_ibf_maint: integer := 3;
subtype fuse_ibf_rsize is integer range AWIDTH-1+8 downto 8;
subtype fuse_ibf_tsize is integer range AWIDTH-1 downto 0;
constant fdat_ibf_val : integer := 15;
constant fdat_ibf_last : integer := 14;
constant fdat_ibf_ferr : integer := 13;
constant fdat_ibf_cal : integer := 11;
subtype fdat_ibf_line is integer range 10 downto 8;
subtype fdat_ibf_data is integer range 7 downto 0;
constant fbuf_ibf_cal : integer := 12;
constant fbuf_ibf_ferr : integer := 11;
subtype fbuf_ibf_line is integer range 10 downto 8;
subtype fbuf_ibf_data is integer range 7 downto 0;
type regs_type is record -- state registers
ibsel : slbit; -- ibus select
ssel : slv2; -- rcsr: status select
rrlim : slv3; -- rcsr: receiver rate limit
trlim : slv3; -- rcsr: transmitter rate limit
dtr : slv8; -- line state: dtr
lena : slv8; -- line state: lena
brk : slv8; -- line state: brk
rxon : slv8; -- line state: rxon
co : slv8; -- line state: co
ring : slv8; -- line state: ring
trdy : slbit; -- csr: transmitter ready
tie : slbit; -- csr: transmitter ie
sa : slbit; -- csr: silo alarm
sae : slbit; -- csr: silo alarm enable
tline : slv3; -- csr: transmit line
rdone : slbit; -- csr: receiver done
rie : slbit; -- csr: receiver ie
mse : slbit; -- csr: master scan enable
clr : slbit; -- csr: clear
maint : slbit; -- csr: maintenance mode
sam : slbit; -- sae monitor
lcnt : slv3; -- line counter
scnt : slv5; -- silo counter
qdtr : slbit; -- queue DTR alert
qbrk : slbit; -- queue BRK alert
qrxon : slbit; -- queue RXON alert
qcsr : slbit; -- queue CSR alert
qclr : slbit; -- queue CLR alert
rintreq : slbit; -- rx interrupt request
tintreq : slbit; -- tx interrupt request
end record regs_type;
constant regs_init : regs_type := (
'0', -- ibsel
"00","000","000", -- ssel,rrlim,trlim
(others=>'0'), -- dtr
(others=>'0'), -- lena
(others=>'0'), -- brk
(others=>'0'), -- rxon
(others=>'0'), -- co
(others=>'0'), -- ring
'0','0','0','0', -- trdy,tie,sa,sae
"000", -- tline
'0','0','0','0','0', -- rdone,rie,mse,clr,maint
'0', -- sam
(others=>'0'), -- lcnt
(others=>'0'), -- scnt
'0','0','0','0','0', -- qdtr,qbrk,qrxon,qcsr,qclr
'0','0' -- rintreq,tintreq
);
constant c_fuse1 : slv(AWIDTH-1 downto 0) := slv(to_unsigned(1,AWIDTH));
signal R_REGS : regs_type := regs_init;
signal N_REGS : regs_type := regs_init;
signal RBUF_CE : slbit := '0';
signal RBUF_WE : slbit := '0';
signal RBUF_DI : slv12 := (others=>'0');
signal RBUF_DO : slv12 := (others=>'0');
signal RBUF_RESET : slbit := '0';
signal RBUF_EMPTY : slbit := '0';
signal RBUF_FULL : slbit := '0';
signal RBUF_FUSE : slv(AWIDTH-1 downto 0) := (others=>'0');
signal TBUF_CE : slbit := '0';
signal TBUF_WE : slbit := '0';
signal TBUF_DI : slv13 := (others=>'0');
signal TBUF_DO : slv13 := (others=>'0');
signal TBUF_RESET : slbit := '0';
signal TBUF_EMPTY : slbit := '0';
signal TBUF_FULL : slbit := '0';
signal TBUF_FUSE : slv(AWIDTH-1 downto 0) := (others=>'0');
signal RRLIM_START : slbit := '0';
signal RRLIM_BUSY : slbit := '0';
signal TRLIM_START : slbit := '0';
signal TRLIM_BUSY : slbit := '0';
pure function toint (val : slv3) return integer is
begin
return to_integer(unsigned(val));
end function toint;
begin
assert AWIDTH>=5 and AWIDTH<=7
report "assert(AWIDTH>=5 and AWIDTH<=7): unsupported AWIDTH"
severity failure;
RBUF : fifo_simple_dram
generic map (
AWIDTH => AWIDTH,
DWIDTH => 12) -- FER+LINE(3)+BUF(8)
port map (
CLK => CLK,
RESET => RBUF_RESET,
CE => RBUF_CE,
WE => RBUF_WE,
DI => RBUF_DI,
DO => RBUF_DO,
EMPTY => RBUF_EMPTY,
FULL => RBUF_FULL,
SIZE => RBUF_FUSE
);
TBUF : fifo_simple_dram
generic map (
AWIDTH => AWIDTH,
DWIDTH => 13) -- CAL+FER+LINE(3)+BUF(8)
port map (
CLK => CLK,
RESET => TBUF_RESET,
CE => TBUF_CE,
WE => TBUF_WE,
DI => TBUF_DI,
DO => TBUF_DO,
EMPTY => TBUF_EMPTY,
FULL => TBUF_FULL,
SIZE => TBUF_FUSE
);
RRLIM : ib_rlim_slv
port map (
CLK => CLK,
RESET => RESET,
RLIM_CEV => RLIM_CEV,
SEL => R_REGS.rrlim,
START => RRLIM_START,
STOP => BRESET,
DONE => open,
BUSY => RRLIM_BUSY
);
TRLIM : ib_rlim_slv
port map (
CLK => CLK,
RESET => RESET,
RLIM_CEV => RLIM_CEV,
SEL => R_REGS.trlim,
START => TRLIM_START,
STOP => BRESET,
DONE => open,
BUSY => TRLIM_BUSY
);
proc_regs: process (CLK)
begin
if rising_edge(CLK) then
if BRESET='1' or R_REGS.clr='1' then
R_REGS <= regs_init;
if RESET = '0' then -- if RESET=0 we do just an ibus reset
R_REGS.ssel <= N_REGS.ssel; -- keep SSEL field
R_REGS.rrlim <= N_REGS.rrlim; -- keep RRLIM field
R_REGS.trlim <= N_REGS.trlim; -- keep TRLIM field
R_REGS.qclr <= N_REGS.qclr; -- keep clr cal request
R_REGS.dtr <= N_REGS.dtr; -- keep DTR (model cntl)
R_REGS.co <= N_REGS.co; -- keep CO (model cntl)
R_REGS.ring <= N_REGS.ring; -- keep RING (model cntl)
end if;
else
R_REGS <= N_REGS;
end if;
end if;
end process proc_regs;
proc_next : process (R_REGS, IB_MREQ, EI_ACK_RX, EI_ACK_TX, RESET,
RBUF_DO, RBUF_EMPTY, RBUF_FULL, RBUF_FUSE, RRLIM_BUSY,
TBUF_DO, TBUF_EMPTY, TBUF_FULL, TBUF_FUSE, TRLIM_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 ibwr : slbit := '0';
variable ibw0 : slbit := '0';
variable ibw1 : slbit := '0';
variable ilam : slbit := '0';
variable irbufdi : slv12 := (others=>'0');
variable irbufce : slbit := '0';
variable irbufwe : slbit := '0';
variable irbufrst : slbit := '0';
variable irrlimsta : slbit := '0';
variable itbufdi : slv13 := (others=>'0');
variable itbufce : slbit := '0';
variable itbufwe : slbit := '0';
variable itbufrst : slbit := '0';
variable itrlimsta : slbit := '0';
variable ixbuffull : slbit := '0';
variable iscntclr : 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;
ibwr := IB_MREQ.we;
ibw0 := IB_MREQ.we and IB_MREQ.be0;
ibw1 := IB_MREQ.we and IB_MREQ.be1;
ilam := '0';
irbufdi := (others=>'0');
irbufce := '0';
irbufwe := '0';
irbufrst := RESET and not r.mse;
irrlimsta := '0';
itbufdi := (others=>'0');
itbufce := '0';
itbufwe := '0';
itbufrst := RESET;
itrlimsta := '0';
iscntclr := not r.mse;
-- setup for rbuf writes
if r.maint = '0' then -- not in maint mode (rem fifo write)
irbufdi(fbuf_ibf_ferr) := IB_MREQ.din(fdat_ibf_ferr);
irbufdi(fbuf_ibf_line) := IB_MREQ.din(fdat_ibf_line);
irbufdi(fbuf_ibf_data) := IB_MREQ.din(fdat_ibf_data);
else -- in maint mode (loc tbuf write)
irbufdi(fbuf_ibf_ferr) := '0'; -- brk ignored on maint mode
irbufdi(fbuf_ibf_line) := r.tline;
irbufdi(fbuf_ibf_data) := IB_MREQ.din(tdr_ibf_tbuf);
end if;
-- ibus address decoder
n.ibsel := '0';
if IB_MREQ.aval='1' and
IB_MREQ.addr(12 downto 3)=IB_ADDR(12 downto 3) then
n.ibsel := '1';
end if;
-- ibus transactions
if r.ibsel = '1' then -- ibus selected ---------------------
-- setup for tbuf writes generated from ibus accesses
itbufdi(fbuf_ibf_ferr) := r.brk(toint(r.tline));
itbufdi(fbuf_ibf_line) := r.tline;
itbufdi(fbuf_ibf_data) := IB_MREQ.din(tdr_ibf_tbuf);
if IB_MREQ.racc = '1' then -- rri view: rem side access -------
case IB_MREQ.addr(2 downto 1) is
when ibaddr_cntl => -- CNTL -- control --------------
idout(cntl_ibf_awdth) := slv(to_unsigned(AWIDTH,3));
idout(cntl_ibf_sam) := r.sam;
idout(cntl_ibf_ssel) := r.ssel;
idout(cntl_ibf_mse) := r.mse;
idout(cntl_ibf_maint) := r.maint;
if ibwr = '1' then
if IB_MREQ.din(cntl_ibf_sam) = '1' then
n.sam := '0';
end if;
if IB_MREQ.din(cntl_ibf_rclr) = '1' then
irbufrst := '1';
end if;
if IB_MREQ.din(cntl_ibf_tclr) = '1' then
itbufrst := '1';
end if;
n.ssel := IB_MREQ.din(cntl_ibf_ssel);
case IB_MREQ.din(cntl_ibf_func) is -- handle cntl.func ------
when func_sco => -- func: set CO ------
n.co := IB_MREQ.din(cntl_ibf_data);
when func_sring => -- func: set RING ----
n.ring := IB_MREQ.din(cntl_ibf_data);
when func_srlim => -- func: set RLIM ----
n.rrlim := IB_MREQ.din(cntl_ibf_rrlim);
n.trlim := IB_MREQ.din(cntl_ibf_trlim);
when others => null;
end case;
end if;
when ibaddr_stat => -- STAT -- status ---------------
case r.ssel is
when ssel_dtle => -- ssel: get DTR and LENA
idout(sdlle_ibf_dtr) := r.dtr;
idout(sdlle_ibf_lena) := r.lena;
when ssel_brrx => -- ssel: get BRK and RXON
idout(sbrrx_ibf_brk) := r.brk;
idout(sbrrx_ibf_rxon) := r.rxon;
when ssel_cori => -- ssel: get CO and RING
idout(scori_ibf_co) := r.co;
idout(scori_ibf_ring) := r.ring;
when ssel_rlcn => -- ssel: get CNTL and RLIM
idout(srlcn_ibf_rrlim) := r.rrlim;
idout(srlcn_ibf_trlim) := r.trlim;
idout(srlcn_ibf_rir) := r.rintreq;
idout(srlcn_ibf_tir) := r.tintreq;
idout(srlcn_ibf_mse) := r.mse;
idout(srlcn_ibf_maint) := r.maint;
when others => null;
end case;
if ibrd = '1' then -- advance ssel on read
n.ssel := slv(unsigned(r.ssel) + 1);
end if;
if ibwr = '1' then -- stat is read-only
iback := '0';
end if;
when ibaddr_fuse => -- FUSE -- fifo usage -----------
idout(fuse_ibf_rsize) := RBUF_FUSE;
idout(fuse_ibf_tsize) := TBUF_FUSE;
when ibaddr_fdat => -- FDAT -- fifo read/write ------
idout(fdat_ibf_val) := not TBUF_EMPTY;
if TBUF_FUSE = c_fuse1 then
idout(fdat_ibf_last) := '1';
end if;
idout(fdat_ibf_ferr) := TBUF_DO(fbuf_ibf_ferr);
idout(fdat_ibf_cal) := TBUF_DO(fbuf_ibf_cal);
idout(fdat_ibf_line) := TBUF_DO(fbuf_ibf_line);
idout(fdat_ibf_data) := TBUF_DO(fbuf_ibf_data);
if ibrd = '1' then -- fifo read
if TBUF_EMPTY = '0' then -- fifo not empty
itbufce := '1'; -- read from fifo
itbufwe := '0';
else -- read from empty fifo
iback := '0'; -- signal nak
end if;
end if;
if ibwr = '1' then -- fifo write
if RBUF_FULL = '0' then -- fifo not full
if r.mse='1' and r.maint='0' then -- running and not in maint
if r.rxon(toint(IB_MREQ.din(fdat_ibf_line))) = '1' then
irbufce := '1'; -- write to fifo
irbufwe := '1'; -- with default irbufdi
else
-- usually the backend is woken up to send more data by an
-- attn send when the last RBUF value is read. When all
-- data is dropped that never happens. So send an attn
-- when a value is dropped and the RBUF is empty.
if RBUF_EMPTY = '0' then -- for drop on empty fifo
ilam := '1'; -- ask for more data
end if;
end if;
end if;
else -- write to full fifo
iback := '0'; -- signal nak
end if;
end if;
when others => null;
end case; -- IB_MREQ.addr
else -- cpu view: loc side access -------
case IB_MREQ.addr(2 downto 1) is
when ibaddr_csr => -- CSR -- control/status -------
idout(csr_ibf_trdy) := r.trdy;
idout(csr_ibf_tie) := r.tie;
idout(csr_ibf_sa) := r.sa;
idout(csr_ibf_sae) := r.sae;
idout(csr_ibf_tline) := r.tline;
idout(csr_ibf_rdone) := r.rdone;
idout(csr_ibf_rie) := r.rie;
idout(csr_ibf_mse) := r.mse;
idout(csr_ibf_clr) := r.clr;
idout(csr_ibf_maint) := r.maint;
if ibw1 = '1' then
n.tie := IB_MREQ.din(csr_ibf_tie);
if IB_MREQ.din(csr_ibf_tie) = '1' then
if r.tie='0' and r.trdy='1' then -- tie 0->1 and trdy
n.rintreq := '1'; -- request interrupt
end if;
else
n.tintreq := '0';
end if;
n.sae := IB_MREQ.din(csr_ibf_sae);
if IB_MREQ.din(csr_ibf_sae) = '1' then
n.sam := '1';
end if;
end if;
if ibw0 = '1' then
n.rie := IB_MREQ.din(csr_ibf_rie);
if IB_MREQ.din(csr_ibf_rie) = '1' then
if r.rie='0' and -- rie 0->1
((r.sae='0' and r.rdone='1') or -- and no silo and rdone
(r.sae='1' and r.sa='1')) -- or silo and alarm
then
n.rintreq := '1';
end if;
else
n.rintreq := '0';
end if;
n.mse := IB_MREQ.din(csr_ibf_mse);
if IB_MREQ.din(csr_ibf_mse) = '0' then -- mse clear
n.rdone := '0';
n.trdy := '0';
end if;
if r.mse /= IB_MREQ.din(csr_ibf_mse) then -- mse change
n.qcsr := '1';
end if;
if IB_MREQ.din(csr_ibf_clr) = '1' then -- clr set ?
n.clr := '1'; -- request clr
n.qclr := '1'; -- queue clr cal
end if;
n.maint := IB_MREQ.din(csr_ibf_maint);
if r.maint /= IB_MREQ.din(csr_ibf_maint) then -- maint change
n.qcsr := '1';
end if;
end if;
when ibaddr_rbuf_lpr => -- RBUF/LPR ---------------------
idout(rbuf_ibf_val) := r.rdone;
idout(rbuf_ibf_ferr) := RBUF_DO(fbuf_ibf_ferr);
idout(rbuf_ibf_line) := RBUF_DO(fbuf_ibf_line);
idout(rbuf_ibf_data) := RBUF_DO(fbuf_ibf_data);
if ibrd = '1' then -- RBUF read
if r.rdone = '1' then
irbufce := '1'; -- read next value from fifo
irbufwe := '0';
if RBUF_FUSE=c_fuse1 and r.maint='0' then -- last val ?
ilam := '1'; -- rri lam
end if;
n.rdone := '0'; -- clear rdone
n.sa := '0'; -- clear silo alarm
n.rintreq := '0'; -- clear interrupt
iscntclr := '1'; -- clear silo count
end if;
end if;
if ibwr = '1' then -- LPR write
n.rxon(toint(IB_MREQ.din(lpr_ibf_line))) :=
IB_MREQ.din(lpr_ibf_rxon);
if r.rxon(toint(IB_MREQ.din(lpr_ibf_line))) /=
IB_MREQ.din(lpr_ibf_rxon) then -- if changed
n.qrxon := '1'; -- queue rxon cal
end if;
end if;
when ibaddr_tcr => -- TCR -- transmit control ---
idout(tcr_ibf_dtr) := r.dtr;
idout(tcr_ibf_lena) := r.lena;
if ibw1 = '1' then -- DTR written
n.dtr := IB_MREQ.din(tcr_ibf_dtr);
if r.dtr /= IB_MREQ.din(tcr_ibf_dtr) then -- if changed
n.qdtr := '1'; -- queue dtr cal
end if;
end if;
if ibw0 = '1' then -- LENA written
n.lena := IB_MREQ.din(tcr_ibf_lena);
-- check if ready and active line is disabled
if r.trdy = '1' and
IB_MREQ.din(tcr_ibf_lena)(toint(r.tline)) = '0' then
n.trdy := '0'; -- clear ready
n.tintreq := '0'; -- clear interrupt
end if;
end if;
when ibaddr_msr_tdr => -- MSR/TDR ----------------------
idout(msr_ibf_co) := r.co;
idout(msr_ibf_ring) := r.ring;
if ibw1 = '1' then -- BRK written
n.brk := IB_MREQ.din(tdr_ibf_brk);
if r.brk /= IB_MREQ.din(tdr_ibf_brk) then -- if changed
n.qbrk := '1'; -- queue brk cal
end if;
end if;
if ibw0 = '1' then -- TBUF written
if r.trdy = '1' then -- ignore buf write when rdy=0
n.trdy := '0'; -- clear ready
n.tintreq := '0'; -- clear interrupt
if r.maint = '0' then -- not in maint mode
if TBUF_FULL = '0' then -- fifo not full
itbufce := '1'; -- write to fifo
itbufwe := '1'; -- with default itbufdi
end if;
else -- in maint mode
if RBUF_FULL = '0' then -- fifo not full
if r.rxon(toint(r.tline)) = '1' then -- line enabled ?
irbufce := '1'; -- write to fifo
irbufwe := '1'; -- with default irbufdi
end if;
end if;
end if;
end if;
end if;
when others => null;
end case; -- IB_MREQ.addr
end if; -- IB_MREQ.racc
-- silo counter logic
if iscntclr = '1' then
n.scnt := (others=>'0');
elsif irbufwe = '1' then
if r.scnt(4) = '0' then
n.scnt := slv(unsigned(r.scnt) + 1);
end if;
end if;
else -- ibus not selected -----------------
-- handle rx done, timer and interrupt
if r.sae = '0' then -- silo alarm disabled
if RBUF_EMPTY='0' and RRLIM_BUSY='0' then -- not empty and not busy ?
if r.rdone = '0' then -- rdone not set ?
n.rdone := '1'; -- set rdone
irrlimsta := '1'; -- start timer
if r.rie = '1' then -- rx irupt enabled ?
n.rintreq := '1'; -- request rx irupt
end if;
end if;
end if;
else -- silo alarm enabled
if RBUF_EMPTY = '0' then -- not empty ?
if r.rdone = '0' then -- rdone not set ?
n.rdone := '1'; -- set rdone
if r.scnt(4)='1' and RRLIM_BUSY='0' then -- silo16 and not busy ?
if r.sa = '0' then -- sa not set ?
n.sa := '1'; -- set sa
irrlimsta := '1'; -- start timer
if r.rie = '1' then -- rx irupt enabled ?
n.rintreq := '1'; -- request rx irupt
end if;
end if;
end if;
end if;
end if;
end if; -- else r.sae='0'
-- handle tx ready, tline, timer and interrupt
if r.maint = '0' then
ixbuffull := TBUF_FULL;
else
ixbuffull := RBUF_FULL;
end if;
if ixbuffull='0' and TRLIM_BUSY='0' then -- not full and not busy ?
if (r.qdtr or r.qbrk or r.qrxon or r.qcsr) = '0' then -- no cal queued
if r.mse = '1' and r.trdy = '0' then -- searching ?
if r.lena(toint(r.lcnt)) = '1' then -- line found
n.tline := r.lcnt; -- remember line
n.trdy := '1'; -- set ready
itrlimsta := '1'; -- start timer
if r.tie='1' then
n.tintreq := '1'; -- request interrupt
end if;
end if;
-- incrementing lcnt here ensures that the start point for the next
-- search (n.lcnt) is the line one past the current winner (r.lcnt).
n.lcnt := slv(unsigned(r.lcnt) + 1); -- go for next line
end if;
end if;
end if;
-- handle queue change alerts
if TBUF_FULL = '0' then -- fifo space available ?
itbufdi(fbuf_ibf_cal) := '1';
if r.qdtr = '1' then -- cal DTR pending
n.qdtr := '0';
itbufdi(fbuf_ibf_line) := cal_dtr;
itbufdi(fbuf_ibf_data) := r.dtr;
itbufce := '1';
itbufwe := '1';
elsif r.qbrk = '1' then -- cal BRK pending
n.qbrk := '0';
itbufdi(fbuf_ibf_line) := cal_brk;
itbufdi(fbuf_ibf_data) := r.brk;
itbufce := '1';
itbufwe := '1';
elsif r.qrxon = '1' then -- cal RXON pending
n.qrxon := '0';
itbufdi(fbuf_ibf_line) := cal_rxon;
itbufdi(fbuf_ibf_data) := r.rxon;
itbufce := '1';
itbufwe := '1';
elsif r.qcsr='1' or r.qclr='1' then -- cal CSR pending
n.qcsr := '0';
n.qclr := '0';
itbufdi(fbuf_ibf_line) := cal_csr;
itbufdi(fbuf_ibf_data) := (others=>'0');
itbufdi(csr_ibf_mse) := r.mse;
itbufdi(csr_ibf_clr) := r.qclr;
itbufdi(csr_ibf_maint) := r.maint;
itbufce := '1';
itbufwe := '1';
end if;
end if;
end if; -- else r.ibsel='1'
if itbufce='1' and itbufwe='1' then -- write to tx fifo
if TBUF_EMPTY='1' then -- first write to empty tx fifo
ilam := '1'; -- request attention
end if;
end if;
-- other state changes
if EI_ACK_RX = '1' then
n.rintreq := '0';
end if;
if EI_ACK_TX = '1' then
n.tintreq := '0';
end if;
N_REGS <= n;
RBUF_RESET <= irbufrst;
RBUF_CE <= irbufce;
RBUF_WE <= irbufwe;
RBUF_DI <= irbufdi;
RRLIM_START <= irrlimsta;
TBUF_RESET <= itbufrst;
TBUF_CE <= itbufce;
TBUF_WE <= itbufwe;
TBUF_DI <= itbufdi;
TRLIM_START <= itrlimsta;
IB_SRES.dout <= idout;
IB_SRES.ack <= iback;
IB_SRES.busy <= '0';
RB_LAM <= ilam;
EI_REQ_RX <= r.rintreq;
EI_REQ_TX <= r.tintreq;
end process proc_next;
end syn;

View File

@@ -15,6 +15,7 @@ ibdr_rk11.vbom
ibdr_tm11.vbom
ibdr_dl11.vbom
ibdr_dl11_buf.vbom
ibdr_dz11.vbom
ibdr_pc11.vbom
ibdr_pc11_buf.vbom
ibdr_lp11.vbom

View File

@@ -1,4 +1,4 @@
-- $Id: ibdr_maxisys.vhd 1142 2019-04-28 19:27:57Z mueller $
-- $Id: ibdr_maxisys.vhd 1148 2019-05-12 10:10:44Z mueller $
--
-- Copyright 2009-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
@@ -26,6 +26,7 @@
-- ibdr_tm11
-- ibdr_dl11
-- ibdr_dl11_buf
-- ibdr_dz11
-- ibdr_pc11
-- ibdr_pc11_buf
-- ibdr_lp11
@@ -54,6 +55,8 @@
--
-- Revision History:
-- Date Rev Version Comment
-- 2019-05-04 1146 1.6.9 add ibdr_dz11
-- 2019-04-28 1142 1.6.8 add ibd_m9312
-- 2019-04-26 1139 1.6.7 add ibdr_dl11_buf
-- 2019-04-23 1136 1.6.6 add CLK port to ib_intmap24
-- 2019-04-14 1131 1.6.5 ib_rlim_gen has CPUSUSP port; RLIM_CEV now slv8
@@ -98,8 +101,8 @@
-- 174400 160 5 12 12 5 2/2 RL11
-- 177400 220 5 11 11 4 2/3 RK11
-- 172520 224 5 10 10 7 2/4 TM11
-- 160100 310? 5 9 9 3 3/1 DZ11-RX
-- 314? 5 8 8 ^ DZ11-TX
-- 160100 310 5 9 9 3 3/1 DZ11-RX
-- 314 5 8 8 ^ DZ11-TX
-- 177560 060 4 7 7 1 3/2 DL11-RX 1st
-- 064 4 6 6 ^ DL11-TX 1st
-- 176500 300 4 5 5 2 3/3 DL11-RX 2nd
@@ -142,6 +145,9 @@ end ibdr_maxisys;
architecture syn of ibdr_maxisys is
constant ibaddr_dl11_1 : slv16 := slv(to_unsigned(8#176500#,16));
constant ibaddr_dz11 : slv16 := slv(to_unsigned(8#160100#,16));
constant conf_intmap24 : intmap24_array_type :=
(intmap_init, -- line 23 (unused)
intmap_init, -- line 22 (unused)
@@ -167,16 +173,16 @@ architecture syn of ibdr_maxisys is
(8#074#,4), -- line 2 PC11-PTP
(8#200#,4), -- line 1 LP11
intmap_init -- line 0 (must be unused!)
);
);
signal RB_LAM_DEUNA : slbit := '0';
signal RB_LAM_RHRP : slbit := '0';
signal RB_LAM_RL11 : slbit := '0';
signal RB_LAM_RK11 : slbit := '0';
signal RB_LAM_TM11 : slbit := '0';
signal RB_LAM_DZ11 : slbit := '0';
signal RB_LAM_DL11_0 : slbit := '0';
signal RB_LAM_DL11_1 : slbit := '0';
signal RB_LAM_DZ11 : slbit := '0';
signal RB_LAM_PC11 : slbit := '0';
signal RB_LAM_LP11 : slbit := '0';
@@ -188,9 +194,9 @@ architecture syn of ibdr_maxisys is
signal IB_SRES_RL11 : ib_sres_type := ib_sres_init;
signal IB_SRES_RK11 : ib_sres_type := ib_sres_init;
signal IB_SRES_TM11 : ib_sres_type := ib_sres_init;
signal IB_SRES_DZ11 : ib_sres_type := ib_sres_init;
signal IB_SRES_DL11_0 : ib_sres_type := ib_sres_init;
signal IB_SRES_DL11_1 : ib_sres_type := ib_sres_init;
signal IB_SRES_DZ11 : ib_sres_type := ib_sres_init;
signal IB_SRES_PC11 : ib_sres_type := ib_sres_init;
signal IB_SRES_LP11 : ib_sres_type := ib_sres_init;
signal IB_SRES_M9312 : ib_sres_type := ib_sres_init;
@@ -212,12 +218,12 @@ architecture syn of ibdr_maxisys is
signal EI_REQ_RL11 : slbit := '0';
signal EI_REQ_RK11 : slbit := '0';
signal EI_REQ_TM11 : slbit := '0';
signal EI_REQ_DZ11RX : slbit := '0';
signal EI_REQ_DZ11TX : slbit := '0';
signal EI_REQ_DL11RX_0 : slbit := '0';
signal EI_REQ_DL11TX_0 : slbit := '0';
signal EI_REQ_DL11RX_1 : slbit := '0';
signal EI_REQ_DL11TX_1 : slbit := '0';
signal EI_REQ_DZ11RX : slbit := '0';
signal EI_REQ_DZ11TX : slbit := '0';
signal EI_REQ_PC11PTR : slbit := '0';
signal EI_REQ_PC11PTP : slbit := '0';
signal EI_REQ_LP11 : slbit := '0';
@@ -230,12 +236,12 @@ architecture syn of ibdr_maxisys is
signal EI_ACK_RL11 : slbit := '0';
signal EI_ACK_RK11 : slbit := '0';
signal EI_ACK_TM11 : slbit := '0';
signal EI_ACK_DZ11RX : slbit := '0';
signal EI_ACK_DZ11TX : slbit := '0';
signal EI_ACK_DL11RX_0 : slbit := '0';
signal EI_ACK_DL11TX_0 : slbit := '0';
signal EI_ACK_DL11RX_1 : slbit := '0';
signal EI_ACK_DL11TX_1 : slbit := '0';
signal EI_ACK_DZ11RX : slbit := '0';
signal EI_ACK_DZ11TX : slbit := '0';
signal EI_ACK_PC11PTR : slbit := '0';
signal EI_ACK_PC11PTP : slbit := '0';
signal EI_ACK_LP11 : slbit := '0';
@@ -427,7 +433,7 @@ begin
begin
TTB : ibdr_dl11
generic map (
IB_ADDR => slv(to_unsigned(8#176500#,16)))
IB_ADDR => ibaddr_dl11_1)
port map (
CLK => CLK,
RESET => RESET,
@@ -447,7 +453,7 @@ begin
begin
TTB : ibdr_dl11_buf
generic map (
IB_ADDR => slv(to_unsigned(8#176500#,16)),
IB_ADDR => ibaddr_dl11_1,
AWIDTH => sys_conf_ibd_dl11_1)
port map (
CLK => CLK,
@@ -464,6 +470,26 @@ begin
);
end generate DL11_1BUF;
DZ11: if sys_conf_ibd_dz11 > 0 generate
DZA : ibdr_dz11
generic map (
IB_ADDR => ibaddr_dz11,
AWIDTH => sys_conf_ibd_dz11)
port map (
CLK => CLK,
RESET => RESET,
BRESET => BRESET,
RLIM_CEV => RLIM_CEV,
RB_LAM => RB_LAM_DZ11,
IB_MREQ => IB_MREQ,
IB_SRES => IB_SRES_DZ11,
EI_REQ_RX => EI_REQ_DZ11RX,
EI_REQ_TX => EI_REQ_DZ11TX,
EI_ACK_RX => EI_ACK_DZ11RX,
EI_ACK_TX => EI_ACK_DZ11TX
);
end generate DZ11;
PC11: if sys_conf_ibd_pc11 = 0 generate
begin
PCA : ibdr_pc11
@@ -574,9 +600,9 @@ begin
SRES_OR_3 : ib_sres_or_3
port map (
IB_SRES_1 => IB_SRES_DZ11,
IB_SRES_2 => IB_SRES_DL11_0,
IB_SRES_3 => IB_SRES_DL11_1,
IB_SRES_1 => IB_SRES_DL11_0,
IB_SRES_2 => IB_SRES_DL11_1,
IB_SRES_3 => IB_SRES_DZ11,
IB_SRES_OR => IB_SRES_3
);