整数到无符号转换出错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)。
我遇到波形输出错误的问题,基本上我的代码用作计数器,当我的负载信号等于“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)。