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

你离开我真会死。 提交于 2019-12-25 05:00:12

问题


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:


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/43069105/how-to-read-image-file-and-convert-it-to-bits-in-vhdl

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!