整数到无符号转换错误VHDL quartus

时间:2016-06-26 23:44:57

标签: integer vhdl unsigned waveform quartus

我遇到波形输出错误的问题,基本上我的代码作为计数器工作,当我的负载信号等于' 1'如果负载信号是“0”,计数器会上升。这个计数器并不重要。我有一个明确的信号让计数器变为0,我的问题在于输出,输出显示总是相同的值,当清除信号等于1时,输入不会为0。

波形下方:

enter image description here

代码下方:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity tot is
port (
      i_CLR  : IN STD_LOGIC;         
      i_CLK  : IN STD_ULOGIC;        
      i_DINL : IN STD_LOGIC ;        
      i_DINK : IN INTEGER;           
      o_DOUTK : BUFFER INTEGER);      
end tot;

architecture arch_1 of tot is
signal w_K : integer;                
begin
PROCESS (i_DINL)
begin
    IF rising_edge(i_CLK) THEN       
        IF (i_CLR = '1') THEN        
            w_K <= 0;                
        ELSE                         
            w_K <= i_DINK;           
        END IF;
        IF (i_DINL = '1') THEN       
            w_K <= w_K + 1;          
        ELSE                      
            w_K <= w_K;              
        END IF;
        o_DOUTK <= w_K;            
    END IF;
    end process;
end arch_1;

更新1:

architecture arch_1 of tot is
    signal w_k:  integer;                
begin
process (i_clk)   -- WAS (i_dinl)
begin
    if rising_edge(i_clk) then     
        if i_clr = '1' then        
            w_k <= 0;                
        else
            w_k <= i_dink;       
        end if;
        if i_dinl = '1' then       
            w_k <= w_k + 1;          
        -- else
        --     w_k <= w_k;          
        end if;
        -- o_doutk <= w_k;            
    end if;
    end process;

    o_doutk <= w_k;  -- MOVED to here.

end architecture arch_1;

当我尝试将此逻辑从k加载到初始计数值时,波形中的错误仍会出现。

波形:

enter image description here

更新2(正确的情况):

阅读完评论后,我得到了解决问题的方法,我使用状态机让我的计数器加载K中的前一个值,使用此代码我可以使代码正常工作。< / p>

LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;
use IEEE.std_logic_arith.ALL;

ENTITY controle IS
  PORT (
      i_RST  : IN STD_LOGIC;
      i_CLR  : IN STD_LOGIC;         -- Sinal vindo do controle para limpar o valor de K
      i_CLK  : IN STD_ULOGIC;        -- Sinal de clock para sincronizar com o controle
      i_DINL : IN STD_LOGIC ;        -- Sinal de load para carregar K
      i_DINK : IN INTEGER;           -- Valor antigo de K
      o_DOUTK : BUFFER INTEGER
      );     
END controle;

ARCHITECTURE arch_1 OF controle IS
  TYPE state_type IS (s0, s1, s2,s3);
  SIGNAL stateT : state_type;

   signal w_k:  integer;  
BEGIN

  PROCESS(i_CLK)
  BEGIN
    IF rising_edge(i_CLK) THEN
      IF (i_RST = '1') THEN
        stateT <= s0;
      ELSE
        CASE stateT IS
          when s0 => if (i_CLR = '1') THEN
                        w_k <= 0;
                        stateT <= s2;
                     else
                        stateT <= s1;
                     end if;
          when s1 => if (i_dinl = '1') then 
                       w_k <= i_dink;
                       stateT <= s2;
                     end if;
          when s2 => w_K <= w_k + 1;
                     stateT <= s3;
          when s3 => o_DOUTK <= w_K; 
                     stateT <= s0;
        END CASE;
      END IF;
    END IF;
  END PROCESS;


END arch_1;

1 个答案:

答案 0 :(得分:2)

您的敏感度列表和if语句不符合您的意图。

尝试:

architecture arch_1 of tot is
    signal w_k:  integer;                
begin
process (i_clk)   -- WAS (i_dinl)
begin
    if rising_edge(i_clk) then       
        if i_clr = '1' then        
            w_k <= 0;                
        -- else
        --     w_k <= i_dink;       
        -- end if;
        elsif i_dinl = '1' then       
            w_k <= w_k + 1;          
        -- else
        --     w_k <= w_k;          
        end if;
        -- o_doutk <= w_k;            
    end if;
    end process;

    o_doutk <= w_k;  -- MOVED to here.

end architecture arch_1;

给出了:

tot_tb.png

我使用此测试平台创建了一个完整的MCVE

library ieee;
use ieee.std_logic_1164.all;

entity tot_tb is
end entity;

