📄 vi_functions.vhd
字号:
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 + -