-- $Id: rlink_mon.vhd 609 2014-12-07 19:35:25Z mueller $
|
-- $Id: rlink_mon.vhd 609 2014-12-07 19:35:25Z mueller $
|
--
|
--
|
-- Copyright 2007-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
-- Copyright 2007-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
--
|
--
|
-- This program is free software; you may redistribute and/or modify it under
|
-- This program is free software; you may redistribute and/or modify it under
|
-- the terms of the GNU General Public License as published by the Free
|
-- the terms of the GNU General Public License as published by the Free
|
-- Software Foundation, either version 2, or at your option any later version.
|
-- Software Foundation, either version 2, or at your option any later version.
|
--
|
--
|
-- This program is distributed in the hope that it will be useful, but
|
-- This program is distributed in the hope that it will be useful, but
|
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
|
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
|
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
-- for complete details.
|
-- for complete details.
|
--
|
--
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
-- Module Name: rlink_mon - sim
|
-- Module Name: rlink_mon - sim
|
-- Description: rlink monitor (for tb's)
|
-- Description: rlink monitor (for tb's)
|
--
|
--
|
-- Dependencies: -
|
-- Dependencies: -
|
-- Test bench: -
|
-- Test bench: -
|
-- Tool versions: xst 8.2-17.7; ghdl 0.18-0.31
|
-- Tool versions: xst 8.2-17.7; ghdl 0.18-0.31
|
--
|
--
|
-- Revision History:
|
-- Revision History:
|
-- Date Rev Version Comment
|
-- Date Rev Version Comment
|
-- 2014-11-08 602 4.0.2 annotate clobber commas
|
-- 2014-11-08 602 4.0.2 annotate clobber commas
|
-- 2014-10-25 599 4.0.1 use writeoptint()
|
-- 2014-10-25 599 4.0.1 use writeoptint()
|
-- 2014-10-12 596 4.0 adopt to new escaping, better 8 bit output
|
-- 2014-10-12 596 4.0 adopt to new escaping, better 8 bit output
|
-- 2011-12-23 444 3.1 CLK_CYCLE now integer
|
-- 2011-12-23 444 3.1 CLK_CYCLE now integer
|
-- 2011-11-19 427 3.0.2 now numeric_std clean
|
-- 2011-11-19 427 3.0.2 now numeric_std clean
|
-- 2010-12-24 347 3.0.1 rename: CP_*->RL->*
|
-- 2010-12-24 347 3.0.1 rename: CP_*->RL->*
|
-- 2010-12-22 346 3.0 renamed rritb_cpmon -> rlink_mon
|
-- 2010-12-22 346 3.0 renamed rritb_cpmon -> rlink_mon
|
-- 2010-06-11 303 2.5.1 fix data9 assignment, always proper width now
|
-- 2010-06-11 303 2.5.1 fix data9 assignment, always proper width now
|
-- 2010-06-07 302 2.5 use sop/eop framing instead of soc+chaining
|
-- 2010-06-07 302 2.5 use sop/eop framing instead of soc+chaining
|
-- 2008-03-24 129 1.0.1 CLK_CYCLE now 31 bits
|
-- 2008-03-24 129 1.0.1 CLK_CYCLE now 31 bits
|
-- 2007-09-09 81 1.0 Initial version
|
-- 2007-09-09 81 1.0 Initial version
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
|
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
use ieee.numeric_std.all;
|
use ieee.numeric_std.all;
|
use ieee.std_logic_textio.all;
|
use ieee.std_logic_textio.all;
|
use std.textio.all;
|
use std.textio.all;
|
|
|
use work.slvtypes.all;
|
use work.slvtypes.all;
|
use work.simlib.all;
|
use work.simlib.all;
|
use work.rlinklib.all;
|
use work.rlinklib.all;
|
use work.comlib.all;
|
use work.comlib.all;
|
|
|
entity rlink_mon is -- rlink monitor
|
entity rlink_mon is -- rlink monitor
|
generic (
|
generic (
|
DWIDTH : positive := 9); -- data port width (8 or 9)
|
DWIDTH : positive := 9); -- data port width (8 or 9)
|
port (
|
port (
|
CLK : in slbit; -- clock
|
CLK : in slbit; -- clock
|
CLK_CYCLE : in integer := 0; -- clock cycle number
|
CLK_CYCLE : in integer := 0; -- clock cycle number
|
ENA : in slbit := '1'; -- enable monitor output
|
ENA : in slbit := '1'; -- enable monitor output
|
RL_DI : in slv(DWIDTH-1 downto 0); -- rlink: data in
|
RL_DI : in slv(DWIDTH-1 downto 0); -- rlink: data in
|
RL_ENA : in slbit; -- rlink: data enable
|
RL_ENA : in slbit; -- rlink: data enable
|
RL_BUSY : in slbit; -- rlink: data busy
|
RL_BUSY : in slbit; -- rlink: data busy
|
RL_DO : in slv(DWIDTH-1 downto 0); -- rlink: data out
|
RL_DO : in slv(DWIDTH-1 downto 0); -- rlink: data out
|
RL_VAL : in slbit; -- rlink: data valid
|
RL_VAL : in slbit; -- rlink: data valid
|
RL_HOLD : in slbit -- rlink: data hold
|
RL_HOLD : in slbit -- rlink: data hold
|
);
|
);
|
end rlink_mon;
|
end rlink_mon;
|
|
|
|
|
architecture sim of rlink_mon is
|
architecture sim of rlink_mon is
|
|
|
begin
|
begin
|
|
|
assert DWIDTH=8 or DWIDTH=9
|
assert DWIDTH=8 or DWIDTH=9
|
report "assert(DWIDTH=8 or DWIDTH=9)" severity failure;
|
report "assert(DWIDTH=8 or DWIDTH=9)" severity failure;
|
|
|
proc_moni: process
|
proc_moni: process
|
variable oline : line;
|
variable oline : line;
|
variable nbusy : integer := 0;
|
variable nbusy : integer := 0;
|
variable nhold : integer := 0;
|
variable nhold : integer := 0;
|
variable edatarx : boolean := false;
|
variable edatarx : boolean := false;
|
variable edatatx : boolean := false;
|
variable edatatx : boolean := false;
|
|
|
procedure write_val(L: inout line;
|
procedure write_val(L: inout line;
|
data: in slv(DWIDTH-1 downto 0);
|
data: in slv(DWIDTH-1 downto 0);
|
nwait: in integer;
|
nwait: in integer;
|
txt1: in string(1 to 2);
|
txt1: in string(1 to 2);
|
txt2: in string;
|
txt2: in string;
|
edata: in boolean) is
|
edata: in boolean) is
|
variable data9 : slv9 := (others=>'0');
|
variable data9 : slv9 := (others=>'0');
|
variable optxt : string(1 to 8) := ": ??rx ";
|
variable optxt : string(1 to 8) := ": ??rx ";
|
begin
|
begin
|
|
|
if DWIDTH = 9 then
|
if DWIDTH = 9 then
|
optxt(3 to 4) := "rl";
|
optxt(3 to 4) := "rl";
|
else
|
else
|
optxt(3 to 4) := "r8";
|
optxt(3 to 4) := "r8";
|
end if;
|
end if;
|
optxt(5 to 6) := txt1;
|
optxt(5 to 6) := txt1;
|
writetimestamp(L, CLK_CYCLE, optxt);
|
writetimestamp(L, CLK_CYCLE, optxt);
|
|
|
if DWIDTH = 9 then
|
if DWIDTH = 9 then
|
write(L, data(data'left), right, 1);
|
write(L, data(data'left), right, 1);
|
else
|
else
|
write(L, string'(" "));
|
write(L, string'(" "));
|
end if;
|
end if;
|
|
|
write(L, data(7 downto 0), right, 9);
|
write(L, data(7 downto 0), right, 9);
|
writeoptint(L, txt2, nwait);
|
writeoptint(L, txt2, nwait);
|
|
|
if DWIDTH=9 and data(data'left)='1' then
|
if DWIDTH=9 and data(data'left)='1' then
|
-- a copy to data9 needed to allow following case construct
|
-- a copy to data9 needed to allow following case construct
|
-- using data directly gives a 'subtype is not locally static' error
|
-- using data directly gives a 'subtype is not locally static' error
|
data9 := (others=>'0');
|
data9 := (others=>'0');
|
data9(data'range) := data;
|
data9(data'range) := data;
|
write(L, string'(" comma"));
|
write(L, string'(" comma"));
|
case data9 is
|
case data9 is
|
when c_rlink_dat_sop => write(L, string'(" sop"));
|
when c_rlink_dat_sop => write(L, string'(" sop"));
|
when c_rlink_dat_eop => write(L, string'(" eop"));
|
when c_rlink_dat_eop => write(L, string'(" eop"));
|
when c_rlink_dat_nak => write(L, string'(" nak"));
|
when c_rlink_dat_nak => write(L, string'(" nak"));
|
when c_rlink_dat_attn => write(L, string'(" attn"));
|
when c_rlink_dat_attn => write(L, string'(" attn"));
|
when others => write(L, string'(" clobber|oob"));
|
when others => write(L, string'(" clobber|oob"));
|
end case;
|
end case;
|
end if;
|
end if;
|
|
|
if DWIDTH = 8 then
|
if DWIDTH = 8 then
|
|
|
if edata then
|
if edata then
|
write(L, string'(" edata"));
|
write(L, string'(" edata"));
|
if data(c_cdata_edf_pref) /= c_cdata_ed_pref or
|
if data(c_cdata_edf_pref) /= c_cdata_ed_pref or
|
(not data(c_cdata_edf_eci)) /= data(c_cdata_edf_ec) then
|
(not data(c_cdata_edf_eci)) /= data(c_cdata_edf_ec) then
|
write(L, string'(" FAIL: bad format"));
|
write(L, string'(" FAIL: bad format"));
|
else
|
else
|
write(L, string'(" ec="));
|
write(L, string'(" ec="));
|
write(L, data(c_cdata_edf_ec));
|
write(L, data(c_cdata_edf_ec));
|
data9 := (others=>'0');
|
data9 := (others=>'0');
|
data9(8) := '1';
|
data9(8) := '1';
|
data9(c_cdata_edf_ec) := data(c_cdata_edf_ec);
|
data9(c_cdata_edf_ec) := data(c_cdata_edf_ec);
|
case data9 is
|
case data9 is
|
when c_rlink_dat_sop => write(L, string'(" (sop)"));
|
when c_rlink_dat_sop => write(L, string'(" (sop)"));
|
when c_rlink_dat_eop => write(L, string'(" (eop)"));
|
when c_rlink_dat_eop => write(L, string'(" (eop)"));
|
when c_rlink_dat_nak => write(L, string'(" (nak)"));
|
when c_rlink_dat_nak => write(L, string'(" (nak)"));
|
when c_rlink_dat_attn => write(L, string'(" (attn)"));
|
when c_rlink_dat_attn => write(L, string'(" (attn)"));
|
when "100000" & c_cdata_ec_xon => write(L, string'(" (xon)"));
|
when "100000" & c_cdata_ec_xon => write(L, string'(" (xon)"));
|
when "100000" & c_cdata_ec_xoff => write(L, string'(" (xoff)"));
|
when "100000" & c_cdata_ec_xoff => write(L, string'(" (xoff)"));
|
when "100000" & c_cdata_ec_fill => write(L, string'(" (fill)"));
|
when "100000" & c_cdata_ec_fill => write(L, string'(" (fill)"));
|
when "100000" & c_cdata_ec_esc => write(L, string'(" (esc)"));
|
when "100000" & c_cdata_ec_esc => write(L, string'(" (esc)"));
|
when others =>
|
when others =>
|
write(L, string'(" FAIL: bad ec"));
|
write(L, string'(" FAIL: bad ec"));
|
end case;
|
end case;
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
if data = c_cdata_escape then
|
if data = c_cdata_escape then
|
write(L, string'(" escape"));
|
write(L, string'(" escape"));
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
writeline(output, L);
|
writeline(output, L);
|
end procedure write_val;
|
end procedure write_val;
|
|
|
begin
|
begin
|
|
|
loop
|
loop
|
|
|
if ENA='0' then -- if disabled
|
if ENA='0' then -- if disabled
|
wait until ENA='1'; -- stall process till enabled
|
wait until ENA='1'; -- stall process till enabled
|
end if;
|
end if;
|
|
|
wait until rising_edge(CLK); -- check at end of clock cycle
|
wait until rising_edge(CLK); -- check at end of clock cycle
|
|
|
if RL_ENA = '1' then
|
if RL_ENA = '1' then
|
if RL_BUSY = '1' then
|
if RL_BUSY = '1' then
|
nbusy := nbusy + 1;
|
nbusy := nbusy + 1;
|
else
|
else
|
write_val(oline, RL_DI, nbusy, "rx", " nbusy=", edatarx);
|
write_val(oline, RL_DI, nbusy, "rx", " nbusy=", edatarx);
|
edatarx := RL_DI=c_cdata_escape;
|
edatarx := RL_DI=c_cdata_escape;
|
nbusy := 0;
|
nbusy := 0;
|
end if;
|
end if;
|
else
|
else
|
nbusy := 0;
|
nbusy := 0;
|
end if;
|
end if;
|
|
|
if RL_VAL = '1' then
|
if RL_VAL = '1' then
|
if RL_HOLD = '1' then
|
if RL_HOLD = '1' then
|
nhold := nhold + 1;
|
nhold := nhold + 1;
|
else
|
else
|
write_val(oline, RL_DO, nhold, "tx", " nhold=", edatatx);
|
write_val(oline, RL_DO, nhold, "tx", " nhold=", edatatx);
|
edatatx := RL_DO=c_cdata_escape;
|
edatatx := RL_DO=c_cdata_escape;
|
nhold := 0;
|
nhold := 0;
|
end if;
|
end if;
|
else
|
else
|
nhold := 0;
|
nhold := 0;
|
end if;
|
end if;
|
|
|
end loop;
|
end loop;
|
end process proc_moni;
|
end process proc_moni;
|
|
|
end sim;
|
end sim;
|
|
|