整数到无符号转换错误VHDL quartus [英] Integer to unsigned conversion going wrong VHDL quartus

查看:251
本文介绍了整数到无符号转换错误VHDL quartus的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



波形下方:





代码下方:

  library ieee; 
使用ieee.std_logic_1164.all;
使用ieee.numeric_std.all;

实体tot是
端口(
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;

架构arch_1 of tot是
信号w_K:整数;
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 arch_1;






更新1:

 架构arch_1 of tot是
signal w_k:integer;
开始
过程(i_clk) - WAS(i_dinl)
如果rising_edge(i_clk)则开始
然后如果i_clr ='1'那么
然后是
w_k < = 0;
else
w_k< = i_dink;
结束如果;
如果i_dinl ='1'则
w_k< = w_k + 1;
- 否则
- w_k< = w_k;
结束如果;
- o_doutk< = w_k;
结束如果;
结束流程;

o_doutk< = w_k; - 移到这里。

end architecture arch_1;

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



波形:








更新2(正确的情况):



阅读后注释我得到了解决我的问题的解决方案,我使用状态机让我的计数器加载K中的前一个值,使用此代码我可以使代码正常工作。

  LIBRARY IEEE; 
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;
使用IEEE.std_logic_arith.ALL;

ENTITY控制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控制;

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

信号w_k:整数;
BEGIN

流程(i_CLK)
BEGIN
IF rising_edge(i_CLK)THEN
IF(i_RST ='1')那么
stateT < = s0;
ELSE
CASE stateT IS
当s0 => if(i_CLR ='1')THEN
w_k< = 0;
stateT< = s2;
else
stateT< = s1;
结束如果;当s1 =>时,
if(i_dinl ='1')然后
w_k< = i_dink;
stateT< = s2;
结束如果;当s2 =>时,
w_K< = w_k + 1;
stateT< = s3;当s3 =>时
o_DOUTK< = w_K;
stateT< = s0;
结束案例;
END IF;
END IF;
END PROCESS;


END arch_1;


解决方案

您的敏感度列表和if语句不做什么你打算。



试试:

 架构arch_1 of tot是
信号w_k:整数;
开始
过程(i_clk) - WAS(i_dinl)
如果rising_edge(i_clk)则开始
然后如果i_clr ='1'那么
然后是
w_k < = 0;
- 否则
- w_k< = i_dink;
- 结束if;
elsif i_dinl ='1'然后
w_k< = w_k + 1;
- 否则
- w_k< = w_k;
结束如果;
- o_doutk< = w_k;
结束如果;
结束流程;

o_doutk< = w_k; - 移到这里。

end architecture arch_1;

给出:





我用这个测试平台创建了一个完整的



这与您提出的任何可能的叙述都不符。



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



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



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

  tot的架构foo是
信号w_k:整数;
开始
过程(i_clk) - WAS(i_dinl)
如果rising_edge(i_clk)则开始
然后如果i_clr ='1'那么
然后是
w_k < = 0;
- 否则
- w_k< = i_dink;
- 结束if;
elsif i_dinl ='1'然后
w_k< = w_k + 1;
- 否则
其他
- w_k< = w_k;
w_k< = i_dink;
结束如果;
- o_doutk< = w_k;
结束如果;
结束流程;

o_doutk< = w_k; - 移到这里。

结束架构;

给出:





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



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



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


I am having problem with an output error in a waveform, basically my code works as a counter, when i have a load signal equal '1' the counter goes up, if the load signal is '0' the counter doesn't counts. I have a clear signal to get the counter in 0, my problem is in the output, the output shows always the same value and doesn't get in 0 when the clear signal is equal 1.

Below the waveform:

Below the code:

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;


Update 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;

When i try to do this logic to load a value from k to the initial count value, the error in the waveform still appears.

Waveform:


Update 2 (correct situation):

After reading the comments i get this solution to my problem, i've used a state machine to make my counter load the previous value from K, with this code I've get the code working correctly.

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;

解决方案

Your sensitivity list and if statements don't do what you intend.

Try:

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;

Which gives:

I used this testbench to create a complete 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;

The use clause mentioning package numeric_std is also not needed (all your arithmetic is integer based).

Without seeing a full representation of what you're intending to do here, o_doutk doesn't need to be mode buffer, it can be mode out.

All assignments are inside the if statement with the condition predicated on the rising edge of i_clk, so i_clk should be a sensitivity list item. There is no other signal that should be in the sensitivity list.

The assignment to the output is a concurrent statement which will be elaborated to an equivalent process. The idea behind a separate statement/process is to prevent a clock delay assigning the new value of w_k to o_doutk in simulation.

No signal value is updated while any pending process has yet to resume and suspend. The reason w_k was not changing is because you had two independent if statements. There's only one projected output waveform for any target simulation time, the second if statement supplanted the projected value for w_k from the first if statement supplying the reset value assignment.

Because the process assigning w_k models sequential (clocked) logic you don't infer latches by failing to provide values for else alternatives. If you had i_clk in your sensitivity list instead of i_dinl and your waveform had shown the entire value of w_k (o_doutk) you would have seen that it incremented during reset, starting at INTEGER'LOW because no initial value nor range constraint is provided in the declaration w_k.

Creating a single if statement allows only one assignment statement to be conditionally encountered, meaning the reset value of 0 will take effect.

From IEEE Std 1076-2008 10.8 If statement:

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.

Your eventual solution with a state machine doesn't appear useful:

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;

It produces:

Which doesn't match any possible narrative constructed from your question.

Note there's a one clock delay between w_k showing an incremented value and o_doutk and you only reach state s3 with a new value on w_k once. There's also a one clock delay between reset invalid and i_dink load into w_k.

If this waveform is what you wanted this answer is wrong. If this isn't what you want your question is unclear, your solution is wrong. In either scenario you should withdraw acceptance of this answer.

Instead of states it might be more appropriate to either load or increment w_k based on the state of i_dinl:

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;

Which gives:

In general you'd expect a separate control signal for count enable, particularly if you had used an asynchronous reset.

The suggest by wahab to use states is predicated on encoding four functions (clr, load, increment, hold) into two inputs. The state is held by whatever provides the two control inputs.

Note that this doesn't match either of your two waveforms and your question isn't a MCVE](https://stackoverflow.com/help/mcve) for either your solution nor this one.

这篇关于整数到无符号转换错误VHDL quartus的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