不模拟的数组数组

时间:2014-03-21 19:24:05

标签: vhdl

我正在创建一个非常简单的SPI从设备作为更大设备的一部分,并希望对SPI数据进行反序列化。我的架构看起来像这样:

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity controller is
       port (
            CLK     : in    std_logic;
            MOSI    : in  std_logic;
            nCS     : in  std_logic;
            SCLK    : in  std_logic;
            OUTPUT_DATA_EN : out   std_logic;
            OUTPUT_DATA : out std_logic_vector (31 downto 0);
            nRST    : in    std_logic
       );
end controller;

architecture BEH of controller is
     signal SCLK_PREV : std_logic;
     signal nCS_PREV : std_logic;

     type sr8x8 is array(0 to 7) of std_logic_vector(7 downto 0);

     signal BIT_SHIFT_REG : std_logic_vector(7 downto 0);
     signal BITS_RECEIVED : unsigned(3 downto 0);
     signal SHIFT_REG : sr8x8;
     signal BYTES_RECEIVED : unsigned (7 downto 0);
begin
    process(CLK)
    begin
        if rising_edge(CLK) then
            if nRST = '0' then
                BIT_SHIFT_REG <= (others => '0');
                SHIFT_REG <= (others => (others => '0'));
                BITS_RECEIVED <= (others => '0');
                BYTES_RECEIVED <= (others => '0');
                OUTPUT_DATA <= (others => '0');
                OUTPUT_DATA_EN <= '0';
            else
                if nCS = '1' then
                    BIT_SHIFT_REG <= (others => '0');
                    SHIFT_REG <= (others => (others => '0'));
                    BITS_RECEIVED <= (others => '0');
                    BYTES_RECEIVED <= (others => '0');
                end if;

                if nCS = '0' and SCLK_PREV = '0' and SCLK = '1' then
                    BIT_SHIFT_REG(7 downto 1) <= BIT_SHIFT_REG(6 downto 0);
                    BIT_SHIFT_REG(0) <= MOSI;
                    BITS_RECEIVED <= BITS_RECEIVED + 1;
                end if;

                if nCS = '0' and SCLK_PREV = '1' and SCLK = '0' then
                    if BITS_RECEIVED = 8 then
                        SHIFT_REG(to_integer(BYTES_RECEIVED)) <= BIT_SHIFT_REG;
                        BITS_RECEIVED <= X"0";
                        BYTES_RECEIVED <= BYTES_RECEIVED + 1;
                    end if;
                end if;

                if nCS_PREV = '0' and nCS = '1' then
                    if SHIFT_REG(0) = X"00" then
                        OUTPUT_DATA(31 downto 24) <= SHIFT_REG(1);
                        OUTPUT_DATA(23 downto 16) <= SHIFT_REG(2);
                        OUTPUT_DATA(15 downto 8)  <= SHIFT_REG(3);
                        OUTPUT_DATA(7 downto 0)   <= SHIFT_REG(4);
                        OUTPUT_DATA_EN <= '1';
                    end if;
                end if;

                SCLK_PREV <= SCLK;
                nCS_PREV <= nCS;
            end if;
        end if;
     end process;
end BEH;

所有内容都会进行编译和综合,但是当我去模拟时,nRST = '0'条件中的所有内容都会重置,但SHIFT_REG除外,其中所有值都保持为&#39; U&#39;,即所有位置8 std_logic_vectors仍然是&#39; U&#39;根据我发现的语法文档,这似乎是构建此寄存器的合理方法。我还尝试了以下方法来重置SHIFT_REG(或任何设置),它们没有效果:

SHIFT_REG <= (others => X"00");
SHIFT_REG(0) <= X"00";

我做了一些无效的合成和/或模拟吗?我有一些代码评估好像正确的值存储在SHIFT_REG中,但内容从未显示在模拟器中。

编辑:如果敏感度列表简化为process(CLK),问题仍然存在。

2 个答案:

答案 0 :(得分:0)

从灵敏度列表中删除不需要的所有内容 - 同步重置只需要时钟:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity controller is
end entity;

architecture foo of controller is
   type sr8x8 is array(0 to 7) of std_logic_vector(7 downto 0);

   signal SHIFT_REG : sr8x8;
   signal BYTES_RECEIVED : unsigned (7 downto 0);
   signal clk:      std_logic := '0';
   signal nRST:     std_logic;


begin
    process(clk)
    begin
        if rising_edge(clk) then
            if nRST = '0' then
                SHIFT_REG <= (others => (others => '0'));
                BYTES_RECEIVED <= (others => '0');
            end if;
        end if;
    end process;
CLOCK:
    process
    begin
        wait for 10 ns;
        clk <= not clk;
        if Now > 100 ns then
            wait;
        end if;
    end process;
STIMULUS:
    process
    begin
        wait for 20 ns;
        nRST <= '0';
        wait for 20 ns;
        nRST <= '1';
        wait for 60 ns;
        wait;
    end process;


end architecture;
  

david_koontz @ Macbook:ghdl -a controller.vhdl
  david_koontz @ Macbook:ghdl -e controller
  david_koontz @ Macbook:ghdl -r controller --wave = controller.ghw

给出:

array of arrays reset

进程的调用(以及进程的恢复)由事件控制。您可能正在检查除rising_edge(clk)之外的其他一些事件的结果。

发布完整控制器代码后

扩大试验台使用它:

library ieee;
use ieee.std_logic_1164.all;

entity tb is
end entity;

architecture foo of tb is

    signal clk:             std_logic := '0';
    signal mosi:            std_logic;
    signal nCS:             std_logic;
    signal sclk:            std_logic;
    signal output_data_en:  std_logic;
    signal output_data:     std_logic_vector (31 downto 0);
    signal nRST:            std_logic;

    begin

DUT:
    entity work.controller   
    port map (
        clk => clk,
        mosi => mosi,
        nCS => nCS,
        sclk => sclk,
        output_data_en => output_data_en,
        output_data => output_data,
        nRST => nRST
    );
CLOCK:
    process
    begin
        wait for 10 ns;
        clk <= not clk;
        if Now > 100 ns then
            wait;
        end if;
    end process;
STIMULUS:
    process
    begin
        wait for 20 ns;
        nRST <= '0';
        wait for 20 ns;
        nRST <= '1';
        wait for 60 ns;
        wait;
    end process;

    end architecture;

给出了:

full controller reset

因此,我们看到重置数组数组只需要CLKnRST

出于模拟的目的,我不会在您的VHDL设计说明中看到任何可能阻止您至少重置SHIFT_REGBYTES_RECEIVED的内容。

Altium Designer的用户文档和设计流程不是第三方可供使用的,Aldec Active-HDL的用户文档也不是。从您的设计描述或叙述中可以获得很少的洞察力。

您可能会通过联系Altium支持人员获得最佳服务,因为Altium支持人员可能会让您获得Aldec的支持服务。

答案 1 :(得分:0)

首先,根据您的目标技术和综合工具,可能会将数组数组合成到某种内存块。您可能无法以您尝试的方式重置这些记忆。检查工具的文档和综合结果。

对于模拟器:从您发布的代码中,一切都应该有效。我最好的猜测是,有另一个进程驱动SHIFT_REG。即使你认为你没有在那个过程中触发任务,它仍然在驱动'U'。与此过程中的“0”一起,仍然可以解析为“U”。