我花了一整天的时间来解决以下问题。我正在建造一个小型平均多通道示波器,我有以下模块来存储信号:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.numeric_std.all;
entity storage is
port
(
clk_in : in std_logic;
reset : in std_logic;
element_in : in std_logic;
data_in : in std_logic_vector(11 downto 0);
addr : in std_logic_vector(9 downto 0);
add : in std_logic; -- add = '1' means add to RAM
-- add = '0' means write to RAM
dump : in std_logic;
element_out : out std_logic;
data_out : out std_logic_vector(31 downto 0)
);
end storage;
architecture rtl of storage is
component bram is
port
(
clk : in std_logic;
we : in std_logic;
en : in std_logic;
addr : in std_logic_vector(9 downto 0);
di : in std_logic_vector(31 downto 0);
do : out std_logic_vector(31 downto 0)
);
end component bram;
type state is (st_startwait, st_add, st_write);
signal current_state : state := st_startwait;
signal next_state : state := st_startwait;
signal start : std_logic;
signal we : std_logic;
signal en : std_logic;
signal di : std_logic_vector(31 downto 0);
signal do : std_logic_vector(31 downto 0);
signal data : std_logic_vector(11 downto 0);
begin
ram : bram port map
(
clk => clk_in,
we => we,
en => en,
addr => addr,
di => di,
do => do
);
process(clk_in, reset, start)
begin
if rising_edge(clk_in) then
if (reset = '1') then
current_state <= st_startwait;
else
start <= '0';
current_state <= next_state;
if (element_in = '1') then
start <= '1';
end if;
end if;
end if;
end process;
process(current_state, start, dump)
variable acc : std_logic_vector(31 downto 0);
begin
element_out <= '0';
en <= '1';
we <= '0';
case current_state is
when st_startwait =>
if (start = '1') then
acc(11 downto 0) := data_in;
acc(31 downto 12) := (others => '0');
next_state <= st_add;
else
next_state <= st_startwait;
end if;
when st_add =>
if (add = '1') then
acc := acc + do;
end if;
we <= '1';
di <= acc;
next_state <= st_write;
when st_write =>
if (dump = '1') then
data_out <= acc;
element_out <= '1';
end if;
next_state <= st_startwait;
end case;
end process;
end rtl;下面是从XST手册复制的BRAM模块。这是一个不变的类型的布拉姆,我相信有问题.其症状是,当我在设备上使用该设计时,虽然模拟得很好,但我只从内存中读取零。
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity bram is
port
(
clk : in std_logic;
we : in std_logic;
en : in std_logic;
addr : in std_logic_vector(9 downto 0);
di : in std_logic_vector(31 downto 0);
do : out std_logic_vector(31 downto 0)
);
end bram;
architecture rtl of bram is
type ram_type is array (0 to 999) of std_logic_vector (31 downto 0);
signal buf : ram_type;
begin
process(clk, en, we)
begin
if rising_edge(clk) then
if en = '1' then
if we = '1' then
buf(conv_integer(addr)) <= di;
else
do <= buf(conv_integer(addr));
end if;
end if;
end if;
end process;
end rtl;下面是对芯片使用和预期输出的描述。"clk_in“是一个50 MHz的时钟。"element_in“为”1“,为20 ns,”0“为60 ns。"addr_in“从0迭代到999,每80 ns修改一次。"element_in“、"data_in”和"addr“都是对齐和同步的。现在,对于1000个元素,"add“是'1‘,然后对于8000个元素,"add”和"dump“都为零,最后,对于1000个元素,"dump”是'1’。现在,如果我有一个从0到999提供"data_in“的测试平台,我希望当”转储“为'1‘时,data_out为0、10、20、30、…、9990。这是根据模拟。实际上我得到0,1,2,3,.,999.
发布于 2013-12-05 08:20:29
下面列出了需要解决的一些初步问题。
process(current_state, start, dump)在storage实体中看起来像是要实现组合元素(门),但是信号(端口) data_in不在灵敏度列表中。
这很可能导致模拟和合成行为之间的差异,因为仿真通常只对灵敏度列表中的信号作出反应,其中综合将实现组合设计并对所有使用的信号作出反应,但可能会对不完全的灵敏度列表或推断锁存发出警告。如果您正在使用VHDL-2008,那么可以使用(all)的灵敏度列表来对所有已使用的信号具有进程敏感性,否则您需要手动添加丢失的信号。
case current_state is in process(current_state, start, dump)缺少一个when others => ...,所以合成工具可能给了您一个关于推断锁存的警告。应该通过将when others =>与进程驱动的所有信号一起添加并分配给相关的值来解决这一问题。
use条款列出:
use IEEE.std_logic_unsigned.all;
use IEEE.numeric_std.all;但不应该同时使用这两种标识符,因为它们声明了一些相同的标识符,例如,在这两种标识符中都声明了unsigned。由于内存使用std_logic_unsigned,我建议您只使用它,并删除numeric_std的使用。但是,对于新代码,我建议使用numeric_std。
同时,process(clk_in, reset, start)在storage实体中实现了对clk_in上升边缘敏感的顺序元素(触发器),因此敏感性列表..., reset, start)中的最后两个信号是不必要的,但不会造成问题。
https://stackoverflow.com/questions/20386979
复制相似问题