I would like to separate my data with new line character in an output file, but the following codes result in error "can't resolve overload for procedure call":
write(out_line, "\n");
write(out_line, "");
write(out_line, '');
An example code how I want to use it:
ENTITY writer IS
PORT ( clk : IN STD_LOGIC := '0'; start : IN STD_LOGIC := '0');
END ENTITY;
ARCHITECTURE arch OF writer IS
SIGNAL vect : STD_LOGIC_VECTOR (2 downto 0) := "000";
TYPE state_type IS (init, write_file);
SIGNAL state : state_type := init;
BEGIN
PROCESS (clk, start)
FILE out_file : text;
VARIABLE out_line : line;
BEGIN
IF rising_edge(clk) THEN
CASE state IS
WHEN init =>
IF start = '1' THEN
state <= write_file;
ELSE
state <= init;
END IF;
WHEN write_file =>
state => init;
FOR i IN 0 TO 10 LOOP
write(out_line, vect);
writeline(out_file, out_line);
-- write(out_line, "\n"); <--
-- write(out_line, ""); <--
-- write(out_line, ''); <-- None of these work
writeline(out_file, out_line);
END LOOP;
END CASE;
END IF;
END PROCESS;
END ARCHITECTURE;
So I would like to know, is it possible in VHDL? If yes, how?
The following will consistently give you a single blank line:
write(out_line, string'(""));
writeline(out_file, out_line);
I suspect what #Dani posted may be tool dependent. For example while on one popular simulator, the following produces one line feed:
write(out_line, LF);
writeline(out_file, out_line);
However when I add a space after the LF, I get two lines:
write(out_line, LF & ' ');
writeline(out_file, out_line);
Creating a minimal, complete and verifiable example from the question's incomplete sample code:
library ieee; -- ADDED
use ieee.std_logic_1164.all; -- ADDED
use std.textio.all; -- ADDED
-- use ieee.std_logic_textio.all; -- ADDED for revisions earlier than -2008
ENTITY writer IS
-- PORT ( clk : IN STD_LOGIC := '0'; start : IN STD_LOGIC := '0');
END ENTITY;
ARCHITECTURE arch OF writer IS
SIGNAL vect : STD_LOGIC_VECTOR (2 downto 0) := "000";
-- TYPE state_type IS (init, write_file);
-- SIGNAL state : state_type := init;
BEGIN
PROCESS -- (clk, start)
FILE out_file : text;
VARIABLE out_line : line;
BEGIN
file_open(out_file, "some_file", WRITE_MODE); -- ADDED
-- IF rising_edge(clk) THEN
-- CASE state IS
-- WHEN init =>
-- IF start = '1' THEN
-- state <= write_file;
-- ELSE
-- state <= init;
-- END IF;
-- WHEN write_file =>
-- state => init;
FOR i IN 0 TO 10 LOOP
write(out_line, vect);
writeline(out_file, out_line);
-- write(out_line, "\n"); <--
-- write(out_line, ""); <--
-- write(out_line, ''); <-- None of these work
writeline(out_file, out_line);
END LOOP;
-- END CASE;
-- END IF;
wait; -- ADDED
END PROCESS;
END ARCHITECTURE;
demonstrates a way to get a blank line in the output:
some_file contents:
000
000
000
000
000
000
000
000
000
000
000
The second writeline procedure call produces an empty line without an intervening write procedure call.
Why is seen in IEEE Std 1076-2008 16.4 Package TEXTIO:
Procedures READLINE, WRITELINE, and TEE declared in package TEXTIO read and write entire lines of a file of type TEXT. Procedure READLINE causes the next line to be read from the file and returns as the value of parameter L an access value that designates an object representing that line. If parameter L contains a non-null access value at the start of the call, the procedure may deallocate the object designated by that value. The representation of the line does not contain the representation of the end of the line. It is an error if the file specified in a call to READLINE is not open or, if open, the file has an access mode other than read-only (see 5.5.2). Procedures WRITELINE and TEE each cause the current line designated by parameter L to be written to the file and returns with the value of parameter L designating a null string. Procedure TEE additionally causes the current line to be written to the file OUTPUT. If parameter L contains a null access value at the start of the call, then a null string is written to the file or files. If parameter L contains a non-null access value at the start of the call, the procedures may deallocate the object designated by that value. It is an error if the file specified in a call to WRITELINE or TEE is not open or, if open, the file has an access mode other than write-only.
The language does not define the representation of the end of a line. An implementation shall allow all possible values of types CHARACTER and STRING to be written to a file. However, as an implementation is permitted to use certain values of types CHARACTER and STRING as line delimiters, it might not be possible to read these values from a TEXT file.
A line feed (LF) format effector occurring as an element of a string written to a file of type TEXT, either using procedure WRITELINE or TEE, or using the WRITE operation implicitly defined for the type TEXT, is interpreted by the implementation as signifying the end of a line. The implementation shall transform the LF into the implementation-defined representation of the end of a line.
...
For each WRITE, OWRITE, and HWRITE procedure, after data is appended to the string value designated by the parameter L, L designates the entire line. The procedure may modify the value of the object designated by the parameter L at the start of the call or may deallocate the object.
If deallocation occurs out_line will have a value of null after a writeline call and a null string is written in the immediately following writeline call which also provides an end of line.
If the object value accessed by out_line is a null array (having no elements, 5.3.2.2 Index constraints and discrete ranges, a null string) the immediately following writeline call will result in an end of line being written to the file.
In essence your code example already contains one of these methods for writing a blank line, which depends on whether deallocation is used conditionally (may).
Variants of allocate() and free() can be relatively expensive in terms of execution time and when the size of the allocated object and it's element size is known a smaller 'allocated' object can be written to the same object space saving simulation time. The simulation kernel representation of an array object can have bounds separate from the array value, deallocation and re-allocation can be reserved for when the object size is larger than the previously allocated size or an explicit deallocate call occurs.
There's also a requirement that an implementation translate an LF character to an end of line in a write to a file. This is the other mechanism that allows you to write an LF character as the last or only character to a line and get a following blank line.
You could also explicitly write a null string to out_line
write(out_line, string'(""));
prior to the second writeline call. The qualified expression provides the type of the string literal unlike the attempt commented out in the original question where the type of the string literal can't be determined. See 9.3.2 Literals "... The type of a string or bit string literal shall be determinable solely from the context in which the literal appears, excluding the literal itself but using the fact that the type of the literal shall be a one-dimensional array of a character type. ...". The procedure write would be ambiguous in this context, failing overload resolution (12.5 The context of overload resolution).
Finally after a lot of searching and trying I found that the following code works:
write(out_line, lf);
writeline(out_file, out_line);
I found that write(out_line, cr); does the same thing, and write(out_line, nul); adds ' ' character between the outputs.
I want to read data from a text file one line at a time. And output at specific instance.
For that I have created to process. The code is used for generating stimulus signals in a test bench.
1st Process:-
Here we are trying to pre-read the data in an array. Also we want to count the no. of data values in one line.
data_count: process
variable anc_line : line;
variable anc_data : std_logic_vector(9 downto 0);
variable data_available : boolean;
variable result : anc_array;
variable count : integer := 0;
begin
file_open(file_anc, "file_anc.txt", read_mode); -- open file
if read_line_enable = '1' then -- read line only when it is high
readline(file_anc, anc_line); -- read 1st line
hread(anc_line, result(1), data_available); -- directing readin into the array and checking
-- data_available boolean. Return false when no data in line remain
while (data_available = true) loop -- LOops till the last data in one line is reached
for i in result'range loop -- initialising the array
hread(anc_line, anc_data, data_available); --redaing one data from the line
result(i) := anc_data;
data_counter <= count + 1; -- counting the no. of data values in one line. Will be used later
end loop;
wait until rising_edge(video_clk);
end loop;
end if;
file_close(file_anc);
wait;
end process;
2nd Process :-
Want to generate the enable signal on basis of condition. Then compare the hcount with the data_count signal to output the array. Hcout is basically a counter increasing with +1 at every clk. We output the data till the hcoutn is greater than the no. of data values in one line.
create_enable: process (video_clk)
begin
if rising_edge(video_clk) then -- creating the enable signal
if vcount = true and hcount = 0 then -- checking for conditions
read_line_enable <= '1';
else
read_line_enable <= '0';
end if;
-- insert data
if hcount <= data_counter then -- output data when condition is met
din_anc <= arr(hcount); -- output data<= array with index using hcoutn
else -- cause hcount increases from 0 to +1 at every clk
-- cycle.
din_anc <= "00"&x"20"; -- if hcount gets greater than the amnt of data in one line
-- put 20h in output
end if;
end if;
end process;
Problem?
1.Text File doesn't open.
2. Values not being read from txt to array
Summary :-
Can someone help in debugging the code. How can I read a text file to a array and then output it at specif condition. Or maybe you have some other way of doing it?
I have a for loop in process, which works fine with std_logic arrays, but not with record arrays. I use Xilinx ISE along with ISIM and the code is vhdl-93. The target will be a Spartan 3.
Here is the record definition:
TYPE spi_rx_t IS RECORD
CS : std_logic;
MOSI : std_logic;
CLK : std_logic;
END RECORD;
constant SYNC_LATCHES : integer := 2;
Here is the array definition and declaration:
type spi_rx_array_t is array (0 to SYNC_LATCHES) of spi_rx_t;
signal spi_in_array : spi_rx_array_t;
Below is the process:
spi_in_array(0).MOSI <= SPI_MOSI;
spi_in_array(0).CLK <= SPI_CLK;
spi_in_array(0).CS <= SPI_CS;
sync_p: process (clk_100)
begin
if rising_edge(clk_100) then
-- for I in 1 to SYNC_LATCHES loop
-- spi_in_array(I) <= spi_in_array(I - 1);
-- end loop;
spi_in_array(1) <= spi_in_array(0);
spi_in_array(2) <= spi_in_array(1);
end if;
end process;
The 2 lines below the commented code works exactly as expected (allowing me to synchronize external signals to clk_100), but I'd rather implement them as a for loop (such the commented one).
However, these commented lines does not produce the same result in my ISIM test bench (spi_in_array stays in unknown state when using the for loop). Why?
Please kindly help me with this.
As commented by Morten Zilmer, this is due to the VHDL concept "longest static prefix". This SO answer is similar to my issue.
In my case, the simplest way to resolve the issue was to move the assignment of the first element of the array into the same process as the for loop. I also had to decrease SYNC_LATCHES constant from 2 to 1, because spi_in_array(0) is now latched with clk_100.
sync_p: process (clk_100)
begin
if rising_edge(clk_100) then
spi_in_array(0).MOSI <= SPI_MOSI;
spi_in_array(0).CLK <= SPI_CLK;
spi_in_array(0).CS <= SPI_CS;
for I in 1 to SYNC_LATCHES-1 loop
spi_in_array(I) <= spi_in_array(I - 1);
end loop;
end if;
end process;
is it possible to write a module code for a test bench? I have a test bench code that reads a text file and shows it in the Isim but I want to put this data on a port and process it. how can I get it out of simulation environment? how can I write a module for that in VHDL? thank you
, the code is here:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use STD.textio.all; --Dont forget to include this library for file operations.
ENTITY read_file IS
END read_file;
ARCHITECTURE beha OF read_file IS
signal bin_value : std_logic_vector(2 downto 0):="000";
BEGIN
--Read process
process
file file_pointer : text;
variable line_content : string(1 to 3);
variable line_num : line;
variable j : integer := 0;
variable char : character:='0';
begin
--Open the file read.txt from the specified location for reading(READ_MODE).
file_open(file_pointer,"C:\read.txt",READ_MODE);
while not endfile(file_pointer) loop --till the end of file is reached continue.
readline (file_pointer,line_num); --Read the whole line from the file
--Read the contents of the line from the file into a variable.
READ (line_num,line_content);
--For each character in the line convert it to binary value.
--And then store it in a signal named 'bin_value'.
for j in 1 to 3 loop
char := line_content(j);
if(char = '0') then
bin_value(3-j) <= '0';
else
bin_value(3-j) <= '1';
end if;
end loop;
wait for 10 ns; --after reading each line wait for 10ns.
end loop;
file_close(file_pointer); --after reading all the lines close the file.
wait;
end process;
end beha;
In my VHDL project, my input is going to be extracted from a text file containing n bits of 1's and 0's. I am trying to make it as general as possible. I am familiar with how to read and write on a text file using test-bench, but I don't know how to check its length.
My code normally takes 64 bit as input, pass them through all the blocks and generate an output. If the remaining bits length is less than 64 then it passes through a specific block.
Let's say the text file contains 1000 bits. 15 x 64 = 960. 960 bits will pass through all blocks, the remaining 40 will pass by a specific block. This looks straight forward but in order for me to do such operations i need to know the length of the text file. If anyone can help that would be very beneficial.
The VHDL data structure length should be considered, not the file length since that is implementation specific and not VHDL specified.
If the bits are in one long string that is to be chopped up into 64-bit pieces with a remainder, then the entire string can be read into a VHDL line type, and reading from that line to a std_logic_vector type can then depend on the remaining bits (characters) in the line.
Below is a code example doing so:
library ieee;
use std.textio.all;
use ieee.std_logic_textio.all; -- Synopsys package; required for VHDL-2002 only
architecture syn of tb is
begin
process is
variable myl_v : line;
file txt_file : text;
variable slv_v : std_logic_vector(63 downto 0);
begin
file_open(txt_file, "input.txt", read_mode);
readline(txt_file, myl_v);
while myl_v'length > 0 loop
if myl_v'length >= slv_v'length then -- Full slv_v
report "Full...: " & myl_v.all(1 to slv_v'length);
read(myl_v, slv_v);
else -- Reduced slv_v
report "Reduced: " & myl_v.all(1 to myl_v'length);
read(myl_v, slv_v(myl_v'length - 1 downto 0)); -- Place reduced at LSBs
end if;
end loop;
file_close(txt_file);
wait;
end process;
end architecture;
Btw, to answer the question of "length of an input text file", then the length in characters can be determined by reading as many characters from the file as possible, for example with code like:
impure function file_length_in_characters(filename : string) return natural is
type char_file_t is file of character;
file char_file : char_file_t;
variable char_v : character;
variable res_v : natural;
begin
res_v := 0;
file_open(char_file, filename, read_mode);
while not endfile(char_file) loop
read(char_file, char_v);
res_v := res_v + 1;
end loop;
file_close(char_file);
return res_v;
end function;