【问题标题】:Vhdl generic fulladder codeVhdl 通用 fulladder 代码
【发布时间】:2015-04-01 00:34:21
【问题描述】:

这是级联全加器的通用代码。

问题在于,fulladder 的结果出现一个事件延迟(我的意思是,当我更改输入 1 和输入 2 时,会出现先前输入的结果)。我知道如果我在没有进程的情况下编写代码,则不会发生这种延迟,但我需要编写一个通用的全加法器,并且没有进程和 for 循环就无法编写通用代码。

所以我问是否有人可以帮助我修复代码,以便输出立即显示结果!!!

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;

entity adders is
    generic(
        numberOfInputs : Integer := 4
    ); port(
        enable  : in std_logic;
        cin     : in std_logic;
        inputs1 : in std_logic_vector(numberOfInputs-1 downto 0);
        inputs2 : in std_logic_vector(numberOfInputs-1 downto 0);
        outputs : out std_logic_vector(numberOfInputs downto 0)
    );
end entity adders;

architecture Generic_Adder of adders is
    signal Couts:std_logic_vector(numberOfInputs downto 0);
    signal temp1:std_logic_vector(numberOfInputs-1 downto 0);
    signal temp2:std_logic_vector(numberOfInputs-1 downto 0);
    signal temp3:std_logic_vector(numberOfInputs-1 downto 0);

begin

    temp2<=inputs1;
    temp3<=inputs2;  
    couts(0)<= cin;

    Sum:process(temp2,temp3,cin,enable,Couts) is
    begin
        for count in 0 to numberOfInputs-1 loop
            temp1(count) <= (temp2(count) xor temp3(count));
            outputs(count) <= Couts(count) xor temp1(count);
            Couts(count+1) <= (temp2(count) and temp3(count)) or(couts(count) and temp1(count));--cout(count) is the previuos cout becuase the first cout is cin
        end loop;
    end process;

    outputs(numberOfInputs) <= Couts(numberOfInputs);
end Generic_Adder;

【问题讨论】:

    标签: vhdl fpga


    【解决方案1】:

    进程中使用了temp1信号,但在敏感度列表中缺失。

    temp1 的更改因此不会触发流程的重新评估,并且 temp1 的新值不会反映在其他驱动信号中,直到另一个信号触发重新评估,因此您可能会遇到“延迟”。

    通过将temp1 添加到敏感度列表来解决此问题,或者按照Bill Lynch 的建议重写,或者如果您使用VHDL-2008 和兼容的编译器,那么敏感度列表可以是process (all) ...

    另外,由于进程内循环驱动outputs,进程外驱动outputs(numberOfInputs),遇到了与“最长静态前缀”相关的VHDL问题。结果是outputs(numberOfInputs) 有一个来自进程的驱动程序'U' 和一个在进程外的驱动程序Couts(numberOfInputs)。基于std_logic 分辨率函数的结果值为“U”。

    在保留进程时,解决此问题的一种方法是将outputs(numberOfInputs) 移动到进程内,例如:

            ...
        end loop;
        outputs(numberOfInputs) <= Couts(numberOfInputs);
    end process;
    

    这个答案https://stackoverflow.com/a/18248941/2352082 有更多关于 VHDL 最长静态前缀的信息。

    【讨论】:

    • 或者如果他们使用了足够新的编译器:process (all)。此外,敏感度列表中不需要cinenable。如果他们想实际使用enable 位并保持输出,我不确定他们将如何在没有锁存器的情况下编写此代码。
    • 您也可以让temp1 成为变量而不是信号。在这种情况下,它不必是一个向量,简单的 std_logic 就可以了。
    • 输出没有延迟,但输出(1)和输出(2)未知(u)!!??我该如何解决??
    • 如果outputs(1)outputs(2) 未知'X' 可能是由于未知'X' 输入数据。但是由于称为“最长静态前缀”的 VHDL 问题,MSB outputs(4) 实际上会变得未知 'X';请在答案中查看更新。
    • 顺便说一句。 Couts 的进位生成看起来不对;请参阅 Bill Lynch 对进位生成的回答。
    【解决方案2】:

    您可以使用生成语句在流程语句之外编写迭代代码。它可能看起来像这样:

    LIBRARY IEEE;
    USE IEEE.STD_LOGIC_1164.ALL;
    
    entity adders is
        generic(
            numberOfInputs : Integer := 4
        ); port(
            enable  : in std_logic;
            cin     : in std_logic;
            inputs1 : in std_logic_vector(numberOfInputs-1 downto 0);
            inputs2 : in std_logic_vector(numberOfInputs-1 downto 0);
            outputs : out std_logic_vector(numberOfInputs downto 0)
        );
    end entity adders;
    
    architecture Generic_Adder of adders is
        signal carry  : std_logic_vector(numberOfInputs     downto 0);
        signal result : std_logic_vector(numberOfInputs - 1 downto 0);
    begin
    
        carry(0) <= cin;
    
        for I in 0 to numberOfInputs-1 generate
        begin
            result(I) <= inputs1(I) xor inputs2(I) xor carry(I);
            carry(I+1) <= 
                (inputs1(I) and inputs2(I)) or 
                (inputs1(I) and carry(I))   or
                (inputs2(I) and carry(I));
        end generate;
    
        outputs <= carry(numberOfInputs) & result;
    
    end Generic_Adder;
    

    【讨论】:

    • @BillLynch:在result(I) 中,+ 应该是xor
    猜你喜欢
    • 2016-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-16
    相关资源
    最近更新 更多