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

📄 vi_functions.vhd

📁 一个完整的viterbi编码程序
💻 VHD
📖 第 1 页 / 共 3 页
字号:
          severity ERROR;
		end if;

--		tmp3 := tmp&tmp2;
--		for I in 1 to n_max+log2_ncodes_a1 loop
--			sel_mcode(H, I) := tmp3(I);
--		end loop;
	end loop;

return sel_mcode;

end gen_mcode_selector;


function Set_bmdeep(n_max, ncodes : NATURAL) return NATURAL is

	variable bmdeep : NATURAL;

begin

if ncodes > 2 then
--  bmdeep := LOG2_ceil_table(n_max+1)+1;
	-- pipeline in branch metric is being flatten for any n so ...
	bmdeep := 3;
else
--	bmdeep := LOG2_ceil_table(n_max+1);
	bmdeep := 2;
end if;
return bmdeep;

end function Set_bmdeep;


function gen_node_sync_mux_ctrl(n, m : STRING; n_max : NATURAL)	return array_of_pla_tables_t is

	Constant ncodes : NATURAL := Get_ncodes(n);
--	Constant n_max : NATURAL := Get_n_max_modes(n => n, m => m);
	Constant log2_ncodes : NATURAL := LOG2_ceil_table(ncodes);
  Constant log2_n_max : NATURAL := LOG2_ceil_table(n_max);
  Constant m_list : NATURAL_ARRAY(1 to ncodes) := Get_modes_list(modes => m, ncodes => ncodes);

	variable n_list : NATURAL_ARRAY(1 to ncodes);
  Variable node_synch_ctrl_matrix : array_of_pla_tables_t(n_max downto 1);
	
	variable tmp : pla_vector(log2_n_max downto 1);
	variable tmp2 : pla_vector(log2_n_max+log2_ncodes downto 1);
	variable in_pla, out_pla, n_sel : NATURAL;

begin

  n_list := Get_n_list(n => n, ncodes => ncodes);
  for I in 1 to n_max loop -- every PLA controlling every MUX between rrff and rrffa in hyb_bmp_cnt
		for J in 0 to 2**log2_ncodes-1 loop -- sel_code
		--  need to consider here the case that ncodes_max now is 5!!
			if (J+1<=ncodes) then
			  if m_list(J+1)=0 then
					n_sel := n_list(J+1);
				elsif m_list(J+1)=1 then
					n_sel := 4;  -- TCM
				end if;
			else
				n_sel := 2;
			end if;
		  for K in 0 to 2**log2_n_max-1 loop  -- state synch
				if K > n_sel-1 then
				-- output to 0
					tmp := (others => '-');
				else
					out_pla := (I-1+K) mod n_sel;
					tmp := natural_2_m(arg => out_pla, size => log2_n_max);
				end if;
				in_pla := J*(2**(log2_n_max)) + K;
				tmp2 := natural_2_m(arg => in_pla, size => log2_n_max+log2_ncodes);
				if 2*log2_n_max+log2_ncodes+1 <= row_size_max then
					-- output first
					for b in log2_n_max downto 1 loop
 						node_synch_ctrl_matrix(I)(in_pla+1)(b) := tmp(b);
  				end loop;
					node_synch_ctrl_matrix(I)(in_pla+1)(log2_n_max+1) := pla_element'(' ');
					-- now the input
					for b in 2*log2_n_max+log2_ncodes+1 downto log2_n_max+2 loop
  					node_synch_ctrl_matrix(I)(in_pla+1)(b) := tmp2(b-log2_n_max-1);
  				end loop;
					if 2*log2_n_max+log2_ncodes+1 < row_size_max then
						for b in row_size_max downto 2*log2_n_max+log2_ncodes+2 loop
  						node_synch_ctrl_matrix(I)(in_pla+1)(b) := pla_element'(' ');
  					end loop;
					end if;
				else
					assert NO_WARNING
          	report "vi_functions.gen_node_sync_mux_ctrl: row_size_max not big enough!!"
          	severity ERROR;
				end if;
			end loop;
		end loop;
		-- Fill the remaining positions in the tables with spaces
		for J in 2**(log2_ncodes+log2_n_max)+1 to max_two_pow_input loop
		  for b in row_size_max downto 1 loop
				node_synch_ctrl_matrix(I)(J)(b) := pla_element'(' ');
			end loop;
		end loop;
	end loop;

