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

📄 vi_bench.vhd

📁 一个完整的viterbi译码程序和测试的程序
💻 VHD
字号:
-------------------------------------------------------------------------
-------------------------------------------------------------------------
--
-- Revision Control Information
--
-- Description	:  This package contains all the functions used by the bench
--
-- ALTERA Proprietary
-- Copyright 1999 (c) Altera Corporation
-- All rights reserved
--
-------------------------------------------------------------------------
-------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;
library Viterbi;
use Viterbi.vi_interface.all;
library STD;
use STD.TEXTIO.all;

package  vi_bench  is

Type real_array is array(NATURAL RANGE <>) of REAL;

function get_units(item : STRING) return TIME;
function String_2_Time(n: STRING) return TIME;

function generate_list_thresholds (softbits : NATURAL; threshold : REAL ) return real_array;

function Check_generics(test_for, node_sync, BER : STRING) return BOOLEAN;

function make_blank_hex (width, widthadd : NATURAL) return STRING;

function natural_2_sv (ARG, SIZE: NATURAL) return Std_Logic_vector;

function To_Character (Value: Std_logic) return Character;
function To_String (Value: INTEGER) return STRING;
function To_String (Value: Std_logic_vector) return STRING;
function evec2Hex(value: std_logic_vector; size: natural) return STRING;
function Hex2slv (Value: STRING; size: NATURAL) return Std_logic_vector;

-- this functions come and are for the high speed model of the lpm_ram_dp:

function int_to_str (value : integer) return STRING;
function hex_str_to_int (str : STRING) return INTEGER;
procedure Shrink_line(L : inout LINE; pos : in integer);

end vi_bench;


package body vi_bench is


function get_units(item : STRING) return TIME is

	variable time_unit : TIME;
	Subtype two_chars is STRING(1 TO 2);
	Subtype thr_chars is STRING(1 TO 3);

begin
	time_unit := 0 ns;
		if item="hr" then
			time_unit := 1 hr;
		elsif item="min" then
			time_unit := 1 min;
		elsif item="sec" then
			time_unit := 1 sec;
		elsif item="ms" then
			time_unit := 1 ms;
		elsif item="us" then
			time_unit := 1 us;
		elsif item="ns" then
			time_unit := 1 ns;
		elsif item="ps" then
			time_unit := 1 ps;
		elsif item="fs" then
			time_unit := 1 fs;
		else
			time_unit := 0 ns;
			ASSERT FALSE
			REPORT "vi_bench.get_units : Time unit not recognized"
			severity ERROR;
		end if;

	return time_unit;

end get_units;


function String_2_Time(n: STRING) return TIME is

	Type succ_stages is (looking_4_numbers, looking_4_spaces, finished);

	Variable stage : succ_stages;

  variable extracted_value : STRING(n'LOW to n'HIGH);
	variable item : character;
	variable I_ext, value : NATURAL;
	variable time_value, time_unit : TIME;

begin

	I_ext := n'LOW;
	stage := looking_4_numbers;
	time_value := 1 ns;
	main: For I_n in n'LOW to n'HIGH loop
	  item := n(I_n);
		if (I_n=n'LOW) and (item=' ') then
			ASSERT NO_WARNING
				REPORT "vi_bench.String_2_Time : Bad format, First item is space"
				severity ERROR;
				return time_value;
		elsif item /= ' ' and (stage = looking_4_numbers) then
			if check_base(item => item, base => "DEC") then
				extracted_value(I_ext) := n(I_n);
			else
				ASSERT NO_WARNING
				REPORT "vi_bench.String_2_Time : mismatch base - digit"
				severity ERROR;
				return time_value;
			end if;
			I_ext := I_ext + 1;
		elsif item /= ' ' and (stage=looking_4_spaces) then
			stage := finished;
			extracted_value(n'LOW to n'HIGH - I_n + 1) := n(I_n to n'HIGH);
			time_unit := get_units(item => extracted_value(n'LOW to n'HIGH - I_n + 1));
		elsif I_n=n'HIGH or (stage = finished) then
		 -- this is finished
			time_value := value * time_unit;
			return time_value;
--  fs-ps-ns-us-ms-sec-min-hr
--  fpnumsecihr
			
		elsif (item=' ') and (stage = looking_4_spaces) then
			I_ext := n'LOW;
		elsif (item=' ') and (stage = looking_4_numbers) then
			value := Convert_str_nat(pol_value => extracted_value(n'LOW to I_ext-1), base => "DEC");
			stage := looking_4_spaces;
			I_ext := n'LOW;
		end if;
	end loop main;
 	
end String_2_Time;


function generate_list_thresholds (softbits : NATURAL; threshold : REAL ) return real_array is

	Constant  size : NATURAL := 2**(softbits-1)-1;

	variable  result: real_array(size downto 1);
	variable  aux, aux1, aux2: REAL;

begin

	for I in 1 to size loop
--		aux1 := (int_2_re(x => integer'(I)) - 1.0)/(2.0**(softbits-1)-1.0);
		aux1 := (REAL(integer'(I)) - 1.0)/(2.0**(softbits-1)-1.0);
		aux2 := 1.0/(2.0**softbits-2.0);
		aux := aux1 + aux2;
		result(I) := aux;
	end loop;

	return result;

end function generate_list_thresholds;


function Check_generics(test_for, node_sync, BER : STRING) return BOOLEAN is
	variable result : BOOLEAN;
begin

result := TRUE;
if (test_for="node_sync" AND BER="unused") then
	ASSERT FALSE  
  report "It's not possible to test node synchronization feature without using BER block"
	severity ERROR;
	result := FALSE;
end if;
--if (test_for="BER" AND BER="unused") then
--	ASSERT FALSE  
--  report "It's not possible to test BER feature if BER is set to unused"
--	severity ERROR;
--	result := FALSE;
--end if;
if (test_for="node_sync" AND node_sync="unused") then
	ASSERT FALSE
  report "It's not possible to test node synchronization feature setting node_sync to unused"
	severity ERROR;
	result := FALSE;
end if;
if (node_sync="used" AND BER="unused") then
	ASSERT FALSE  
  report "It's not possible to have node synchronization feature without using then BER block"
	severity ERROR;
	result := FALSE;
end if;
return result;

end Check_generics;

function make_blank_hex (width, widthadd : NATURAL) return STRING is

		Constant FILE_NAME: STRING := "blank_"&To_String(INTEGER'(width))&"_"&To_String(INTEGER'(widthadd))&".hex";
		Constant colon : STRING := ":";
		constant zero_two : STRING := "02";
		constant zero_one : STRING := "01";
		Constant zero_zero : STRING := "00";
		Constant Hex_header : STRING := ":020000020000FC";
		Constant End_of_file_record : STRING := ":00000001FF";

		FILE F: TEXT open WRITE_MODE is FILE_NAME;

		Variable L: Line;
		Variable m_offset, l_offset: NATURAL := 0;
		Variable l_offset_str, m_offset_str, chksum_str, rlen_str : STRING(1 to 2) := "00";
		variable check_sum_nat: NATURAL := 0;

	begin

		WRITE(L, Hex_header, left);
		WRITELINE(F, L);		
		for offset in 0 to 2**widthadd-1 loop
			WRITE(L, colon, left);
			check_sum_nat := Ceil_DIV(width, 8);
			rlen_str := evec2Hex(value => natural_2_sv(arg => check_sum_nat, size => 8), size => 2);
			WRITE(L, rlen_str, left);
--			if width<=16 and width>8 then
--				WRITE(L, zero_two, left);
--			else
--				WRITE(L, zero_one, left);
--			end if;
			m_offset := offset/256;
			m_offset_str := evec2Hex(value => natural_2_sv(arg => m_offset, size => 8), size => 2);
			l_offset := offset mod 256;
			l_offset_str := evec2Hex(value => natural_2_sv(arg => l_offset, size => 8), size => 2);
			WRITE(L, m_offset_str, left);
			WRITE(L, l_offset_str, left);
			WRITE(L, zero_zero, left);  -- separator
			for I in 1 to check_sum_nat loop
				WRITE(L, zero_zero, left);
			end loop;
--			if width<=16 and width>8 then
--			  WRITE(L, zero_zero, left);  -- if m> 8 LSB data
--				check_sum_nat := 2;
--			else
--			  check_sum_nat := 1;
--			end if;
			check_sum_nat := check_sum_nat+m_offset+l_offset;
			-- calculate checksum
			check_sum_nat := check_sum_nat mod 256;
			check_sum_nat := 255 - check_sum_nat + 1;
			check_sum_nat := check_sum_nat mod 256;
			chksum_str := evec2Hex(value => natural_2_sv(arg => check_sum_nat, size => 8), size => 2);
			-- drop checksum
			WRITE(L, chksum_str, left);
			WRITELINE(F, L);
		end loop;
		WRITE(L, End_of_file_record, left);
		WRITELINE(F, L);

		return FILE_NAME;


end make_blank_hex;


function natural_2_sv (ARG, SIZE: NATURAL) return Std_Logic_vector is
    variable RESULT: Std_Logic_vector(SIZE-1 downto 0);
    variable I_VAL: NATURAL := ARG;
  begin
    --if (SIZE < 1) then return NASV;
    --end if;
    for I in 0 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 "RS_functions.Natural_2_sv: vector truncated"
          severity WARNING;
    end if;
    return RESULT;
end natural_2_sv;


function To_String (Value: Integer) return String is
  variable V: Integer;
  variable Result: String(1 to 11);
  variable Width: Natural := 0;
begin
  V := abs Value;
  for I in Result'Reverse_range loop
    case V mod 10 is
    when 0 => Result(I) := '0';
    when 1 => Result(I) := '1';
    when 2 => Result(I) := '2';
    when 3 => Result(I) := '3';
    when 4 => Result(I) := '4';
    when 5 => Result(I) := '5';
    when 6 => Result(I) := '6';
    when 7 => Result(I) := '7';
    when 8 => Result(I) := '8';
    when 9 => Result(I) := '9';
    when others =>
              Result(I) := '?';
    end case;
    if V > 0 then
       Width := Width + 1;
    end if;
    V := V / 10;
  end loop;
  if Width = 0 then
    Width := 1;
  end if;
  if Value < 0 then
    Result(Result'Length - Width) := '-';
    Width := Width + 1;
  end if;
  return Result(Result'Length - Width + 1 to Result'Length);
end To_String;

function To_Character (Value: Std_logic) return Character is
begin
  case Value is
  when 'U' => return 'U';
  when 'X' => return 'X';
  when '0' => return '0';
  when '1' => return '1';
  when 'W' => return 'W';
  when 'L' => return 'L';
  when 'H' => return 'H';
  when 'Z' => return 'Z';
  when '-' => return '-';
  end case;    
end To_Character;


function To_String (Value: Std_logic_vector) return String is
  constant V: Std_logic_vector(1 to Value'Length) := Value;
  variable Result: String(1 to Value'Length);
begin
  for I in Result'Range loop
    Result(I) := To_character(V(I));
  end loop;
  return Result;
end To_String;


function evec2Hex(value: std_logic_vector; size: natural) return string is
--	Subtype Quartet is Std_logic_vector(3+value'LOW downto value'LOW);
	Subtype Quartet is Std_logic_vector(3 downto 0);
	variable result : string(size downto 1);

begin
	for I in 1 to size loop

      case Quartet'(value((4*(I-1))+(3+value'LOW) downto 4*(I-1)+value'LOW )) is
      when "0000" => Result(I) := '0';
      when "0001" => Result(I) := '1';
      when "0010" => Result(I) := '2';
      when "0011" => Result(I) := '3';
      when "0100" => Result(I) := '4';
      when "0101" => Result(I) := '5';
      when "0110" => Result(I) := '6';
      when "0111" => Result(I) := '7';
      when "1000" => Result(I) := '8';
      when "1001" => Result(I) := '9';
      when "1010" => Result(I) := 'A';
      when "1011" => Result(I) := 'B';
      when "1100" => Result(I) := 'C';
      when "1101" => Result(I) := 'D';
      when "1110" => Result(I) := 'E';
      when "1111" => Result(I) := 'F';
      when others =>
          Result(I) := '?';
					assert FALSE
						report "value in evec2Hex function cannot be translated to Hex"
						severity WARNING;
      end case;			

	end loop;
	return result;			 
end evec2Hex;

function Hex2slv (Value: String; size: natural) return Std_logic_vector is
	variable result: Std_logic_vector(size downto 1);
begin
	For I in 1 to size/4 loop
	case Value(I) is
	when '0' => result(4*I downto 4*(I-1)+1):="0000";
	when '1' => result(4*I downto 4*(I-1)+1):="0001";
	when '2' => result(4*I downto 4*(I-1)+1):="0010";
	when '3' => result(4*I downto 4*(I-1)+1):="0011";
	when '4' => result(4*I downto 4*(I-1)+1):="0100";
	when '5' => result(4*I downto 4*(I-1)+1):="0101";
	when '6' => result(4*I downto 4*(I-1)+1):="0110";
	when '7' => result(4*I downto 4*(I-1)+1):="0111";
	when '8' => result(4*I downto 4*(I-1)+1):="1000";
	when '9' => result(4*I downto 4*(I-1)+1):="1001";
	when 'A'|'a' => result(4*I downto 4*(I-1)+1):="1010";
	when 'B'|'b' => result(4*I downto 4*(I-1)+1):="1011";
	when 'C'|'c' => result(4*I downto 4*(I-1)+1):="1100";
	when 'D'|'d' => result(4*I downto 4*(I-1)+1):="1101";
	when 'E'|'e'=> result(4*I downto 4*(I-1)+1):="1110";
	when 'F'|'f' => result(4*I downto 4*(I-1)+1):="1111";
	when others => result(4*I downto 4*(I-1)+1):="XXXX";
	end case;
	end loop;
	return result;
end Hex2slv;

function int_to_str( value : integer ) return string is
variable ivalue,index : integer;
variable digit : integer;
variable line_no: string(8 downto 1) := "        ";  
begin
	ivalue := value;
	index := 1;
	while (ivalue > 0) loop
		digit := ivalue MOD 10;
		ivalue := ivalue/10;
		case digit is
			when 0 =>
				line_no(index) := '0';
			when 1 =>
				line_no(index) := '1';
			when 2 =>
				line_no(index) := '2';
			when 3 =>
				line_no(index) := '3';
			when 4 =>
				line_no(index) := '4';
			when 5 =>
				line_no(index) := '5';
			when 6 =>
				line_no(index) := '6';
			when 7 =>
				line_no(index) := '7';
			when 8 =>
				line_no(index) := '8';
			when 9 =>
				line_no(index) := '9';
			when others =>
				ASSERT FALSE
				REPORT "Illegal number!"
				SEVERITY ERROR;
		end case;
		index := index + 1;
	end loop;
	return line_no;
end int_to_str;


function hex_str_to_int( str : string ) return integer is
variable len : integer := str'length;
variable ivalue : integer := 0;
variable digit : integer;
begin
	for i in len downto 1 loop
		case str(i) is
			when '0' =>
				digit := 0;
			when '1' =>
				digit := 1;
			when '2' =>
				digit := 2;
			when '3' =>
				digit := 3;
			when '4' =>
				digit := 4;
			when '5' =>
				digit := 5;
			when '6' =>
				digit := 6;
			when '7' =>
				digit := 7;
			when '8' =>
				digit := 8;
			when '9' =>
				digit := 9;
			when 'A' =>
				digit := 10;
			when 'a' =>
				digit := 10;
			when 'B' =>
				digit := 11;
			when 'b' =>
				digit := 11;
			when 'C' =>
				digit := 12;
			when 'c' =>
				digit := 12;
			when 'D' =>
				digit := 13;
			when 'd' =>
				digit := 13;
			when 'E' =>
				digit := 14;
			when 'e' =>
				digit := 14;
			when 'F' =>
				digit := 15;
			when 'f' =>
				digit := 15;
			when others =>
				ASSERT FALSE
				REPORT "Illegal character "&  str(i) & "in Intel Hex File! "
				SEVERITY ERROR;
		end case;
		ivalue := ivalue * 16 + digit;
	end loop;
	return ivalue;
end hex_str_to_int;


procedure Shrink_line(L : inout LINE; pos : in integer) is
	subtype nstring is string(1 to pos);
	variable stmp : nstring;
begin
	if pos >= 1 then
		read(l, stmp);
	end if;
end Shrink_line;


end vi_bench;

⌨️ 快捷键说明

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