我正在尝试使用vhdl中的textio包读取图像文件。 如果我用记事本打开一个.jpg,我会得到一些垃圾数据,但实际上它是ASCII数据。在这里,我试图读取这些ascii数据并将它们转换为字节。
下面是我的代码:
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;
测试平台:
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;
我只获得波形中的一个字节。预期结果是:每个时钟周期新字符应该是rread并且应该获得新字节。
答案 0 :(得分:1)
您在流程的while
部分内放置了rising_edge
循环。发生的情况是,当第一个时钟边沿发生时,while
循环将迭代直到文件末尾,并为您提供输入图像的最后一个字节。
删除while
循环语句可以解决您的问题。
答案 1 :(得分:1)
这个问题有一个根本性的缺陷。您不能使用textio来读取二进制值,而是用于文本。
参见IEEE Std 1076-2008 16.4包TEXTIO第3段(部分)和4:
程序包TEXTIO中声明的READLINE,WRITELINE和TEE读取和写入TEXT类型文件的整行。过程READLINE导致从文件中读取下一行,并返回参数L的值作为指定表示该行的对象的访问值。如果参数L在调用开始时包含非空访问值,则该过程可以解除分配该值指定的对象。 该行的表示不包含行尾的表示 。 ...
该语言未定义行尾的表示形式。实现应允许将CHARACTER和STRING类型的所有可能值写入文件。但是,由于允许实现使用CHARACTER和STRING类型的某些值作为行分隔符,因此可能无法从TEXT文件中读取这些值。
这可以用你的Chrysanthemum.jpg来证明:
VHDL可以一次读取一个原始字符(符合您的需要)。
请参阅IEEE Std 1076-2008 5.5文件类型:
所以我们要做的就是声明一个文件类型,然后我们隐式定义这些过程。
我们可以使用它们来调用原始读取,而不会因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;
现在我们可以拥有所有字符,而不是可以在我们的阅读中界定一行:
请注意,包std.textio不会通过任何上下文项显示。