【问题标题】:VHDL. Why doesn't my "rdy" value change to 1? Still confused高密度脂蛋白。为什么我的“rdy”值没有变为 1?还是一头雾水
【发布时间】:2014-09-27 08:04:57
【问题描述】:

在我的波形图中,我想知道为什么我的“rdy”值在 400ns 后没有变为 1。 为什么我的“d”值在前两个输出之后没有输出任何东西?我已经尝试找到错误几个小时但无济于事。请帮忙,提前谢谢。

这是我的波形图:

这是我的主要代码。

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;

entity GCD is
port(st , clk: in std_logic;        --clk temporarily taken out
     d1, d2 : in std_logic_vector(7 downto 0);
     dout : out std_logic_vector(7 downto 0);
     rdy : out std_logic);
end GCD;

architecture behav of GCD is
type state is (S0, S1, S2, S3, S4, S5, S6, S7);

--temporary clk
--signal clk : std_logic;

signal new_state : state;
signal eq : boolean;
signal eq1 : boolean;
signal lt : boolean;

begin
    --State transition
    process is
    variable curr_state : state:= S0;
    begin
        if clk = '1' then
        case curr_state is
            when S0 => 
                if st = '1' then curr_state := S1;
                end if;
            when S1 =>
                curr_state := S2;
            when S2 =>
                if eq and not lt then curr_state := S7;
                elsif lt and not eq then curr_state := S4;
                elsif not eq and not lt then curr_state := S3;
                end if;
            when S3 => 
                curr_state := S4;
            when S4 =>
                curr_state := S5;
           when S5 =>
                if eq1 = true then curr_state := S7;
                else curr_state := S6;
                end if;
            when S6 =>
                curr_state := S1;
            when S7 =>
                if st = '0' then curr_state := S0;
                end if;
        end case;
        new_state <= curr_state;
        end if;
        wait on clk;
    end process;


--Asserted Output Process
process is
variable M, N, dout_val, tmp: std_logic_vector(7 downto 0);
variable rdy_val : std_logic;
variable lt_val, eq_val, eq1_val : boolean;
begin
    rdy_val := '0';
    case new_state is

        when S0 =>
            M :=  d1;
            N := d2;
        when S1 =>
            if (to_integer(M) = to_integer(N)) then eq_val := true;
            elsif (to_integer(M) < to_integer(N)) then lt_val := true;
            end if;

        when S2 =>
        when S3 =>
            M := N;
            N := M;         
        when S4 =>
            if (to_integer(M) = 1) then eq1_val := true;
            end if;
        when S5 =>
        when S6 =>
            N := (N - M);
        when S7 =>
            rdy_val := '1';
            dout_val := M; 
    end case;
    dout <= dout_val;   
    rdy <= rdy_val;
    lt <= lt_val;
    eq <= eq_val;
    eq1 <= eq1_val;
    wait on new_state;
end process;
end behav;

这是我的测试平台:

library IEEE;

use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;

use work.all;

entity test_GCD is
end test_GCD;

architecture testbench of test_GCD is
signal m, n ,d: std_logic_vector(7 downto 0);
signal clk, st, rdy : std_logic;

begin

    --Component Instantiation
    device : GCD
    port map( clk => clk, st => st, d1 => m, 
              d2 => n, dout => d, rdy => rdy);


    --Process to Generate Test Data
    process is
    begin
        st <= '0';
        wait for 10ns;
        m <= "00001001";    --9 , 15    
        n <= "00001111";
        wait for 10ns;
        st <= '1';
        wait until rdy = '1';
        wait for 10ns;

        st <= '0';
        wait for 10ns;
        m <= "00001111";    --15, 9
        n <= "00001001";        
        wait for 10ns;
        st <= '1';
        wait until rdy = '1';
        wait for 10ns;

        st <= '0';
        wait for 10ns;      --15 , 14
        m <= "00001111";
        n <= "00001110";
        wait for 10ns;
        st <= '1';
        wait until rdy = '1';
        wait for 10ns;

        st <= '0';
        wait for 10ns;
        m <= "00010010";    --18 , 36
        n <= "00100100";
        wait for 30ns;
        st <= '1';
        wait until rdy = '1';
        wait for 10ns;

        st <= '0';
        wait for 10ns;
        m <= "01011011";    --91 = 01011011 , 39 = 00100111
        n <= "00100111";
        wait for 10ns;
        st <= '1';
        --wait for 10ns;
        wait until rdy = '1';
        wait for 10ns;

        st <= '0';
        wait for 10ns;
        m <= "01111111";    --127, 127
        n <= "01111111";
        wait for 10ns;
        st <= '1';
        wait until rdy = '1';
        wait for 10ns;

        wait;
    end process;

process is
begin
    clk <= '0', '1' after 15ns;
    wait for 30ns;
end process;

end testbench;