architecture foo of tot_tb is
    signal clr:     std_logic := '1';
    signal clk:     std_logic := '0';
    signal dinl:    std_logic := '1';
    signal dink:    integer := 8;
    signal doutk:   integer;
begin
DUT:
    entity work.tot
        port map (
            i_clr => clr,
            i_clk => clk,
            i_dinl => dinl,
            i_dink => dink,
            o_doutk => doutk
        );
CLOCK:
    process
    begin
        wait for 10 ns;
        clk <= not clk;
        if now > 650 ns then
            wait;
        end if;
    end process;
STIMULI:
    process
    begin
        wait for 240 ns;
        clr <= '0';
        wait for 100 ns;
        clr <= '1';
        wait for 40 ns;
        clr <= '0';
        wait;
    end process;

end architecture;

也不需要提及包numeric_std的use子句(所有算术都是基于整数的。)

如果没有完全代表您打算在此处执行的操作,则o_doutk不需要是模式buffer,它可以是模式out

所有赋值都在if语句中,条件是在i_clk的上升沿预测,因此i_clk应该是敏感列表项。敏感度列表中没有其他信号。

对输出的赋值是一个并发语句,它将被详细描述为一个等效的过程。单独的语句/过程背后的想法是防止在模拟中将w_k的新值分配给o_doutk的时钟延迟。

当任何待处理进程尚未恢复和暂停时,不会更新任何信号值。 w_k没有改变的原因是因为你有两个独立的if语句。对于任何目标模拟时间,只有一个预测输出波形,第二个if语句从提供重置值赋值的第一个if语句中取代了w_k的预计值。

由于流程分配w_k模型顺序(时钟)逻辑,因此无法通过为其他备选方案提供值来推断锁存器。 如果你的灵敏度列表中有i_clk而不是i_dinl并且你的波形显示了w_k(o_doutk)的整个值,你会看到它在复位期间递增,从INTEGER'LOW开始,因为没有提供初始值和范围约束。声明w_k。

创建单个if语句只允许有条件地遇到一个赋值语句,这意味着重置值0将生效。

来自IEEE Std 1076-2008 10.8如果声明:

  

if语句根据一个或多个相应条件的值选择执行一个或不包含的语句序列。

使用状态机的最终解决方案似乎没有用处:

architecture arch_1 of tot is          -- WAS controle NOW tot
    type state_type is (s0, s1, s2,s3);
    signal statet : state_type;

    signal w_k:  integer;  

begin

    process (i_clk)
    begin
        if rising_edge(i_clk) then
            if i_clr = '1' then           -- WAS i_rst NOW i_clr
                statet <= s0;
            else
                case statet is
                    when s0 => 
                        if i_clr = '1' then
                            w_k <= 0;
                        else
                            statet <= s1;
                        end if;
                    when s1 => 
                        if i_dinl = '1' then 
                            w_k <= i_dink;
                            statet <= s2;
                        end if;
                    when s2 => 
                        w_k <= w_k + 1;
                        statet <= s3;
                    when s3 => 
                        o_doutk <= w_k; 
                        statet <= s0;
                end case;
            end if;
        end if;
    end process;
END arch_1;

它产生:

tot_tb_state.png

哪个与您的问题构成的任何可能的叙述都不匹配。

请注意,w_k之间有一个时钟延迟,显示增加的值和o_doutk,并且您只能在w_k上使用新值到达状态s3一次。复位无效和i_dink加载到w_k之间也有一个时钟延迟。

如果您想要此波形,则此答案是错误的。如果这不是你想要的,你的问题不清楚,你的解决方案是错误的。在任何一种情况下,你都应该撤回对这个答案的接受。

而不是状态,根据i_dinl的状态加载或增加w_k可能更合适:

architecture foo of tot is
    signal w_k:  integer;
begin
    process (i_clk)   -- WAS (i_dinl)
    begin
        if rising_edge(i_clk) then
            if i_clr = '1' then
                w_k <= 0;
            -- else
            --     w_k <= i_dink;
            -- end if;
            elsif i_dinl = '1' then
                w_k <= w_k + 1;
            -- else
            else 
            --     w_k <= w_k;
                w_k <= i_dink;
            end if;
            -- o_doutk <= w_k;
        end if;
    end process;

    o_doutk <= w_k;  -- MOVED to here.

end architecture;

给出了:

tot_tb_dinl.png

一般情况下,您希望有一个单独的控制信号用于计数启用,特别是如果您使用了异步复位。

wahab建议使用状态是基于将四个函数(clr,load,increment,hold)编码为两个输入。任何提供两个控制输入的状态都保持状态。

请注意,对于您的解决方案或此解决方案,这与您的两个波形中的任何一个都不匹配,并且您的问题不是MCVE](https://stackoverflow.com/help/mcve)。