我花了一整天时间试图解决以下问题。我正在构建一个小型平均多通道示波器,我有以下用于存储信号的模块:
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模块。这是一种不变型的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”在20 ns时为“1”,在60 ns时为“0”。 “addr_in”从0到999迭代,每80 ns更改一次。 “element_in”,“data_in”和“addr”都是对齐和同步的。现在对于1000个元素,“add”为'1',然后对于8000个元素,“add”和“dump”都为零,最后对于1000个元素,“dump”为“1”。现在,如果我有一个从0到999提供“data_in”的测试平台,我希望当“dump”为“1”时,data_out为0,10,20,30,...,9990。这是根据模拟。实际上我得到0,1,2,3,......,999 ......
答案 0 :(得分:0)
下面列出了一些需要解决的初步问题。
process(current_state, start, dump)
实体中的storage
看起来像是这样
旨在实现组合元素(门),但信号(端口)
data_in
不在敏感列表中。
这很可能会导致模拟和合成之间的差异
行为,因为模拟通常只会对信号产生反应
灵敏度列表,其中综合将实现组合设计和
对所有使用的信号做出反应,但可能会对不完整的灵敏度发出警告
列表或推断的锁存器。如果您使用的是VHDL-2008,那么使用可以使用
(all)
的敏感性列表,以使过程对所有使用的过程敏感
信号,否则你需要手动添加缺失的信号。
case current_state is
中的process(current_state, start, dump)
缺少
when others => ...
,因此综合工具可能会给你一个警告
关于推断的锁存器。这应该通过添加when others =>
来解决
使用并将过程驱动的所有信号分配给相关值。
use
子句列出:
use IEEE.std_logic_unsigned.all;
use IEEE.numeric_std.all;
但是这两个都不应该同时使用,因为它们声明了一些
例如,两者中都标识了unsigned
。自从
RAM使用std_logic_unsigned
我建议你只坚持使用{和}
删除numeric_std
的使用。对于新代码,我会建议使用
numeric_std
。
process(clk_in, reset, start)
实体中的storage
也实现了
顺序元素(触发器)仅对clk_in
的上升沿敏感,所以
灵敏度列表..., reset, start)
中的最后两个信号是不必要的,
但不会引起问题。