how to read a 32 bit std_logic_vector data from a text file in VHDL - vhdl

I want to read 32bit signed number from a text file and store that in a variable. I have program for integer read but it is not working for std_logic_vector type.

With VHDL-2008, it can be done like:
library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;
architecture syn of tb is
begin
process is
file txt_file : text;
variable line_v : line;
variable slv_v : std_logic_vector(31 downto 0);
variable good_v : boolean;
begin
-- Write text file with std_logic_vector
file_open(txt_file, "test.txt", write_mode);
slv_v := X"1234" & "XXXXXXXX" & "ZZZZZZZZ" ;
write(line_v, slv_v);
writeline(txt_file, line_v);
file_close(txt_file);
-- Read text file with std_logic_vector
file_open(txt_file, "test.txt", read_mode);
readline(txt_file, line_v);
report "line_v: " & line_v.all;
read(line_v, slv_v, good_v);
file_close(txt_file);
-- Done
wait;
end process;
end architecture;
The "test.txt" text file then contains:
0001001000110100XXXXXXXXZZZZZZZZ
With VHDL-2002, the std_logic_vector is not supported in write/read procedures, but the Synopsys package ieee.std_logic_textio can be used to provide procedures with:
use ieee.std_logic_textio.all;

Related

ISE14.6 VHDL textio problem, about writing line at the output file

while preparing for a project about digital circuit class, I have a question about reading lines from 'input.txt' to writing lines at 'output.txt'.
I was intend to copy the 'input.txt' lines to 'output.txt' lines. However, there was unintended integers at the 'output.txt'. My codes are below.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.STD_LOGIC_TEXTIO.ALL;
use STD.TEXTIO.ALL;
entity TOP_Xray_cnn is
port( clk: in std_logic);
end TOP_Xray_cnn;
architecture Behavioral of TOP_Xray_cnn is
begin
process(clk)
file inFile : text open read_mode is "input.txt";
file outFile: text open write_mode is "output.txt";
variable line_in : line;
variable line_out : line;
variable data_in : integer;
variable data_out : integer;
begin
if rising_edge(clk) then
while not(endfile(inFile)) loop
readline(inFile, line_in);
read(line_in, data_in);
data_out := data_in + 1;
write(line_out, data_out);
writeline(outFile, line_out);
end loop;
end if;
file_close(inFile);
file_close(outFile);
end process;
end Behavioral;
Input.txt
1
2
3
4
5
output.txt
22
3
4
5
6
what happen to the first row of output.txt file?
why are there two '2' which I intend one '2' ??

how to read image file and convert it to bits in vhdl

I am trying to read an image file using textio package in vhdl.
If i open an .jpg with notepad , i will get some junk data but actually it is ASCII data . Here i am trying to read these ascii data and convert them into bytes.
below is my code:
library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;
use ieee.std_logic_textio.all;
entity file_io is
port (
clk: in std_logic;
Data: out std_logic_vector(7 downto 0)
);
end entity;
architecture behav of file_io is
signal test_data : std_logic_vector(7 downto 0);
use ieee.numeric_std.all;
use std.textio.all;
use ieee.std_logic_textio.all;
begin
File_reader:process(clk)
file f : text open read_mode is "C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg";
variable L: line;
variable var_int: integer:= 0;
variable var_char: character;
begin
if rising_edge(clk) then
while not endfile(f) loop
readline(f, L);
read(L, var_char);
var_int := character'pos(var_char);
test_data <= std_logic_vector(to_unsigned(var_int, test_data'length));
end loop;
end if;
Data <= test_data;
end process;
end architecture behav;
testbench:
LIBRARY ieee;
use ieee.std_logic_1164.ALL;
use std.textio.all;
ENTITY file_io_test IS
END file_io_test;
ARCHITECTURE behavior OF file_io_test IS
use work.io.all;
signal clk: std_logic := '0';
signal Data: std_logic_vector(7 downto 0);
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
UUT:
entity work.file_io(behav)
port map (
clk => clk,
Data => Data
);
-- Clock process definitions( clock with 50% duty cycle is generated here.
clk_process :process
begin
clk <= '1';
wait for clk_period/2; --for 5 ns signal is '1'.
clk <= '0';
wait for clk_period/2; --for next 5 ns signal is '0'.
end process;
end behavior;
I am getting only one byte in waveform. expected result is : Every clock cycle new character should be rread and new byte should be obtained.
below is waveform:
below is the image I am trying to read:
You have a while loop placed inside the rising_edge part of your process. What happens is that when the first clock edge occurs, the while loop iterates until the end of the file and gives you the last byte of the input image.
Removing the while loop statement should solve your issue.
The question has a fundamental flaw. You can't use textio to read binary values, it's for text.
See IEEE Std 1076-2008 16.4 Package TEXTIO paragraphs 3 (in part) and 4:
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. ...
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.
And that can be demonstrated with your Chrysanthemum.jpg:
It is possible in VHDL to read raw characters one at a time (matching your need).
See IEEE Std 1076-2008 5.5 File types:
So all we have to do is declare a file type and we get these procedures defined implicitly.
We can use them to invoke raw read, without any end of line issues caused by textio:
library ieee;
use ieee.std_logic_1164.all;
entity file_io is
port (
clk: in std_logic;
Data: out std_logic_vector(7 downto 0);
done: out boolean
);
end entity;
architecture foo of file_io is
use ieee.numeric_std.all;
begin
File_reader:
process (clk)
-- "C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg";
constant filename: string := "Chrysanthemum.jpg"; -- local to sim
variable char_val: character;
variable status: FILE_OPEN_STATUS;
variable openfile: boolean; -- FALSE by default
type f is file of character;
file ffile: f;
variable char_count: natural := 0;
begin
if rising_edge (clk) then
if not openfile then
file_open (status, ffile, filename, READ_MODE);
if status /= OPEN_OK then
report "FILE_OPEN_STATUS = " &
FILE_OPEN_STATUS'IMAGE(status)
severity FAILURE;
end if;
report "FILE_OPEN_STATUS = " & FILE_OPEN_STATUS'IMAGE(status);
openfile := TRUE;
else
if not endfile(ffile) then
read(ffile, char_val);
-- report "char_val = " & character'image(char_val);
char_count := char_count + 1;
Data <= std_logic_vector (
to_unsigned(character'pos(char_val),
Data'length) );
end if;
if endfile(ffile) then -- can occur after last character
report "ENDFILE, read " &
integer'image(char_count) & "characters";
done <= TRUE;
FILE_CLOSE(ffile);
end if;
end if;
end if;
end process;
end architecture foo;
library ieee;
use ieee.std_logic_1164.all;
entity file_io_test is
end file_io_test;
architecture behavior of file_io_test is
signal clk: std_logic := '0';
signal data: std_logic_vector(7 downto 0);
signal done: boolean;
constant clk_period: time := 10 ns;
begin
uut:
entity work.file_io(foo)
port map (
clk => clk,
data => data,
done => done
);
clk_process:
process
begin
if not done then
clk <= '1';
wait for clk_period/2;
clk <= '0';
wait for clk_period/2;
else
wait;
end if;
end process;
end architecture behavior;
Now we can have all the characters than can delimit a line show up in our read:
Note that package std.textio is not made visible through any context item.

Read textfile in VHDL testbench

I have a file source.txt, it looks like this:
00660066006700670067006800680069006B006D006E
00660066006700670067006800680069006B006D006E
00660066006700670067006800680069006B006D006E
00660066006700670067006800680069006B006D006E
00660066006700670067006800680069006B006D006E
0065006500660067006700690069006A006B006C006E
00650065006600670067006700680069006A006C006D
00650065006600670067006600660068006A006B006D
006500650066006700670065006600670069006B006D
00650065006600670067006600670068006A006C006D
0065006500660067006700690069006A006B006C006E
*
After each line there is the hidden newline character '\n'.
The asterix '*' is my visible end-of-file character.
How do I write a testbench in VHDL that does the following:
read file
store one line in a vector
write that vector in a new target.txt
Using VHDL-2008, and showing the std_logic_vector underway, the code can be:
library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;
entity tb is
end entity;
architecture syn of tb is
begin
process is
variable line_v : line;
file read_file : text;
file write_file : text;
variable slv_v : std_logic_vector(44 * 4 - 1 downto 0);
begin
file_open(read_file, "source.txt", read_mode);
file_open(write_file, "target.txt", write_mode);
while not endfile(read_file) loop
readline(read_file, line_v);
hread(line_v, slv_v);
report "slv_v: " & to_hstring(slv_v);
hwrite(line_v, slv_v);
writeline(write_file, line_v);
end loop;
file_close(read_file);
file_close(write_file);
wait;
end process;
end architecture;

errors in VHDL code using fpga advantage

I need your help in fixing some errors in my vhdl code. I am using fpga advantage 5.2, its too old, but I am using it because of block diagram, instead of writing the codes with myself.I am developing mips processor using vhdl, I have finished all the blocks except two blocks, which are data memory and instruction memory. Both blocks have the same errors:
Data memory errors:
ERROR: C:/Single-cycle processor/Processor/hdl/dmem_untitled.vhd(34):
near "is": expecting: BEGIN ERROR: C:/Single-cycle
processor/Processor/hdl/dmem_untitled.vhd(51): near "process":
expecting: ';'
instruction memory errors:
ERROR: C:/Single-cycle processor/Processor/hdl/imem_untitled.vhd(38):
near "is": expecting: BEGIN ERROR: C:/Single-cycle
processor/Processor/hdl/imem_untitled.vhd(53): near "process":
expecting: ';'
here is the code for the data memory:
-- hds header_start
--
-- VHDL Architecture Processor.dmem.untitled
--
-- Created:
-- by - Ahmed.UNKNOWN (AHMED-PC)
-- at - 01:58:50 04/21/2016
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2001.5 (Build 170)
--
-- hds header_end
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.all;
use IEEE.STD_LOGIC_SIGNED.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.std_logic_textio.all;
library STD;
use STD.textio.all;
ENTITY dmem IS
-- Declarations
port(clk, we: in STD_LOGIC;
a, wd: in STD_LOGIC_VECTOR (15 downto 0);
rd: out STD_LOGIC_VECTOR (15 downto 0));
END dmem ;
-- hds interface_end
ARCHITECTURE untitled OF dmem IS
BEGIN
process is
type ramtype is array (63 downto 0) of STD_LOGIC_VECTOR(15 downto 0);
variable mem: ramtype;
variable IADR: INTEGER;
begin
IADR:= CONV_INTEGER(a(7 downto 2));
-- read or write memory
--loop
if rising_edge(clk) then
if (we='1') then mem (IADR):= wd;
end if;
end if;
rd <= mem (IADR);
wait on clk, a;
--end loop;
end process;
END untitled;
Also the code for the instruction memory :
-- hds header_start
--
-- VHDL Architecture Processor.IMEM.untitled
--
-- Created:
-- by - Ahmed.UNKNOWN (AHMED-PC)
-- at - 02:17:30 04/21/2016
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2001.5 (Build 170)
--
-- hds header_end
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_SIGNED.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.std_logic_textio.all;
library STD;
use STD.textio.all;
ENTITY IMEM IS
-- Declarations
port(
rd: out STD_LOGIC_VECTOR(31 downto 0);
a: in STD_LOGIC_VECTOR(5 downto 0)
);
END IMEM ;
-- hds interface_end
ARCHITECTURE untitled OF IMEM IS
begin
ROM_PROCESS: process(a) is
type MEM is array(0 to 63) of STD_LOGIC_VECTOR(31 downto 0);
variable MEMORY: MEM := (others => X"00000000");
variable IADR: INTEGER;
begin
memory(0) := X"00611820" ; -- add $3, $3, $1
memory(1) := X"ac030004" ; -- sw $3, 4($0)
memory(2) := X"00221024" ; -- and $2,$1,$2
memory(3) := X"10220001" ; -- beq $1, $2, SAME
memory(4) := X"8c010004" ; -- lw $1, 4($0)
memory(5) := X"0022182a" ; -- SAME: slt $3, $1, $2
IADR:= CONV_INTEGER(a);
rd <= MEMORY(IADR);
end process;
END untitled;
The is in a process statement is optional from IEEE Std 1076-1993 forward but not allowed in the -1987 original revision of the VHDL standard.
Remove the is in both files following the process sensitivity lists. This tells us you are analyzing the VHDL with a -1987 compliant tool (for synthesis?).
Also note your use clauses are a mess. Package numeric_std should never be used with Synopsys packages std_logic_arith or std_logic_unsigned. You can simply comment out that use clause.
There's an implicit library clause making the library logical name std available, you don't need that. You aren't using textio either.
Your code would analyzes unchanged with a -1993 revision compliant VHDL tool.

Error : Library "IEEE" does not contain primary unit "numeric_std_unsigned"

I'm using Quartus prime edition v15.1 for writing a register file and I need to use the numeric_std_unsigned package. On compiling, there's an error saying
Error (10481): VHDL Use Clause error : design library "IEEE" does not contain primary unit "NUMERIC_STD_unsigned". Verify that the primary unit exists in the library and has been successfully compiled.
How doesn't the IEEE library have the numeric_std_unsigned package? I've searched a lot and found that IEEE actually supports it. And if so, how can I firstly download the package and install it to the compiler or add it to my project?
EDIT
Here's my code:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.numeric_std_unsigned.all;
entity regfile is
port( clk: in STD_LOGIC;
regwrite: in STD_LOGIC;
rs, rt, rd: in STD_LOGIC_VECTOR(1 downto 0);
data_in: in STD_LOGIC_VECTOR(15 downto 0);
rd1, rd2: out STD_LOGIC_VECTOR(15 downto 0));
end;
architecture behave of regfile is
type registerFile is array (3 downto 0) of STD_LOGIC_VECTOR(15 downto 0);
signal registers: registerFile;
begin
process(clk) begin
if rising_edge(clk) then
if regwrite='1' then
registers(to_integer(unsigned(rd))) <= data_in;
end if;
end if;
end process;
process(all)
begin
if (to_integer(rs)=0)
then rd1 <= X"0000";
else rd1 <= registers(to_integer(unsigned(rs)));
end if;
if (to_integer(rt)=0)
then rd2 <= X"0000";
else rd2 <= registers(to_integer(unsigned(rt)));
end if;
end process;
end;
When I use IEEE.numeric_std_unsigned.all the compiler reports the error I posted above.
And when I use IEEE_numeric_std.all the compiler reports
can't determine type of object at to_integer
more than one Use Clause imports a declaration of simple name unsigned -- none of the declarations are directly visible
Once you edited your question to provide a Minimal, Complete, and Verifiable example the error is clearly visible.
Remove the use clause with std_logic_arith, it's incompatible with the unsigned declaration package numeric_std_unsigned uses (referenced from a use clause invoking ieee.numeric_std.all). In it's place use
use ieee.numeric_std.all;
Some of the to_integer function calls found in your regfile architecture have a signature of [STD_ULOGIC_VECTOR return NATURAL].
(STD_ULOGIC_VECTOR is the base type for resolved subtype STD_LOGIC_VECTOR in package std_logic_1164 in VHDL -2008).
Some to_integer conversion function calls (e.g. to_integer(rs)) require package numeric_std_unsigned.
Those depending on package numeric_std (e.g. registers(to_integer(unsigned(rs))) also depend on a visible declaration for type unsigned being the same as the type declaration of the same name being visible in package numeric_std (referenced in a use clause in package numeric_std_unsigned).
In VHDL each declaration is unique even if they have the same name. Which one you are referencing is governed by visibility rules.
Before changing the use clause only the unsigned type declared in the Synopsys package was visible in your entity and architecture pair.
After switching std_logic_arith to numeric_std your code analyzes with a -2008 compliant VHDL implementation:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
-- use IEEE.std_logic_arith.all;
use ieee.numeric_std.all;
use IEEE.numeric_std_unsigned.all;
entity regfile is
port (
clk: in STD_LOGIC;
regwrite: in STD_LOGIC;
rs, rt, rd: in STD_LOGIC_VECTOR(1 downto 0);
data_in: in STD_LOGIC_VECTOR(15 downto 0);
rd1, rd2: out STD_LOGIC_VECTOR(15 downto 0)
);
end entity;
architecture behave of regfile is
type registerFile is array (3 downto 0) of STD_LOGIC_VECTOR(15 downto 0);
signal registers: registerFile;
begin
process (clk)
begin
if rising_edge(clk) then
if regwrite = '1' then
registers(to_integer(unsigned(rd))) <= data_in;
end if;
end if;
end process;
process (all)
begin
if to_integer(rs) = 0 then
rd1 <= X"0000";
else
rd1 <= registers(to_integer(unsigned(rs)));
end if;
if to_integer(rt) = 0 then
rd2 <= X"0000";
else
rd2 <= registers(to_integer(unsigned(rt)));
end if;
end process;
end architecture;
Style changes not withstanding the only change is the use clause.
You could remove the dependency on package numeric_std by changing the to_integer function calls with the signature [UNSIGNED return NATURAL] to [STD_ULOGIC_VECTOR return NATURAL]:
library ieee;
use ieee.std_logic_1164.all;
-- use IEEE.std_logic_arith.all;
-- use ieee.numeric_std.all;
use IEEE.numeric_std_unsigned.all;
entity regfile is
port (
clk: in std_logic;
regwrite: in std_logic;
rs, rt, rd: in std_logic_vector(1 downto 0);
data_in: in std_logic_vector(15 downto 0);
rd1, rd2: out STD_LOGIC_VECTOR(15 downto 0)
);
end entity;
architecture behave of regfile is
type registerFile is array (3 downto 0) of STD_LOGIC_VECTOR(15 downto 0);
signal registers: registerFile;
begin
process (clk)
begin
if rising_edge(clk) then
if regwrite = '1' then
registers(to_integer(rd)) <= data_in;
end if;
end if;
end process;
process (all)
begin
if to_integer(rs) = 0 then
rd1 <= X"0000";
else
rd1 <= registers(to_integer(rs));
end if;
if to_integer(rt) = 0 then
rd2 <= X"0000";
else
rd2 <= registers(to_integer(rt));
end if;
end process;
end architecture;
Note we've gotten rid of the use clause with package numeric_std and dropped some type conversions for generating the indexes for indexed names selecting registers elements for writes to the register file as well as both read ports.
Both these modifications to your code example analyze, elaborate and simulate telling us the indexes work correctly. The second one using only package numeric_std_unsigned enhances readability.
And of course if your VHDL tool is actually missing package numeric_std_unsigned and it isn't cured by re-installation or updating the Quartus tools you could use a -1993 compliant design description:
library ieee;
use ieee.std_logic_1164.all;
-- use IEEE.std_logic_arith.all;
use ieee.numeric_std.all;
-- use IEEE.numeric_std_unsigned.all;
entity regfile is
port (
clk: in std_logic;
regwrite: in std_logic;
rs, rt, rd: in std_logic_vector(1 downto 0);
data_in: in std_logic_vector(15 downto 0);
rd1, rd2: out STD_LOGIC_VECTOR(15 downto 0)
);
end entity;
architecture behave of regfile is
type registerFile is array (3 downto 0) of STD_LOGIC_VECTOR(15 downto 0);
signal registers: registerFile;
begin
process (clk)
begin
if rising_edge(clk) then
if regwrite = '1' then
registers(to_integer(unsigned(rd))) <= data_in;
end if;
end if;
end process;
process (rs, rt) -- (all)
begin
if to_integer(unsigned(rs)) = 0 then
rd1 <= X"0000";
else
rd1 <= registers(to_integer(unsigned(rs)));
end if;
if to_integer(unsigned(rt)) = 0 then
rd2 <= X"0000";
else
rd2 <= registers(to_integer(unsigned(rt)));
end if;
end process;
end architecture;
Where the process sensitivity list is manually specified and all to_integer calls are from package numeric_std, requiring unsigned type conversions for std_logic_vector values.
(And this analyzes, elaborates and simulates).
I assume you mean the unsigned type of the numeric_std package in the ieee library.
library ieee;
use ieee.numeric_std.all;
...
signal foo : unsigned(7 downto 0);
or
library ieee;
use ieee.numric_std;
...
signal bar : numeric_std.unsigned(7 downto 0);
The installation folder of Quartus Prime 15.1 actually contains a file called numeric_std_unsigned_vhdl2008.vhd which defines the package numeric_std_unsigned and its body. But, apparently the synthesizer does not support it.
The Quartus Prime Standard Handbook v15.1.1, Volume 1 gives in Section 16 under "VHDL Synthesis Support" -> "VHDL-2008 Support" a link to this online help page. At the time of writing this answer, the list of supported VHDL'08 features does not reference Section 16.8.5 of the VHDL'08 Standard which defines the package numeric_std_unsigned. There is also no reference to Appendix A.2.4.
The following sub-section in the Quartus manual states further:
The Quartus Prime software includes the standard IEEE libraries and several vendor-specific VHDL libraries.
The IEEE library includes the standard VHDL packages std_logic_1164, numeric_std, numeric_bit, and math_real.
Given that, you must revert back to using the numeric_std package. But, this package defines the type unsigned which is also defined in std_logic_arith. You should not use the non-standard std_logic_arith package from Synopsys anymore.
Thus, you have to use the package numeric_std instead of both numeric_std_unsigned and std_logic_arith.. Then you have to convert all std_logic_vector to unsigned first, before passing them as an argument to the function to_integer, e.g.:
to_integer(unsigned(rs))
instead of
to_integer(rs)

Resources