这是我在vhdl中的代码
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
USE IEEE.STD_LOGIC_TEXTIO.ALL;
USE STD.TEXTIO.ALL;
entity inst_mem is
port(
load: in std_logic;
address: in std_logic_vector (5 downto 0);
dataout: out std_logic_vector (10 downto 0)
);
end entity;
architecture arch_inst_mem of inst_mem is
TYPE inst_mem is array (0 to 32) of std_logic_vector(10 downto 0);
procedure init_mem(variable memory : out inst_mem;
constant datafile : string) is
file stddata: text;
variable l: line;
variable data: std_logic_vector (10 downto 0);
begin
file_open (stddata, datafile, READ_MODE);
for i in memory'range(1) loop
readline (stddata, l);
read (l, data);
memory(i):= data;
end LOOP;
end procedure;
begin
process (load , address)
variable memory: inst_mem;
begin
if (load = '1') then
init_mem (memory, "inst_mem.txt");
dataout <= memory (conv_integer(address));
end if;
end process;
end arch_inst_mem;
在编译中我没有错误芽,当我模拟它时modelsim我有这个错误,(#CoLoop循环中的致命错误:C:/Users/Bana/Desktop/Q1/inst_mem.vhd第29行) 为什么? 谢谢,bana。
答案 0 :(得分:4)
我支持Brian的评论,for循环中只有3个语句。听起来你的stddata文件有问题。正如Patrick Lehmann所说,你可以测试EOF(ENDFILE),这可以让你注意你的文件是否很短。 inst_mem是数组(0到32),有32个条目,如Morten Zilmer所说。
我实例化了你的模型(通过更改来支持符合-1993的VHDL工具,并在包numeric_std中从conv_integer切换到to_integer,你可以忽略架构声明区域中的额外内容):
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
-- USE IEEE.STD_LOGIC_TEXTIO.ALL;
USE STD.TEXTIO.ALL;
entity inst_mem is
port(
load: in std_logic;
address: in std_logic_vector (5 downto 0);
dataout: out std_logic_vector (10 downto 0)
);
end entity;
architecture arch_inst_mem of inst_mem is
TYPE inst_mem is array (0 to 32) of std_logic_vector(10 downto 0);
type MVL9plus is ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-', ERROR);
type MVL9_indexed_by_char is array (character) of STD_ULOGIC;
type MVL9plus_indexed_by_char is array (character) of MVL9plus;
constant char_to_MVL9: MVL9_indexed_by_char :=
('U' => 'U', 'X' => 'X', '0' => '0', '1' => '1', 'Z' => 'Z',
'W' => 'W', 'L' => 'L', 'H' => 'H', '-' => '-', others => 'U');
constant char_to_MVL9plus: MVL9plus_indexed_by_char :=
('U' => 'U', 'X' => 'X', '0' => '0', '1' => '1', 'Z' => 'Z',
'W' => 'W', 'L' => 'L', 'H' => 'H', '-' => '-', others => ERROR);
procedure READ(L:inout LINE; VALUE:out STD_LOGIC_VECTOR) is
variable m: STD_ULOGIC;
variable c: character;
variable s: string(1 to value'length-1);
variable mv: STD_LOGIC_VECTOR(0 to value'length-1);
constant allU: STD_LOGIC_VECTOR(0 to value'length-1)
:= (others => 'U');
variable GOOD: boolean;
begin
loop -- skip white space
read(l,c);
exit when ((c /= ' ') and (c /= CR) and (c /= HT));
end loop;
if (char_to_MVL9plus(c) = ERROR) then
value := allU;
good := FALSE;
return;
end if;
read(l, s);
for i in integer range 1 to value'length-1 loop
if (char_to_MVL9plus(s(i)) = ERROR) then
value := allU;
good := FALSE;
return;
end if;
end loop;
mv(0) := char_to_MVL9(c);
for i in integer range 1 to value'length-1 loop
mv(i) := char_to_MVL9(s(i));
end loop;
value := mv;
good := TRUE;
end READ;
procedure init_mem(variable memory : out inst_mem;
constant datafile : string) is
file stddata: text;
variable l: line;
variable data: std_logic_vector (10 downto 0);
begin
file_open (stddata, datafile, READ_MODE);
for i in memory'range(1) loop
readline (stddata, l);
read (l, data);
memory(i):= data;
end LOOP;
end procedure;
begin
process (load , address)
variable memory: inst_mem;
begin
if (load = '1') then
init_mem (memory, "inst_mem.txt");
dataout <= memory (to_integer(unsigned(address))); -- (conv_integer(address));
end if;
end process;
end arch_inst_mem;
在inst_mem.txt文件中生成,包含33个条目:
00000000000
00000000001
00000000010
00000000011
00000000100
00000000101
00000000110
00000000111
00000001000
00000001001
00000001010
00000001011
00000001100
00000001101
00000001110
00000001111
00000010000
00000010001
00000010010
00000010011
00000010100
00000010101
00000010110
00000010111
00000011000
00000011001
00000011010
00000011011
00000011100
00000011101
00000011110
00000011111
00000100000
该模型成功运行于ghdl(符合0.31,-1993)。
通过在ghdl中做一些非常难看的东西(它不支持波形中的变量显示)我可以证明inst_mem内存是由init_mem顺序过程调用初始化的: (点击)
更多的可能是,你在inst_mem.txt中输入的条目数量错误,这会导致失败,因为ENDFILE不用于检测EOF:
ghdl -r inst_mem --wave = inst_mem.ghw
../../../src/std/textio_body.v93:558:5:@1ns :(断言失败):字符读取失败
./inst_mem:error:断言失败
./inst_mem:error:模拟失败
ghdl:编译错误
仅限32个条目。
(你注意到ghdl没有追溯到设计规范中。)
如果有非法入境,你会得到一堆 在特定的内存位置取消定义。
所以看起来你应该定义:
TYPE inst_mem is array (0 to 31) of std_logic_vector(10 downto 0);
输入inst_mem作为32条目数组,或者保证你的inst_mem.txt文件有适当数量的条目,或者使用ENDFILE测试并且根本没有初始化任何剩余的数组元素。
添加ENDFILE测试:
procedure init_mem(signal memory : out inst_mem;
constant datafile : string) is
file stddata: text;
variable l: line;
variable data: std_logic_vector (10 downto 0);
begin
file_open (stddata, datafile, READ_MODE);
for i in memory'range(1) loop
if not ENDFILE(stddata) then
readline (stddata, l);
read (l, data);
memory(i) <= data;
end if;
end LOOP;
FILE_CLOSE(stddata);
end procedure;
消除了上述错误。这也有留下任何剩余数组元素未初始化的副作用。
你还注意到我添加了Morten推荐的FILE_CLOSE程序,理论上你可以在加载或地址和load ='1'的任何时候重新初始化内存数组。
这也告诉你,你应该检测到负载高而不是水平:
process (load , address)
variable memory: inst_mem;
begin
if load'event and load = '1' then
init_mem (memory, "inst_mem.txt");
dataout <= memory (conv_integer(address));
end if;
end process;
假设这是在测试平台或不是合成目标。
如果您打算提供嵌入FPGA比特流的初始化文件,那么您需要遵守供应商流程。
您尝试使用相同的过程,因为您已将内存声明为变量。它可以是一个共享变量。你可以有两个独立的进程来初始化,一个进行读取。
将内存作为信号实现更容易,在这种情况下不会产生任何性能损失。
(我对textio问题感兴趣。)