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

📄 vi_functions.vhd

📁 一个完整的viterbi译码程序和测试的程序
💻 VHD
📖 第 1 页 / 共 3 页
字号:
-------------------------------------------------------------------------
-------------------------------------------------------------------------
--
-- Revision Control Information
--
-- Description	:  
--
-- ALTERA Proprietary
-- Copyright 2000 (c) Altera Corporation
-- All rights reserved
--
-------------------------------------------------------------------------
-------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
Library viterbi;
use viterbi.vi_interface.all;

package  vi_functions  is

--Constant NO_WARNING: BOOLEAN := FALSE;

-- It's got to be 32 to allow to have ACS units =32
-- 14/02/2004 I have aim for types that do not require 
-- these _max constant. types like the ones 
--   Std_Logic_3D_CUBE in vi_interface.
Constant BMG_MAX : NATURAL := 32;

Constant MAX_N : NATURAL := 7;

type INTEGER_ARRAY is array(NATURAL RANGE <>) of INTEGER;
--type NATURAL_ARRAY is array(NATURAL RANGE <>) of NATURAL;
type BOOLEAN_ARRAY is array(NATURAL RANGE <>) of BOOLEAN;
--type std_logic_matrix is array (natural range <>, natural range <>) of std_logic;
--type std_logic_cube is array (natural range <>, natural range <>, natural range <>) of std_logic;

--  this Constant is the maximum to value for n+LOG2_ceil_table(n)
--  which happens when n=7
Constant N_log2n_max : NATURAL := 10;

Subtype group_signals is Std_Logic_Vector(N_log2n_max downto 1);
Type mini_rom is ARRAY(NATURAL RANGE <>) of group_signals;

Constant max_two_pow_input : NATURAL := 2**6;

Subtype L_vector is Std_Logic_Vector(BMG_MAX downto 1);
type vector_2D is array(NATURAL RANGE <>) of L_vector;

Constant row_size_max: NATURAL := 31;

-- the previous value allows bitsout max of 26 which in turn allows V max to be about 207
-- combinations of L and ACS_units "on the rim" : L=4 ACS=1 ; L=5 and ACS=2 and so on.
Type pla_element is ('1', '0', '-', ' ');
type pla_vector is array (NATURAL range <>) of pla_element;
subtype pla_row is pla_vector(row_size_max downto 1);
Type pla_table_t is array (NATURAL range <>) of pla_row;
Subtype max_pla_table is pla_table_t(max_two_pow_input downto 1);
-- this type to substitute std_logic_cube 
Type array_of_pla_tables_t is array (NATURAL RANGE <>) of max_pla_table;


--function Ceil_DIV(a, d: in NATURAL) return NATURAL;
--function check_base(item : character; base : STRING) return BOOLEAN;
--function Convert_str_nat(pol_value, base : STRING) return NATURAL;
--function LOG2_ceil_table(x: in NATURAL) return NATURAL;
--function Get_ncodes(n: NATURAL_ARRAY) return NATURAL;
--function Get_n_max(n : NATURAL_ARRAY) return NATURAL;
--function Get_rr_size(n, softbits: in NATURAL; punctured_rate : in STRING) return NATURAL;
--function LOG2_ceil_avoid_one(n : in NATURAL) return NATURAL;
--function mul(a, b: in NATURAL) return NATURAL;

Function Trellis_constructor(n, L : NATURAL; ga, gb, gc, gd, ge, gf, gg : STRING) return NATURAL_ARRAY;
function Trellis_constructor_ncodes(ncodes, n_max, L_max : NATURAL; hypobit : Std_Logic;
                                    n, L, ga, gb, gc, gd, ge, gf, gg : STRING) return NATURAL_2D_ARRAY;

function a_ge_b(a, b : NATURAL) return NATURAL;

procedure pla_table(signal invec: in std_logic_vector;
										variable outvec: out std_logic_vector;
										Constant table: pla_table_t);

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

function get_polynomials(n, L_max, L_code : NATURAL; gen_pols : NATURAL_ARRAY) return vector_2D;

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

function natural_2_m (ARG, SIZE: NATURAL) return Std_Logic_vector;
function natural_2_m (ARG, SIZE: NATURAL) return pla_vector;

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

function Get_pol(pols : STRING;  index : NATURAL) return NATURAL;
--function Get_pol(pols : NATURAL_ARRAY; base : STRING;  index : NATURAL) return NATURAL;

function Get_n_min(n : NATURAL_ARRAY) return NATURAL;

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

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

function Transform_punctured_rate(punctured_rate : STRING) return NATURAL_ARRAY;

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

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

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

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

function Build_tree_arch(n : NATURAL) return NATURAL_ARRAY;

function Build_binary_table(n : NATURAL) return Vector_2D;

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

function gen_mcode_selector(n : NATURAL_ARRAY; n_max, ncodes : NATURAL) return pla_table_t;

function Set_bmdeep(n_max, ncodes : NATURAL) return NATURAL; --LOG2_ceil_table(n_max+1)+1;

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

function gen_num_bit_errors(m : NATURAL) return pla_table_t;

function Get_log2_n_list(n_list : NATURAL_ARRAY) return NATURAL_ARRAY;

function set_sequencer_count(arg : NATURAL) return Std_Logic_Vector;

function gen_read_trellis_seq(arg : NATURAL) return pla_table_t;

function gen_wr_trellis_even_seq(arg : NATURAL) return pla_table_t;

function gen_wr_trellis_odd_seq(arg : NATURAL) return pla_table_t;

function set_sequencer_width(arg : NATURAL) return NATURAL;

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

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

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

end vi_functions;


package body  vi_functions  is


function natural_2_m (ARG, SIZE: NATURAL) return Std_Logic_vector is
    variable RESULT: Std_Logic_vector(SIZE downto 1);
    variable I_VAL: NATURAL;
  begin
  	I_VAL := ARG;
    for I in 1 to RESULT'LEFT loop
      if (I_VAL mod 2) = 0 then
        RESULT(I) := '0';
      else RESULT(I) := '1';
      end if;
      I_VAL := I_VAL/2;
    end loop;
    if not(I_VAL =0) then
      assert NO_WARNING
          report "vi_functions.Natural_2_m: vector truncated"
          severity WARNING;
    end if;
    return RESULT;
end natural_2_m;


-- overloading 
function natural_2_m (ARG, SIZE: NATURAL) return pla_vector is
    variable RESULT: pla_vector(SIZE downto 1);
    variable I_VAL: NATURAL;
  begin
  	I_VAL := ARG;
    for I in 1 to RESULT'LEFT loop
      if (I_VAL mod 2) = 0 then
        RESULT(I) := '0';
      else RESULT(I) := '1';
      end if;
      I_VAL := I_VAL/2;
    end loop;
    if not(I_VAL =0) then
      assert NO_WARNING
          report "vi_functions.Natural_2_m: vector truncated"
          severity WARNING;
    end if;
    return RESULT;
end natural_2_m;


--  trying to make it FPGA Express compliant
--   Avoid while loops
function Get_pol(pols : STRING;  index : NATURAL) return NATURAL is
  variable extracted_value : STRING(pols'LOW to pols'HIGH);
	variable item : character;
	variable I_ext, count_spaces : NATURAL; -- indexes
	variable result : NATURAL;
	variable not_finished, looking_for_more_spaces : BOOLEAN;
	Constant base : STRING := "DEC";  -- DEC -> decimal or OCT -> octal base

begin

  count_spaces := 0;
	I_ext := pols'LOW;
	not_finished := TRUE;
	looking_for_more_spaces := FALSE;
	main: For I_pols in pols'LOW to pols'HIGH loop
	  item := pols(I_pols);
		if (I_pols=pols'LOW) and ((item=' ') or (item='_')) and not_finished then
			ASSERT NO_WARNING
				REPORT "vi_functions.Get_pol : Bad format on STRING of pols. First item is space"
				severity ERROR;
				return 0;
		elsif (item /= ' ') and (item /= '_') and not_finished then
			if check_base(item => item, base => base) then
				extracted_value(I_ext) := pols(I_pols);
			else
				ASSERT NO_WARNING
				REPORT "vi_functions.Get_pol : mismatch base - digit"
				severity ERROR;
				return 0;
			end if;
			-- finish here if last
			if count_spaces=index-1 and (I_pols=pols'HIGH) then
		 -- this is finished
			  not_finished := FALSE;
				result := Convert_str_nat(pol_value => extracted_value(pols'LOW to I_ext), base => base);
			else
				I_ext := I_ext + 1;
				looking_for_more_spaces := FALSE;
			end if;
		elsif ((item=' ') or (item='_')) and (not looking_for_more_spaces) and not_finished then
			count_spaces := count_spaces+1;
			looking_for_more_spaces := TRUE;
			if count_spaces=index then
		 -- this is finished
			  not_finished := FALSE;
				result := Convert_str_nat(pol_value => extracted_value(pols'LOW to I_ext-1), base => base);
			else
				I_ext := pols'LOW;
			end if;
		end if;
	end loop main;
	if not not_finished then
		return result;
	else
		ASSERT NO_WARNING
			REPORT "vi_functions.Get_pol : main loop has finished without a value : check ncodes and polynomials"
			severity ERROR;
		return 0;
	end if;
  	
end Get_pol;


function get_polynomials(n, L_max, L_code : NATURAL; gen_pols : NATURAL_ARRAY) return vector_2D is

	variable  result: vector_2D(n downto 1);

  begin

	for I in 1 to n loop
		result(I)(L_max downto 1) := natural_2_m(arg => gen_pols(I)*(2**(L_max-L_code)), size => L_max);
	end loop;
	
	return result;

end get_polynomials;


-- This function used in the parallel, not hybrid.
function Trellis_constructor(n, L : NATURAL; ga, gb, gc, gd, ge, gf, gg : STRING) return NATURAL_ARRAY is

	Subtype gen_pol_con Is NATURAL_ARRAY(1 to 7);

	Constant pol_sel : NATURAL := 1; 
	Constant halfstates : NATURAL := 2**(L-2);

	Constant g_a : NATURAL := Get_pol(pols => ga, index => pol_sel);
	Constant g_b : NATURAL := Get_pol(pols => gb, index => pol_sel);
	Constant g_c : NATURAL := Get_pol(pols => gc, index => pol_sel);
	Constant g_d : NATURAL := Get_pol(pols => gd, index => pol_sel);
	Constant g_e : NATURAL := Get_pol(pols => ge, index => pol_sel);
	Constant g_f : NATURAL := Get_pol(pols => gf, index => pol_sel);
	Constant g_g : NATURAL := Get_pol(pols => gg, index => pol_sel);
	Constant gen_pols : NATURAL_ARRAY(1 TO 7) := gen_pol_con'(g_a, g_b, g_c, g_d, g_e, g_f, g_g);
	Constant genvec : Vector_2D(n downto 1) := get_polynomials(n=>n, L_max=>L, L_code=>L, gen_pols=>gen_pols);

	Variable vecnode : Vector_2D(n downto 1);
	Variable state : Std_Logic_Vector(L downto 1);
 	variable vector : Std_Logic_Vector(n downto 1);
	variable trellis_hypo : NATURAL_ARRAY(halfstates downto 1);

	begin

----------

gha: FOR I IN 0 TO (halfstates-1) loop

	state(L downto 2) := natural_2_m(arg => I, size => L-1);
	state(1) := '0';
--	source(k+1)(L downto 2) <= natural_2_m(arg => K, size => L-1);
--	source(k+1)(1) <= '0';

	fg1: FOR k IN 1 TO n loop
	   vecnode(k)(1) := state(1) and genvec(k)(1);
	  fg2: FOR j IN 2 TO L loop
		  vecnode(k)(j) := (state(j) and genvec(k)(j)) xor vecnode(k)(j-1); 
	  END loop fg2;
	END loop fg1;
	fg3: FOR k IN 1 TO n loop
		--***********************
	  --*** LSB FIRST !!!!! ***
	  --***********************
		vector(k) := vecnode(n-k+1)(L);
	end loop fg3;
	trellis_hypo(I+1) := 1 + NATURAL'(conv_integer(arg => unsigned(vector)));

end loop gha;

--  encoder: auk_vit_vit_var_enc
--		Generic map (n => n, L => L, ga => ga, gb => gb, gc => gc, gd => gd, ge => ge, gf => gf, gg => gg)
--	  port map (state => source(k+1)(L downto 1), vector => hypotop(k+1)(n downto 1) );

  return trellis_hypo;
		
end function Trellis_constructor;


function Trellis_constructor_ncodes(ncodes, n_max, L_max : NATURAL; hypobit : Std_Logic;
                                    n, L, ga, gb, gc, gd, ge, gf, gg : STRING)
                                    return NATURAL_2D_ARRAY is

	Subtype gen_pol_con Is NATURAL_ARRAY(1 to 7);

	
--	Constant halfstates : NATURAL := 2**(L_max-2);
	Constant maxstates : NATURAL := 2**(L_max-1);
	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);
	
	
	Variable pol_sel : NATURAL;
	Variable g_a, g_b, g_c, g_d, g_e, g_f, g_g : NATURAL;
	Variable gen_pols : NATURAL_ARRAY(1 TO 7);
	Variable vecnode, genvec : Vector_2D(n_max downto 1);
	Variable state : Std_Logic_Vector(L_max downto 1);
 	variable vector : Std_Logic_Vector(n_max downto 1);
	variable trellis_hypo : NATURAL_2D_ARRAY(ncodes downto 1, maxstates downto 1);

	begin

----------

nc_loop: for H in 1 to ncodes loop

  pol_sel := H;
	g_a := Get_pol(pols => ga, index => pol_sel);
	g_b := Get_pol(pols => gb, index => pol_sel);
	g_c := Get_pol(pols => gc, index => pol_sel);
	g_d := Get_pol(pols => gd, index => pol_sel);
	g_e := Get_pol(pols => ge, index => pol_sel);
	g_f := Get_pol(pols => gf, index => pol_sel);
	g_g := Get_pol(pols => gg, index => pol_sel);
	gen_pols := gen_pol_con'(g_a, g_b, g_c, g_d, g_e, g_f, g_g);
	genvec := get_polynomials(n=>n_max, L_max=>L_max, L_code=>L_list(H), gen_pols=>gen_pols);


	gha: FOR I IN 0 TO (maxstates-1) loop

		state(L_max downto 2) := natural_2_m(arg => I, size => L_max-1);
--		state(1) := '0';
		state(1) := hypobit;

		fg1: FOR k IN 1 TO n_list(H) loop
		   vecnode(k)(1) := state(1) and genvec(k)(1);
		  fg2: FOR j IN 2 TO L_max loop
			  vecnode(k)(j) := (state(j) and genvec(k)(j)) xor vecnode(k)(j-1); 
		  END loop fg2;
		END loop fg1;
		fg3: FOR k IN 1 TO n_list(H) loop
			--***********************
		  --*** LSB FIRST !!!!! ***
		  --***********************
			vector(k) := vecnode(n_list(H)-k+1)(L_max);
		end loop fg3;
		trellis_hypo(H, I+1) := 1 + NATURAL'(conv_integer(arg => unsigned(vector(n_list(H) downto 1))));

	end loop gha;
end loop nc_loop;


return trellis_hypo;
		
end function Trellis_constructor_ncodes;



function a_ge_b(a, b : NATURAL) return NATURAL is

	variable result : NATURAL;

begin
	if a >= b then
	  result := 1;
	else
		result := 0;
	end if;
	return result;

end function a_ge_b;



procedure pla_table(signal invec: 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'HIGH+1;
    for j in outvec'HIGH+invec'HIGH+1 downto outvec'HIGH+invec'LOW+1 loop
      in_pos := in_pos - 1;

⌨️ 快捷键说明

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