输出上的VHDL仿真错误

IAGO SISTER奥乔亚

我正在尝试为quartus II中的2个模块做一个握手协议。首先,我使用一个简单的IF-ELSE架构来做到这一点,并且它起作用了,现在我正尝试将IF-ELSE的这种架构适应状态机。电路的工作原理基本上是这样的:PRODUCER模块将4位信号发送到CONSUMER模块,CONSUMER模块等待来自PRODUCER的REQ信号,当他的REQ信号为“ 1”时,需要使用“ RDY” LED激活后,当用户拧紧de RCV按钮时,从CONSUMER的输出将显示4个LED上从PRODUCER接收的4位数据,并通过输出呼叫ACK向生产者发送确认信号。PRODUCER模块中的状态机正常工作,但是当我模拟CONSUMER状态机时,输出不起作用。

在PRODUCER和CONSUMER模块的两个代码下面:

生产者:

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

我使用了三种状态来做消费者的状态机:

         s0 --> Ready to receive  
         s1 --> Waiting authorization to receive (authorization is send by the RCV input)
         s2 --> Receiving

*两个模块通过BDF文件通过电线连接。

以下CONSUMER模块的体系结构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;

错误显示在下面的图像中:

1)输出上的生产者-消费者状态机错误在此处输入图片说明

2)使用状态机架构和使用IF-ELSE架构的使用者模块与PRODUCER进行仿真:

在此处输入图片说明

3)BDF文件连接两个模块:

在此处输入图片说明

如果必须使用PRODUCER模块的体系结构IF-ELSE来解决此问题,则如下所示:

ARCHITECTURE arch_1 OF produtor IS
SIGNAL entrada : STD_LOGIC_VECTOR (W-1 DOWNTO 0);
BEGIN
  PROCESS(i_SND,i_DIN,i_ACK)
  BEGIN
    IF (i_ACK = '1') THEN
        o_RDY <= '1';
    ELSE
        o_RDY <= '0';
    END IF;
    IF (o_RDY = '1') THEN
       IF (i_DIN(0) = '1') THEN
          entrada(0) <= '1';
       END IF;
       IF (i_DIN(0) = '0') THEN
          entrada(0) <= '0';
       END IF;
       IF (i_DIN(1) = '1') THEN
          entrada(1) <= '1';
       END IF;
       IF (i_DIN(1) = '0') THEN
          entrada(1) <= '0';
       END IF;
       IF (i_DIN(2) = '1') THEN
          entrada(2) <= '1';
       END IF;
       IF (i_DIN(2) = '0') THEN
          entrada(2) <= '0';
       END IF;
       IF (i_DIN(3) = '1') THEN
          entrada(3) <= '1';
       END IF;
       IF (i_DIN(3) = '0') THEN
          entrada(3) <= '0';
       END IF;
       IF (i_SND = '1') THEN
          o_DOUT <= entrada;
          o_REQ <= '1';
          o_RDY <= '0';
       ELSE
          o_REQ <= '0';
          o_RDY <= '1';
       END IF;
    END IF;
  END PROCESS;
END arch_1;

我相信错误在于使用者的状态机上,在执行该状态机后,模拟不再起作用。


                            *****UPDATE*****

Changing the circuit to a Synchronous mode with Clock and Reset Entrance. Now the simulation works but the Leds and the output stay always with the same value...

The new architecture

CONSUMER:

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;

PRODUCER:

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;

The Clock and Reset signal are the same for the two modules in BDF. Now the simulation goes like this:

模拟

What's happening now to the output stay with XXXX value, the logic of the two modules seems to be correct.

Martin Zabel

On Altera FPGAs, latches are implemented using the look-up table (LUT) and a combinational feedback path within the logic element (LE). The state of such a latch is undefined after programming the FPGA. The simulation of the synthesized netlist with an Vector Waveform File (VWF) shows this as 'X'es. In your original code, the synthesizer reports warnings about latches for state and next_state (both state machines) and o_DOUT (consumidor). Thus, signals such as RDY_PRODUCER and RDY_CONSUMER which depend on the (unknown) state will be unknown too (as observed by you).


An asynchronous design using latches is possible, but only if the logic is free of timing hazards. The actual requirements for Altera FPGAs are described in the Altera Quartus-II / Quartus Prime Handbook, Volume 1, Recommended HDL Coding Styles, Register and Latch Coding Guidelines.

