我正在制作某种缓存,我在实体中使用了一些表(大的),这些表由std_logic_vectors组成,我在Quartus 2网页版中进行操作。
在仿真中一切正常,但是当我尝试合成它时,它只用锁存器,AND和OR组件完成。
有没有办法指定Quartus为这些表而不是这些组合元素使用内存模块?或者也许可以通过VHDL代码本身完成某些事情。
library ieee;
use ieee.std_logic_1164.all;
package UTIL_PACK is
type matrix16x8 is array (0 to 15) of std_logic_vector(0 to 7);
type matrix2p4x8 is array (0 to 2**4) of matrix16x8;
end package;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.util_pack.all;
entity RAM16B is
port(
signal RD: in std_logic;
signal WR: in std_logic;
signal CLK: in std_logic;
signal A: in std_logic_vector(7 downto 0);
signal D: inout matrix16x8;
signal FC: out std_logic
);
end entity ;
architecture RAM16B_IMPL of RAM16B is
signal memory: matrix2p4x8 := ((others => (others => (others => 'Z'))));
begin
run:process(clk)is
variable slot:integer range 0 to 15 :=0;
begin
if(clk='1') then
slot := TO_INTEGER(unsigned(A)) rem 16;
if(rd = '1')then
FC<='0';
for i in 0 to 3 loop
D(i) <= memory(i)(slot);
end loop;
FC<='1';
elsif(wr = '1')then
FC<='0';
for i in 0 to 3 loop
memory(i)(slot) <= D(i);
end loop;
FC<='1';
else
FC <= 'Z';
D <= ( others => ( others => 'Z' ));
end if;
else
FC <= 'Z';
D <= ( others => ( others => 'Z' ));
end if;
end process;
end architecture RAM16B_IMPL;
RAM由16个内存块组成,每个块为16个字节。我试图平行读取更多数据,所以我每个周期读取/写入16个字节的数据。 Slot定义了正在进行读/写的块。
答案 0 :(得分:1)
是的,您可以使用VHDL代码执行此操作。为了确保Quartus了解您正在为内存建模,您应该按照Altera的推荐的HDL编码样式指南中的描述对其进行编码。查看名为从HDL代码中推断内存函数(http://www.altera.com/literature/hb/qts/qts_qii51007.pdf)的部分,然后相应地修改代码。
从Altera建议的确切存储器模型开始,确保Quartus使用FPGA的专用存储器位合成设计可能是一个好主意。接下来,您可以逐步更改模型以实现所需的行为,始终综合并查看编译报告,以确保您的更改不会偏离Quartus推断的内存块。
答案 1 :(得分:1)
如果确实想要确保使用硬内存块,则应使用mega-function向导来制作自定义ram组件,或者直接从库中实例化altsyncram组件,使用泛型来配置它你想要的方式(如果你不是非常熟悉这些选项,这可能会很棘手)。这会导致移植问题,但无论何时推断ram,您通常都会有移植问题。如果您确实需要迁移到其他地方,那么使用自定义库组件可以非常明显且易于识别您可能遇到问题的位置。
至于您的具体实现,您无法将锁存器自动迁移到边缘驱动设备的硬RAM块中。在你的过程中使用rising_edge(clk)而不是clk ='1'来解决这个问题。
此外,芯片内部不支持三态操作,需要独立数据输入和数据输出端口。你得到了很多离散逻辑因为和&amp;或者正在使用门来模拟三态总线(并且由于上面的锁存问题)。