⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bench_vit_par_atl_arc_ben_node_sync.vhd

📁 一个完整的viterbi译码程序和测试的程序
💻 VHD
📖 第 1 页 / 共 2 页
字号:
-------------------------------------------------------------------------
-------------------------------------------------------------------------
--
-- 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 + -