📄 tst_bench.vhd
字号:
-- **************************************************************
-- Owner: Xilinx Inc.
-- File: tst_bench.vhd
--
-- Purpose: Test bench that connects encoder and decoder for
-- 16B/20B serial transmission. Synchronizes sending
-- and receiving, and verification of transmission.
--
-- Author: Jennifer Jenkins
-- Date: 7-10-2000
--
-- **************************************************************
library ieee;
use IEEE.std_logic_1164.all;
use WORK.pkg_convert.all;
use WORK.pkg_spc_char.all;
entity TST_16B20B is
port (
clk20 : inout STD_LOGIC; -- Local clock to encoder & decoder @ 20MHz
sync_reset : out std_logic; -- Control signals to encoder
data_trs : out STD_LOGIC_VECTOR (15 downto 0); -- Date byte to encode
k_char : out STD_LOGIC; -- Asserted denotes special
-- character transmission
disparity : out STD_LOGIC; -- Denotes incoming parity
run_dis : in STD_LOGIC; -- Running disparity
frame_to_enc : inout STD_LOGIC; -- Control to start data encoding
frame_out_enc : in STD_LOGIC; -- Asserted - done with encoding
data_rcv : in STD_LOGIC_VECTOR (15 downto 0); -- Incoming data from decoder
frame_in_dec : out STD_LOGIC; -- Control to start decoding
frame_out_dec : in STD_LOGIC; -- Asserted - done decoding
data_from_enc : in STD_LOGIC_VECTOR (19 downto 0); -- Encoded data from encoder module
data_to_dec : out STD_LOGIC_VECTOR (19 downto 0); -- Encoded data to decoder module
ill_char_det : in STD_LOGIC -- Asserted when error detected
-- in ERR_DET s.m.
);
end TST_16B20B;
architecture BEHAVIOR of TST_16B20B is
-- ********************** CONSTANT DECLARATIONS *********************
constant RESET_ACTIVE : STD_LOGIC := '0';
constant CLOCK_PERIOD : time := 12600 pS;
constant HALFCLOCKPERIOD : time := 6300 pS;
constant CLOCKSKEW : time := 5500 pS;
constant CLK2QDELAY : time := 10 nS;
constant SKEW20 : time := 1200 pS;
constant CLKOUTDELAY : time := 3 nS;
constant LATENCY : integer := 13;
constant ENC_DELAY : integer := 8;
constant DATA_STREAM : integer := 300;
constant LEN_SPC_CHAR : integer := 12;
-- ************************ SIGNAL DECLARATIONS **********************
signal rst_load : STD_LOGIC := '0';
signal data_error : STD_LOGIC := '0';
signal send_data : STD_LOGIC;
signal count_trns, dis_hold : STD_LOGIC;
signal serial_data_hold : STD_LOGIC_VECTOR(19 downto 0);
signal data_rcv_hold : STD_LOGIC_VECTOR(15 downto 0);
begin
-- ******************** Process: GEN_CLOCK ********************
-- Generate local clock for encoder/decoder
GEN_CLOCK: process
begin
clk20 <= '0';
wait for 100 nS;
loop
clk20 <= not(clk20) after SKEW20;
wait for HALFCLOCKPERIOD;
end loop;
end process GEN_CLOCK;
-- ***************** Process: TRNS_CTRL ************************
-- This process generates the reset signal and control signal to
-- coordinate transmition of data
TRNS_CTRL: process
begin
sync_reset <= not(RESET_ACTIVE);
rst_load <= '1';
send_data <= '0';
count_trns <= '0';
dis_hold <= '0';
wait for 200 nS;
-- Assert the reset pulse sync'd with the 20MHz clock
wait until clk20'event and clk20 = '1';
sync_reset <= RESET_ACTIVE after 10 nS;
-- Terminate the reset pulse
wait for 300 nS;
wait until clk20'event and clk20 = '1';
sync_reset <= not(RESET_ACTIVE) after 10 nS;
wait for 300 nS;
rst_load <= '0';
wait for 100 nS;
loop -- Process runs forever
-- Begin loop of sending data
for i in 0 to DATA_STREAM loop
-- Wait for rising edge on clock to assert frame_in for encoder module
wait until clk20'event AND clk20 = '1';
send_data <= '1' after CLK2QDELAY;
wait until frame_to_enc'event and frame_to_enc = '1' and
frame_to_enc'last_value = '0';
count_trns <= '1';
-- Wait until module is complete encoding data byte
wait until frame_out_enc'event and frame_out_enc = '1' and
frame_out_enc'last_value = '0';
-- Store encoded data to be sent
serial_data_hold <= data_from_enc;
-- Save current disparity
dis_hold <= run_dis;
-- End byte transmission
count_trns <= '0';
send_data <= '0' after CLK2QDELAY;
-- Wait before configuring next test
wait for 10 nS;
end loop;
end loop;
end process TRNS_CTRL;
-- ***************** Process: RCV_CTRL ************************
-- This process generates the control signals for the decoder
-- module receiving data
RCV_CTRL: process
begin
frame_in_dec <= '0';
-- Wait until reset is configured
wait until rst_load'event and rst_load = '0' and rst_load'last_value = '1';
loop -- Process runs forever
-- Begin loop of sending data
for i in 0 to DATA_STREAM loop
wait until frame_out_enc'event and frame_out_enc= '1' and
frame_out_enc'last_value = '0';
-- Wait for rising edge on clock to assert frame_in to decoder module
-- and transfer data from encoder to decoder
wait until clk20'event AND clk20 = '1';
data_to_dec <= serial_data_hold after CLK2QDELAY;
frame_in_dec <= '1' after CLK2QDELAY;
-- Deassert frame_in to decoder module
wait until clk20'event AND clk20 = '1';
frame_in_dec <= '0' after CLK2QDELAY;
-- When decoding finishes store decoded data
wait until frame_out_dec'event and frame_out_dec= '1' and
frame_out_dec'last_value = '0';
data_rcv_hold <= data_rcv;
assert ill_char_det = '0'
report "Illegal character detected"
severity WARNING;
end loop;
end loop;
end process RCV_CTRL;
-- ********************** Process: GEN_DATA *******************************
-- Process gen_data generates 25 random data nibbles. It asserts the hsync
-- signal when it begins to output the data so that the data checking process
-- knows when to begin counting clocks to determine when valid data has
-- reached the next board.
GEN_DATA: process
variable gen_data : std_logic_vector (15 downto 0);
variable count : integer; -- Number of data nibbles output
begin
-- Specify special character transmission
frame_to_enc <= '0';
disparity <= '0';
-- Wait until reset is configured
wait until rst_load'event and rst_load = '0' and rst_load'last_value = '1';
loop -- Process runs continuously
-- ************ Non-Special Characters, k_char=0 ************
-- Number of data output bytes
count := 0;
-- Only generate DATA_STREAM numbers to transmit
while count < DATA_STREAM loop
-- Wait for rising edge on clock
wait until send_data'event and send_data = '1' and
send_data'last_value = '0';
-- Data to send
gen_data := int2vec(count);
-- Assign the number & control to the output ports
data_trs <= gen_data after CLK2QDELAY;
frame_to_enc <= '1' after CLK2QDELAY;
disparity <= dis_hold after CLK2QDELAY;
k_char <= '0' after CLK2QDELAY;
wait until clk20'event and clk20 = '1';
wait until clk20'event and clk20 = '1';
frame_to_enc <= '0' after CLK2QDELAY;
-- Wait for end of encoding
wait until send_data'event and send_data = '0' and
send_data'last_value = '1';
-- Increment the number of sets of data nibbles generated
count := count + 1;
end loop; -- While count < DATA_STREAM
end loop;
end process GEN_DATA;
-- ********************** Process: CHK_DATA *******************************
-- Process chk_data checks the data read from the decoder and compares it to
-- the data generated
CHK_DATA: process
variable data_in : std_logic_vector (15 downto 0);
variable clk_count : integer; -- Number of clocks since data generator started outputting data
variable chk_count : integer; -- Number of data nibbles checked
variable rcv_data : integer; -- Random number, number read in from LSP
variable cmp_data : integer;
begin
loop -- Process runs continuously
-- Wait until reset is configured
wait until rst_load'event and rst_load = '0' and rst_load'last_value = '1';
-- Wait for configuration to take effect
wait for 100 nS;
chk_count := 0; -- Initialize the count of nibbles checked
clk_count := 0; -- Initialize the clock count
while chk_count < DATA_STREAM loop -- Loop for all data words
-- Wait for rising edge on clock
wait until clk20'event and clk20 = '1';
-- data_trs is outputting data - start counting clocks
if count_trns = '1' then
clk_count := clk_count + 1;
end if;
-- Data has had time to transfer to encoder & decoder
if clk_count = (LATENCY + (chk_count * ENC_DELAY)) then
-- Put the incoming data into a variable for checking
-- Correct alignment of data that went to encoder
-- for error checking
data_in(0) := data_rcv_hold(7);
data_in(1) := data_rcv_hold(6);
data_in(2) := data_rcv_hold(5);
data_in(3) := data_rcv_hold(4);
data_in(4) := data_rcv_hold(3);
data_in(5) := data_rcv_hold(2);
data_in(6) := data_rcv_hold(1);
data_in(7) := data_rcv_hold(0);
data_in(8) := data_rcv_hold(15);
data_in(9) := data_rcv_hold(14);
data_in(10) := data_rcv_hold(13);
data_in(11) := data_rcv_hold(12);
data_in(12) := data_rcv_hold(11);
data_in(13) := data_rcv_hold(10);
data_in(14) := data_rcv_hold(9);
data_in(15) := data_rcv_hold(8);
-- Test the incoming data
rcv_data := vec2int(data_in);
if (chk_count = rcv_data) then
data_error <= '0';
else data_error <= '1';
end if;
-- Increment the number of data nibbles checked
chk_count := chk_count + 1;
end if;
end loop; -- While chk_count < DATA_STREAM
end loop;
end process CHK_DATA;
end BEHAVIOR;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -