1 ------------------------------------------------------------------------------- 3 --! @author Hipolito Guzman-Miranda 4 --! @brief Generates stimuli from a file 5 ------------------------------------------------------------------------------- 7 --! Use IEEE standard definitions library 9 --! Use std_logic* signal types 10 use ieee.std_logic_1164.
ALL;
11 --! Allows use of arithmetical operations between integers and vectors 13 --! Allows writing strings to lines and lines to files 15 --! Allows writing std_logic_vector(s) to line(s) in BIN, HEX, OCT and reading BIN, HEX, OCT vector(s) from line(s) 16 use ieee.std_logic_textio.
all;
17 --! For print() function 19 --! For datagen_invalid_data definition 22 --! @brief Reads stimuli from file and outputs it with specified format 24 --! @detailed Reads file at STIMULI_FILE, expecting STIMULI_NIBBLES chars in 25 --! each line. Data is expected in hex format: 4 bits per character (nibble). 26 --! Reads the data and outputs it with a width of DATA_WIDTH bits, asserting 27 --! valid='1' when a new data is available. Outputs a new data each THROUGHPUT 28 --! cycles, unless can_write='0'. When valid='0', output bits are set to 29 --! INVALID_DATA. After last data in STIMULI_FILE has been output, waits for 30 --! CYCLES_AFTER_LAST_VECTOR clk cycles and afterwards asserts endsim. 33 VERBOSE : := false;
--! Print more internal details 34 DEBUG : := false;
--! Print debug info (developers only) 35 STIMULI_FILE : := "../test/datagen_test.txt";
--! File where data is stored 38 THROUGHPUT : := 0;
--! Output 1 valid data each THROUGHPUT cycles 43 clk : in ;
--! Align generated data to this clock 44 can_write : in ;
--! Active high, tells datagen it can assert valid. Use for control-flow 46 valid : out ;
--! Active high, indicates data is valid 47 endsim : out --! Active high, tells the other simulation processes to close their open files 51 --! Architecture reads file lines and slices it into chunks of size \c DATA_WIDTH 52 architecture data_generation
of datagen is
66 report "datagen: STIMULI_NIBBLES must be a positive non-zero integer" 70 report "datagen: DATA_WIDTH must be a positive non-zero integer" 74 report "datagen: THROUGHPUT must be a positive non-zero integer" 78 report "datagen: DATA_WIDTH (" & 'image(DATA_WIDTH) & ") bits must fit into STIMULI_NIBBLES nibbles (4*" & 'image(STIMULI_NIBBLES) & ") bits" 82 report "datagen: An exact multiple of DATA_WIDTH (" & 'image(DATA_WIDTH) & ") must fit into STIMULI_NIBBLES nibbles (4*" & 'image(STIMULI_NIBBLES) & ") bits." 86 report "datagen: sent_data is negative (" & 'image(sent_data) & "). Aborting." 89 --! @brief Manage data generation from data in STIMULI_FILE 90 datagen_read :
process 92 file file_pointer : text;
--! File pointer 93 variable current_line : line;
--! Last line read from file 94 variable current_hex_data : (STIMULI_NIBBLES*4-1 downto 0);
--! Last line read, converted to hex data 95 variable chunk_idx : range 0 to NUM_CHUNKS := 0;
--! Points to current data chunk in line 96 variable cycles_to_wait : := THROUGHPUT - 1;
--! Cycles to wait before outputting next data 100 assert cycles_to_wait >= 0 101 report "datagen: cycles_to_wait is negative (" & 'image(cycles_to_wait) & "). Aborting." 105 print ("datagen: NUM_CHUNKS: " & 'image(NUM_CHUNKS));
107 file_open(file_pointer, STIMULI_FILE, READ_MODE);
109 wait until rising_edge(clk);
-- do nothing until first valid clock event 111 while (not endfile(file_pointer)) loop 113 print (DEBUG, "datagen: reading line");
114 readline (file_pointer, current_line);
-- Read the whole line from the file 116 -- Before converting line to std_logic_vector, assert that number of nibbles read matches expected 117 -- Since a line is a pointer (technically an "access", in VHDL) to a string, 118 -- current_line.all is a string, so check its length 120 report "datagen: unexpected number of nibbles in stimuli file, got " & 'image(current_line.all'LENGTH) & ", expected " & 'image(STIMULI_NIBBLES) 123 hread (current_line, current_hex_data);
-- Interpret the line as hex data and put it in a std_logic_vector 126 print (DEBUG, "datagen: chunk_idx: " & 'image(chunk_idx));
128 while (cycles_to_wait > 0) loop 129 print (DEBUG, "datagen: cycles_to_wait: " & 'image(cycles_to_wait));
130 cycles_to_wait := cycles_to_wait - 1;
134 wait until rising_edge(clk);
142 data <= current_hex_data(DATA_WIDTH*(chunk_idx+1)-1 downto DATA_WIDTH*chunk_idx);
--Get DATA_WIDTH bits from current_hex_data into data 143 last_valid_data <= current_hex_data(DATA_WIDTH*(chunk_idx+1)-1 downto DATA_WIDTH*chunk_idx);
--Store also, for the case where we have to output last_valid_data when valid='0' 147 chunk_idx := chunk_idx + 1;
148 wait until rising_edge(clk);
154 print ("datagen: " & 'image(sent_data) & " data sent, closing input file");
155 file_close(file_pointer);
158 while (cycles_to_wait > 0) loop 159 cycles_to_wait := cycles_to_wait - 1;
163 wait until rising_edge(clk);
166 report "datagen: asserting endsim. cycle_count: " & 'image(cycle_count) severity note;
170 end process datagen_read;
172 --! @brief Determine what will be the output when data_valid = '0' 191 end process invalid_data_behavior;
Reads stimuli from file and outputs it with specified format.
out validstd_logic
Active high, indicates data is valid.
DEBUGboolean := false
Print debug info (developers only)
Common datatypes and component declarations.
CYCLES_AFTER_LAST_VECTORinteger := 10
Number of cycles between last data and assertion of endsim.
std_logic_vector( DATA_WIDTH- 1 downto 0) invalid_output
Output value when data_valid = '0'.
integer := 0 sent_data
Data sent to output.
INVALID_DATAdatagen_invalid_data := unknown
Output value when data is not valid.
STIMULI_NIBBLESinteger := 2
Maximum hex chars for each input data.
THROUGHPUTinteger := 0
Output 1 valid data each THROUGHPUT cycles.
(keep,uninitialized,unknown,zero,one,high_impedance,weak_unknown,weak_zero,weak_one,dont_care) datagen_invalid_data
Output of datagen when valid='0'.
out datastd_logic_vector( DATA_WIDTH- 1 downto 0)
Generated data.
integer := 4* STIMULI_NIBBLES/ DATA_WIDTH NUM_CHUNKS
Each line in input file equals to NUM_CHUNK data of DATA_WIDTH.
VERBOSEboolean := false
Print more internal details.
in can_writestd_logic
Active high, tells datagen it can assert valid. Use for control-flow.
in clkstd_logic
Align generated data to this clock.
STIMULI_FILEstring := "../test/datagen_test.txt"
File where data is stored.
integer := 0 cycle_count
Cycle counter.
std_logic_vector( DATA_WIDTH- 1 downto 0) last_valid_data
Last data when valid was '1'.
DATA_WIDTHinteger := 8
Width of generated data.
out endsimstd_logic
Active high, tells the other simulation processes to close their open files.
Allows for text output in simulation.
_library_ ieeeieee
Use IEEE standard definitions library.