📄 bench_vit_par_atl_arc_ben_node_sync.vhd
字号:
-------------------------------------------------------------------------
-------------------------------------------------------------------------
--
-- Revision Control Information
--
-- $RCSfile: Bench_vit_par_atl_arc_ben.vhd,v $
-- $Source: /disk2/cvs/data/Projects/Viterbi/Testbenches/Attic/Bench_vit_par_atl_arc_ben.vhd,v $
--
-- $Revision: 1.1.2.7.4.6.2.3 $
-- $Date: 2004/04/30 18:35:45 $
-- Check in by : $Author: admanero $
-- Author : Alejandro Diaz-Manero
--
-- Project : viterbi
--
-- Description :
--
-- Copyright 2003 (c) Altera Corporation
-- All rights reserved
--
-------------------------------------------------------------------------
-------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.math_real.all;
library viterbi;
use viterbi.vi_interface.all;
use viterbi.vi_functions.all;
use viterbi.vi_bench.all;
use Std.TextIO.all;
Architecture Bench of bench_vit_par_atl_node_sync is
Constant dummy : BOOLEAN := Check_generics(test_for, node_sync, BER);
Constant L_max : NATURAL := constraint_length_m_1+1;
Constant ncodes : NATURAL := Get_ncodes(n);
Constant n_list : NATURAL_ARRAY(1 to ncodes) := Get_n_list(n => n, ncodes => ncodes);
Constant L_list : NATURAL_ARRAY(1 to ncodes) := Get_n_list(n => L, ncodes => ncodes);
Constant m_list : NATURAL_ARRAY(1 to ncodes) := Get_modes_list(modes => dec_modes, ncodes => ncodes);
Constant clockPeriod : TIME := String_2_Time(n => clock_period);
Constant clockOffset : TIME := String_2_Time(n => clock_offset);
Constant time_lapse_max : TIME := 1 ms;
COMPONENT auk_vit_vit_var_enc
Generic (
n : NATURAL := 2;
L_max : NATURAL := 7;
L_code : NATURAL := 7;
pol_sel : NATURAL := 1;
ga : STRING := "91_91";
gb : STRING := "121_101";
gc : STRING := "0_125";
gd : STRING := "0_0";
ge : STRING := "0_0";
gf : STRING := "0_0";
gg : STRING := "0_0"
);
Port (
state : in Std_Logic_Vector(L_max downto 1);
vector : out Std_Logic_Vector(n downto 1)
);
END COMPONENT;
Subtype data_vector is Std_Logic_Vector(rr_size downto 1);
Subtype eras_vector is Std_Logic_Vector(n_max downto 1);
type data_vector_2D is array(NATURAL RANGE <>) of data_vector;
type eras_vector_2D is array(NATURAL RANGE <>) of eras_vector;
Type atl_buffer_fsm is (out_idle, out_dav, out_active, out_hold, out_hold_last, out_last_ena,
out_dav_s, out_dav_m, dav_toggling);
signal atl_buffer_state, atl_buffer_next_state : atl_buffer_fsm;
Signal time_lapse : TIME;
Signal ben_2_dec_data_pipe : data_vector_2D(3 downto 1);
Signal ben_2_dec_eras_pipe : eras_vector_2D(3 downto 1);
signal sop_source_pipe, eop_source_pipe : Std_Logic_Vector(3 downto 1);
Signal bench_2_decoder_s, bench_2_decoder_shunt : Std_Logic_Vector(rr_size downto 1);
Signal eras_sym_s, eras_sym_shunt : Std_Logic_Vector(n_max downto 1);
Signal lfsr_conv_enc : Std_Logic_Vector(L_max downto 1);
signal sop_source_gen, eop_source_gen : Std_Logic;
Signal sop_source_shunt, eop_source_shunt : Std_Logic;
Signal allow_val_assert, allow_ena_assert : Std_Logic;
signal keep_clk_running, data_available : BOOLEAN := TRUE;
Signal clk_int, reset_int : Std_Logic;
Signal decbit_dec_q, sink_dav_master_q : Std_Logic;
Signal sink_val_q, sink_sop_q, sink_eop_q : Std_Logic;
Signal sel_code_sig : NATURAL;
Signal enc_bits_rx : Vector_2D(ncodes downto 1);
Signal m_sel_fifo, c_sel_fifo : NATURAL_ARRAY(1 to 8);
signal m_sel_wr_cursor, m_sel_rd_cursor : NATURAL := 1;
signal sink_eop_counter, source_eop_counter : NATURAL := 0;
Signal dav_source_int_gen, dav_source_int, ena_data_sourcing : Std_Logic;
signal out_fsm_buf : Std_Logic_Vector(3 downto 1);
signal out_sync_del : std_logic;
begin
clk <= clk_int;
reset <= reset_int;
Osc: process
begin
while keep_clk_running loop
clk_int <= '1';
wait for clockPeriod/2; -- half de clock period
clk_int <= '0';
wait for clockPeriod/2;
end loop;
wait;
end process Osc;
stim_atlantic: process
FILE F: TEXT open READ_MODE is INPUT_FILE;
FILE FBLK: TEXT open READ_MODE is BLOCKS_FILE;
variable L, L_selcode, L_bm_init_state, L_tb_length, L_tr_init_state : Line;
variable L_tb_type, L_size_of_block : Line;
variable seed1, seed2: positive := 1;
variable x: real;
Constant times_four : NATURAL := Ceil_DIV(softbits, 4);
-- Constant n_hex : NATURAL := n_sel*times_four;
Variable n_hex, n_sel : NATURAL;
-- variable tmp : STRING(n_hex downto 1);
variable tmp : STRING(14 downto 1);
variable car : CHARACTER;
variable good_read : BOOLEAN;
variable cursor, cnt_outvalids : NATURAL;
variable bench_2_decoder_var : Std_Logic_Vector(n_max*4*times_four downto 1);
variable eras_sym_var : Std_Logic_Vector(n_max downto 1);
variable bit_in_block, block_size, sel_code_var : natural;
variable bm_init_state_var, tb_length_var : natural;
variable tr_init_state_var, tb_type_var, m_sel_var : natural;
variable last_symbol : boolean;
begin
READLINE(FBLK, L_selcode);
READLINE(FBLK, L_bm_init_state);
READLINE(FBLK, L_tb_length);
READLINE(FBLK, L_tr_init_state);
READLINE(FBLK, L_tb_type);
READLINE(FBLK, L_size_of_block);
-- this signals change on block periodicity.
-- they are to be loaded from file block_period_stim.txt
data_available <= TRUE;
m_sel_wr_cursor <= 1;
READ(L_selcode, sel_code_var, good_read);
sel_code_sig <= sel_code_var+1;
n_sel := n_list(sel_code_var+1);
m_sel_var := m_list(sel_code_var+1); -- signal for memory and inter-process communication
m_sel_fifo(m_sel_wr_cursor) <= m_list(sel_code_var+1);
c_sel_fifo(m_sel_wr_cursor) <= sel_code_var+1;
--if m_sel_wr_cursor=8 then
-- m_sel_wr_cursor <= 1;
--else
m_sel_wr_cursor <= m_sel_wr_cursor+1;
--end if;
if m_list(sel_code_var+1)=0 then
n_hex := n_sel*times_four;
else
n_sel := 4;
n_hex := 4*times_four; -- n_sel = 4 for TCM
end if;
tb_type <= '0';
tr_init_state <= (others => '0');
state_node_sync <= (others => '0');
sel_code <= natural_2_m(arg => sel_code_var, size => sel_code_size);
READ(L_bm_init_state, bm_init_state_var, good_read);
READ(L_tb_length, tb_length_var, good_read);
tb_length <= natural_2_m(arg => tb_length_var, size => vlog_wide);
last_symbol := FALSE;
reset_int <= '1';
dav_source_int_gen <= '0';
bench_2_decoder_s <= (others => '0');
eras_sym_s <= (others => '0');
sop_source_gen <= '0';
eop_source_gen <= '0';
bit_in_block := 1;
wait for clockPeriod;
reset_int <= '0' after clockOffset;
wait for clockPeriod;
dav_source_int_gen <= '1';
main: while (not ENDFILE(F)) and keep_clk_running loop
--wait for clockPeriod;
cursor := 0;
READLINE(F, L);
tmp := (others => '0');
if bit_in_block=1 then
READ(L_size_of_block, block_size, good_read);
if not good_read then
-- last symbol being read
ASSERT FALSE
REPORT "Not good reading of block size" severity Note;
exit;
end if;
end if;
nested_1: while (cursor < 20) and keep_clk_running loop
if ena_data_sourcing='1' then
eras_sym_var := (others => '0');
nested_2: for J in 1 to n_hex+1 loop
READ(L, car, good_read);
if car /=' ' and good_read then
tmp(n_hex+1-J) := car;
if car='X' then
eras_sym_var(n_hex+1-J) := '1';
end if;
elsif J /= n_hex+1 then
tmp(n_hex+1-J) := '0';
elsif not good_read then
exit nested_2;
end if;
end loop nested_2;
-- transformation Slv to hex by groups of size times_four
bench_2_decoder_var(n_sel*4*times_four downto 1):= Hex2slv (Value => tmp(n_hex downto 1), size => n_sel*4*times_four);
uniform (seed1, seed2, x);
x := x - 0.3;
if (test_for="dav_sink" or test_for="both_sides") and (x < 0.0) then
uniform (seed1, seed2, x);
-- dav_source_int_gen shouldn't change when ena_data_sourcing is de-asserted.
if 5.0 * x >= 1.0 and ena_data_sourcing='1' then
dav_source_int_gen <= '0';
wait for natural(5.0 * x)*clockPeriod;
elsif ena_data_sourcing='0' then
wait until ena_data_sourcing='1';
end if;
dav_source_int_gen <= '1';
end if;
if ena_data_sourcing='0' then
wait until ena_data_sourcing='1';
end if;
for I in 1 to n_sel loop
bench_2_decoder_s(I*softbits downto (I-1)*softbits+1) <=
bench_2_decoder_var(softbits+(I-1)*4*times_four downto (I-1)*4*times_four+1) after clockOffset;
end loop;
eras_sym_s <= eras_sym_var after clockOffset;
bench_2_decoder_var := (others => '0');
if (n_sel<n_max) and m_sel_var=0 then
bench_2_decoder_s(n_max*softbits downto n_sel*softbits+1) <= (others => '0') after clockOffset;
end if;
if bit_in_block = 1 then
sop_source_gen <= '1' after clockOffset;
eop_source_gen <= '0' after clockOffset;
wait for clockPeriod;
elsif bit_in_block = block_size then
sop_source_gen <= '0' after clockOffset;
eop_source_gen <= '1' after clockOffset;
READ(L_tr_init_state, tr_init_state_var, good_read);
tr_init_state <= natural_2_m(arg => tr_init_state_var, size => constraint_length_m_1);
READ(L_tb_type, tb_type_var, good_read);
if tb_type_var=0 then
tb_type <= '0';
else
tb_type <= '1';
end if;
wait for clockPeriod;
-- this signals change on block period.
-- they are to be loaded from file block_period_stim.txt
READ(L_selcode, sel_code_var, good_read);
sel_code_sig <= sel_code_var+1;
n_sel := n_list(sel_code_var+1);
m_sel_var := m_list(sel_code_var+1);
m_sel_fifo(m_sel_wr_cursor) <= m_list(sel_code_var+1);
c_sel_fifo(m_sel_wr_cursor) <= sel_code_var+1;
source_eop_counter <= source_eop_counter + 1;
if m_sel_wr_cursor=8 then
m_sel_wr_cursor <= 1;
else
m_sel_wr_cursor <= m_sel_wr_cursor+1;
end if;
if m_list(sel_code_var+1)=0 then
n_hex := n_sel*times_four;
else
n_sel := 4;
n_hex := 4*times_four; -- n_sel = 4 for TCM
end if;
sel_code <= natural_2_m(arg => sel_code_var, size => sel_code_size);
READ(L_bm_init_state, bm_init_state_var, good_read);
READ(L_tb_length, tb_length_var, good_read);
tb_length <= natural_2_m(arg => tb_length_var, size => vlog_wide);
else
if ena_data_sourcing='1' then
sop_source_gen <= '0' after clockOffset;
eop_source_gen <= '0' after clockOffset;
end if;
wait for clockPeriod;
end if;
cursor := cursor + 1;
--if bit_in_block = block_size then
-- bit_in_block := 1;
-- cursor := 20; -- that will provoke exit of nested_1 while loop
--else
-- bit_in_block := bit_in_block + 1;
--end if;
if out_sync_del = '1' then
bit_in_block := block_size;
elsif bit_in_block = block_size then
bit_in_block := 1;
cursor := 20; -- that will provoke exit of nested_1 while loop
else
bit_in_block := bit_in_block + 1;
end if;
exit when good_read=FALSE;
else
wait for clockPeriod;
end if; -- ena sourcing
bits_cnt <= CONV_STD_LOGIC_VECTOR(bit_in_block, numerr_size);
end loop nested_1;
end loop main;
-- In this new version of the bench, the file is going to be read and then when finish reading
-- the running time is going to extend to allow all the decoding bits to come out.
-- if I add after clockOffset then I get an extra spurious cycle of dav, ena and val.
if ena_data_sourcing='0' then
wait until ena_data_sourcing='1';
wait for clockPeriod;
end if;
dav_source_int_gen <= '0'; -- after clockOffset;
-- if I don't add clockoffset, the last eop pulse gets lost
sop_source_gen <= '0' after clockOffset;
eop_source_gen <= '0' after clockOffset;
if keep_clk_running then
wait until sink_eop_q='1';
wait for 2*clockPeriod;
end if;
-- need to wait until the eop_source comes out to gather all the data!!
data_available <= FALSE;
wait;
end process stim_atlantic;
out_sync_latch: Process (clk_int, reset_int)
begin
if reset_int='1' then
out_sync_del <= '0';
--elsif (out_sync = '1' or source_val_sig(1) = '1') then
elsif (out_sync = '1') then
out_sync_del <= out_sync;
else
out_sync_del <= '0';
end if;
end process out_sync_latch;
end_block_stim: Process
begin
m_sel_rd_cursor <= 1;
while keep_clk_running loop
wait until Rising_edge(sink_eop_q);
wait for clockPeriod;
wait for clockPeriod/2;
if m_sel_rd_cursor=8 then
m_sel_rd_cursor <= 1;
else
m_sel_rd_cursor <= m_sel_rd_cursor+1;
end if;
sink_eop_counter <= sink_eop_counter + 1;
wait for clockPeriod;
end loop;
wait;
end process end_block_stim;
-- This is to avoid hang ups in regtest
monitor_toggling_activity: Process(clk_int, reset_int, sink_dav_master_q,
sink_val_q, sink_sop_q, sink_eop_q, data_available)
begin
if reset_int='1' then
time_lapse <= 0 ns;
elsif sink_dav_master_q'event or sink_val_q'event or
sink_sop_q'event or sink_eop_q'event or data_available'event then
time_lapse <= 0 ns;
elsif rising_edge(clk_int) then
time_lapse <= time_lapse + clockPeriod;
end if;
end process monitor_toggling_activity;
clk_running_ctrl: Process(reset_int, source_eop_counter,
sink_eop_counter, data_available, time_lapse)
begin
if reset_int='1' then
keep_clk_running <= TRUE;
elsif (source_eop_counter = sink_eop_counter) and not data_available then
keep_clk_running <= FALSE after 3*clockPeriod;
elsif (time_lapse > time_lapse_max) then
ASSERT FALSE
REPORT "Reached time_lapse_max without activity, probable hang up" severity Error;
keep_clk_running <= FALSE;
end if;
end process clk_running_ctrl;
clk_FSM_atl: Process (clk_int, reset_int)
begin
if reset_int='1' then
atl_buffer_state <= out_idle;
elsif Rising_edge(clk_int) then
atl_buffer_state <= atl_buffer_next_state;
end if;
end process clk_FSM_atl;
dav_source_int <= dav_source_int_gen and ena_data_sourcing;
FSM_out : process(atl_buffer_state, dav_source_int, source_ena_slave)
-- dav_source_int is 1 clock prior to dav_source (here = source_dav_slave)
variable atl_buffer_next_state_var : atl_buffer_fsm;
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -