VHDL-从HEX文件初始化std_logic_vector数组



我有一个简单的"RAM"实现为:

type memory_array is array(31 downto 0) of std_logic_vector(7 downto 0);
signal ram : memory_array;

我想从HEX文件初始化它的内容。我想知道如何阅读这样的文件:

ram_init: process
    file file_ptr : text;
    variable line_text : string(1 to 14);
    variable line_num : line;
    variable lines_read : integer := 0;
    variable char : character;
    variable tmp_hexnum : string(1 to 2);
begin
    file_open(file_ptr,"../RAM.HEX",READ_MODE);
    while (not endfile(file_ptr)) loop
        readline (file_ptr,line_num);
        READ (line_num,line_text);
        if (lines_read < 32) then
            tmp_hexnum := line_text(10 to 11);
            -- ram(lines_read) <= tmp_hexnum;
            lines_read := lines_read + 1;
            wait for 10 ns;
        end if;
    end loop;
    file_close(file_ptr);
    wait;
end process;

问题是(如果上面的代码能起作用,我甚至不知道),如何将tmp_hexknum字符串转换为std_logic_vvector。

VHDL初学者,请耐心等待。

第一个错误是使用流程:如果你试图综合设计,那么在设计构建并运行之前,流程不会做任何事情;太晚了,无法读取文件!

相反,将init代码封装在一个函数中,并使用该函数初始化内存

signal ram : memory_array := my_ram_init(filename => "../RAM.HEX");

这将在模拟中起作用,许多合成工具将推断RAM并正确初始化它。如果你声明了一个常数而不是一个信号,这将创建一个ROM而不是RAM。

不管怎样,这个功能看起来有点像

function my_ram_init(filename : string) return memory_array is
   variable temp : memory_array;
   -- other variables
begin
   file_open(...);
   -- you have a good handle on the function body
   file_close(...);
   return temp;
end function;

给你留下了最初的问题:

temp(lines_read) <= to_slv(tmp_hexnum);

编写tosv函数。应该有一个标准的图书馆,但由于某种原因,没有一个普遍接受的图书馆。所以,这是一个开始。。。

function to_slv (tmp_hexnum : string) return std_logic_vector is
   variable temp  : std_logic_vector(7 downto 0);
   variable digit : natural;
begin
   for i in tmp_hexnum'range loop
      case tmp_hexnum(i) is
      when '0' to '9' => 
         digit := Character'pos(tmp_hexnum(i)) - Character'pos('0');
      when 'A' to 'F' => 
         digit := Character'pos(tmp_hexnum(i)) - Character'pos('A') + 10;
      when 'a' to 'f' =>
         digit := Character'pos(tmp_hexnum(i)) - Character'pos('a') + 10;
      when others => digit := 0;
      end case;
      temp(i*4+3 downto i*4) := std_logic_vector(to_unsigned(digit));
   end loop;
   return temp;
end function;

将可变长度的字符串转换为长度为4的std_logic_vvector*字符串的长度,可以用下面的函数来完成:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
...
-- Convert string to std_logic_vector, assuming characters in '0' to '9',
-- 'A' to 'F', or 'a' to 'f'.
function str_to_slv(str : string) return std_logic_vector is
  alias str_norm : string(1 to str'length) is str;
  variable char_v : character;
  variable val_of_char_v : natural;
  variable res_v : std_logic_vector(4 * str'length - 1 downto 0);
begin
  for str_norm_idx in str_norm'range loop
    char_v := str_norm(str_norm_idx);
    case char_v is
      when '0' to '9' => val_of_char_v := character'pos(char_v) - character'pos('0');
      when 'A' to 'F' => val_of_char_v := character'pos(char_v) - character'pos('A') + 10;
      when 'a' to 'f' => val_of_char_v := character'pos(char_v) - character'pos('a') + 10;
      when others => report "str_to_slv: Invalid characters for convert" severity ERROR;
    end case;
    res_v(res_v'left - 4 * str_norm_idx + 4 downto res_v'left - 4 * str_norm_idx + 1) :=
      std_logic_vector(to_unsigned(val_of_char_v, 4));
  end loop;
  return res_v;
end function;

你(两个)的回答对我帮助很大。但它似乎不起作用。

function ram_init(filename : string) return memory_array is
    variable temp : memory_array;
    file file_ptr : text;
    variable line_line : line;
    variable line_text : string(1 to 14);
    variable tmp_hexnum : string(1 to 2);
    variable lines_read : integer := 0;
    begin
        file_open(file_ptr,filename,READ_MODE);
        while (lines_read < 32 and not endfile(file_ptr)) loop
            readline (file_ptr,line_line);
            read (line_line,line_text);
            tmp_hexnum := line_text(10 to 11);
            temp(lines_read) := hex_to_bin(tmp_hexnum);
            lines_read := lines_read + 1;
        end loop;
        file_close(file_ptr);
    return temp;
end function;
signal ram : memory_array := ram_init(filename=>"../RAM.HEX");

如果我将tmp_hexknum设置为例如"0A",这是可以的,但从文件中读取不会填充RAM。

你也能帮我查一下文件的部分吗?

最新更新