VHDL如果条件不正常

时间:2013-02-03 22:57:18

标签: vhdl

我在确定代码无法正常工作的原因时遇到了一些困难。我正在尝试使用3位操作码创建一个ALU。

除了一个条件之外的所有条件都不能正常工作;操作码011(SEQ)。它被定义为(a == b)z< ='0'并且输出< ='0'。 a和b是输入,z是零标志。我希望通过以下VHDL代码获得此功能

....
    BEGIN

    result <= dummy_result;

    PROCESS (a, b, op) 

        VARIABLE carry: STD_LOGIC:='0';

         --DEFINE ALIAS TO SEPERATE ALU-OP SIGNAL
        alias NEG_TSEL      : STD_LOGIC IS op(2);
        alias ALU_SELECT    : STD_LOGIC_VECTOR(1 downto 0) IS op(1 downto 0);
    BEGIN
         if ALU_SELECT="11" THEN

                if NEG_TSEL='0'  THEN   -- SEQ

                    if a = b THEN
                        dummy_result <="00000";
                    end if;

                elsif NEG_TSEL='1' THEN     --SCO

                    cout <= '1';
                    result <= "XXXXX";


                end if;


        elsif ALU_SELECT="00" THEN...

使用此代码,当op = 011时,结果始终设置为零。

当我将代码更改为:

            .....
            if a = b THEN
                dummy_result <="00000";

            else
                dummy_result <= "10101";
            end if;
.....

它工作正常,但结果不能改变,所以而不是“10101”向量,我将其更改为“dummy_result&lt; = dummy_result;”但这给了我原始案例给我的相同结果。

有什么建议吗?我做错了吗?

2 个答案:

答案 0 :(得分:0)

以下是我的代码问题:

就我个人而言,我觉得在每个周期中你应该输出一些内容resultcoutzero。目前,您始终输出到zero,但您只能有条件地输出到其他两个端口。这可能是创建锁存器,这可能不是你想要的。因此,例如,SCO操作也应该将某些内容推送到cout,并且SCO操作应该将某些内容推送到dummy_result信号。

您的减法实施方式无法实现您的预​​期效果。

when "110" => -- SUB
    tmp_b <= NOT b;
    carry := '1';

    for i in 0 to 4 loop
        dummy_result(i) <= carry XOR a(i) XOR tmp_b(i);
        carry := (a(i) AND tmp_b(i)) OR (tmp_b(i) AND carry) OR (carry AND a(i));
    end loop;
    cout <= carry;

tmp_b是一个信号。在那里发生的逻辑将与此过程中的其他所有内容同时发生,而不是顺序发生。你可能希望它是一个变量,就像carry一样。


我还想让您了解案例陈述(与链条相对)。您的代码可能如下所示:

PROCESS (a, b, op)
    VARIABLE carry: STD_LOGIC:='0';
BEGIN

    case op is
        when "011" => -- SEQ
            dummy_result <= "00000";

        when "111" => -- SCO
            cout <= '1';

        when "000" => -- AND
            dummy_result <= a AND b;

        ...

        when others =>
            dummy_result <= "00000";
            cout <= '0';
    end case;
end process;

要回到原始问题SEQ,原始代码如下:

when op = "011" =>
    if a = b then
        dummy_result <= "00000";
    end if;

正如我上面提到的,这里的问题是这可能是一个闩锁。当a / = b时,您需要输出您期望值的值,并且不能只是dummy_result <= dummy_result。如果你把它推到物理线和芯片上,你会怎么想?

相反,你应该将最后一个dummy_result的值传递给这个实体,或者如果一个特定的操作应该保存结果的值,你应该输出&#34; 00000&#34;并且还输出一个附加信号,表示无论持有之前的值(在寄存器中),都不应该更新它。

答案 1 :(得分:0)

这里的意图是除非另有指定,否则dummy_result旨在保留“result”的先前值。不幸的是,这个单元已经实现为一个没有时钟的组合过程。

因此,本机无法可靠地实施存储 因此必须在本单元外实施 几乎可以肯定的是;在作为计时过程实现的寄存器中。

因此,将该寄存器的输出作为新的输入端口“prev_result”重新输入,并使用对dummy_result的默认赋值。这不仅会克服到目前为止发现的特定故障,而且还会克服“dummy_result”(还有另一个)的所有其他缺失分配,以同步方式保留“结果”的旧值。

    PROCESS (a, b, op, prev_result) 
       -- declarations here
    BEGIN
       -- default assignment
       dummy_result <= prev_result;

       if ALU_SELECT="11" THEN
          if NEG_TSEL='0' THEN    -- SEQ
             if a = b THEN
                dummy_result <="00000";
             end if;
       ...
    END PROCESS;

我认为你会更好地重组设计,使ALU成为一个时钟进程,但如果你不遵守指示,那么你将不得不采用这个(或类似的)解决方案。