return node_synch_ctrl_matrix;

end function gen_node_sync_mux_ctrl;


function gen_num_bit_errors(m : NATURAL) return pla_table_t is
	
	Constant two_pow_m		: NATURAL := 2**m;
	Constant log2m        : NATURAL := log2_ceil_table(m+1);    

	variable tmp : pla_vector(m downto 1);
	variable tmp2 : pla_vector(log2m downto 1);

	variable tmp_nat, count_bits : NATURAL;

	variable num_bit_err_matrix : pla_table_t(two_pow_m downto 1);

begin

  for H in 1 to two_pow_m loop
		tmp_nat := H-1;
		count_bits := 0;
		for J in 1 to m loop
			if tmp_nat mod 2 = 1 then
				count_bits := count_bits + 1;
			end if;
			tmp_nat := tmp_nat / 2;
		end loop;
		tmp := natural_2_m(arg => H-1, size => m);
		tmp2 := natural_2_m(arg => count_bits, size => log2m);
		if log2m+m+1 <= row_size_max then
  		for I in log2m downto 1 loop
 				num_bit_err_matrix(H)(I) := tmp2(I);
  		end loop;
  		num_bit_err_matrix(H)(log2m+1) := pla_element'(' ');
  		for I in log2m+m+1 downto log2m+2 loop
  			num_bit_err_matrix(H)(I) := tmp(I-log2m-1);
  		end loop;
			if log2m+m+1 < row_size_max then
				for I in row_size_max downto log2m+m+2 loop
  				num_bit_err_matrix(H)(I) := pla_element'(' ');
  			end loop;
			end if;
		else
			assert NO_WARNING
          report "vi_functions.gen_num_bit_errors: row_size_max not big enough!!"
          severity ERROR;
		end if;
	end loop;

return num_bit_err_matrix;

end gen_num_bit_errors;

function Get_log2_n_list(n_list : NATURAL_ARRAY) return NATURAL_ARRAY is

	variable log2_n_list : NATURAL_ARRAY(n_list'LOW to n_list'HIGH);

begin

	For I in n_list'LOW to n_list'HIGH loop
		log2_n_list(I) := LOG2_ceil_table(n_list(I)+1);
	end loop;
	return log2_n_list;
	
end Get_log2_n_list;

function set_sequencer_count(arg : NATURAL) return Std_Logic_Vector is

	variable result : Std_Logic_Vector(arg+1 downto 1);

begin
-- if log2_cc=3 then 10-1 , else 2**log2_cc-1
	if arg=3 then
		result :=	natural_2_m(arg => 9, size => arg+1);
	else
		result :=	natural_2_m(arg => 2**arg-1, size => arg+1);
	end if;
	return result;

end set_sequencer_count;



-- at first arg will be L-2-log2(ACS) where ACS=1
function gen_read_trellis_seq(arg : NATURAL) return pla_table_t is
	
	Constant num_arg : NATURAL := 2**arg;
	variable tmp, tmp_keep, tmp_rot, index : pla_vector(arg downto 1);

	variable read_seq : pla_table_t(num_arg downto 1);

