在VHDL中为模块创建“初始化”和“结束”信号

时间:2018-11-20 02:45:36

标签: vhdl fpga

library IEEE;  
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.NUMERIC_STD.ALL; 
entity struture_test is
        Port ( clk : in STD_LOGIC;
               rst : in STD_LOGIC;
               Init  : in STD_LOGIC;
               i_ia : in STD_LOGIC_VECTOR (11 downto 0);
               i_ib : in STD_LOGIC_VECTOR (11 downto 0);
               end_s : out  std_logic;
               result : out STD_LOGIC_VECTOR (11 downto 0)); 
end struture_test;

architecture Behavioral of struture_test is
    signal en_sn : std_logic := '0'; 
begin 
PROCESS (clk,rst)
    variable acc : signed (23 downto 0) ;
    variable x   : signed (35 downto 0) ; 
begin
    if (rst = '0') then
        result <= (others => '0');
        end_s  <= '0';
    elsif (rising_edge (clk)) then

        if ((Init) = '1') then
            acc := signed (i_ia)*signed (i_ib);
            x   := acc * signed (i_ia);

            result <= std_logic_vector (x(23 downto 12));
            end_s  <= '1';
         else
            end_s  <= '0';
         end if;    
    end if; 
end process;

end Behavioral;

大家好 我有一个项目,其中包括一些街区。这些块通过初始化或结束信号相互链接。这意味着一个块的结束信号连接到下一个块的初始化信号。 我感到困惑的是,上面的代码是否可以实现良好的Init和End信号?

如果我更改代码并将其转换为Pipelined结构以使用更高频率的时钟进行操作。变量转换为信号

PROCESS (clk,rst)
    signal acc : signed (23 downto 0) ;
    signal x   : signed (35 downto 0) ; 
begin
    if (rst = '0') then
        result <= (others => '0');
        end_s  <= '0';
    elsif (rising_edge (clk)) then

        if ((Init) = '1') then
            acc <= signed (i_ia)*signed (i_ib);
            x   <= acc * signed (i_ia);

            result <= std_logic_vector (x(23 downto 12));
            end_s  <= '1';
         else
            end_s  <= '0';
         end if;    
    end if; 
end process;

在这种情况下如何创建Init和End信号?方框如图所示

1 个答案:

答案 0 :(得分:0)

这个主意不错,但是代码错误。此外,它还有一些不好的编码气味。

基本规则:

  1. 请勿使用异步重置。
  2. 您不能在流程中声明信号。进程允许变量声明;体系结构允许信号声明。
  3. 一个时钟过程中的每个信号分配都会产生一个时钟周期的触发器/延迟。因此总共有3个时钟周期的延迟,但是您的end信号仅延迟了一个周期。
  4. 不启用流水线操作。使用有效位的延迟链。
  5. 请勿重置管道结果,因为基础硬件资源(例如DSP(乘法)单元)不支持重置。

更改代码:

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

entity struture_test is
  port (
    clk    : in  std_logic;
    rst    : in  std_logic;
    Init   : in  std_logic;
    i_ia   : in  std_logic_vector(11 downto 0);
    i_ib   : in  std_logic_vector(11 downto 0);
    end_s  : out std_logic;
    result : out std_logic_vector(11 downto 0)    := (others => '0');
  ); 
end entity;

architecture rtl of struture_test is
  signal ValidChain : std_logic_value(2 downto 0) := (others => '0');
  signal ia_delayed : signed(i_ia'range)          := (others => '0');
  signal acc        : signed(23 downto 0)         := (others => '0');
  signal x          : signed(35 downto 0)         := (others => '0');
begin
  process(clk)
  begin
    if rising_edge(clk) then
      ValidChain <= ValidChain(ValidChain'high - 1 downto ValidChain'low) & Init;

      acc        <= signed(i_ia) * signed(i_ib);
      ia_delayed <= signed(i_ia);
      x          <= acc * ia_delayed;
      result     <= std_logic_vector(x(23 downto 12));
    end if; 
  end process;

  end_s <= ValidChain(ValidChain'high);
end architecture;

请注意:第二次乘法中使用的信号i_ia需要延迟一个周期,否则您将混合来自不同管线周期的ia值。