输出上的VHDL模拟错误
我正在尝试为quartus II中的两个模块执行握手协议。首先,我使用了一个简单的IF-ELSE体系结构来实现这一点,它是有效的,现在我正在尝试将IF-ELSE的体系结构调整到一个状态机。电路基本上是这样工作的:生产者模块向消费者模块发送一个4位信号,消费者模块等待来自生产者的REQ信号,当REQ信号为“1”时,需要激活一个“RDY”led,当用户拧紧de RCV按钮时,来自耗电元件的de output在4个LED上显示从生产者接收的4位数据,并通过输出呼叫ACK向生产者发送确认信号。 生产者模块中的状态机工作正常,但当我模拟消费者状态机时,输出不工作 以下是生产者和消费者模块中的两个代码: 制作人:输出上的VHDL模拟错误,vhdl,simulator,state-machine,quartus,Vhdl,Simulator,State Machine,Quartus,我正在尝试为quartus II中的两个模块执行握手协议。首先,我使用了一个简单的IF-ELSE体系结构来实现这一点,它是有效的,现在我正在尝试将IF-ELSE的体系结构调整到一个状态机。电路基本上是这样工作的:生产者模块向消费者模块发送一个4位信号,消费者模块等待来自生产者的REQ信号,当REQ信号为“1”时,需要激活一个“RDY”led,当用户拧紧de RCV按钮时,来自耗电元件的de output在4个LED上显示从生产者接收的4位数据,并通过输出呼叫ACK向生产者发送确认信号。 生产者模
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;
use IEEE.std_logic_arith.ALL;
ENTITY produtor IS
GENERIC(W : NATURAL := 4);
PORT (o_RDY : OUT BIT;
i_SND : IN BIT;
i_DIN : IN STD_LOGIC_VECTOR(W-1 DOWNTO 0);
o_DOUT : OUT STD_LOGIC_VECTOR(W-1 DOWNTO 0);
o_REQ : OUT BIT;
i_ACK : IN BIT);
END produtor;
ARCHITECTURE arch_1 OF produtor IS
TYPE state_type IS (s0, s1);
SIGNAL state_reg : state_type;
SIGNAL next_state: state_type;
BEGIN
p_state_reg: PROCESS(i_SND,i_DIN,i_ACK)
BEGIN
IF (i_ACK ='0') THEN
state_reg <= s0;
ELSIF (i_ACK ='1') THEN
state_reg <= next_state;
END IF;
END PROCESS;
p_next_state: PROCESS(state_reg,i_SND,i_ACK)
BEGIN
CASE (state_reg) IS
WHEN s0 => IF (i_ACK = '1') THEN
next_state <= s1;
ELSIF (i_ACK = '0') THEN
next_state <= s0;
END IF;
WHEN s1 => IF (i_SND ='1') THEN
next_state <= s1;
ELSIF (i_SND='0') THEN
next_state <= s0;
END IF;
WHEN OTHERS=> next_state <= s0;
END CASE;
END PROCESS;
o_DOUT <= i_DIN WHEN (state_reg = s1);
o_REQ <= '1' WHEN (state_reg = s1) ELSE '0';
o_RDY <= '0' WHEN (state_reg = s1) ELSE '1';
END arch_1;
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;
use IEEE.std_logic_arith.ALL;
ENTITY produtor IS
GENERIC(W : NATURAL := 4);
PORT (
i_RST : IN BIT;
i_ACK : IN BIT;
i_CLK : IN STD_ULOGIC;
i_SND : IN BIT;-- data input
i_DIN : IN STD_LOGIC_VECTOR(W-1 DOWNTO 0); -- clock
o_DOUT : OUT STD_LOGIC_VECTOR(W-1 DOWNTO 0); -- clear
o_REQ : OUT BIT; -- enable
o_RDY : OUT BIT);-- data output
END produtor;
ARCHITECTURE arch_1 OF produtor IS
TYPE state_type IS (s0, s1, s2);
SIGNAL stateT : state_type;
BEGIN
PROCESS(i_CLK)
BEGIN
IF rising_edge(i_CLK) THEN
IF (i_RST = '1') THEN
CASE stateT IS
WHEN s0 => IF (i_ACK = '0') THEN
stateT <= s0;
ELSE
stateT <= s1;
END IF;
WHEN s1 => IF (i_SND = '1') THEN
stateT <= s2;
ELSE
stateT <= s0;
END IF;
WHEN s2 => stateT <= s0;
END CASE;
END IF;
END IF;
END PROCESS;
o_DOUT <= i_DIN WHEN (stateT = s2);
o_REQ <= '1' WHEN (stateT = s1) ELSE '0';
o_RDY <= '1' WHEN (stateT = s0) ELSE '0';
END arch_1;
*两个模块通过BDF文件使用导线连接。
消费者模块的架构IF-ELSE如下所示:
ARCHITECTURE arch_1 OF consumidor IS
BEGIN
PROCESS(i_RCV, i_DIN, i_REQ)
BEGIN
IF (i_REQ = '1') THEN
o_RDY <= '1';
ELSE
o_RDY <= '0';
END IF;
IF (i_RCV = '1') THEN
o_DOUT <= i_DIN;
o_ACK <= '1';
ELSE
o_ACK <= '0';
END IF;
END PROCESS;
END arch_1;
将电路更改为具有时钟和复位入口的同步模式。
现在模拟工作,但LED和输出始终保持相同的值
新建筑
消费者:
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;
use IEEE.std_logic_arith.ALL;
ENTITY consumidor IS
GENERIC(W : NATURAL := 4);
PORT (o_RDY : OUT BIT;
i_RCV : IN BIT;
i_DIN : IN STD_LOGIC_VECTOR(W-1 DOWNTO 0);
o_DOUT : OUT STD_LOGIC_VECTOR(W-1 DOWNTO 0);
i_REQ : IN BIT;
o_ACK : OUT BIT);
END consumidor;
ARCHITECTURE arch_1 OF consumidor IS
TYPE state_type IS (s0, s1, s2);
SIGNAL state_reg : state_type;
SIGNAL next_state: state_type;
BEGIN
p_state_reg: PROCESS(i_RCV,i_REQ,i_DIN)
BEGIN
IF (i_REQ ='0') THEN
state_reg <= s0;
ELSIF (i_REQ ='1') THEN
state_reg <= next_state;
END IF;
END PROCESS;
p_next_state: PROCESS(state_reg,i_RCV,i_REQ,i_DIN)
BEGIN
CASE (state_reg) IS
WHEN s0 => IF (i_REQ = '1') THEN
next_state <= s1;
ELSIF (i_REQ = '0') THEN
next_state <= s0;
END IF;
o_RDY <= '1';
o_ACK <= '0';
WHEN s1 => IF (i_RCV ='1') THEN
next_state <= s2;
ELSIF (i_RCV='0') THEN
next_state <= s0;
END IF;
o_RDY <= '0';
o_ACK <= '1';
WHEN s2 => o_DOUT <= i_DIN;
o_ACK <= '0';
o_RDY <= '0';
next_state <= s0;
WHEN OTHERS=> next_state <= s0;
END CASE;
END PROCESS;
--o_DOUT <= i_DIN WHEN (state_reg = s2);
--o_ACK <= '1' WHEN (state_reg = s1) ELSE '0';
--o_RDY <= '1' WHEN (state_reg = s0) ELSE '0';
END arch_1;
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;
use IEEE.std_logic_arith.ALL;
ENTITY consumidor IS
GENERIC(W : NATURAL := 4);
PORT (o_RDY : OUT BIT;-- data input
i_RST : IN BIT;
i_CLK : IN STD_ULOGIC;
i_RCV : IN BIT;-- data input
i_DIN : IN STD_LOGIC_VECTOR(W-1 DOWNTO 0); -- clock
o_DOUT : OUT STD_LOGIC_VECTOR(W-1 DOWNTO 0); -- clear
i_REQ : IN BIT; -- enable
o_ACK : OUT BIT);-- data output
END consumidor;
ARCHITECTURE arch_1 OF consumidor IS
TYPE state_type IS (s0, s1, s2);
SIGNAL stateT : state_type;
BEGIN
PROCESS(i_CLK)
BEGIN
IF rising_edge(i_CLK) THEN
IF (i_RST = '1') THEN
CASE stateT IS
WHEN s0 => IF (i_REQ = '0') THEN
stateT <= s0;
ELSE
stateT <= s1;
END IF;
WHEN s1 => IF (i_RCV = '1') THEN
stateT <= s2;
ELSE
stateT <= s0;
END IF;
WHEN s2 => stateT <= s0;
END CASE;
END IF;
END IF;
END PROCESS;
o_DOUT <= i_DIN WHEN (stateT = s2);
o_ACK <= '1' WHEN (stateT = s1) ELSE '0';
o_RDY <= '1' WHEN (stateT = s0) ELSE '0';
END arch_1;
IEEE库;
使用IEEE.std_logic_1164.ALL;
使用IEEE.std_logic_unsigned.ALL;
使用IEEE.std_logic_arith.ALL;
实体consumidor是
通用型(W:天然型:=4);
端口(o_RDY:OUT位;--数据输入
首先:以位为单位;
时钟:标准逻辑;
i_RCV:位;--数据输入
i_DIN:标准逻辑向量(W-1向下至0);--时钟
输出标准逻辑向量(W-1向下到0);--清除
i_请求:以位为单位;--启用
o_ACK:OUT BIT);--数据输出
康苏米多尔终点;
consumidor的建筑拱门1为
类型状态_类型为(s0、s1、s2);
信号状态:状态类型;
开始
过程(i_CLK)
开始
如果上升沿(i_CLK),则
如果(i_RST='1'),则
案例stateT是
当s0=>IF(i_REQ='0')时,则
stateT在Altera FPGA上,使用查找表(LUT)和逻辑元件(LE)内的组合反馈路径实现锁存。在对FPGA编程后,此类锁存器的状态未定义。使用矢量波形文件(VWF)对合成网络表进行的模拟显示为“X”。在原始代码中,合成器会报告有关状态
和下一个状态
(两个状态机)和o\u DOUT
(consumidor)锁存的警告。因此,依赖于(未知)状态的信号,如RDY_生产者
和RDY_消费者
,也将是未知的(如您所观察到的)
使用锁存器的异步设计是可能的,但前提是
逻辑是没有时间危险的。Altera的实际需求
Altera Quartus II/Quartus Prime手册中描述了FPGA,
第1卷,推荐的HDL编码样式,寄存器和锁存器编码
准则
如果您的设计包含闩锁,则编译报告将
表示它们是否没有计时危险。该信息可在中找到
“分析与综合->优化结果->寄存器”部分
统计->用户指定和推断的闩锁
Altera和我建议改用同步设计。我有
注释中已经提供了一个代码模板,但是
错。(对不起!)您已经在您的
问题,但必须在另一时间更改为:
PROCESS(i_CLK)
BEGIN
IF rising_edge(i_CLK) THEN
IF (i_RST = '1') THEN
stateT <= s0;
ELSE
CASE stateT IS
-- description of state machine here
END CASE;
END IF;
END IF;
END PROCESS;
以及消费者的实现(仅在请求后更新为信号就绪的代码):
consumidor的建筑拱门1是
类型状态_类型为(s0、s1、s2);
信号状态:状态类型;
开始
过程(i_CLK)
开始
如果上升沿(i_CLK),则
如果(i_RST='1'),则
stateT IF(i_REQ='1'),然后--等待请求
stateT if(i_RCV='1'),然后——等待直到启用接收
stateT IF(i_REQ='0'),然后--等待请求完成
stateT在Altera FPGA上,使用查找表(LUT)和逻辑元件(LE)内的组合反馈路径实现锁存。在对FPGA编程后,此类锁存器的状态未定义。使用矢量波形文件(VWF)对合成网络表进行的模拟显示为“X”。在原始代码中,合成器会报告有关状态
和下一个状态
(两个状态机)和o\u DOUT
(consumidor)锁存的警告。因此,依赖于(未知)状态的信号,如RDY_生产者
和RDY_消费者
,也将是未知的(如您所观察到的)
使用锁存器的异步设计是可能的,但前提是
逻辑是没有时间危险的。Altera的实际需求
Altera Quartus II/Quartus Prime手册中描述了FPGA,
第1卷,推荐的HDL编码样式,寄存器和锁存器编码
准则
如果您的设计包含闩锁,则编译报告将
表示它们是否没有计时危险。该信息可在中找到
“分析与综合->优化结果->寄存器”部分
统计->用户指定和推断的闩锁
Altera和我建议改用同步设计。我有
注释中已经提供了一个代码模板,但是
错。(对不起!)您已经在您的
问题,但必须在另一时间更改为:
PROCESS(i_CLK)
BEGIN
IF rising_edge(i_CLK) THEN
IF (i_RST = '1') THEN
stateT <= s0;
ELSE
CASE stateT IS
-- description of state machine here
END CASE;
END IF;
END IF;
END PROCESS;
以及消费者的实现(仅在请求后更新为信号就绪的代码):
consumidor的建筑拱门1是
类型状态_类型为(s0、s1、s2);
信号状态:状态类型;
开始
过程(i_CLK)
开始
如果上升沿(i_CLK),则
如果(i_RST='1'),则
stateT IF(i_REQ='1'),然后--等待请求
stateT if(i_RCV='1'),然后——等待直到启用接收
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;
use IEEE.std_logic_arith.ALL;
ENTITY produtor IS
GENERIC(W : NATURAL := 4);
PORT (
i_RST : IN BIT;
i_ACK : IN BIT;
i_CLK : IN STD_ULOGIC;
i_SND : IN BIT;-- data input
i_DIN : IN STD_LOGIC_VECTOR(W-1 DOWNTO 0); -- clock
o_DOUT : OUT STD_LOGIC_VECTOR(W-1 DOWNTO 0); -- clear
o_REQ : OUT BIT; -- enable
o_RDY : OUT BIT);-- data output
END produtor;
ARCHITECTURE arch_1 OF produtor IS
TYPE state_type IS (s0, s1, s2);
SIGNAL stateT : state_type;
BEGIN
PROCESS(i_CLK)
BEGIN
IF rising_edge(i_CLK) THEN
IF (i_RST = '1') THEN
CASE stateT IS
WHEN s0 => IF (i_ACK = '0') THEN
stateT <= s0;
ELSE
stateT <= s1;
END IF;
WHEN s1 => IF (i_SND = '1') THEN
stateT <= s2;
ELSE
stateT <= s0;
END IF;
WHEN s2 => stateT <= s0;
END CASE;
END IF;
END IF;
END PROCESS;
o_DOUT <= i_DIN WHEN (stateT = s2);
o_REQ <= '1' WHEN (stateT = s1) ELSE '0';
o_RDY <= '1' WHEN (stateT = s0) ELSE '0';
END arch_1;
PROCESS(i_CLK)
BEGIN
IF rising_edge(i_CLK) THEN
IF (i_RST = '1') THEN
stateT <= s0;
ELSE
CASE stateT IS
-- description of state machine here
END CASE;
END IF;
END IF;
END PROCESS;
ARCHITECTURE arch_1 OF produtor IS
TYPE state_type IS (s0, s1, s2);
SIGNAL stateT : state_type;
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_SND = '1') then -- wait until sending enabled
stateT <= s1; -- issue new request
end if;
when s1 => if (i_ACK = '1') then -- wait until acknowledge
stateT <= s2; -- finish request
end if;
when s2 => if (i_ACK = '0') and (i_SND = '0') then
-- wait until acknowledge finished and `i_SND` low
-- before starting a new transaction.
stateT <= s0;
end if;
END CASE;
END IF;
END IF;
END PROCESS;
o_DOUT <= i_DIN WHEN (stateT = s0); -- latch open when ready
o_REQ <= '1' WHEN (stateT = s1) ELSE '0';
o_RDY <= '1' WHEN (stateT = s0) ELSE '0';
END arch_1;
ARCHITECTURE arch_1 OF consumidor IS
TYPE state_type IS (s0, s1, s2);
SIGNAL stateT : state_type;
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_REQ = '1') then -- wait until request
stateT <= s1; -- signal ready
END IF;
when s1 => if (i_RCV = '1') then -- wait until receiving enabled
stateT <= s2; -- save data and acknowledge
end if;
WHEN s2 => IF (i_REQ = '0') then -- wait until request finished
stateT <= s0; -- finish acknowledge
END IF;
END CASE;
END IF;
END IF;
END PROCESS;
o_DOUT <= i_DIN WHEN (stateT = s2); -- latch open during acknowledge
o_ACK <= '1' WHEN (stateT = s2) ELSE '0';
o_RDY <= '1' WHEN (stateT = s1) ELSE '0';
END arch_1;