If your design contains latches, then the Compilation Report will denote if they are free of timing hazards. The information is found in the section Analysis & Synthesis -> Optimization Results -> Register Statistics -> User-Specified and Inferred Latches.

Altera and I recommend to use a synchronous design instead. I have already given a code template in the comments, but it was wrong. (Sorry!)) You have used it in the updated code in your question, but it must be changed another time to:

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;

A reset i_RST needs to be asserted during the startup of the FPGA only, if state machines may toggle states immediately. The initial state will always be defined by the declaration of signal stateT.

But even fixing this does not help. The producer keeps staying in state s0 because it is awaiting an acknowledge. But, the consumer is waiting for an request first before replying with an acknowledge. Thus, the state machines are in a dead-lock.

A producer-consumer scheme will work as follows instead:

  1. The producer issues a new request (o_REQ <= '1') if sending is enabled (i_SND = '1').

  2. The consumer waits for a request and then saves the incoming data if receiving is enabled (i_RCV = '1'). The consumer replies with an acknowledge afterwards (o_ACK <= '1')

  3. The producer waits for the acknowledge and then finished the request (o_REQ <= '0') afterwards.

  4. The consumer finishes the acknowledge as well (o_ACK <= '0') either after 1 clock cycle or after the request has been finished.

  5. Continue with step 1. But, your waveforms indicates that a new transaction should be issued by the producer only if i_SND is low in between. This is necessary to detect when new data DIN is available.

The implementation of the producer will now be:

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;

And the implementation of the consumer (code updated to signal ready only after request):

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;

I have used the inputs from your waveform, but some changes are required:

  • RCV and SND must be low at the beginning otherwise a reset is needed.

  • 时钟频率必须是2倍,以便输入在时钟的上升沿附近不会发生变化。

  • RCV 在第三笔交易开始时禁用此功能,以演示数据输出和确认的延迟。

现在,模拟输出为:

带o_DOUT锁存器的模拟输出

我的波形还包括两个状态机之间REQACK信号,以演示握手(此处分别命名为DEBUG_REQ和DEBUG_ACK)。

o_DOUT两个状态机中的信号分配仍然描述了锁存器。根据编译报告,Quartus可以在没有时序风险的情况下实施它们。但是,最好将它们也实现为同步寄存器。我将把它留作练习。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

输出上的VHDL仿真错误

来自分类Dev

输出上的Python WSGI错误

来自分类Dev

标准输出上的数据显示错误:C文件操作

来自分类Dev

VHDL仿真时序行为

来自分类Dev

VHDL Testbench仿真

来自分类Dev

错误” ...非错误输出上的OLE DB Source.Outputs [OLE DB源输出] .Columns [XXXXXXXX]没有相应的输出

来自分类Dev

在日志输出上设置阈值

来自分类Dev

在python3-- gdb输出上运行cython时出现分段错误

来自分类Dev

XSane前端上的I / O错误,但标准输出上没有

来自分类Dev

为什么在输出上放置滤波器,然后修改源信号?这是Simulink错误吗?

来自分类Dev

当输出重叠时,种类卡在输出上

来自分类Dev

OMShell仿真次数输出

来自分类Dev

Verilog仿真x的输出

来自分类Dev

Vhdl代码无法在仿真中工作

来自分类Dev

Nokogiri的xml输出上的命名空间

来自分类Dev

在candisc :: cancor输出上使用xtable函数

来自分类Dev

文件导出脚本挂在大输出上

来自分类Dev

时间单元在.xlsx输出上失败

来自分类Dev

在查询的输出上应用DENSE_RANK()

来自分类Dev

在iOS中的AVCaptureDevice的输出上设置GrayScale

来自分类Dev

无法在GroupByKey转换输出上多次迭代

来自分类Dev

如何防止Powershell在输出上打印警告?

来自分类Dev

更改SSRS报告输出上的页数

来自分类Dev

在表/输出上定位最小值

来自分类Dev

在命令输出上打印换行符

来自分类Dev

HP Laserjet 1018卡纸在输出上

来自分类Dev

在终端输出上播放声音

来自分类Dev

在shell命令输出上执行命令

来自分类Dev

在不同的输出上使用nohup和时间