📄 accel_tb_utils.vhd
字号:
if (iteration_io = FIXED_OP) then
write( l, string'( "fixed data rate ") );
elsif (iteration_io = DELAYED_OP) then
write( l, string'( "delayed data rate ") );
elsif (iteration_io = RANDOM_OP) then
write( l, string'( "random data rate ") );
end if ;
write( l, string'( "simulation completed " ) );
if errors /= 0 then
write( l, string'( "with " ) );
write( l, errors );
write( l, string'( " errors" ) );
else
write( l, string'( "without errors" ) );
end if;
writeline( output, l );
wait until eos = '0';
end process;
watch:
process ( errors )
begin
if max_errors /= 0 and errors > max_errors then
report "max differences exceeded" severity failure;
end if;
end process watch;
end arch;
library std;
use std.textio.all;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.numeric_bit.rising_edge;
use ieee.math_real.uniform;
library work;
use work.accel_tb_utils.all;
entity random is
generic ( seedOne : positive := 1
; seedTwo : positive := 1 );
port ( delay : out integer := 0
; action : in std_logic
; min : in integer
; max : in integer
);
end random;
architecture arch of random is
begin
process ( action, min, max )
variable seed1 : positive := seedOne;
variable seed2 : positive := seedTwo;
variable v : real;
variable i : integer;
variable m : integer;
variable old_input : std_logic;
variable current_min : natural;
variable current_max : natural;
variable first : boolean := true;
begin
if first or min /= current_min or max /= current_max then
seed1 := seedOne;
seed2 := seedTwo;
current_min := min;
current_max := max;
first := false;
end if;
if min = 0 and max = 0 then
delay <= 0;
elsif min = max then
delay <= min;
else
uniform( seed1, seed2, v );
v := real( max - min ) * v + real( min );
delay <= integer(v);
end if;
end process;
end arch;
----------------------------------------------------------------------------------
-- Clock Generator: Produces Both Phases of Clock --
----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity clk_generator is
generic ( clock_high : time := 50 ns;
clock_low : time := 50 ns
);
port ( rst : in std_logic;
clk : out std_logic;
clk_bar : out std_logic
);
end clk_generator;
architecture beh of clk_generator is
signal clk_tmp : std_logic; -- Internal name for clock
begin
clk <= clk_tmp;
clk_bar <= NOT( clk_tmp );
process (rst, clk_tmp)
begin
if ( rst = '1' ) then
clk_tmp <= '0';
else
if (clk_tmp = '1') then
clk_tmp <= '0' after clock_high;
else
clk_tmp <= '1' after clock_low;
end if;
end if;
end process;
end architecture beh; -- for clk_generator entity
----------------------------------------------------------------------------------
-- Reset Generator: Generates the System Wide Reset at Start of Simulation --
----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity rst_generator is
generic ( clock_low : time := 50 ns;
clock_high : time := 50 ns
);
port ( clk : in std_logic;
rst : out std_logic
);
end entity rst_generator;
architecture beh of rst_generator is
constant POWERUPDELAY : time := 200 ns;
begin
-- DR 952091: To get rid of the warning message about a "wait" statment
-- that does not have a sensitity list, replaced the commented out Process
-- Stmt with one concurrent assignment stmt.
--PKB process
--PKB begin
--PKB rst <= '1';
--PKB wait for POWERUPDELAY;
--PKB wait for (clock_low + clock_high);
--PKB rst <= '0' AFTER clock_low/10;
--PKB wait until ( false );
--PKB end process;
rst <= '1',
'0' AFTER (clock_low/10 + clock_low + clock_high + POWERUPDELAY);
end architecture beh; -- for rst_generator
----------------------------------------------------------------------------------
-- Input Stimulus Generators for Signed Types --
-- Reads Data From File Saved by Verify -fixedpoint --
----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use work.accel_tb_utils.all;
entity input_generator_signed is
generic ( -- define the generics
filename : string := "";
precision : integer := 0;
resolution : integer := 0;
num_of_elements : integer := 0;
input_delay_type : integer := 0;
input_delay_amount : integer := 0;
output_delay_type : integer := 0;
output_delay_amount : integer := 0;
push_mode_delay : integer := 16;
dut_sample_rate : integer := 16;
dut_latency : integer := 16
);
port ( rst : in std_logic;
clk : in std_logic;
data_req : in std_logic; -- when '1', then time to get more data
data : out signed( num_of_elements*(precision+resolution)-1 downto 0 );
data_avail : out std_logic; -- set to '1' when data is ready for reading.
end_of_file : out std_logic -- set to '1' when all data has been read.
);
end entity input_generator_signed;
architecture beh of input_generator_signed is
-- The Input Generator is used to mimc an upstream circuit that supplies
-- data to the Design Under Test (DUT) which was the RTL version of the
-- MATLAB Design Function. The basic operation is as follows
-- 1) Behavior is on the rising edge of the given clock. It is
-- assumed that this clock is 180 degrees out of phase
-- with the clock supplied to the DUT.
-- 2) Upon a Reset, all handshaking signals are initialized, and
-- the first set of data is applied and a delay counter
-- is set based upon the delay_type and delay_aount.
-- 3) When not in Reset, if we have delayed the appropriate number
-- of clock cycles from the previous time data was given and
-- if there is a request for more data, then give that new
-- data and set the fact we have to delay for the appropriate
-- number of clock cycles.
-- 4) When not in Reset, and we have not delayed the appropriate amount
-- of time since giving the last set of data, then continue
-- waiting.
constant BIT_WIDTH : integer := precision + resolution;
constant TOTAL_NUM_BITS : integer := num_of_elements*(precision+resolution);
file file_handle : text;
signal file_opened : boolean := false;
signal internal_eof : std_logic;
signal internal_data : signed( TOTAL_NUM_BITS-1 downto 0 );
signal delay_cnt : integer := 0;
signal delay_value : integer := 0;
begin
data <= internal_data;
end_of_file <= internal_eof;
process (rst, clk)
variable file_status : file_open_status;
variable frame_cnt : integer := 0;
variable num_lines_read : integer := 0;
variable data_line : line;
variable cur_data_as_integer : integer;
variable start_bit : integer; -- When working with a Vector of Data, this bit
variable end_bit : integer; -- Bit Positions are the locations the data is placed
-- within the flattened version of the port.
variable read_status : boolean;
begin
if ( rst = '1' ) then
-- Clear all status flags
num_lines_read := 1;
-- If Delays required, set the delay counter.
if ( push_mode_delay > 0 ) then
delay_cnt <= push_mode_delay - 1;
delay_value <= push_mode_delay - 1;
elsif ( input_delay_type = IGNORE_DELAY ) then
delay_cnt <= 0;
delay_value <= 0;
elsif ( input_delay_type = FIXED_DELAY ) then
delay_cnt <= input_delay_amount;
delay_value <= input_delay_amount;
elsif ( input_delay_type = RANDOM_DELAY ) then
assert true
report "RANDOM Delay during Input Generation is currently not supported. Will use Fixed Delay Type."
severity WARNING;
delay_cnt <= input_delay_amount;
delay_value <= input_delay_amount;
else
assert true
report "Unknown Delay Type on Input Generation. Will Ignore Delays."
severity WARNING;
delay_cnt <= 0;
delay_value <= 0;
end if;
if ( NOT( file_opened ) ) then
FILE_OPEN( file_status, file_handle, filename, READ_MODE );
assert (file_status = open_ok)
report "Could not open the input file " & filename & "\ for reading."
severity FAILURE;
file_opened <= true;
READLINE( file_handle, data_line );
for frame_cnt in num_of_elements-1 downto 0 loop
READ( data_line, cur_data_as_integer, read_status );
-- If data was not read from the line correctly, then it is an indicator
-- that the data is written in a format different from what is expected,
-- such as expecting 4 data elements on the line, but only got 3.
assert read_status
report "Failure to read data correctly from the file: " & filename
severity FAILURE;
-- We need to get the indivitual data elements from the file, and place
-- into a single vector. If there are multiple values, they are placed
-- into the single vector such that the "first" value is placed into the
-- most significant bits, and the "last" value is placed into the
-- least significant bits.
start_bit := TOTAL_NUM_BITS - frame_cnt*BIT_WIDTH - 1;
end_bit := TOTAL_NUM_BITS - (frame_cnt+1)*BIT_WIDTH;
internal_data( start_bit downto end_bit ) <= to_signed( cur_data_as_integer, BIT_WIDTH );
end loop;
if ( ENDFILE( file_handle ) ) then
internal_eof <= '1';
else
internal_eof <= '0';
end if;
data_avail <= '1';
end if;
elsif ( rising_edge(clk) ) then
if ( delay_cnt > 0 ) then
delay_cnt <= delay_cnt - 1;
if ( push_mode_delay = 0 ) then
--ETP internal_data <= (others => 'X');
data_avail <= '0';
else
if ( ( push_mode_delay - delay_cnt ) >= dut_sample_rate ) then
data_avail <= '0';
end if;
end if;
else
if ( ( data_req = '1' ) or ( push_mode_delay > 0 ) ) then
if ( internal_eof = '0' ) then
READLINE( file_handle, data_line );
for frame_cnt in num_of_elements-1 downto 0 loop
READ( data_line, cur_data_as_integer, read_status );
-- If data was not read from the line correctly, then it is an indicator
-- that the data is written in a format different from what is expected,
-- such as expecting 4 data elements on the line, but only got 3.
assert read_status
report "Failure to read data correctly from the file: " & filename
severity FAILURE;
-- We need to get the indivitual data elements from the file, and place
-- into a single vector. If there are multiple values, they are placed
-- into the single vector such that the "first" value is placed into the
-- most significant bits, and the "last" value is placed into the
-- least significant bits.
start_bit := TOTAL_NUM_BITS - frame_cnt*BIT_WIDTH - 1;
end_bit := TOTAL_NUM_BITS - (frame_cnt+1)*BIT_WIDTH;
internal_data( start_bit downto end_bit ) <= to_signed( cur_data_as_integer, BIT_WIDTH );
end loop;
data_avail <= '1';
delay_cnt <= delay_value;
num_lines_read := num_lines_read + 1;
if ( ENDFILE( file_handle ) ) then
internal_eof <= '1';
else
internal_eof <= '0';
end if;
else
data_avail <= '1';
end if;
else
data_avail <= '0';
end if;
end if;
end if;
end process;
end architecture beh; --of input_generator_signed
----------------------------------------------------------------------------------
-- Input Stimulus Generators for Unsigned Types --
-- Reads Data From File Saved by Verify -fixedpoint --
----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use work.accel_tb_utils.all;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -