My requirement is to read data bits from input file and write data into memory array(output) in vhdl. As i am not aware of the amount of data in input file, i need to declare array of unknown size and assign data to memory at later stages.
我的要求是读取输入文件中的数据位,并将数据写入到vhdl中的内存数组(输出)中。由于我不知道输入文件中的数据量,所以需要声明未知大小的数组,并在稍后的阶段将数据分配给内存。
My code is as below:
我的代码如下:
Declarations :
声明:
PACKAGE io IS
type memory is array (natural range<>) of std_logic_vector(3 downto 0);
END;
entity File_io is
port (
clk: in std_logic;
Data_memory: out memory
);
end entity;
architecture behav of File_io is
signal mem: memory;
begin
process(clk)
begin
for i in 0 to 15 loop -- Took just 16 values for explaination purpose.
-- i may need more values to be written which is unknown.
mem(i) <= std_logic_vector(to_unsigned(i, 4));
end loop;
Data_memory <= mem;
end process;
end architecture behav;
I have minimized the actual code to exact requiremnet of mine. Ignore if any syntax errors.
我已经最小化了实际代码,以准确地确定我的需求。忽略任何语法错误。
The problem is I can not assign values to array which is unconstrained, that is of undefined size. How do i do this ? any suggestions or alternatives? Guide me
问题是我不能为无约束的,无定义大小的数组赋值。我该怎么做呢?任何建议或选择呢?引导我
2 个解决方案
#1
2
Looking at your other question - How to Eliminate whitespaces while Reading a file in VHDL provides an example memory init file as well as a problem reading it.
查看您的另一个问题——如何在读取VHDL中的文件时消除空白,这提供了一个示例内存初始化文件以及读取它的问题。
Incorporating that fix and using the method method J.H. Bonarius suggests gives rise to a Minimal, Complete and Verifiable example:
结合这一修复并使用J.H.博纳留斯建议的方法,产生了一个最小的、完整的、可验证的示例:
library ieee;
use ieee.std_logic_1164.all;
PACKAGE io IS
type memory is array (natural range<>) of std_logic_vector(3 downto 0);
function iswhitespace (inpstr: in string) return boolean;
END;
package body io is
function iswhitespace (inpstr: in string) return boolean is
constant NBSP: character := character'val(128);
begin
for i in inpstr'range loop
if inpstr(i) /= ' ' and inpstr(i) /= NBSP and inpstr(i) /= HT then
exit;
elsif i = inpstr'RIGHT then
return TRUE;
end if;
end loop;
return FALSE;
end function;
end package body;
library ieee;
use ieee.std_logic_1164.all;
use work.io.all;
entity File_io is
generic (
constant MEMORY_SIZE: natural := 42;
constant filename: string := "C:\Users\ChowdaryS\Downloads\topo.bin"
);
port (
clk: in std_logic;
Data_memory: out memory (0 to MEMORY_SIZE - 1)
);
end entity;
architecture foo of File_io is
signal mem: memory (0 to MEMORY_SIZE - 1); -- ADDED subtype indication
use ieee.numeric_std.all; -- MISSING cntext item
use std.textio.all;
signal mem_inited: boolean := FALSE; -- ADDED
begin
process(clk)
file f: text open read_mode is filename;
variable L: line;
variable i: integer:= 0;
variable b: bit_vector(3 downto 0);
begin
if not mem_inited then
i := 0;
while not endfile(f) loop
readline(f, L);
while L.all'length >= b'length and not iswhitespace(L.all) loop
read(L, b);
mem(i) <= to_stdlogicvector(b);
i := i + 1;
end loop;
end loop;
report "mem values loaded = " & integer'image(i);
mem_inited <= TRUE;
end if;
end process;
Data_memory <= mem;
end architecture foo;
There are a changes. A function iswhitespace has been added to package io. You can see the above cited question for trade-offs and whether it's required.
有变化。将函数iswhitespace添加到包io中。您可以看到上面提到的权衡问题,以及是否需要它。
The assignment to the output port has been moved outside the process. It's assumed you'll have some sort of writes to mem included in the process.
将分配给输出端口的任务移动到流程之外。假设您将在过程中对mem进行某种写入。
There's also a testbench that instantiates file_io and determines the size of the memory array, passing that as a generic.
还有一个testbench来实例化file_io并确定内存数组的大小,并将其作为泛型传递。
library ieee;
use ieee.std_logic_1164.all;
use work.io.all;
entity file_io_tb is
end entity;
architecture foo of file_io_tb is
constant MEMSIZ: natural := 16;
constant filename: string := "topo.bin"; -- found locally.
signal clk: std_logic := '0';
signal Data_memory: memory (0 to MEMSIZ - 1);
use std.textio.all;
impure function getarraysize return natural is
variable L: Line;
variable i: natural;
variable b: bit_vector (3 downto 0);
file f: text open read_mode is filename;
begin
i := 0;
while not endfile(f) loop
readline(f, L);
while L.all'length >= b'length and not iswhitespace(L.all) loop
read(L, b);
i := i + 1;
end loop;
end loop;
report " memory size = " & integer'image(i);
return i;
end function;
begin
DUT:
entity work.file_io
generic map (MEMORY_SIZE => getarraysize, filename => filename)
port map (
clk => clk,
Data_memory => Data_memory
);
CLOCK:
process
begin
wait for 10 ns;
clk <= not clk;
if now > 50 ns then
wait;
end if;
end process;
end architecture;
The function is performs the file read at elaboration time to set a generic.
该函数执行精化时读取的文件来设置泛型。
And we see this initializes mem:
我们看到它初始化了mem
The copy of topo.bin used has four trailing spaces on the first line:
威尼斯平底渔船的副本。bin used在第一行有四个尾随空格:
10101100 11010100 10101100 11010100
11111110 10111001 11111110 10111001
The values shown in the waveform match the above two lines from topo.bin.
波形中显示的值与topo.bin中的两行匹配。
(And all this got written to find the issue with whitespace in the other question).
(所有这些都是为了在另一个问题中找到空格的问题而写的)。
#2
2
Read the file twice and determine the amount of lines the first time. For example
两次读取文件,第一次确定行数。例如
edit: finally had access to a vhdl simulator. Fixed the code. I've been switching between VHDL, C++, C#, matlab and python so much lately, that I keep mixing syntaxes.
编辑:终于可以访问vhdl模拟器了。固定的代码。我最近经常在VHDL、c++、c#、matlab和python之间切换,我一直在混合语法。
library IEEE;
use IEEE.std_logic_1164.all;
use std.textio.all;
entity file_io is
generic (
data_width : positive := 4;
file_name : string
);
port (
clk : in std_logic;
file_output : out std_logic_vector(data_width-1 downto 0) := (others => '0')
);
end entity file_io;
architecture behaviour of file_io is
impure function get_line_count return positive is
file file_pointer : text;
variable line_data : line;
variable lineCount : natural := 0;
begin
file_open(file_pointer, file_name, read_mode);
while not endfile(file_pointer) loop
readline(file_pointer, line_data);
lineCount := lineCount + 1;
end loop;
file_close(file_pointer);
return lineCount;
end function get_line_count;
constant memory_size : positive := get_line_count;
subtype data_type is std_logic_vector(data_width-1 downto 0);
type memory_type is array (0 to memory_size-1) of data_type;
impure function get_data return memory_type is
file file_pointer : text;
variable line_data : line;
variable line_value : bit_vector(data_width-1 downto 0);
variable memory : memory_type;
variable index : natural := 0;
begin
file_open(file_pointer, file_name, read_mode);
while not endfile(file_pointer) loop
readline(file_pointer, line_data);
read(line_data, line_value);
memory(index) := to_stdlogicvector(line_value);
index := index + 1;
end loop;
file_close(file_pointer);
return memory;
end function get_data;
constant memory : memory_type := get_data;
signal index : natural := 0;
begin
process(clk)
begin
if rising_edge(clk) then
file_output <= memory(index);
if (index < memory_size-1) then
index <= index + 1;
else
index <= 0;
end if;
end if;
end process;
end architecture behaviour;
and test bench:
和实验台:
library IEEE;
use IEEE.std_logic_1164.all;
entity file_io_tb is
end entity file_io_tb;
architecture behaviour of file_io_tb is
signal clk : std_logic := '0';
constant data_width : positive := 4;
signal data : std_logic_vector(data_width-1 downto 0);
begin
file_io_inst : entity work.file_io
generic map(
data_width => 4,
file_name => "data_file.txt"
)
port map(
clk => clk,
file_output => data
);
clk_prc : process
begin
loop
clk <= '0', '1' after 1 ns;
wait for 2 ns;
end loop;
end process;
end architecture behaviour;
data_file.txt just contains
data_file。三只包含
0101
1010
1100
0011
...
this works fine for me...
这对我来说没问题……
#1
2
Looking at your other question - How to Eliminate whitespaces while Reading a file in VHDL provides an example memory init file as well as a problem reading it.
查看您的另一个问题——如何在读取VHDL中的文件时消除空白,这提供了一个示例内存初始化文件以及读取它的问题。
Incorporating that fix and using the method method J.H. Bonarius suggests gives rise to a Minimal, Complete and Verifiable example:
结合这一修复并使用J.H.博纳留斯建议的方法,产生了一个最小的、完整的、可验证的示例:
library ieee;
use ieee.std_logic_1164.all;
PACKAGE io IS
type memory is array (natural range<>) of std_logic_vector(3 downto 0);
function iswhitespace (inpstr: in string) return boolean;
END;
package body io is
function iswhitespace (inpstr: in string) return boolean is
constant NBSP: character := character'val(128);
begin
for i in inpstr'range loop
if inpstr(i) /= ' ' and inpstr(i) /= NBSP and inpstr(i) /= HT then
exit;
elsif i = inpstr'RIGHT then
return TRUE;
end if;
end loop;
return FALSE;
end function;
end package body;
library ieee;
use ieee.std_logic_1164.all;
use work.io.all;
entity File_io is
generic (
constant MEMORY_SIZE: natural := 42;
constant filename: string := "C:\Users\ChowdaryS\Downloads\topo.bin"
);
port (
clk: in std_logic;
Data_memory: out memory (0 to MEMORY_SIZE - 1)
);
end entity;
architecture foo of File_io is
signal mem: memory (0 to MEMORY_SIZE - 1); -- ADDED subtype indication
use ieee.numeric_std.all; -- MISSING cntext item
use std.textio.all;
signal mem_inited: boolean := FALSE; -- ADDED
begin
process(clk)
file f: text open read_mode is filename;
variable L: line;
variable i: integer:= 0;
variable b: bit_vector(3 downto 0);
begin
if not mem_inited then
i := 0;
while not endfile(f) loop
readline(f, L);
while L.all'length >= b'length and not iswhitespace(L.all) loop
read(L, b);
mem(i) <= to_stdlogicvector(b);
i := i + 1;
end loop;
end loop;
report "mem values loaded = " & integer'image(i);
mem_inited <= TRUE;
end if;
end process;
Data_memory <= mem;
end architecture foo;
There are a changes. A function iswhitespace has been added to package io. You can see the above cited question for trade-offs and whether it's required.
有变化。将函数iswhitespace添加到包io中。您可以看到上面提到的权衡问题,以及是否需要它。
The assignment to the output port has been moved outside the process. It's assumed you'll have some sort of writes to mem included in the process.
将分配给输出端口的任务移动到流程之外。假设您将在过程中对mem进行某种写入。
There's also a testbench that instantiates file_io and determines the size of the memory array, passing that as a generic.
还有一个testbench来实例化file_io并确定内存数组的大小,并将其作为泛型传递。
library ieee;
use ieee.std_logic_1164.all;
use work.io.all;
entity file_io_tb is
end entity;
architecture foo of file_io_tb is
constant MEMSIZ: natural := 16;
constant filename: string := "topo.bin"; -- found locally.
signal clk: std_logic := '0';
signal Data_memory: memory (0 to MEMSIZ - 1);
use std.textio.all;
impure function getarraysize return natural is
variable L: Line;
variable i: natural;
variable b: bit_vector (3 downto 0);
file f: text open read_mode is filename;
begin
i := 0;
while not endfile(f) loop
readline(f, L);
while L.all'length >= b'length and not iswhitespace(L.all) loop
read(L, b);
i := i + 1;
end loop;
end loop;
report " memory size = " & integer'image(i);
return i;
end function;
begin
DUT:
entity work.file_io
generic map (MEMORY_SIZE => getarraysize, filename => filename)
port map (
clk => clk,
Data_memory => Data_memory
);
CLOCK:
process
begin
wait for 10 ns;
clk <= not clk;
if now > 50 ns then
wait;
end if;
end process;
end architecture;
The function is performs the file read at elaboration time to set a generic.
该函数执行精化时读取的文件来设置泛型。
And we see this initializes mem:
我们看到它初始化了mem
The copy of topo.bin used has four trailing spaces on the first line:
威尼斯平底渔船的副本。bin used在第一行有四个尾随空格:
10101100 11010100 10101100 11010100
11111110 10111001 11111110 10111001
The values shown in the waveform match the above two lines from topo.bin.
波形中显示的值与topo.bin中的两行匹配。
(And all this got written to find the issue with whitespace in the other question).
(所有这些都是为了在另一个问题中找到空格的问题而写的)。
#2
2
Read the file twice and determine the amount of lines the first time. For example
两次读取文件,第一次确定行数。例如
edit: finally had access to a vhdl simulator. Fixed the code. I've been switching between VHDL, C++, C#, matlab and python so much lately, that I keep mixing syntaxes.
编辑:终于可以访问vhdl模拟器了。固定的代码。我最近经常在VHDL、c++、c#、matlab和python之间切换,我一直在混合语法。
library IEEE;
use IEEE.std_logic_1164.all;
use std.textio.all;
entity file_io is
generic (
data_width : positive := 4;
file_name : string
);
port (
clk : in std_logic;
file_output : out std_logic_vector(data_width-1 downto 0) := (others => '0')
);
end entity file_io;
architecture behaviour of file_io is
impure function get_line_count return positive is
file file_pointer : text;
variable line_data : line;
variable lineCount : natural := 0;
begin
file_open(file_pointer, file_name, read_mode);
while not endfile(file_pointer) loop
readline(file_pointer, line_data);
lineCount := lineCount + 1;
end loop;
file_close(file_pointer);
return lineCount;
end function get_line_count;
constant memory_size : positive := get_line_count;
subtype data_type is std_logic_vector(data_width-1 downto 0);
type memory_type is array (0 to memory_size-1) of data_type;
impure function get_data return memory_type is
file file_pointer : text;
variable line_data : line;
variable line_value : bit_vector(data_width-1 downto 0);
variable memory : memory_type;
variable index : natural := 0;
begin
file_open(file_pointer, file_name, read_mode);
while not endfile(file_pointer) loop
readline(file_pointer, line_data);
read(line_data, line_value);
memory(index) := to_stdlogicvector(line_value);
index := index + 1;
end loop;
file_close(file_pointer);
return memory;
end function get_data;
constant memory : memory_type := get_data;
signal index : natural := 0;
begin
process(clk)
begin
if rising_edge(clk) then
file_output <= memory(index);
if (index < memory_size-1) then
index <= index + 1;
else
index <= 0;
end if;
end if;
end process;
end architecture behaviour;
and test bench:
和实验台:
library IEEE;
use IEEE.std_logic_1164.all;
entity file_io_tb is
end entity file_io_tb;
architecture behaviour of file_io_tb is
signal clk : std_logic := '0';
constant data_width : positive := 4;
signal data : std_logic_vector(data_width-1 downto 0);
begin
file_io_inst : entity work.file_io
generic map(
data_width => 4,
file_name => "data_file.txt"
)
port map(
clk => clk,
file_output => data
);
clk_prc : process
begin
loop
clk <= '0', '1' after 1 ns;
wait for 2 ns;
end loop;
end process;
end architecture behaviour;
data_file.txt just contains
data_file。三只包含
0101
1010
1100
0011
...
this works fine for me...
这对我来说没问题……