在VHDL语言中,插入内存的一种常见方法是:
type mem0_type (0 to MEM0_SIZE-1) of std_logic_vector(DATA_WIDTH-1 downto 0);
signal mem0 : mem0_type;为了便于以后在内存和注册adressnig表中使用,我正在考虑使用:
type mem0_type (MEM0_ADDR to MEM0_ADDR+MEM0_SIZE-1) of std_logic_vector(DATA_WIDTH-1 downto 0);
signal mem0 : mem0_type;能够做这样的事情:
case switch is
when mem0'range => mem0(switch) <= data;
when mem1'range => mem1(switch) <= data;
when mem2'range => mem2(switch) <= data;
when mem3'range => mem3(switch) <= data;
when REG0_ADDR => reg0 <= data;
when REG1_ADDR => reg1 <= data;
when REG2_ADDR => reg2 <= data;
...
end case;而不是像:
case switch is
when MEM0ADDR to MEM0ADDR+MEM0_SIZE-1 => mem0(switch-MEM0ADDR) <= data;
when MEM1ADDR to MEM1ADDR+MEM1_SIZE-1 => mem1(switch-MEM1ADDR) <= data;
when MEM2ADDR to MEM2ADDR+MEM2_SIZE-1 => mem2(switch-MEM2ADDR) <= data;
when REG0_ADDR => reg0 <= data;
when REG1_ADDR => reg1 <= data;
when REG2_ADDR => reg2 <= data;
...
end case;如果我的合成工具允许的话,使用非零索引作为起始入口有什么坏处吗?
谢谢您抽出时间,我希望看到更多的HDL活动在堆栈上<3
发布于 2019-08-29 08:05:23
您可以按建议来做,但是--由于合成规则没有严格标准化--我不相信每一个合成工具都能可靠地从构造中检测和推断内存。
对于使用别名的替代结构来说,这似乎是一个完美的用例:
entity mem is
generic
(
MEM_SIZE : natural;
DATA_WIDTH : natural;
START_ADDRESS : unsigned(31 downto 0)
);
port
(
...
);
end entity mem;
architecture alias_architecture of mem is
type mem_type is array (natural range <>) of std_ulogic_vector(DATA_WIDTH - 1 downto 0);
signal mem : mem_type(0 to MEM_SIZE - 1);
alias amem : mem_type(to_integer(START_ADDRESS) to to_integer(START_ADDRESS) + MEM_SIZE - 1) is mem;
begin
...这样,您仍然可以方便地寻址,唯一需要处理偏移量的地方是别名定义。它可能不能保证所有可用的工具都能猜出您的意思,但我认为它至少会增加您的喜好。
P.S.:出于好奇在Quartus II中尝试了这一点,不幸的是,似乎无法通过别名数组推断RAM块。YMMV与其他合成工具。
https://stackoverflow.com/questions/57704232
复制相似问题