寄存器VHDL出现意外延迟

时间:2014-05-11 08:20:10

标签: vhdl cpu-registers

我编码的这个寄存器发现了奇怪的事。我是VHDL的新手,但是在为data_out这样的输出端口写一个值时我被教导你应该总是使用"中间人"信号传递你的价值。在这里,我尝试使用信号"数据"传输信号,但这种实现导致data_out改变之前的延迟(当ld变高时)。完全取出数据并编写我在C程序中的编码方式可以消除这种延迟,并且寄存器可以完美地工作。知道为什么会这样,为什么我不应该这样做?

代码破碎:

entity register is

  generic (
    DATA_WIDTH : natural := 12);

  port (
    data_in  : in  std_logic_vector(DATA_WIDTH-1 downto 0);
    ld       : in  std_logic;
    clk      : in  std_logic;
    rst_L    : in  std_logic;
    data_out : out std_logic_vector(DATA_WIDTH-1 downto 0));

end entity register;


architecture bhv of register is
  signal data : std_logic_vector(DATA_WIDTH-1 downto 0);
begin  -- bhv

  REG : process (clk, rst_L, ld, data_in)
  begin  -- process REG
    if rst_L = '0' then
      data <= (others => '0');
    else
      if clk'event and clk = '1' then
        if ld = '1' then
          data <= data_in;
        end if;
      end if;
    end if;
    data_out <= data;
  end process REG;

end architecture bhv;

使其运作的流程变更:

  REG : process (clk, rst_L, ld, data_in)
  begin  -- process REG
    if rst_L = '0' then
      data <= (others => '0');
    else
      if clk'event and clk = '1' then
        if ld = '1' then
          data_out <= data_in;
        end if;
      end if;
    end if;
  end process REG;

只是想知道我做错了什么以及如果代码工作正常我甚至必须使用信号来传输值。谢谢!

2 个答案:

答案 0 :(得分:1)

过程代码损坏的问题是data信号未更新 读取直到delta延迟,因此data_out更新 data_out <= data assign被推迟到下一次执行流程代码,从而延迟了模拟。

请注意,初始过程的敏感性列表中的lddata_in不是必需的,因为clk的上升会保护它们的使用。

更新代码可以是:

reg : process (clk, rst_L)
begin  -- process REG
  if rst_L = '0' then
    data <= (others => '0');
  else
    if clk'event and clk = '1' then  -- May be written as rising_edge(clk) instead
      if ld = '1' then
        data <= data_in;
      end if;
    end if;
  end if;
end process REG;

data_out <= data;

查看 VHDL's crown jewel以获取有关VHDL中的进程和增量周期的一些信息可能很有用。

请注意,register是VHDL保留字,因此不能用作标识符 对于实体。

答案 1 :(得分:0)

注册VHDL意外延迟

原始过程的问题是data不在敏感列表中,将分配延迟到data_out,直到下一次执行过程而不是下一个模拟数据循环。该过程将在敏感性列表中的任何信号事务上执行 - 最初表示为ld

data添加到原始流程的敏感度列表中:

  REG : process (clk, rst_L, data)
  begin  -- process REG
    if rst_L = '0' then
      data <= (others => '0');
    else
      if clk'event and clk = '1' then
        if ld = '1' then
          data <= data_in;
        end if;
      end if;
    end if;
    data_out <= data;
  end process REG;

允许在delta模拟周期中分配data_out,而不是等到灵敏度列表中当前信号的转换。

我从敏感名单中删除了无关信号,原因与Morten在答案中所做的相同。这些导致其他时间执行该流程,但在data上发生交易时却没有。

是的,只要你的体系结构中的表达式中没有data_out信号(例如在赋值语句的右侧),就不需要中间变量{{1你的模拟会更快一些。

一旦灵敏度列表被削减,您更改的过程是最有效的实现。

简单地将数据添加到敏感度列表会导致原始过程正确模拟,请随意尝试。