begin

  for H in 1 to num_arg loop
		tmp := natural_2_m(arg => (H-1)/2, size => arg);
		index := natural_2_m(arg => (H-1), size => arg);
		if ((H-1) mod 2)=0 then
			tmp_keep := tmp;
			for J in 1 to arg loop
				tmp_rot(J) := tmp(arg-J+1);
			end loop;
		else
			for J in 1 to arg loop
				if tmp_keep(arg-J+1)='1' then
					tmp_rot(J) := '0';
				elsif tmp_keep(arg-J+1)='0' then
					tmp_rot(J) := '1';
				else
					assert NO_WARNING
          report "vi_functions.gen_read_trellis_seq: bit in pla_table not 0 nor 1!!"
          severity ERROR;
				end if;
			end loop;
		end if;
		if 2*arg+1 <= row_size_max then
  		for b in arg downto 1 loop
 				read_seq(H)(b) := tmp_rot(b);
  		end loop;
  		read_seq(H)(arg+1) := pla_element'(' ');
  		for b in 2*arg+1 downto arg+2 loop
  			read_seq(H)(b) := index(b-arg-1);
  		end loop;
			if 2*arg+1 < row_size_max then
				for b in row_size_max downto 2*arg+2 loop
  				read_seq(H)(b) := pla_element'(' ');
  			end loop;
			end if;
		else
			assert NO_WARNING
          report "vi_functions.gen_read_trellis_seq: row_size_max not big enough!!"
          severity ERROR;
		end if;
	end loop;

return read_seq;

end gen_read_trellis_seq;


-- at first arg will be L-2-log2(ACS) where ACS=1
function gen_wr_trellis_even_seq(arg : NATURAL) return pla_table_t is
	
	Constant num_arg : NATURAL := 2**arg;
	variable tmp, tmp_rot : pla_vector(arg downto 1);

	variable wr_even_seq : pla_table_t(num_arg downto 1);

begin

  for H in 1 to num_arg loop
		tmp := natural_2_m(arg => H-1, size => arg);
		-- rotated
		for J in 1 to arg loop
			tmp_rot(J) := tmp(arg-J+1);
		end loop;
		if 2*arg+1 <= row_size_max then
  		for b in arg downto 1 loop
 				wr_even_seq(H)(b) := tmp_rot(b);
  		end loop;
  		wr_even_seq(H)(arg+1) := pla_element'(' ');
  		for b in 2*arg+1 downto arg+2 loop
  			wr_even_seq(H)(b) := tmp(b-arg-1);
  		end loop;
			if 2*arg+1 < row_size_max then
				for b in row_size_max downto 2*arg+2 loop
  				wr_even_seq(H)(b) := pla_element'(' ');
  			end loop;
			end if;
		else
			assert NO_WARNING
          report "vi_functions.gen_wr_trellis_even_seq: row_size_max not big enough!!"
          severity ERROR;
		end if;
	end loop;

return wr_even_seq;

end gen_wr_trellis_even_seq;

-- at first arg will be L-2-log2(ACS) where ACS=1
function gen_wr_trellis_odd_seq(arg : NATURAL) return pla_table_t is
	
	Constant num_arg : NATURAL := 2**arg;
	variable tmp, tmp_rot : pla_vector(arg downto 1);

	variable wr_odd_seq : pla_table_t(num_arg downto 1);

begin


  for H in 1 to num_arg loop
		tmp := natural_2_m(arg => H-1, size => arg);
		-- rotated and negated
		for J in 1 to arg loop
			if tmp(arg-J+1)='1' then
				tmp_rot(J) := '0';
			elsif tmp(arg-J+1)='0' then
				tmp_rot(J) := '1';
			else
				assert NO_WARNING
        report "vi_functions.gen_wr_trellis_odd_seq: bit in pla_table not 0 nor 1!!"
        severity ERROR;
			end if;
		end loop;
		if 2*arg+1 <= row_size_max then
  		for b in arg downto 1 loop
 				wr_odd_seq(H)(b) := tmp_rot(b);
  		end loop;
  		wr_odd_seq(H)(arg+1) := pla_element'(' ');
  		for b in 2*arg+1 downto arg+2 loop
  			wr_odd_seq(H)(b) := tmp(b-arg-1);
  		end loop;
			if 2*arg+1 < row_size_max then
				for b in row_size_max downto 2*arg+2 loop
  				wr_odd_seq(H)(b) := pla_element'(' ');
  			end loop;
			end if;
		else
			assert NO_WARNING
          report "vi_functions.gen_wr_trellis_odd_seq: row_size_max not big enough!!"
          severity ERROR;
		end if;
	end loop;

