FPGA系统的顶层entity,通常包括数据输入din和输出dout. 初始数据从memory经din传输到系统,经FPGA处理后,经dout输出至memory. 本文介绍了怎么利用文本代替内存,对电路进行综合前的行为仿真。
存储在文本中的数据,可以是用户定义的任意输入。本例中采用Impulse C生成的trace file.该文件是在进行系统级仿真时,自动生成的。文件内容见最后【附】。
STD库的textio包提供了file_open, file_close, readline, read,endfile等方法,用于对外部文件的访问。
例子来自Impulse-C的co_trace.VHD文件, entity:
co_trace_stream_read_file从trace文件按行读取数据,将之输出至output_data. testbench可将该输出数据连接到系统的din port,作为FPGA的输入.
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;
entity
co_trace_stream_read_file is
generic
(
datawidth
: positive := 8;
inputFilename
: string := ""
);
port
(
reset,
clk : in std_ulogic;
output_en
: out std_ulogic;
output_rdy
: in std_ulogic;
output_eof
: out std_ulogic;
output_eos
: out std_ulogic;
output_data
: out std_ulogic_vector (datawidth-1 downto 0)
);
end
co_trace_stream_read_file;
architecture
behavior of co_trace_stream_read_file is
--函数定义,将字符转变成对应整形值
function
hexchar2int(inchar:character) return integer is
variable
x:integer;
begin
case
inchar is
when
'0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9' => x:=character'pos(inchar)-48;
when
'A'|'B'|'C'|'D'|'E'|'F' => x:=character'pos(inchar) - 55;
when
'a'|'b'|'c'|'d'|'e'|'f' => x:=character'pos(inchar) - 87;
when
others => x := 0;--return 0h when invalid character
end
case;
return x;
end;
begin
reader_proc
: process --进程:从文件中读取数据
use
std.textio.all; --调用textio程序包
--定义变量,主要用作buffer存取数据
variable
outDataNibbles : std_ulogic_vector ((((datawidth+7)/8)*8)-1 downto 0);
variable
fileDataBitWidth : integer;
variable
dataNibbleWidth : integer;
variable
data_line : line;
variable
line_cmd : character;
variable
hexChar : character;
variable
hexInt : integer;
file
data_in_file : text;
begin
--
init values
file_open(
data_in_file, inputFilename, read_mode );
output_en <=
'0';
output_eof <=
'0';
output_eos <=
'0';
-- 读取外部文件的格式头
readline(data_in_file,
data_line); --读取一行存在data_line中
read(
data_line, fileDataBitWidth ); --行内按空格分隔
dataNibbleWidth
:= (fileDataBitWidth+3)/4;
if
( (dataNibbleWidth/2) /= ((dataNibbleWidth+1)/2) ) then
dataNibbleWidth
:= dataNibbleWidth + 1;
end
if;
--
dataNibbleWidth决定了数据的长度(16进制字符个数)
--
wait for reset
wait
until rising_edge(clk) and (reset = '0');
wait
until rising_edge(clk);
-- 循环读取外部文件的数据部分,若起始字符为c表示结束
--endfile函数能检测到EOF
while
( not endfile(data_in_file)
) loop
-- read
next data from file. 文件格式见最后
readline(data_in_file,
data_line);
read(
data_line, line_cmd );
if
( line_cmd = 'c' ) then
output_data
<= (others => '0');
output_eos
<= '1';
else
output_eos
<= '0';
read(
data_line, hexChar ); -- discard ' '
read(
data_line, hexChar ); -- discard '0'
read(
data_line, hexChar ); -- discard 'x'
for
i in dataNibbleWidth downto 1 loop
read(
data_line, hexChar );
hexInt
:= hexchar2int( hexChar );
outDataNibbles((i*4
- 1) downto (i*4 - 4)) := std_ulogic_vector(conv_std_logic_vector(hexInt,4));
end
loop;
output_data
<= outDataNibbles((datawidth-1) downto 0);
end
if;
output_en <=
'1';
wait
until rising_edge(clk) and ( output_rdy = '1' );
end loop;
--
end of file
file_close(
data_in_file );
output_en <=
'0';
output_eof <=
'1';
output_eos <=
'0';
wait; --
wait forever
end
process;
end;
【附】外部文件格式为:
16
w 0xFFFA
w 0xFFFA
w 0xFFFA
w 0xFFFA
w 0xFFFA
w 0xFFFA
w 0xFFFA
w 0xFFFA
c
文章评论(0条评论)
登录后参与讨论