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

📄 vi_functions.vhd

📁 一个完整的viterbi译码程序和测试的程序
💻 VHD
📖 第 1 页 / 共 3 页
字号:
      if(row(j) = pla_element'( '1' )) then
      	match := match and
      	(invec(in_pos) = Std_Logic'( '1' ));
      elsif(row(j) = pla_element'( '0' )) then
      	match := match and
      	(invec(in_pos) = Std_Logic'( '0' ));
      else
      	null;
      end if;
    end loop;
    if(match) then
    	for j in outvec'range loop
    		if (row(j) = pla_element'('1')) then
    			outvec(j) := Std_Logic'('1');
    		end if;
  		end loop;
  	end if;
	end if;
end loop;

end pla_table;

procedure pla_table_v(variable invec_v: in std_logic_vector;
										variable outvec: out std_logic_vector;
										Constant table: pla_table_t) is

	subtype result_type is Std_Logic_Vector(outvec'HIGH downto outvec'LOW);
	Constant nil_row : pla_row := (others => pla_element'(' '));
	variable row: pla_row;
	variable match: boolean;
	variable in_pos: NATURAL;


begin
	
outvec := result_type'(others => Std_Logic'( '0' ));
for i in table'range loop
  row := table(i);
	if row /= nil_row then
    match := true;
    in_pos := invec_v'HIGH+1;
    for j in outvec'HIGH+invec_v'HIGH+1 downto outvec'HIGH+invec_v'LOW+1 loop
      in_pos := in_pos - 1;
      if(row(j) = pla_element'( '1' )) then
      	match := match and
      	(invec_v(in_pos) = Std_Logic'( '1' ));
      elsif(row(j) = pla_element'( '0' )) then
      	match := match and
      	(invec_v(in_pos) = Std_Logic'( '0' ));
      else
      	null;
      end if;
    end loop;
    if(match) then
    	for j in outvec'range loop
    		if (row(j) = pla_element'('1')) then
    			outvec(j) := Std_Logic'('1');
    		end if;
  		end loop;
  	end if;
	end if;
end loop;

end pla_table_v;


function Extract_item(list : NATURAL_ARRAY; index : NATURAL) return NATURAL is

  variable item : NATURAL;

begin
	if list'HIGH < index then
	  item := 0;
	else
	  item := list(index);
	end if;
	return item;
end Extract_item;



function bin_mod(a, d: in NATURAL) return NATURAL is

  variable result : NATURAL;

begin

	if (a mod d)/=0 then
		result := 1;
	else
		result := 0;
	end if;
	return result;
	
end function bin_mod;


function Get_n_min(n : NATURAL_ARRAY) return NATURAL is

	variable n_min : NATURAL;

begin

	if n(n'LOW) >= 2 then
		n_min := n(n'LOW);
	else
	  n_min := 2;
	end if;
	For I in n'LOW to n'HIGH loop
		if (n(I) < n_min) and (n(I) >= 2) then
			n_min := n(I);
		end if;
	end loop;
	return n_min;
	
end Get_n_min;

function Get_max_of_three(param_1, param_2, param_3 : NATURAL) return NATURAL is

  variable max : NATURAL;

begin

	max := param_1;
	if param_2 > max then
		max := param_2;
	end if;
	if param_3 > max then
		max := param_3;
	end if;
	return max;

end Get_max_of_three;


function Get_min(param_1, param_2 : NATURAL) return NATURAL is

  variable min : NATURAL;

begin

	min := param_1;
	if param_2 < min then
		min := param_2;
	end if;
	return min;

end Get_min;
 

function Transform_punctured_rate(punctured_rate : STRING) return NATURAL_ARRAY is

  variable fraction : NATURAL_ARRAY(2 downto 1);
	variable extracted_value : STRING(punctured_rate'HIGH downto 1);
	variable item : character;
	variable I_ext, I_n : NATURAL; -- indexes

begin

--	variable n_list : NATURAL_ARRAY(1 to ncodes);
--	variable not_finished : BOOLEAN;

--  count_items := 1;
	I_ext := 1;
	I_n := 1;
	item := punctured_rate(I_n);
--	second: while (item /= '/') and (I_n <= punctured_rate'HIGH) loop
	first: while (item /= '/') loop
		if check_base(item => item, base => "DEC") then
			extracted_value(I_ext) := punctured_rate(I_n);
		end if;
		I_ext := I_ext + 1;
		I_n := I_n + 1;
		if I_n <= punctured_rate'HIGH then
			item := punctured_rate(I_n);
		end if;
	end loop first;  -- numerator
	fraction(2) := Convert_str_nat(pol_value => extracted_value(I_ext downto 1), base => "DEC");
	I_n := I_n+1;
	I_ext := 1;
	if I_n <= punctured_rate'HIGH then
		item := punctured_rate(I_n);
	end if;
	second: while (item /= '/') and (I_n <= punctured_rate'HIGH) loop
--	first: while (item /= '/') loop
		if check_base(item => item, base => "DEC") then
			extracted_value(I_ext) := punctured_rate(I_n);
		end if;
		I_ext := I_ext + 1;
		I_n := I_n + 1;
		if I_n <= punctured_rate'HIGH then
			item := punctured_rate(I_n);
		end if;
	end loop second;  -- denominator
	fraction(1) := Convert_str_nat(pol_value => extracted_value(I_ext downto 1), base => "DEC");

	return fraction;

end function Transform_punctured_rate;

function Calc_puncturing_rate(n : NATURAL; punctured_rate_fraction : NATURAL_ARRAY) return NATURAL_ARRAY is

	variable fraction : NATURAL_ARRAY(2 downto 1);

begin
	
	fraction(2) := punctured_rate_fraction(1);
	fraction(1) := punctured_rate_fraction(2)*n;
	return fraction;

end function Calc_puncturing_rate;


function Transform_pattern_2_mini_rom(n : NATURAL;
																			punctured_rate, puncturing_pattern : STRING)
																			return mini_rom is

	Constant punctured_rate_fraction : NATURAL_ARRAY(2 downto 1) := 
				 Transform_punctured_rate(punctured_rate);  -- 2 numerator, 1 denominator

	Constant puncturing_rate_fraction : NATURAL_ARRAY(2 downto 1) := 
				 Calc_puncturing_rate(n, punctured_rate_fraction);  -- 2 numerator, 1 denominator

	Constant top_sequencer_val : NATURAL := 
				 puncturing_rate_fraction(2)*puncturing_pattern'HIGH/puncturing_rate_fraction(1);

	variable ser_2_par_ref : INTEGER_ARRAY(1 to n*top_sequencer_val);
	variable pun_operation : INTEGER_ARRAY(1 to n*top_sequencer_val);
	variable ref, hypo : INTEGER_ARRAY(1 to n);
	variable pat_cursor, pattern_order : NATURAL;
	variable result : mini_rom(0 to top_sequencer_val);
	variable upgrade_hypo : BOOLEAN;


begin
	
	upgrade_hypo := TRUE;
	--  First build reference for serial to parallel conversion.
	first : For I in 1 to top_sequencer_val loop
		second : For J in 0 to n-1 loop
			if J >= I then
				ser_2_par_ref(I*n-J) := 0;
			else
				ser_2_par_ref(I*n-J) := I-J;
			end if;
		end loop second;
	end loop first;
	--  Build puncturing operation implementation
	pat_cursor := 1;
	--ref_cursor := 1;
	pattern_order := 1;
	f3 : For ref_cursor in 1 to top_sequencer_val loop
  	-- Extract reference and hypotesis partial strings
  	ref := ser_2_par_ref(n*(ref_cursor-1)+1 to n*ref_cursor);
		if upgrade_hypo then
    	third: For I in 1 to n loop
    		if puncturing_pattern(n*(pat_cursor-1)+I)='0' then
    			hypo(I) := pattern_order;
    			pattern_order := pattern_order+1;
    		else -- puncturing code = -1
    			hypo(I) := -1;
    		end if;
    	end loop third;
		end if;
  	if Have_same_elements(hypo, ref) then
  		pun_operation(n*(ref_cursor-1)+1 to n*ref_cursor) := hypo;
  		pat_cursor := pat_cursor+1;
			upgrade_hypo := TRUE;
  	else -- code -2 introduce : Freeze operation as serial data still to come
  		-- this others may not work in FPGA Express : loop will be needed.
  		pun_operation(n*(ref_cursor-1)+1 to n*ref_cursor) := (others => -2);
			upgrade_hypo := FALSE;
  	end if;
	end loop f3;
	--  Now I have to fill in the mini_rom table according to the data in 
	--  pun_operation and ser_2_par_ref
	-- at 0 result = all 1
	result(0) := (others => '1');
	f4 : For J in 1 to top_sequencer_val loop
		swap : For I in 1 to n loop
			if (pun_operation(n*(J-1)+I)=-2) or (pun_operation(n*(J-1)+I)=-1)	then
				result(J)(n-I+1) := '1';
			else
				result(J)(n-I+1) := '0';
			end if;
			hypo(I) := pun_operation(n*(J-1)+I);
			ref(I)  := ser_2_par_ref(n*(J-1)+I);
		end loop swap;
		if Are_they_aligned(hypo, ref) then
			result(J)(3) := '0';
		else
			result(J)(3) := '1';
		end if;
	end loop f4;

	return result;
	
end function Transform_pattern_2_mini_rom;

function Have_same_elements(hypo, ref : INTEGER_ARRAY) return BOOLEAN is

	variable hypo_check : BOOLEAN_ARRAY(1 to hypo'HIGH);
	variable result, found_match : BOOLEAN;
	variable posibility_of_using_wild_card : BOOLEAN;
	variable position_wirl_card : NATURAL;

begin
	result := TRUE;
	hypo_check := (others => FALSE);
	posibility_of_using_wild_card := FALSE;
	found_match := FALSE;
	first: For I in 1 to ref'HIGH loop
		if result then
  		second: For J in 1 to hypo'HIGH loop
  			if hypo_check(J)=FALSE and (ref(I)=hypo(J)) then
  				found_match := TRUE;
  				hypo_check(J) := TRUE;
  			elsif hypo_check(J)=FALSE and (hypo(J)=-1) then
  				posibility_of_using_wild_card := TRUE;
  				position_wirl_card := J;
  			end if;
  		end loop second;
  		if found_match then
  			found_match := FALSE;
  		elsif posibility_of_using_wild_card then
  			posibility_of_using_wild_card := FALSE;
  			hypo_check(position_wirl_card) := TRUE;
  		else -- cannot have same items
  			result := FALSE;
  		end if;
		end if;
	end loop first;
	
	return result;

end function Have_same_elements;


function Are_they_aligned(hypo, ref : INTEGER_ARRAY) return BOOLEAN is

	variable result : BOOLEAN;

begin
	result := TRUE;
	first: For I in 1 to ref'HIGH loop
		if result then
 			if (hypo(I)/=-1) and (hypo(I)/=-2) and (ref(I)/=hypo(I)) then
				result := FALSE;
 			end if;
		end if;
	end loop first;
	
	return result;

end function Are_they_aligned;

function Build_tree_arch(n : NATURAL) return NATURAL_ARRAY is

	Constant log2_n : NATURAL := LOG2_ceil_table(n);
	variable tmp : NATURAL;
	variable tree_arch : NATURAL_ARRAY(0 to log2_n);

begin

tree_arch(0):=n;
tmp := n;
for I in 1 to log2_n loop
	tmp := tmp/2 + (tmp mod 2);
	tree_arch(I):=tmp;
end loop;
return tree_arch;

end function Build_tree_arch;


function Build_binary_table(n : NATURAL) return Vector_2D is

	Constant log_size : NATURAL := LOG2_ceil_avoid_one(n);
	variable binary_table : Vector_2D(0 to n-1);

begin

for I in 0 to n-1 loop
	binary_table(I)(log_size downto 1) := natural_2_m(arg => I, size => log_size);
end loop;
return binary_table;

end function Build_binary_table;


function Build_two_power_L_list(L, ACS_units : NATURAL) return NATURAL_ARRAY is

	Constant log2_ACS_units : NATURAL := LOG2_ceil_table(ACS_units);
	variable states_fractions : NATURAL_ARRAY(0 to log2_ACS_units+1);

begin

for I in 0 to log2_ACS_units+1 loop
	states_fractions(I) := 2**(L-1-I);
end loop;
return states_fractions;
	
end function Build_two_power_L_list;


function gen_mcode_selector(n : NATURAL_ARRAY; n_max, ncodes : NATURAL) return pla_table_t is
	
--	Constant ncodes		: NATURAL := Get_ncodes(n);
--	Constant n_max : NATURAL := Get_n_max(n);
	Constant log2_ncodes_a1 : NATURAL := LOG2_ceil_avoid_one(ncodes);

	variable tmp : pla_vector(log2_ncodes_a1 downto 1);
	variable tmp2 : pla_vector(n_max downto 1);

	variable sel_mcode : pla_table_t(ncodes downto 1);

begin

  for H in 1 to ncodes loop
		for J in 1 to n_max loop
			if n(H) >= J then
				tmp2(J) := '1';
			else
				tmp2(J) := '0';
			end if;
		end loop;
		tmp := natural_2_m(arg => H-1, size => log2_ncodes_a1);
		if n_max+log2_ncodes_a1+1 <= row_size_max then
  		for b in n_max downto 1 loop
 				sel_mcode(H)(b) := tmp2(b);
  		end loop;
  		sel_mcode(H)(n_max+1) := pla_element'(' ');
  		for b in n_max+log2_ncodes_a1+1 downto n_max+2 loop
  			sel_mcode(H)(b) := tmp(b-n_max-1);
  		end loop;
			if n_max+log2_ncodes_a1+1 < row_size_max then
				for b in row_size_max downto n_max+log2_ncodes_a1+2 loop
  				sel_mcode(H)(b) := pla_element'(' ');
  			end loop;
			end if;
		else
			assert NO_WARNING
          report "vi_functions.gen_num_bit_errors: row_size_max not big enough!!"

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -