?? vi_functions.vhd
字號:
-------------------------------------------------------------------------
-------------------------------------------------------------------------
--
-- 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 + -