【问题讨论】:

  • 出于好奇,您使用的是哪个 VHDL 工具,它不需要数字文字和单位之间的空格(例如 10ns)?此外,它不需要 GCD 的组件声明,并且您没有用于 synopsys 包 std_logic_unsigned(或 numeric_std_unsigned)的 use 子句。
  • 我正在使用 Capilano Computing 的 DesignWorks 5。
  • 您的 DesignWorks 在您的代码中展示的三个方面并不严格符合 VHDL 标准。

标签: vhdl diagram waveform


【解决方案1】:

你是今天第二个在同样的作业中提问的人。

在第三组 st/rdy 中,你打乱了时间关系:

    st <= '0';
    wait for 10ns;
    m <= "00010010";    --18 , 36
    n <= "00100100";
    wait for 30ns;
    st <= '1';
    wait until rdy = '1';
    wait for 10ns;

前两组等待了 10 ns。这个有 30 ns。那有什么作用?

你的状态机在未标记状态转换过程中缺少st

在帮助某人和为他们完成任务之间有一个很好的平衡。


附录

您能否详细说明我在状态转换中缺少 st

这个想法是让您查看分布在两个未标记进程中的状态机的操作。

即使您的代码未编写为符合综合条件,您的状态机仍在正时钟沿运行。该过程仅由一个事件驱动,clk 并且表达式 clk = '1' 在第一个 if 语句条件中进行评估。

如果您将new_state 添加到波形转储中(在波形显示中显示):

(您可以在单独的选项卡或窗口中打开图像,它是指向自身的链接)

(请注意,第一个 GCD 的“答案”全是 U。第二个“答案”似乎也不是 15 到 9 之间的最大公分母。)

您会看到您的状态机退出转换,仍然停留在 S2 中,该 S2 评估 lteq,但不会在断言输出过程中修改它们(您可以使用标签而不是 cmets,任何语句都可以用 VHDL 标记)。

我们查看之前的状态 S1,其中分配了 eq_vallt_val。它们依赖于MN,它们是从S0 中的d1d2 分配的。

返回 S2 通知:

        when S2 =>
            if eq and not lt then 
                curr_state := S7;
            elsif lt and not eq then 
                curr_state := S4;
            elsif not eq and not lt then 
                curr_state := S3;
            end if;

如果您查看上述波形中的eqlt,您会发现它们都是true。怎么可能?有一个过渡条件,你坚持S2

那么两个条件怎么可能同时是true呢?

    when S1 =>
        if (to_integer(M) = to_integer(N)) then 
            eq_val := true;
        elsif (to_integer(M) < to_integer(N)) then 
            lt_val := true;
        end if;

您只分配其中一个。

但是,另一个保持在之前的状态,由new_state 锁定。

作为一个短期演示,我在评估之前分配了eq_vallt_val 两者false。这样最多只会留下一个true

不幸的是,这揭示了您设计中的另一个缺陷:

这不是你问题的主题。

您似乎使用了链接中 PDF 中的流程图(图 1)中所示的 Euclid (GCD) 算法。布尔类型似乎是一项作业要求(其他学生也使用它们)。生成的 VHDL 表示该算法至少还有一个错误。

您将N 用作查找GCD 的累加器,并且您还更改了M 的内容。 N 有三个源,d2,S6 and swappingMandNinS3(which has the effect of assigningNtoM, andN 中的N-M 的结果给自己,变量赋值是立即的)。 M 和 N 应该是信号,或者你需要一个中间值来交换。 (它们应该是信号)。

您可以使用波形显示对设计进行故障排除。当您推断锁存器时,您还应该注意,当您有条件分配而没有等效于“else”时,就会发生这种情况。

我在查看您的设计时使用的开源工具(ghdl 和 gtkwave)不会捕获波形转储中的变量。我怀疑 DesignWorks 5 也没有(而且可能是错误的)。 这样做的影响是您无法在模拟期间看到数据在做什么。您的设计足够小,您可以在整个过程中使用信号,而不会显着影响仿真时间。直接在 S1 中分配给 eqlt 将需要 else 分配 (false)。如果您需要使用变量进行分配,您可以将它们分配给信号,以便它们可见,如果 DesignWorks 5 不显示变量。完成后,您可以移除信号。

为什么我的“rdy”值没有变为 1? 的答案是您推断出的锁存器创建了一个您没有检测到的从 S2 分支出来的案例。 p>

一旦你理顺了MNS3 中的交换,它看起来可能有很好的机会或工作(可能还有另一个或两个问题)。

当你使用tmp 来保存 M 的值时(不使用信号):

        when S3 =>
            tmp := M;
            M := N;
            N := tmp;      

你开始得到正确的答案:

如果没有看到为您的项目提供的讲义,我预计您使用的是链接 PDF 的图 1 中的伪代码。它可能是在预期使用信号时编写的。

【讨论】:

  • 感谢您的回复大卫。您能否详细说明我在状态转换中缺少 st
  • 谢谢大卫。我已经阅读了它,似乎已经解决了大部分问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-24
  • 2018-09-20
相关资源
最近更新 更多