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

Integer to unsigned conversion going wrong VHDL quartus

我遇到波形输出错误的问题,基本上我的代码用作计数器,当我的负载信号等于“1”时,计数器上升,如果负载信号为“0”,计数器上升不算数。我有一个明确的信号让计数器为 0,我的问题出在输出上,输出始终显示相同的值,并且当明确信号等于 1 时不会进入 0。

波形下方:

代码下方:

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 加载到初始计数值时,波形中的错误仍然出现。

波形:


更新 2(正确情况):

阅读评论后我得到了我的问题的解决方案,我使用状态机使我的计数器从 K 加载先前的值,使用这段代码我使代码正常工作。

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;

您的敏感度列表和 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;

给出:

我用这个测试平台创建了一个完整的 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 应该是敏感列表项。敏感度列表中没有其他信号。

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

当任何挂起的进程尚未恢复和挂起时,没有更新信号值。 w_k 没有改变的原因是你有两个独立的 if 语句。对于任何目标仿真时间,只有一个预计输出波形,第二个 if 语句从第一个提供重置值分配的 if 语句中取代了 w_k 的预计值。

因为分配 w_k 模型的过程是顺序(时钟)逻辑,所以您不会通过未能为 else 替代方案提供值来推断锁存器。 如果您的灵敏度列表中有 i_clk 而不是 i_dinl 并且您的波形显示了 w_k (o_doutk) 的整个值,您会看到它在重置期间递增,从 INTEGER'LOW 开始,因为在声明 w_k.

中没有提供初始值和范围约束

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

来自 IEEE Std 1076-2008 10.8 If 语句:

An if statement selects for execution one or none of the enclosed sequences of statements, depending on the value of one or more corresponding conditions.

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

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;

它产生:

这与根据您的问题构建的任何可能叙述都不匹配。

请注意,在 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;

给出:

一般来说,您会希望有一个单独的控制信号来启用计数,尤其是在您使用了异步复位的情况下。

wahab 建议使用状态的前提是将四个函数(clr、load、increment、hold)编码为两个输入。状态由提供两个控制输入的任何东西保持。

请注意,这与您的两个波形都不匹配,您的问题既不是您的解决方案也不是这个解决方案的 MCVE](https://whosebug.com/help/mcve)。