1
0
mirror of https://github.com/wfjm/w11.git synced 2026-04-26 04:08:17 +00:00
Files
wfjm.w11/rtl/vlib/rlink/tb/tb_rlink.vhd
2019-08-21 12:04:09 +02:00

986 lines
36 KiB
VHDL

-- $Id: tb_rlink.vhd 1203 2019-08-19 21:41:03Z mueller $
-- SPDX-License-Identifier: GPL-3.0-or-later
-- Copyright 2007-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
------------------------------------------------------------------------------
-- Module Name: tb_rlink - sim
-- Description: Test bench for rlink_core
--
-- Dependencies: simlib/simclk
-- simlib/simclkcnt
-- genlib/tb/clkdivce_tb
-- rbus/rbd_tester
-- tbd_rlink_gen [UUT]
--
-- To test: rlink_core (via tbd_rlink_direct)
-- rlink_base (via tbd_rlink_serport)
-- rlink_serport (via tbd_rlink_serport)
--
-- Target Devices: generic
-- Tool versions: xst 8.2-14.7; viv 2019.1; ghdl 0.18-0.36
--
-- Revision History:
-- Date Rev Version Comment
-- 2019-08-17 1203 4.1.3 fix for ghdl V0.36 -Whide warnings
-- 2019-06-02 1159 4.1.2 use rbaddr_ constants
-- 2016-09-10 806 4.1.1 use clkdivce_tb
-- 2014-10-12 596 4.1 use readgen_ea; add get_cmd_ea; labo instead of stat
-- add txblk,rxblk,rxrbeg,rxrend,rxcbs,anmsg commands
-- 2014-08-28 588 4.0 now rlink v4 iface -> txcac has 16 bit; 4 bit STAT
-- 2014-08-15 583 3.5 rb_mreq addr now 16 bit; adopt txca,txcad,txcac
-- 2011-12-23 444 3.1 use new simclk/simclkcnt
-- 2011-11-19 427 3.0.7 fix crc8_update_tbl usage; now numeric_std clean
-- 2010-12-29 351 3.0.6 use new rbd_tester addr 111100xx (from 111101xx)
-- 2010-12-26 348 3.0.5 use simbus to export clkcycle (for tbd_..serport)
-- 2010-12-23 347 3.0.4 use rb_mon, rlink_mon directly; rename CP_*->RL_*
-- 2010-12-22 346 3.0.3 add .rlmon and .rbmon commands
-- 2010-12-21 345 3.0.2 rename commands .[rt]x... to [rt]x...;
-- add .[rt]x(idle|attn) cmds; remove 'bbbbbbbb' cmd
-- 2010-12-12 344 3.0.1 add .attn again; add .txbad, .txoof; ren oob->oof
-- 2010-12-05 343 3.0 rri->rlink renames; port to rbus V3 protocol;
-- use rbd_tester instead of sim target;
-- 2010-06-06 302 2.5 use sop/eop framing instead of soc+chaining
-- 2010-06-03 299 2.2.2 new init encoding (WE=0/1 int/ext);use sv_ prefix
-- for shared variables
-- 2010-05-02 287 2.2.1 ren CE_XSEC->CE_INT,RP_STAT->RB_STAT,AP_LAM->RB_LAM
-- drop RP_IINT signal from interfaces
-- 2010-04-03 274 2.2 add CE_USEC in tbd_rri_gen interface
-- 2009-03-14 197 2.1 remove records in interface to allow _ssim usage
-- 2008-08-24 162 2.0 with new rb_mreq/rb_sres interface
-- 2008-03-24 129 1.1.2 CLK_CYCLE now 31 bits
-- 2008-01-20 112 1.1.1 rename clkgen->clkdivce
-- 2007-11-24 98 1.1 add RP_IINT support, add checkmiss_tx to test
-- for missing responses
-- 2007-10-26 92 1.0.2 add DONE timestamp at end of execution
-- 2007-10-12 88 1.0.1 avoid ieee.std_logic_unsigned, use cast to unsigned
-- 2007-09-09 81 1.0 Initial version
------------------------------------------------------------------------------
-- command set:
-- .reset assert RESET for 1 clk
-- .rlmon ien enable rlink monitor (9 bit)
-- .rlbmo ien enable rlink monitor (8 bit)
-- .rbmon ien enable rbus monitor
-- .wait n wait n clks
-- .iowt n wait n clks for rlink i/o; auto-extend
-- .attn dat(16) pulse attn lines with dat
--
-- - high level ---
-- anmsg apat attn notify message
-- sop start packet
-- eop end packet
-- rreg seq addr data stat rreg cmd
-- wreg seq addr data stat wreg cmd
-- init seq addr data stat init cmd
-- attn seq data stat attn cmd
-- labo seq data stat labo cmd
-- rblks seq addr nblk data stat rblk cmd (with seq)
-- wblks seq addr nblk data stat wblk cmd (with seq)
-- rblkd seq addr ndone stat rblk cmd (with data list)
-- wblkd seq addr ndone stat wblk cmd (with data list)
-- .dclr clear data list
-- .dwrd data add word to data list
-- .dseq nblk data add sequence to data list
--
-- - low level ---
-- txcrc send crc
-- txbad send bad (inverted) crc
-- txc cmd(8) send cmd - crc
-- txca cmd(8) addr(16) send cmd - al ah - crcl crch
-- txcad cmd(8) addr(16) dat(16) send cmd - al ah - dl dh - crcl crch
-- txcac cmd(8) addr(16) cnt(16) send cmd - al ah - cl ch - crcl crch
-- txoof dat(9) send out-of-frame symbol
-- rxcrc expect crc
-- rxcs cmd(8) stat(8) expect cmd - stat - crcl crch
-- rxcds cmd(8) dat(16) stat(8) expect cmd - dl dh - stat - crcl crch
-- rxcbs cmd(8) dat(8) stat(8) expect cmd - dl - stat - crcl crch
-- rxrbeg cmd(8) cnt(16) expect cmd - cl ch
-- rxrend dcnt(16) expect dcl dch - stat - crcl crch
-- rxoof dat(9) expect out-of-frame symbol
--
-- - raw level ---
-- txsop send <sop>
-- txeop send <eop>
-- txnak send <nak>
-- txattn send <attn>
-- tx8 dat(8) send 8 bit value
-- tx16 dat(16) send 16 bit value
-- txblk n start send n 16 values
-- rxsop reset rx list; expect sop
-- rxeop expect <eop>
-- rxnak expect <nak>
-- rxattn expect <attn>
-- rx8 dat(8) expect 8 bit value
-- rx16 dat(16) expect 16 bit value
-- rxblk n start expect n 16 values
--
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_textio.all;
use std.textio.all;
use work.slvtypes.all;
use work.genlib.all;
use work.comlib.all;
use work.rblib.all;
use work.rbdlib.all;
use work.rlinklib.all;
use work.simlib.all;
use work.simbus.all;
entity tb_rlink is
end tb_rlink;
architecture sim of tb_rlink is
constant d_f_cflag : integer := 8; -- d9: comma flag
subtype d_f_data is integer range 7 downto 0; -- d9: data field
subtype f_byte1 is integer range 15 downto 8;
subtype f_byte0 is integer range 7 downto 0;
signal CLK : slbit := '0';
signal CE_USEC : slbit := '0';
signal CE_MSEC : slbit := '0';
signal RESET : slbit := '0';
signal RL_DI : slv9 := (others=>'0');
signal RL_ENA : slbit := '0';
signal RL_BUSY : slbit := '0';
signal RL_DO : slv9 := (others=>'0');
signal RL_VAL : slbit := '0';
signal RL_HOLD : slbit := '0';
signal RB_MREQ_aval : slbit := '0';
signal RB_MREQ_re : slbit := '0';
signal RB_MREQ_we : slbit := '0';
signal RB_MREQ_initt: slbit := '0';
signal RB_MREQ_addr : slv16 := (others=>'0');
signal RB_MREQ_din : slv16 := (others=>'0');
signal RB_SRES_ack : slbit := '0';
signal RB_SRES_busy : slbit := '0';
signal RB_SRES_err : slbit := '0';
signal RB_SRES_dout : slv16 := (others=>'0');
signal RB_LAM_TBENCH : slv16 := (others=>'0');
signal RB_LAM_TESTER : slv16 := (others=>'0');
signal RB_LAM : slv16 := (others=>'0');
signal RB_STAT : slv4 := (others=>'0');
signal TXRXACT : slbit := '0';
signal RB_MREQ : rb_mreq_type := rb_mreq_init;
signal RB_SRES : rb_sres_type := rb_sres_init;
signal CLK_STOP : slbit := '0';
signal CLK_CYCLE : integer := 0;
constant rxlist_size : positive := 4096; -- size of rxlist
constant txlist_size : positive := 4096; -- size of txlist
constant datlist_size : positive := 2048; -- size of datlist
constant slv9_zero : slv9 := (others=>'0');
constant slv16_zero : slv16 := (others=>'0');
type rxlist_array_type is array (0 to rxlist_size-1) of slv9;
type txlist_array_type is array (0 to txlist_size-1) of slv9;
type datlist_array_type is array (0 to datlist_size-1) of slv16;
shared variable sv_rxlist : rxlist_array_type := (others=>slv9_zero);
shared variable sv_nrxlist : natural := 0;
shared variable sv_rxind : natural := 0;
constant clock_period : Delay_length := 20 ns;
constant clock_offset : Delay_length := 200 ns;
constant setup_time : Delay_length := 5 ns;
constant c2out_time : Delay_length := 10 ns;
component tbd_rlink_gen is -- rlink, generic tb design interface
port (
CLK : in slbit; -- clock
CE_INT : in slbit; -- rlink ito time unit clock enable
CE_USEC : in slbit; -- 1 usec clock enable
RESET : in slbit; -- reset
RL_DI : in slv9; -- rlink: data in
RL_ENA : in slbit; -- rlink: data enable
RL_BUSY : out slbit; -- rlink: data busy
RL_DO : out slv9; -- rlink: data out
RL_VAL : out slbit; -- rlink: data valid
RL_HOLD : in slbit; -- rlink: data hold
RB_MREQ_aval : out slbit; -- rbus: request - aval
RB_MREQ_re : out slbit; -- rbus: request - re
RB_MREQ_we : out slbit; -- rbus: request - we
RB_MREQ_initt: out slbit; -- rbus: request - init; avoid name coll
RB_MREQ_addr : out slv16; -- rbus: request - addr
RB_MREQ_din : out slv16; -- rbus: request - din
RB_SRES_ack : in slbit; -- rbus: response - ack
RB_SRES_busy : in slbit; -- rbus: response - busy
RB_SRES_err : in slbit; -- rbus: response - err
RB_SRES_dout : in slv16; -- rbus: response - dout
RB_LAM : in slv16; -- rbus: look at me
RB_STAT : in slv4; -- rbus: status flags
TXRXACT : out slbit -- txrx active flag
);
end component;
begin
CLKGEN : simclk
generic map (
PERIOD => clock_period,
OFFSET => clock_offset)
port map (
CLK => CLK,
CLK_STOP => CLK_STOP
);
CLKCNT : simclkcnt port map (CLK => CLK, CLK_CYCLE => CLK_CYCLE);
CLKDIV : entity work.clkdivce_tb
generic map (
CDUWIDTH => 6,
USECDIV => 4,
MSECDIV => 5)
port map (
CLK => CLK,
CE_USEC => CE_USEC,
CE_MSEC => CE_MSEC
);
RB_MREQ.aval <= RB_MREQ_aval;
RB_MREQ.re <= RB_MREQ_re;
RB_MREQ.we <= RB_MREQ_we;
RB_MREQ.init <= RB_MREQ_initt;
RB_MREQ.addr <= RB_MREQ_addr;
RB_MREQ.din <= RB_MREQ_din;
RB_SRES_ack <= RB_SRES.ack;
RB_SRES_busy <= RB_SRES.busy;
RB_SRES_err <= RB_SRES.err;
RB_SRES_dout <= RB_SRES.dout;
RBTEST : rbd_tester
generic map (
RB_ADDR => rbaddr_tester)
port map (
CLK => CLK,
RESET => '0',
RB_MREQ => RB_MREQ,
RB_SRES => RB_SRES,
RB_LAM => RB_LAM_TESTER,
RB_STAT => RB_STAT
);
RB_LAM <= RB_LAM_TESTER or RB_LAM_TBENCH;
UUT : tbd_rlink_gen
port map (
CLK => CLK,
CE_INT => CE_MSEC,
CE_USEC => CE_USEC,
RESET => RESET,
RL_DI => RL_DI,
RL_ENA => RL_ENA,
RL_BUSY => RL_BUSY,
RL_DO => RL_DO,
RL_VAL => RL_VAL,
RL_HOLD => RL_HOLD,
RB_MREQ_aval => RB_MREQ_aval,
RB_MREQ_re => RB_MREQ_re,
RB_MREQ_we => RB_MREQ_we,
RB_MREQ_initt=> RB_MREQ_initt,
RB_MREQ_addr => RB_MREQ_addr,
RB_MREQ_din => RB_MREQ_din,
RB_SRES_ack => RB_SRES_ack,
RB_SRES_busy => RB_SRES_busy,
RB_SRES_err => RB_SRES_err,
RB_SRES_dout => RB_SRES_dout,
RB_LAM => RB_LAM,
RB_STAT => RB_STAT,
TXRXACT => TXRXACT
);
proc_stim: process
file fstim : text open read_mode is "tb_rlink_stim";
variable iline : line;
variable oline : line;
variable ien : slbit := '0';
variable icmd : slv8 := (others=>'0');
variable iaddr : slv16 := (others=>'0');
variable icnt : slv16 := (others=>'0');
variable ibabo : slv8 := (others=>'0');
variable istat : slv8 := (others=>'0');
variable iattn : slv16 := (others=>'0');
variable idata : slv16 := (others=>'0');
variable idat8 : slv8 := (others=>'0');
variable ioof : slv9 := (others=>'0');
variable iblkval : slv16 := (others=>'0');
variable iblkmsk : slv16 := (others=>'0');
variable nblk : natural := 1;
variable ndone : natural := 1;
variable rxlabo : boolean := false;
variable ok : boolean;
variable dname : string(1 to 6) := (others=>' ');
variable idelta : integer := 0;
variable iowait : integer := 0;
variable txcrc,rxcrc : slv16 := (others=>'0');
variable txlist : txlist_array_type := (others=>slv9_zero);
variable ntxlist : natural := 0;
variable datlist : datlist_array_type := (others=>slv16_zero);
variable ndatlist : natural := 0;
-- read command line helpers ------------------------------------
procedure get_cmd_ea ( -- ---- get_cmd_ea -----------
L : inout line;
picmd : out slv8) is
variable cname : string(1 to 4) := (others=>' ');
variable ival : natural;
variable lok : boolean;
variable cmd : slv3;
variable dat : slv8;
begin
readword_ea(L, cname);
ival := 0;
readoptchar(L, ',', lok);
if lok then
readint_ea(L, ival, 0, 31);
end if;
case cname is
when "rreg" => cmd := c_rlink_cmd_rreg;
when "rblk" => cmd := c_rlink_cmd_rblk;
when "wreg" => cmd := c_rlink_cmd_wreg;
when "wblk" => cmd := c_rlink_cmd_wblk;
when "labo" => cmd := c_rlink_cmd_labo;
when "attn" => cmd := c_rlink_cmd_attn;
when "init" => cmd := c_rlink_cmd_init;
when others =>
report "unknown cmd code" severity failure;
end case;
dat := (others=>'0');
dat(c_rlink_cmd_rbf_seq) := slv(to_unsigned(ival,5));
dat(c_rlink_cmd_rbf_code) := cmd;
picmd := dat;
end procedure get_cmd_ea;
procedure get_seq_ea ( -- ---- get_seq_ea -----------
L : inout line;
pcode : in slv3;
picmd : out slv8) is
variable ival : natural;
variable dat : slv8;
begin
readint_ea(L, ival, 0, 31);
dat := (others=>'0');
dat(c_rlink_cmd_rbf_seq) := slv(to_unsigned(ival,5));
dat(c_rlink_cmd_rbf_code) := pcode;
picmd := dat;
end procedure get_seq_ea;
-- tx helpers ----------------------------------------------------
procedure do_tx9 (data : in slv9) is -- ---- do_tx9 -------------
begin
txlist(ntxlist) := data;
ntxlist := ntxlist + 1;
end procedure do_tx9;
procedure do_tx8 (data : in slv8) is -- ---- do_tx8 -------------
begin
do_tx9('0' & data);
txcrc := crc16_update_tbl(txcrc, data);
end procedure do_tx8;
procedure do_tx16 (data : in slv16) is -- ---- do_tx16 ----------
begin
do_tx8(data( f_byte0));
do_tx8(data(f_byte1));
end procedure do_tx16;
procedure do_txcrc is -- ---- do_txcrc -------------
begin
do_tx9('0' & txcrc(f_byte0));
do_tx9('0' & txcrc(f_byte1));
end procedure do_txcrc;
procedure do_txsop is -- ---- do_txsop -------------
begin
do_tx9(c_rlink_dat_sop);
txcrc := (others=>'0');
end procedure do_txsop;
procedure do_txeop is -- ---- do_txeop -------------
begin
do_tx9(c_rlink_dat_eop);
end procedure do_txeop;
procedure do_txc (picmd : in slv8) is -- ---- do_txc -------------
begin
do_tx8(picmd);
do_txcrc;
end procedure do_txc;
procedure do_txca ( -- ---- do_txca --------------
picmd : in slv8;
piaddr : in slv16) is
begin
do_tx8(picmd);
do_tx16(piaddr);
do_txcrc;
end procedure do_txca;
procedure do_txcad ( -- ---- do_txcad -------------
picmd : in slv8;
piaddr : in slv16;
pidata : in slv16) is
begin
do_tx8(picmd);
do_tx16(piaddr);
do_tx16(pidata);
do_txcrc;
end procedure do_txcad;
procedure do_txblks ( -- ---- do_txblks ------------
pnblk : in natural;
pstart : in slv16) is
variable lidata : slv16;
begin
lidata := pstart;
for i in 1 to pnblk loop
do_tx16(lidata);
lidata := slv(unsigned(lidata) + 1);
end loop;
end procedure do_txblks;
-- rx helpers ----------------------------------------------------
procedure checkmiss_rx is -- ---- checkmiss_rx ---------
begin
if sv_rxind < sv_nrxlist then
for i in sv_rxind to sv_nrxlist-1 loop
writetimestamp(oline, CLK_CYCLE, ": moni ");
write(oline, string'(" FAIL MISSING DATA="));
write(oline, sv_rxlist(i)(d_f_cflag));
write(oline, string'(" "));
write(oline, sv_rxlist(i)(f_byte0));
writeline(output, oline);
end loop;
end if;
end procedure checkmiss_rx;
procedure do_rx9 (data : in slv9) is -- ---- do_rx9 -------------
begin
sv_rxlist(sv_nrxlist) := data;
sv_nrxlist := sv_nrxlist + 1;
end procedure do_rx9;
procedure do_rx8 (data : in slv8) is -- ---- do_rx8 -------------
begin
if not rxlabo then
do_rx9('0' & data);
rxcrc := crc16_update_tbl(rxcrc, data);
end if;
end procedure do_rx8;
procedure do_rx16 (data : in slv16) is -- ---- do_rx16 ----------
begin
do_rx8(data(f_byte0));
do_rx8(data(f_byte1));
end procedure do_rx16;
procedure do_rxattn is -- ---- do_rxattn ------------
begin
do_rx9(c_rlink_dat_attn);
rxcrc := (others=>'0');
end procedure do_rxattn;
procedure do_rxcrc is -- ---- do_rxcrc -------------
begin
if not rxlabo then
do_rx9('0' & rxcrc(f_byte0));
do_rx9('0' & rxcrc(f_byte1));
end if;
end procedure do_rxcrc;
procedure do_rxsop is -- ---- do_rxsop -------------
begin
checkmiss_rx;
sv_nrxlist := 0;
sv_rxind := 0;
rxcrc := (others=>'0');
do_rx9(c_rlink_dat_sop);
end procedure do_rxsop;
procedure do_rxeop is -- ---- do_rxeop -------------
begin
do_rx9(c_rlink_dat_eop);
end procedure do_rxeop;
procedure do_rxcs ( -- ---- do_rxcs ----------
picmd : in slv8;
pistat : in slv8) is
begin
do_rx8(picmd);
do_rx8(pistat);
do_rxcrc;
end procedure do_rxcs;
procedure do_rxcds ( -- ---- do_rxcds ----------
picmd : in slv8;
pidata : in slv16;
pistat : in slv8) is
begin
do_rx8(picmd);
do_rx16(pidata);
do_rx8(pistat);
do_rxcrc;
end procedure do_rxcds;
procedure do_rxcbs ( -- ---- do_rxcbs ----------
picmd : in slv8;
pibabo : in slv8;
pistat : in slv8) is
begin
do_rx8(picmd);
do_rx8(pibabo);
do_rx8(pistat);
do_rxcrc;
end procedure do_rxcbs;
procedure do_rxrbeg ( -- ---- do_rxrbeg -------------
picmd : in slv8;
pnblk : in natural) is
begin
do_rx8(picmd);
do_rx16(slv(to_unsigned(pnblk,16)));
end procedure do_rxrbeg;
procedure do_rxrend ( -- ---- do_rxrend -------------
pnblk : in natural;
pistat : in slv8) is
begin
do_rx16(slv(to_unsigned(pnblk,16)));
do_rx8(pistat);
do_rxcrc;
end procedure do_rxrend;
procedure do_rxblks ( -- ---- do_rxblks ------------
pnblk : in natural;
pstart : in slv16) is
variable lidata : slv16;
begin
lidata := pstart;
for i in 1 to pnblk loop
do_rx16(lidata);
lidata := slv(unsigned(lidata) + 1);
end loop;
end procedure do_rxblks;
begin
SB_CNTL <= (others=>'0');
wait for clock_offset - setup_time;
file_loop: while not endfile(fstim) loop
readline (fstim, iline);
readcomment(iline, ok);
next file_loop when ok;
readword(iline, dname, ok);
if ok then
case dname is
when ".reset" => -- .reset
write(oline, string'(".reset"));
writeline(output, oline);
RESET <= '1';
wait for clock_period;
RESET <= '0';
wait for 9*clock_period;
when ".rlmon" => -- .rlmon
read_ea(iline, ien);
SB_CNTL(sbcntl_sbf_rlmon) <= ien;
wait for 2*clock_period; -- wait for monitor to start
when ".rlbmo" => -- .rlbmo
read_ea(iline, ien);
SB_CNTL(sbcntl_sbf_rlbmon) <= ien;
wait for 2*clock_period; -- wait for monitor to start
when ".rbmon" => -- .rbmon
read_ea(iline, ien);
SB_CNTL(sbcntl_sbf_rbmon) <= ien;
wait for 2*clock_period; -- wait for monitor to start
when ".wait " => -- .wait
read_ea(iline, idelta);
wait for idelta*clock_period;
when ".iowt " => -- .iowt
read_ea(iline, iowait);
idelta := iowait;
while idelta > 0 loop -- until time has expired
if TXRXACT = '1' then -- if any io activity
idelta := iowait; -- restart timer
else
idelta := idelta - 1; -- otherwise count down time
end if;
wait for clock_period;
end loop;
when ".attn " => -- .attn
read_ea(iline, iattn);
RB_LAM_TBENCH <= iattn; -- pulse attn lines
wait for clock_period; -- for 1 clock
RB_LAM_TBENCH <= (others=>'0');
when "txsop " => -- txsop send sop
do_txsop;
when "txeop " => -- txeop send eop
do_txeop;
when "txnak " => -- txnak send nak
do_tx9(c_rlink_dat_nak);
when "txattn" => -- txattn send attn
do_tx9(c_rlink_dat_attn);
when "tx8 " => -- tx8 send 8 bit value
readgen_ea(iline, idat8, 2);
do_tx8(idat8);
when "tx16 " => -- tx16 send 16 bit value
readgen_ea(iline, idata, 2);
do_tx16(idata);
when "txblk " => -- txblk send n 16 bit values
read_ea(iline, nblk);
readgen_ea(iline, idata, 2);
do_txblks(nblk, idata);
when "txcrc " => -- txcrc send crc
do_txcrc;
when "txbad " => -- txbad send bad crc
do_tx9('0' & (not txcrc(f_byte0)));
do_tx9('0' & (not txcrc(f_byte1)));
when "txc " => -- txc send: cmd crc
get_cmd_ea(iline, icmd);
do_txc(icmd);
when "txca " => -- txc send: cmd addr crc
get_cmd_ea(iline, icmd);
readgen_ea(iline, iaddr, 2);
do_txca(icmd, iaddr);
when "txcad " => -- txc send: cmd addr data crc
get_cmd_ea(iline, icmd);
readgen_ea(iline, iaddr, 2);
readgen_ea(iline, idata, 2);
do_txcad(icmd, iaddr, idata);
when "txcac " => -- txc send: cmd addr cnt crc
get_cmd_ea(iline, icmd);
readgen_ea(iline, iaddr, 2);
readgen_ea(iline, icnt, 2);
do_txcad(icmd, iaddr, icnt);
when "txoof " => -- txoof send out-of-frame symbol
readgen_ea(iline, txlist(0), 2);
ntxlist := 1;
when "rxsop " => -- rxsop expect sop
do_rxsop;
when "rxeop " => -- rxeop expect eop
do_rxeop;
when "rxnak " => -- rxnak expect nak
do_rx9(c_rlink_dat_nak);
when "rxattn" => -- rxattn expect attn
do_rxattn;
when "rx8 " => -- rx8 expect 8 bit value
readgen_ea(iline, idat8, 2);
do_rx8(idat8);
when "rx16 " => -- rx16 expect 16 bit value
readgen_ea(iline, idata, 2);
do_rx16(idata);
when "rxblk " => -- rxblk expect n 16 bit values
read_ea(iline, nblk);
readgen_ea(iline, idata, 2);
do_rxblks(nblk, idata);
when "rxcrc " => -- rxcrc expect crc
do_rxcrc;
when "rxcs " => -- rxcs expect: cmd stat crc
get_cmd_ea(iline, icmd);
readgen_ea(iline, istat, 2);
do_rxcs(icmd, istat);
when "rxcds " => -- rxcsd expect: cmd data stat crc
get_cmd_ea(iline, icmd);
readgen_ea(iline, idata, 2);
readgen_ea(iline, istat, 2);
do_rxcds(icmd, idata, istat);
when "rxcbs " => -- rxcsd expect: cmd babo stat crc
get_cmd_ea(iline, icmd);
readgen_ea(iline, ibabo, 2);
readgen_ea(iline, istat, 2);
do_rxcbs(icmd, ibabo, istat);
when "rxrbeg" => -- rxrbeg expect: cmd - cl ch
get_cmd_ea(iline, icmd);
read_ea(iline, nblk);
do_rxrbeg(icmd, nblk);
when "rxrend" => -- rxrend expect: dcl dch - stat - crc
read_ea(iline, nblk);
readgen_ea(iline, istat, 2);
do_rxrend(nblk, istat);
when "rxoof " => -- rxoof expect: out-of-frame symbol
readgen_ea(iline, ioof, 2);
sv_rxlist(sv_nrxlist) := ioof;
sv_nrxlist := sv_nrxlist + 1;
when "anmsg " => -- anmsg
readgen_ea(iline, idata, 2); -- apat
do_rxattn;
do_rx16(idata);
do_rxcrc;
do_rxeop;
when "sop " => -- sop
do_rxsop;
do_txsop;
rxlabo := false;
when "eop " => -- eop
do_rxeop;
do_txeop;
when "rreg " => -- rreg seq addr data stat
get_seq_ea(iline, c_rlink_cmd_rreg, icmd); -- seq
readgen_ea(iline, iaddr, 2); -- addr
readgen_ea(iline, idata, 2); -- data
readgen_ea(iline, istat, 2); -- stat
do_rxcds(icmd, idata, istat); -- rx: cmd dl sh stat ccsr
do_txca (icmd, iaddr); -- tx: cmd al ah ccsr
when "wreg " => -- wreg seq addr data stat
get_seq_ea(iline, c_rlink_cmd_wreg, icmd); -- seq
readgen_ea(iline, iaddr, 2); -- addr
readgen_ea(iline, idata, 2); -- data
readgen_ea(iline, istat, 2); -- stat
do_rxcs (icmd, istat); -- rx: cmd stat ccsr
do_txcad(icmd, iaddr, idata); -- tx: cmd al ah dl dh ccsr
when "init " => -- init seq addr data stat
get_seq_ea(iline, c_rlink_cmd_init, icmd); -- seq
readgen_ea(iline, iaddr, 2); -- addr
readgen_ea(iline, idata, 2); -- data
readgen_ea(iline, istat, 2); -- stat
do_rxcs (icmd, istat); -- rx: cmd stat ccsr
do_txcad(icmd, iaddr, idata); -- tx: cmd al ah dl dh ccsr
when "attn " => -- attn seq data stat
get_seq_ea(iline, c_rlink_cmd_attn, icmd); -- seq
readgen_ea(iline, idata, 2); -- data
readgen_ea(iline, istat, 2); -- stat
do_rxcds (icmd, idata, istat); -- rx: cmd dl dh stat ccsr
do_txc (icmd); -- tx: cmd ccsr
when "labo " => -- labo seq babo stat
get_seq_ea(iline, c_rlink_cmd_labo, icmd); -- seq
readgen_ea(iline, ibabo, 2); -- babo
readgen_ea(iline, istat, 2); -- stat
do_rxcbs (icmd, ibabo, istat); -- rx: cmd dl stat ccsr
do_txc (icmd); -- tx: cmd ccsr
rxlabo := ibabo /= x"00"; -- set rxlabo flag
when "rblks " => -- rblks seq addr nblk data stat
get_seq_ea(iline, c_rlink_cmd_rblk, icmd); -- seq
readgen_ea(iline, iaddr, 2); -- addr
read_ea(iline, nblk); -- nblk
readgen_ea(iline, idata, 2); -- start
readgen_ea(iline, istat, 2); -- stat
do_rxrbeg(icmd, nblk); --rx: cmd cl ch
do_rxblks(nblk, idata); -- nblk*(dl dh)
do_rxrend(nblk, istat); -- dcl dch stat ccrc
do_txcad(icmd, iaddr, -- tx: cmd al ah cl ch ccrc
slv(to_unsigned(nblk,16)));
when "wblks " => -- wblks seq addr nblk data stat
get_seq_ea(iline, c_rlink_cmd_wblk, icmd); -- seq
readgen_ea(iline, iaddr, 2); -- addr
read_ea(iline, nblk); -- nblk
readgen_ea(iline, idata, 2); -- start
readgen_ea(iline, istat, 2); -- stat
do_rxcds(icmd, -- rx: cmd dcl dch stat ccsr
slv(to_unsigned(nblk,16)),
istat);
do_txcad(icmd, iaddr, -- tx: cmd al ah cl ch ccrc
slv(to_unsigned(nblk,16)));
do_txblks(nblk, idata); -- nblk*(dl dh)
do_txcrc; -- dcrc
when "rblkd " => -- rblkd seq addr ndone stat
get_seq_ea(iline, c_rlink_cmd_rblk, icmd); -- seq
readgen_ea(iline, iaddr, 2); -- addr
read_ea(iline, ndone); -- ndone
readgen_ea(iline, istat, 2); -- stat
do_rxrbeg(icmd, ndatlist); --rx: cmd cl ch
for i in 0 to ndatlist-1 loop
do_rx16(datlist(i)); -- nblk*(dl dh)
end loop; -- i
do_rxrend(ndone, istat); -- dcl dch stat ccrc
do_txcad(icmd, iaddr, -- tx: cmd al ah cl ch ccrc
slv(to_unsigned(ndatlist,16)));
when "wblkd " => -- wblkd seq addr ndone stat
get_seq_ea(iline, c_rlink_cmd_wblk, icmd); -- seq
readgen_ea(iline, iaddr, 2); -- addr
read_ea(iline, ndone); -- ndone
readgen_ea(iline, istat, 2); -- stat
do_rxcds(icmd, -- rx: cmd dcl dch stat ccsr
slv(to_unsigned(ndone,16)),
istat);
do_txcad(icmd, iaddr, -- tx: cmd al ah cl ch ccrc
slv(to_unsigned(ndatlist,16)));
for i in 0 to ndatlist-1 loop
do_tx16(datlist(i)); -- nblk*(dl dh)
end loop; -- i
do_txcrc; -- dcrc
when ".dclr " => -- .dclr
ndatlist := 0;
when ".dwrd " => -- .dwrd data
readgen_ea(iline, idata, 2);
datlist(ndatlist) := idata;
ndatlist := ndatlist + 1;
when ".dseq " => -- .dseq nblk start
read_ea(iline, nblk);
readgen_ea(iline, idata, 2);
for i in 1 to nblk loop
datlist(ndatlist) := idata;
ndatlist := ndatlist + 1;
idata := slv(unsigned(idata) + 1);
end loop;
when others => -- bad command
write(oline, string'("?? unknown command: "));
write(oline, dname);
writeline(output, oline);
report "aborting" severity failure;
end case;
else
report "failed to find command" severity failure;
end if;
testempty_ea(iline);
next file_loop when ntxlist=0;
for i in 0 to ntxlist-1 loop
RL_DI <= txlist(i);
RL_ENA <= '1';
writetimestamp(oline, CLK_CYCLE, ": stim");
write(oline, txlist(i)(d_f_cflag), right, 3);
write(oline, txlist(i)(d_f_data), right, 9);
if txlist(i)(d_f_cflag) = '1' then
case txlist(i) is
when c_rlink_dat_sop =>
write(oline, string'(" (sop) "));
when c_rlink_dat_eop =>
write(oline, string'(" (eop) "));
when c_rlink_dat_nak =>
write(oline, string'(" (nak) "));
when c_rlink_dat_attn =>
write(oline, string'(" (attn)"));
when others =>
write(oline, string'(" (????)"));
end case;
end if;
writeline(output, oline);
wait for clock_period;
while RL_BUSY = '1' loop
wait for clock_period;
end loop;
RL_ENA <= '0';
end loop; -- i
ntxlist := 0;
end loop; -- file fstim
wait for 50*clock_period;
checkmiss_rx;
writetimestamp(oline, CLK_CYCLE, ": DONE ");
writeline(output, oline);
CLK_STOP <= '1';
wait; -- suspend proc_stim forever
-- clock is stopped, sim will end
end process proc_stim;
proc_moni: process
variable oline : line;
begin
loop
wait until rising_edge(CLK);
wait for c2out_time;
if RL_VAL = '1' then
writetimestamp(oline, CLK_CYCLE, ": moni");
write(oline, RL_DO(d_f_cflag), right, 3);
write(oline, RL_DO(d_f_data), right, 9);
if RL_DO(d_f_cflag) = '1' then
case RL_DO is
when c_rlink_dat_sop =>
write(oline, string'(" (sop) "));
when c_rlink_dat_eop =>
write(oline, string'(" (eop) "));
when c_rlink_dat_nak =>
write(oline, string'(" (nak) "));
when c_rlink_dat_attn =>
write(oline, string'(" (attn)"));
when others =>
write(oline, string'(" (????)"));
end case;
end if;
if sv_nrxlist > 0 then
write(oline, string'(" CHECK"));
if sv_rxind < sv_nrxlist then
if RL_DO = sv_rxlist(sv_rxind) then
write(oline, string'(" OK"));
else
write(oline, string'(" FAIL, exp="));
write(oline, sv_rxlist(sv_rxind)(d_f_cflag), right, 2);
write(oline, sv_rxlist(sv_rxind)(d_f_data), right, 9);
end if;
sv_rxind := sv_rxind + 1;
else
write(oline, string'(" FAIL, UNEXPECTED"));
end if;
end if;
writeline(output, oline);
end if;
end loop;
end process proc_moni;
end sim;