From 334c7214be65db578f3a4850cb1892cfca7711e4 Mon Sep 17 00:00:00 2001 From: wfjm Date: Sat, 25 May 2019 19:43:35 +0200 Subject: [PATCH] add dz11 device - ibus/ibdr_maxisys: instantiate ibdr_dz11 - ibus/ibdr_dz11: added, 8 line serial port multiplexer --- doc/CHANGELOG.md | 2 + rtl/ibus/ibdlib.vhd | 6 +- rtl/ibus/ibdr_dz11.vbom | 9 + rtl/ibus/ibdr_dz11.vhd | 782 +++++++++++++++++++++++++++++++++++++ rtl/ibus/ibdr_maxisys.vbom | 1 + rtl/ibus/ibdr_maxisys.vhd | 56 ++- 6 files changed, 839 insertions(+), 17 deletions(-) create mode 100644 rtl/ibus/ibdr_dz11.vbom create mode 100644 rtl/ibus/ibdr_dz11.vhd diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 4d1ba26b..16f3553e 100644 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -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 diff --git a/rtl/ibus/ibdlib.vhd b/rtl/ibus/ibdlib.vhd index 0c197d0e..fb9fad87 100644 --- a/rtl/ibus/ibdlib.vhd +++ b/rtl/ibus/ibdlib.vhd @@ -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 -- @@ -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 diff --git a/rtl/ibus/ibdr_dz11.vbom b/rtl/ibus/ibdr_dz11.vbom new file mode 100644 index 00000000..38378aee --- /dev/null +++ b/rtl/ibus/ibdr_dz11.vbom @@ -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 diff --git a/rtl/ibus/ibdr_dz11.vhd b/rtl/ibus/ibdr_dz11.vhd new file mode 100644 index 00000000..e623f287 --- /dev/null +++ b/rtl/ibus/ibdr_dz11.vhd @@ -0,0 +1,782 @@ +-- $Id: ibdr_dz11.vhd 1150 2019-05-19 17:52:54Z mueller $ +-- +-- Copyright 2019- by Walter F.J. Mueller +-- +-- 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; diff --git a/rtl/ibus/ibdr_maxisys.vbom b/rtl/ibus/ibdr_maxisys.vbom index 8888cc5d..0a005ee9 100644 --- a/rtl/ibus/ibdr_maxisys.vbom +++ b/rtl/ibus/ibdr_maxisys.vbom @@ -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 diff --git a/rtl/ibus/ibdr_maxisys.vhd b/rtl/ibus/ibdr_maxisys.vhd index 42d02665..1bfba527 100644 --- a/rtl/ibus/ibdr_maxisys.vhd +++ b/rtl/ibus/ibdr_maxisys.vhd @@ -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 -- @@ -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 );