I'm trying to do a handshake protocol for 2 modules in quartus II. First I used a simple IF-ELSE architecture to do this and it works, now I'm trying to adapt this architecture of IF-ELSE to a state machine. The circuito works basically like this: the PRODUCER module sends a 4-bit signal to the CONSUMER module, the CONSUMER module waits the REQ signal that comes from the PRODUCER, when he REQ signal is '1' a "RDY" led needs to be activated, when the user tightens de RCV button de output from the CONSUMER shows the 4-bit data received from the PRODUCER on 4 leds, and sends a confirmation signal to the producer by an output call ACK. The state machine from the PRODUCER module it's working correctly, but when I simulate the CONSUMER state machine the outputs doesn't works.
Below the two codes from the PRODUCER and CONSUMER module:
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 (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;
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;
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;
I used three states to do the state machine of consumer:
s0 --> Ready to receive
s1 --> Waiting authorization to receive (authorization is send by the RCV input)
s2 --> Receiving
* The two modules are connected by a BDF file using wires.
The architecture IF-ELSE of the CONSUMER module below:
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;
The error is shown in the images below:
1) Error with the producer-consumer state machine on the outputs
:
2) Simulation working with the PRODUCER using state machine architecture and consumer module using IF-ELSE architecture:
3) BDF file conecting the two modules:
If the architecture IF-ELSE of the PRODUCER module is necessary to solve this, It's below:
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;
I believe the error is on the state machine of consumer, after doing this state machine the simulation doesn't works anymore.
*****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.




stateandnext_state(both state machines) ando_DOUT(consumidor). As long as these warnings persist, the behavior of the synthesized netlist may differ from the VHDL description. You will have to fix the warnings first before worrying about the simulation result. Do you really want to save the currentstatein a latch? - Martin Zabelp_state_regprocess with pastebin.com/aarkTqxJ . Now two more inputsi_clockandi_resetin both components are required, and this inputs must be connected to the sameCLOCKandRESETsignal on the top-level. In the VWF file you will have to apply a clock waveform onCLOCKand a high pulse onRESETfor at least one clock cycle. - Martin Zabel