带有 MIF 文件的 VHDL 预加载 RAM 存储器
VHDL Pre-loading RAM Memory with MIF File
我正在尝试在 VHDL 中实现内存,当在 DE2 板上测试它时,我想用生成的值预加载内存。我首先尝试通过读取文本文件来执行此操作,但这没有用,因为无法将文本文件加载到 FPGA 板上。所以我转向了 mif 文件。但是,我不知道如何让 vhdl/quartus ii 将我生成的 MIF 文件与我创建的 RAM 相关联。
我也尝试过使用 1 端口 RAM LPM,但因为它为读取和写入计时,这导致它无法足够快地提供有用的数据。
下面是我创建的 RAM 的代码:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
entity instruction_memory is
port (
input_address : in std_logic_vector(31 downto 0);
opcode : out std_logic_vector(31 downto 0)
);
end instruction_memory;
architecture archInstruction_Memory of instruction_memory is
subtype word_t is std_logic_vector(31 downto 0);
type ram_t is array(0 to 4095) of Reichman_word_t;
impure function ReadMemFile(FileName : STRING) return ram_t is
file FileHandle : TEXT open READ_MODE is FileName;
variable CurrentLine : LINE;
variable TempWord : bit_vector(31 downto 0);
variable Result : ram_t := (others => (others => '0'));
begin
for i in 0 to 4095 loop
exit when endfile(FileHandle);
readline(FileHandle, CurrentLine);
read(CurrentLine, TempWord);
Result(i) := to_stdlogicvector(TempWord);
end loop;
return Result;
end function;
signal ram : ram_t := ReadMemFile("instructions_memory.txt");
attribute ram_init_file : string;
attribute ram_init_file of ram : signal is "instructions_memory.mif";
begin
opcode <= ram(to_integer(unsigned(input_address(31 downto 0))));
end archInstruction_Memory;
我怎样才能让它在 .mif 文件中预加载数据,以便当我在 DE2 板上测试它时它显示它使用这些值?
我正在使用 tcl 脚本将二进制数据(代码)转换为可用于生成 ROM 的 VHDL 常量:
package require cmdline
post_message "embed_m68k.tcl"
exec /bin/bash -c "(cd m68k; make)"
set binfile m68k/simple.bin
set fp [open $binfile r]
fconfigure $fp -translation binary
set bindata [read $fp]
close $fp
set filename simple.vhd
set date [clock format [clock seconds] -format { %a, %Y-%m-%d, %H:%M }]
set file [open $filename w]
set script [info script]
puts $file "library ieee;"
puts $file "use ieee.std_logic_1164.all;"
puts $file ""
puts $file " -- VHDL representation of $binfile"
puts $file " -- generated by $script on $date"
puts $file " -- m68k executable as preloaded RAM contents"
puts $file ""
puts $file "package m68k_binary is"
puts $file " subtype ubyte is std_logic_vector(7 downto 0);"
puts $file " type ubyte_array is array (natural range <>) of ubyte;"
puts $file ""
puts $file " constant m68k_binary : ubyte_array :="
puts $file " ("
puts -nonewline $file " "
set len [string length $bindata]
for {set i 0} {$i < $len} {incr i} {
set char [string index $bindata $i]
binary scan $char H2 byte
puts -nonewline $file "x\""
puts -nonewline $file $byte
puts -nonewline $file "\""
if { ! ([expr $i + 1] == $len) } {
puts -nonewline $file ", "
}
if { [expr ($i + 1) % 8] == 0 } {
puts $file ""
puts -nonewline $file " "
}
}
puts $file ""
puts $file " );"
puts $file "end package m68k_binary;"
close $file
您可以使用 .qsf 中的 PRE_FLOW_SCRIPT_FILE
变量轻松地将脚本包含到您的 Quartus 工作流中:
set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:precmd.tcl"
然后PRE_FLOW_SCRIPT_FILE
将在合成过程开始时自动执行。只需将生成的 .vhd 文件包含到您的项目中即可。
我正在尝试在 VHDL 中实现内存,当在 DE2 板上测试它时,我想用生成的值预加载内存。我首先尝试通过读取文本文件来执行此操作,但这没有用,因为无法将文本文件加载到 FPGA 板上。所以我转向了 mif 文件。但是,我不知道如何让 vhdl/quartus ii 将我生成的 MIF 文件与我创建的 RAM 相关联。
我也尝试过使用 1 端口 RAM LPM,但因为它为读取和写入计时,这导致它无法足够快地提供有用的数据。
下面是我创建的 RAM 的代码:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
entity instruction_memory is
port (
input_address : in std_logic_vector(31 downto 0);
opcode : out std_logic_vector(31 downto 0)
);
end instruction_memory;
architecture archInstruction_Memory of instruction_memory is
subtype word_t is std_logic_vector(31 downto 0);
type ram_t is array(0 to 4095) of Reichman_word_t;
impure function ReadMemFile(FileName : STRING) return ram_t is
file FileHandle : TEXT open READ_MODE is FileName;
variable CurrentLine : LINE;
variable TempWord : bit_vector(31 downto 0);
variable Result : ram_t := (others => (others => '0'));
begin
for i in 0 to 4095 loop
exit when endfile(FileHandle);
readline(FileHandle, CurrentLine);
read(CurrentLine, TempWord);
Result(i) := to_stdlogicvector(TempWord);
end loop;
return Result;
end function;
signal ram : ram_t := ReadMemFile("instructions_memory.txt");
attribute ram_init_file : string;
attribute ram_init_file of ram : signal is "instructions_memory.mif";
begin
opcode <= ram(to_integer(unsigned(input_address(31 downto 0))));
end archInstruction_Memory;
我怎样才能让它在 .mif 文件中预加载数据,以便当我在 DE2 板上测试它时它显示它使用这些值?
我正在使用 tcl 脚本将二进制数据(代码)转换为可用于生成 ROM 的 VHDL 常量:
package require cmdline
post_message "embed_m68k.tcl"
exec /bin/bash -c "(cd m68k; make)"
set binfile m68k/simple.bin
set fp [open $binfile r]
fconfigure $fp -translation binary
set bindata [read $fp]
close $fp
set filename simple.vhd
set date [clock format [clock seconds] -format { %a, %Y-%m-%d, %H:%M }]
set file [open $filename w]
set script [info script]
puts $file "library ieee;"
puts $file "use ieee.std_logic_1164.all;"
puts $file ""
puts $file " -- VHDL representation of $binfile"
puts $file " -- generated by $script on $date"
puts $file " -- m68k executable as preloaded RAM contents"
puts $file ""
puts $file "package m68k_binary is"
puts $file " subtype ubyte is std_logic_vector(7 downto 0);"
puts $file " type ubyte_array is array (natural range <>) of ubyte;"
puts $file ""
puts $file " constant m68k_binary : ubyte_array :="
puts $file " ("
puts -nonewline $file " "
set len [string length $bindata]
for {set i 0} {$i < $len} {incr i} {
set char [string index $bindata $i]
binary scan $char H2 byte
puts -nonewline $file "x\""
puts -nonewline $file $byte
puts -nonewline $file "\""
if { ! ([expr $i + 1] == $len) } {
puts -nonewline $file ", "
}
if { [expr ($i + 1) % 8] == 0 } {
puts $file ""
puts -nonewline $file " "
}
}
puts $file ""
puts $file " );"
puts $file "end package m68k_binary;"
close $file
您可以使用 .qsf 中的 PRE_FLOW_SCRIPT_FILE
变量轻松地将脚本包含到您的 Quartus 工作流中:
set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:precmd.tcl"
然后PRE_FLOW_SCRIPT_FILE
将在合成过程开始时自动执行。只需将生成的 .vhd 文件包含到您的项目中即可。