-- $Id: tb_serport_uart_rxtx.vhd 444 2011-12-25 10:04:58Z mueller $
|
-- $Id: tb_serport_uart_rxtx.vhd 476 2013-01-26 22:23:53Z mueller $
|
--
|
--
|
-- Copyright 2007-2011 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
-- Copyright 2007-2011 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: tb_serport_uart_rxtx - sim
|
-- Module Name: tb_serport_uart_rxtx - sim
|
-- Description: Test bench for serport_uart_rxtx
|
-- Description: Test bench for serport_uart_rxtx
|
--
|
--
|
-- Dependencies: simlib/simclk
|
-- Dependencies: simlib/simclk
|
-- tbd_serport_uart_rxtx [UUT]
|
-- tbd_serport_uart_rxtx [UUT]
|
--
|
--
|
-- To test: serport_uart_rxtx
|
-- To test: serport_uart_rxtx
|
--
|
--
|
-- Target Devices: generic
|
-- Target Devices: generic
|
--
|
--
|
-- Verified (with tb_serport_uart_rxtx_stim.dat):
|
-- Verified (with tb_serport_uart_rxtx_stim.dat):
|
-- Date Rev Code ghdl ise Target Comment
|
-- Date Rev Code ghdl ise Target Comment
|
-- 2007-11-02 93 _tsim 0.26 8.2.03 I34 xc3s1000 d:ok
|
-- 2007-11-02 93 _tsim 0.26 8.2.03 I34 xc3s1000 d:ok
|
-- 2007-10-21 91 _ssim 0.26 8.1.03 I27 xc3s1000 c:ok
|
-- 2007-10-21 91 _ssim 0.26 8.1.03 I27 xc3s1000 c:ok
|
-- 2007-10-21 91 - 0.26 - - c:ok
|
-- 2007-10-21 91 - 0.26 - - c:ok
|
-- 2007-10-14 89 - 0.26 - - c:ok
|
-- 2007-10-14 89 - 0.26 - - c:ok
|
-- 2007-10-12 88 _ssim 0.26 8.1.03 I27 xc3s1000 c:ok
|
-- 2007-10-12 88 _ssim 0.26 8.1.03 I27 xc3s1000 c:ok
|
-- 2007-10-12 88 - 0.26 - - c:ok
|
-- 2007-10-12 88 - 0.26 - - c:ok
|
--
|
--
|
-- Revision History:
|
-- Revision History:
|
-- Date Rev Version Comment
|
-- Date Rev Version Comment
|
-- 2011-12-23 444 1.2 use new simclk/simclkcnt
|
-- 2011-12-23 444 1.2 use new simclk/simclkcnt
|
-- 2011-10-22 417 1.1.3 now numeric_std clean
|
-- 2011-10-22 417 1.1.3 now numeric_std clean
|
-- 2010-04-24 281 1.1.2 use direct instatiation for tbd_
|
-- 2010-04-24 281 1.1.2 use direct instatiation for tbd_
|
-- 2008-03-24 129 1.1.1 CLK_CYCLE now 31 bits
|
-- 2008-03-24 129 1.1.1 CLK_CYCLE now 31 bits
|
-- 2007-10-21 91 1.1 now use 'send' command, self-checking (FAIL's)
|
-- 2007-10-21 91 1.1 now use 'send' command, self-checking (FAIL's)
|
-- 2007-10-12 88 1.0.1 avoid ieee.std_logic_unsigned, use cast to unsigned
|
-- 2007-10-12 88 1.0.1 avoid ieee.std_logic_unsigned, use cast to unsigned
|
-- 2007-08-27 76 1.0 Initial version
|
-- 2007-08-27 76 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.serport.all;
|
use work.serportlib.all;
|
|
|
entity tb_serport_uart_rxtx is
|
entity tb_serport_uart_rxtx is
|
end tb_serport_uart_rxtx;
|
end tb_serport_uart_rxtx;
|
|
|
architecture sim of tb_serport_uart_rxtx is
|
architecture sim of tb_serport_uart_rxtx is
|
|
|
signal CLK : slbit := '0';
|
signal CLK : slbit := '0';
|
signal RESET : slbit := '0';
|
signal RESET : slbit := '0';
|
signal CLKDIV : slv13 := slv(to_unsigned(15, 13));
|
signal CLKDIV : slv13 := slv(to_unsigned(15, 13));
|
signal RXDATA : slv8 := (others=>'0');
|
signal RXDATA : slv8 := (others=>'0');
|
signal RXVAL : slbit := '0';
|
signal RXVAL : slbit := '0';
|
signal RXERR : slbit := '0';
|
signal RXERR : slbit := '0';
|
signal RXACT : slbit := '0';
|
signal RXACT : slbit := '0';
|
signal TXSD : slbit := '0';
|
signal TXSD : slbit := '0';
|
signal TXDATA : slv8 := (others=>'0');
|
signal TXDATA : slv8 := (others=>'0');
|
signal TXENA : slbit := '0';
|
signal TXENA : slbit := '0';
|
signal TXBUSY : slbit := '0';
|
signal TXBUSY : slbit := '0';
|
|
|
signal CLK_STOP : slbit := '0';
|
signal CLK_STOP : slbit := '0';
|
signal CLK_CYCLE : integer := 0;
|
signal CLK_CYCLE : integer := 0;
|
|
|
signal N_MON_VAL : slbit := '0';
|
signal N_MON_VAL : slbit := '0';
|
signal N_MON_DAT : slv8 := (others=>'0');
|
signal N_MON_DAT : slv8 := (others=>'0');
|
signal R_MON_VAL_1 : slbit := '0';
|
signal R_MON_VAL_1 : slbit := '0';
|
signal R_MON_DAT_1 : slv8 := (others=>'0');
|
signal R_MON_DAT_1 : slv8 := (others=>'0');
|
signal R_MON_VAL_2 : slbit := '0';
|
signal R_MON_VAL_2 : slbit := '0';
|
signal R_MON_DAT_2 : slv8 := (others=>'0');
|
signal R_MON_DAT_2 : slv8 := (others=>'0');
|
|
|
constant clock_period : time := 20 ns;
|
constant clock_period : time := 20 ns;
|
constant clock_offset : time := 200 ns;
|
constant clock_offset : time := 200 ns;
|
constant setup_time : time := 5 ns;
|
constant setup_time : time := 5 ns;
|
constant c2out_time : time := 10 ns;
|
constant c2out_time : time := 10 ns;
|
|
|
begin
|
begin
|
|
|
CLKGEN : simclk
|
CLKGEN : simclk
|
generic map (
|
generic map (
|
PERIOD => clock_period,
|
PERIOD => clock_period,
|
OFFSET => clock_offset)
|
OFFSET => clock_offset)
|
port map (
|
port map (
|
CLK => CLK,
|
CLK => CLK,
|
CLK_STOP => CLK_STOP
|
CLK_STOP => CLK_STOP
|
);
|
);
|
|
|
CLKCNT : simclkcnt port map (CLK => CLK, CLK_CYCLE => CLK_CYCLE);
|
CLKCNT : simclkcnt port map (CLK => CLK, CLK_CYCLE => CLK_CYCLE);
|
|
|
UUT : entity work.tbd_serport_uart_rxtx
|
UUT : entity work.tbd_serport_uart_rxtx
|
port map (
|
port map (
|
CLK => CLK,
|
CLK => CLK,
|
RESET => RESET,
|
RESET => RESET,
|
CLKDIV => CLKDIV,
|
CLKDIV => CLKDIV,
|
RXSD => TXSD,
|
RXSD => TXSD,
|
RXDATA => RXDATA,
|
RXDATA => RXDATA,
|
RXVAL => RXVAL,
|
RXVAL => RXVAL,
|
RXERR => RXERR,
|
RXERR => RXERR,
|
RXACT => RXACT,
|
RXACT => RXACT,
|
TXSD => TXSD,
|
TXSD => TXSD,
|
TXDATA => TXDATA,
|
TXDATA => TXDATA,
|
TXENA => TXENA,
|
TXENA => TXENA,
|
TXBUSY => TXBUSY
|
TXBUSY => TXBUSY
|
);
|
);
|
|
|
|
|
proc_stim: process
|
proc_stim: process
|
file fstim : text open read_mode is "tb_serport_uart_rxtx_stim";
|
file fstim : text open read_mode is "tb_serport_uart_rxtx_stim";
|
variable iline : line;
|
variable iline : line;
|
variable oline : line;
|
variable oline : line;
|
variable idelta : integer := 0;
|
variable idelta : integer := 0;
|
variable itxdata : slv8 := (others=>'0');
|
variable itxdata : slv8 := (others=>'0');
|
variable ok : boolean;
|
variable ok : boolean;
|
variable dname : string(1 to 6) := (others=>' ');
|
variable dname : string(1 to 6) := (others=>' ');
|
variable irate : integer := 16;
|
variable irate : integer := 16;
|
|
|
begin
|
begin
|
|
|
wait for clock_offset - setup_time;
|
wait for clock_offset - setup_time;
|
|
|
file_loop: while not endfile(fstim) loop
|
file_loop: while not endfile(fstim) loop
|
|
|
readline (fstim, iline);
|
readline (fstim, iline);
|
|
|
readcomment(iline, ok);
|
readcomment(iline, ok);
|
next file_loop when ok;
|
next file_loop when ok;
|
|
|
readword(iline, dname, ok);
|
readword(iline, dname, ok);
|
if ok then
|
if ok then
|
case dname is
|
case dname is
|
when ".reset" => -- .reset
|
when ".reset" => -- .reset
|
write(oline, string'(".reset"));
|
write(oline, string'(".reset"));
|
writeline(output, oline);
|
writeline(output, oline);
|
RESET <= '1';
|
RESET <= '1';
|
wait for clock_period;
|
wait for clock_period;
|
RESET <= '0';
|
RESET <= '0';
|
wait for 9*clock_period;
|
wait for 9*clock_period;
|
|
|
when ".wait " => -- .wait
|
when ".wait " => -- .wait
|
read_ea(iline, idelta);
|
read_ea(iline, idelta);
|
wait for idelta*clock_period;
|
wait for idelta*clock_period;
|
|
|
when ".rate " => -- .rate
|
when ".rate " => -- .rate
|
read_ea(iline, irate);
|
read_ea(iline, irate);
|
CLKDIV <= slv(to_unsigned(irate-1, 13));
|
CLKDIV <= slv(to_unsigned(irate-1, 13));
|
|
|
when "send " => -- send
|
when "send " => -- send
|
read_ea(iline, idelta);
|
read_ea(iline, idelta);
|
read_ea(iline, itxdata);
|
read_ea(iline, itxdata);
|
|
|
while TXBUSY='1' loop
|
while TXBUSY='1' loop
|
wait for clock_period;
|
wait for clock_period;
|
end loop;
|
end loop;
|
|
|
wait for idelta*clock_period;
|
wait for idelta*clock_period;
|
|
|
writetimestamp(oline, CLK_CYCLE, ": send ");
|
writetimestamp(oline, CLK_CYCLE, ": send ");
|
write(oline, itxdata, right, 10);
|
write(oline, itxdata, right, 10);
|
writeline(output, oline);
|
writeline(output, oline);
|
|
|
TXDATA <= itxdata;
|
TXDATA <= itxdata;
|
TXENA <= '1';
|
TXENA <= '1';
|
N_MON_VAL <= '1';
|
N_MON_VAL <= '1';
|
N_MON_DAT <= itxdata;
|
N_MON_DAT <= itxdata;
|
|
|
wait for clock_period;
|
wait for clock_period;
|
TXENA <= '0';
|
TXENA <= '0';
|
N_MON_VAL <= '0';
|
N_MON_VAL <= '0';
|
|
|
when others => -- unknown command
|
when others => -- unknown command
|
write(oline, string'("?? unknown command: "));
|
write(oline, string'("?? unknown command: "));
|
write(oline, dname);
|
write(oline, dname);
|
writeline(output, oline);
|
writeline(output, oline);
|
report "aborting" severity failure;
|
report "aborting" severity failure;
|
end case;
|
end case;
|
|
|
else
|
else
|
report "failed to find command" severity failure;
|
report "failed to find command" severity failure;
|
|
|
end if;
|
end if;
|
|
|
testempty_ea(iline);
|
testempty_ea(iline);
|
end loop; -- file_loop
|
end loop; -- file_loop
|
|
|
idelta := 0;
|
idelta := 0;
|
while TXBUSY='1' or RXACT='1' loop
|
while TXBUSY='1' or RXACT='1' loop
|
wait for clock_period;
|
wait for clock_period;
|
idelta := idelta + 1;
|
idelta := idelta + 1;
|
exit when idelta>3000;
|
exit when idelta>3000;
|
end loop;
|
end loop;
|
|
|
writetimestamp(oline, CLK_CYCLE, ": DONE ");
|
writetimestamp(oline, CLK_CYCLE, ": DONE ");
|
writeline(output, oline);
|
writeline(output, oline);
|
|
|
wait for 12*irate*clock_period;
|
wait for 12*irate*clock_period;
|
|
|
CLK_STOP <= '1';
|
CLK_STOP <= '1';
|
|
|
wait; -- suspend proc_stim forever
|
wait; -- suspend proc_stim forever
|
-- clock is stopped, sim will end
|
-- clock is stopped, sim will end
|
|
|
end process proc_stim;
|
end process proc_stim;
|
|
|
|
|
proc_moni: process
|
proc_moni: process
|
variable oline : line;
|
variable oline : line;
|
begin
|
begin
|
|
|
loop
|
loop
|
wait until rising_edge(CLK);
|
wait until rising_edge(CLK);
|
|
|
if R_MON_VAL_1 = '1' then
|
if R_MON_VAL_1 = '1' then
|
if R_MON_VAL_2 = '1' then
|
if R_MON_VAL_2 = '1' then
|
writetimestamp(oline, CLK_CYCLE, ": moni ");
|
writetimestamp(oline, CLK_CYCLE, ": moni ");
|
write(oline, string'(" FAIL MISSING DATA="));
|
write(oline, string'(" FAIL MISSING DATA="));
|
write(oline, R_MON_DAT_2);
|
write(oline, R_MON_DAT_2);
|
writeline(output, oline);
|
writeline(output, oline);
|
end if;
|
end if;
|
R_MON_VAL_2 <= R_MON_VAL_1;
|
R_MON_VAL_2 <= R_MON_VAL_1;
|
R_MON_DAT_2 <= R_MON_DAT_1;
|
R_MON_DAT_2 <= R_MON_DAT_1;
|
end if;
|
end if;
|
|
|
R_MON_VAL_1 <= N_MON_VAL;
|
R_MON_VAL_1 <= N_MON_VAL;
|
R_MON_DAT_1 <= N_MON_DAT;
|
R_MON_DAT_1 <= N_MON_DAT;
|
|
|
if RXVAL='1' or RXERR='1' then
|
if RXVAL='1' or RXERR='1' then
|
writetimestamp(oline, CLK_CYCLE, ": moni ");
|
writetimestamp(oline, CLK_CYCLE, ": moni ");
|
write(oline, RXDATA, right, 10);
|
write(oline, RXDATA, right, 10);
|
if RXERR = '1' then
|
if RXERR = '1' then
|
write(oline, string'(" RXERR=1"));
|
write(oline, string'(" RXERR=1"));
|
end if;
|
end if;
|
|
|
if R_MON_VAL_2 = '0' then
|
if R_MON_VAL_2 = '0' then
|
write(oline, string'(" FAIL UNEXPECTED"));
|
write(oline, string'(" FAIL UNEXPECTED"));
|
else
|
else
|
write(oline, string'(" CHECK"));
|
write(oline, string'(" CHECK"));
|
R_MON_VAL_2 <= '0';
|
R_MON_VAL_2 <= '0';
|
|
|
if R_MON_DAT_2 = RXDATA and
|
if R_MON_DAT_2 = RXDATA and
|
RXERR='0' then
|
RXERR='0' then
|
write(oline, string'(" OK"));
|
write(oline, string'(" OK"));
|
else
|
else
|
write(oline, string'(" FAIL"));
|
write(oline, string'(" FAIL"));
|
end if;
|
end if;
|
|
|
end if;
|
end if;
|
|
|
writeline(output, oline);
|
writeline(output, oline);
|
end if;
|
end if;
|
|
|
end loop;
|
end loop;
|
|
|
end process proc_moni;
|
end process proc_moni;
|
|
|
end sim;
|
end sim;
|
|
|