为什么此VHDL在仿真中工作并且在Virtex 5器件上不起作用

时间:2013-12-04 22:01:08

标签: vhdl xilinx

我花了一整天时间试图解决以下问题。我正在构建一个小型平均多通道示波器,我有以下用于存储信号的模块:


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 ......

1 个答案:

答案 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)中的最后两个信号是不必要的, 但不会引起问题。