return wr_odd_seq;

end gen_wr_trellis_odd_seq;

function set_sequencer_width(arg : NATURAL) return NATURAL is

	variable result : NATURAL;

begin
	if arg=3 then
		result :=	3;
	else
		result :=	arg+1;
	end if;
	return result;

end set_sequencer_width;


function Calc_bitsout(L, ACS, V : NATURAL) return NATURAL is

	variable log2_cc, bitsout, bitsout_tmp, divisor : NATURAL;

begin
	log2_cc := L-2-LOG2_ceil_table(ACS);
	if log2_cc = 3 then
		divisor := 10;
	else
		divisor := 2** log2_cc;
	end if;
	bitsout_tmp := ceil_DIV(v+1, divisor);
	bitsout     := ceil_DIV(v+1+bitsout_tmp, divisor);
	if bitsout < 3 then
		bitsout := 3;
	end if;
	bitsout := bitsout + 1;
	return bitsout;
end function Calc_bitsout;


function un_encoded_bit_extract(two_re_enc_bits : Std_Logic_Vector(2 downto 1); sector: natural) return CHARACTER is

  variable unenc_bit : CHARACTER;

begin

if two_re_enc_bits="00" then
  if sector=1 or sector=0 or sector=7 or sector=6 then 
    unenc_bit:='0';
  else
    unenc_bit:='1';
  end if;
elsif two_re_enc_bits="01" then
	if sector=0 or sector=1 or sector=2 or sector=7 then 
    unenc_bit:='0';
  else
    unenc_bit:='1';
  end if;
elsif two_re_enc_bits="10" then
  if sector=4 or sector=1 or sector=2 or sector=3 then 
    unenc_bit:='0';
  else
    unenc_bit:='1';
  end if;
elsif two_re_enc_bits="11" then
  if sector=0 or sector=1 or sector=2 or sector=3 then 
    unenc_bit:='0';
  else
    unenc_bit:='1';
  end if;
else 
  unenc_bit :='X';
end if;
return unenc_bit;

end function un_encoded_bit_extract;


function init_state_metric_constructor(L_max, ncodes, bmgwide : NATURAL; L : STRING) return Std_Logic_3D_CUBE is

	Constant halfstates : NATURAL := 2**(L_max-2);
	Constant L_list  : NATURAL_ARRAY(1 to ncodes) := Get_n_list(n => L, ncodes => ncodes);
--	Constant bm_init_val : Std_Logic_Vector(bmgwide downto 1) := natural_2_m(arg => 2**(bmgwide-2), size => bmgwide);
	variable states_selection : NATURAL;
	variable bm_init_matrix : Std_Logic_3D_CUBE(ncodes downto 1, halfstates downto 1, bmgwide downto 1);

begin
	for I in 1 to ncodes loop
		states_selection := 2**(L_max - l_list(I));
		for J in 1 to halfstates loop
			if J=1 or J<= states_selection then
				for K in 1 to bmgwide loop
				-- value 2**(bmgwide-2) added
					if K=(bmgwide-1) then
						bm_init_matrix(I, J, K) := '1';
					else
						bm_init_matrix(I, J, K) := '0';
					end if;
				end loop;
			else
				for K in 1 to bmgwide loop
					bm_init_matrix(I, J, K) := '0';
				end loop;
			end if;
		end loop;
	end loop;

	return bm_init_matrix;

end function init_state_metric_constructor;


end vi_functions;

⌨️ 快捷键说明

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