INOUT Vectors data is incorrect

M

Matt

Hello,

I wrote this peice of code (a single process state machine) and I
have two INOUT Standard Vectors. When an IOR pin is high, one data bus
should write to the other and vice versa. When I try to simulate this
code in Quartus II, the data bus that should have info written to it
is left as a high impedence. I attempted to cut out any unnesicary
code to allow easier reading. I have surrounded the places I feel are
incorrect in *'s. Any help would be great because this is driving me a
little crazy.

Thank you













ENTITY singleprocess IS

PORT( SA: IN STD_LOGIC_VECTOR (19 downto 0); --system address
lines

D: INOUT STD_LOGIC_VECTOR (7 downto 0); --data bus
DATA: INOUT STD_LOGIC_VECTOR (7 downto 0));

END singleprocess;
----------------------------------------------------------
ARCHITECTURE state_machine OF singleprocess IS

TYPE state IS (state1, state2, state3, SILENT);
SIGNAL pr_state, nx_state: state;

CONSTANT address1: STD_LOGIC_VECTOR (19 downto 0) :=
X"002E8"; --declare base address vector for channel
CONSTANT interrupt: STD_LOGIC_VECTOR (10 downto 0) :=
"00000000001"; --declare interupt vector
SIGNAL FLAG: STD_LOGIC; --used to
inform the internal system an interrupt has been thrown
SIGNAL BASEADDRESS: STD_LOGIC_VECTOR (19 downto 0); --contains
the usable address



BEGIN


BASEADDRESS <= SA AND "11111111111111111000"; --base address

----------------STATE MACHINE----------------------------
PROCESS (RSET, BCLK)

VARIABLE RorW: STD_LOGIC;

BEGIN

IF (RSET='1') THEN

pr_state<=SILENT;


ELSIF (BCLK'EVENT AND BCLK='1' AND AEN ='0' AND
BASEADDRESS=address1) THEN-- AND AEN ='0') THEN
pr_state<=nx_state;



END IF;

CASE pr_state IS

WHEN state1 =>

IF(IOR='0') THEN
*********************************************
D<=DATA;
*********************************************
ELSIF(IOW='0') THEN
*********************************************
DATA<=D;
*********************************************
END IF;

nx_state<= state2;

WHEN state2 =>


IF(IOR='0') THEN
*********************************************
D<=DATA;
*********************************************
RorW:='0'; --IORC and IOWC unset during the
middle of the third clock cycle. This is used to hold vaule.

ELSIF(IOW='0') THEN
*********************************************
DATA<=D;
*********************************************
RorW:='1'; --IORC and IOWC unset during the
middle of the third clock cycle. This is used to hold vaule.

END IF;

nx_state<= state3;

WHEN state3 =>



IF(RorW='0') THEN
*********************************************
D<=DATA;
*********************************************
ELSIF(RorW='1') THEN
*********************************************
DATA<=D;
*********************************************
END IF;

nx_state<= SILENT;

WHEN SILENT =>


D<= "ZZZZZZZZ";
DATA<= "ZZZZZZZZ";



nx_state<= state1;


END CASE;
END PROCESS;
END state_machine;
 
M

Matt

Hello,

   I wrote this peice of code (a single process state machine) and I
have two INOUT Standard Vectors. When an IOR pin is high, one data bus
should write to the other and vice versa. When I try to simulate this
code in Quartus II, the data bus that should have info written to it
is left as a high impedence. I attempted to cut out any unnesicary
code to allow easier reading. I have surrounded the places I feel are
incorrect in *'s. Any help would be great because this is driving me a
little crazy.

Thank you

ENTITY singleprocess IS

   PORT(  SA: IN STD_LOGIC_VECTOR (19 downto 0);   --system address
lines

              D:  INOUT STD_LOGIC_VECTOR (7 downto 0); --data bus
              DATA: INOUT STD_LOGIC_VECTOR (7 downto 0));

END singleprocess;
----------------------------------------------------------
ARCHITECTURE state_machine OF singleprocess IS

    TYPE state IS (state1, state2, state3, SILENT);
    SIGNAL pr_state, nx_state: state;

    CONSTANT address1:  STD_LOGIC_VECTOR (19 downto 0) :=
X"002E8";      --declare base address vector for channel
    CONSTANT interrupt: STD_LOGIC_VECTOR (10 downto 0) :=
"00000000001"; --declare interupt vector
    SIGNAL FLAG:  STD_LOGIC;                              --used to
inform the internal system an interrupt has been thrown
    SIGNAL BASEADDRESS: STD_LOGIC_VECTOR (19 downto 0);  --contains
the usable address

BEGIN

BASEADDRESS <= SA AND "11111111111111111000"; --base address

----------------STATE MACHINE----------------------------
PROCESS (RSET, BCLK)

    VARIABLE RorW: STD_LOGIC;

BEGIN

   IF (RSET='1') THEN

       pr_state<=SILENT;

   ELSIF (BCLK'EVENT AND BCLK='1' AND AEN ='0' AND
BASEADDRESS=address1) THEN-- AND AEN ='0') THEN
     pr_state<=nx_state;

   END IF;

 CASE pr_state IS

 WHEN state1 =>

         IF(IOR='0') THEN
*********************************************
            D<=DATA;
*********************************************
         ELSIF(IOW='0') THEN
*********************************************
            DATA<=D;
 *********************************************
         END IF;

  nx_state<= state2;

  WHEN state2 =>

         IF(IOR='0') THEN
*********************************************
            D<=DATA;
*********************************************
            RorW:='0';               --IORC and IOWC unset during the
middle of the third clock cycle. This is used to hold vaule.

         ELSIF(IOW='0') THEN
*********************************************
            DATA<=D;
*********************************************
            RorW:='1';               --IORC and IOWC unset during the
middle of the third clock cycle. This is used to hold vaule.

            END IF;

  nx_state<= state3;

  WHEN state3 =>

         IF(RorW='0') THEN
*********************************************
            D<=DATA;
 *********************************************
         ELSIF(RorW='1') THEN
*********************************************
            DATA<=D;
  *********************************************
         END IF;

   nx_state<= SILENT;

   WHEN SILENT =>

         D<= "ZZZZZZZZ";
         DATA<= "ZZZZZZZZ";

   nx_state<= state1;

       END CASE;
    END PROCESS;
END state_machine;

I also forgot to add that I get the following error from Quartus if in
simulation when I set a particular bit ( in this case the lsb) high.

Warning: Found logic contention at time 693.0 ns on bus node "|
singleprocess|D[0]~result"
Info: Node "D[0]~output" has logic level of 0
Info: Node "D[0]" has logic level of 1
 
D

Dwayne Dilbeck

You have a problem in your state logic for the D and Data
In the tables below I use a symbol ND, this symbol means "not defined".
Your code is infering a latch/FF. Your if statment does not return the D
and Data to the correct Z states that you wish to have. Basically you left
alot of input combinations without a default condition.

In addition, when you convert the signals IOW and IOR to RoW, You
completely take away half of the possible conditions and again infer a
latch/FF.

state1:
IOR 0 1 0 1
IOW 0 0 1 1
D Data Z Data Z
Data Z D Z Z

state2:
IOR 0 1 0 1
IOW 0 0 1 1
D Data ND Data ND
Data ND D ND ND

state3:
RorW 0 1
D Data ND
Data ND D
 
D

Dwayne Dilbeck

Based on my assumptions on how you want the circuit to operate, I would code
it like so: (Note: There is likely to be type-Os and I have been doing most
of my coding in System Verilog lately so my VHDL is a little rusty.)



ENTITY singleprocess IS

PORT( SA: IN STD_LOGIC_VECTOR (19 downto 0); --system address
lines

D: INOUT STD_LOGIC_VECTOR (7 downto 0); --data bus
DATA: INOUT STD_LOGIC_VECTOR (7 downto 0));

END singleprocess;
----------------------------------------------------------
ARCHITECTURE state_machine OF singleprocess IS

TYPE state IS (state1, state2, state3, SILENT);
SIGNAL pr_state, nx_state: state;

CONSTANT address1: STD_LOGIC_VECTOR (19 downto 0) :=
X"002E8"; --declare base address vector for channel
CONSTANT interrupt: STD_LOGIC_VECTOR (10 downto 0) :=
"00000000001"; --declare interupt vector
SIGNAL FLAG: STD_LOGIC; --used to inform the internal system an interrupt
has been thrown
SIGNAL BASEADDRESS: STD_LOGIC_VECTOR (19 downto 0);
BEGIN

signal en1,en2:bit:='0';

BASEADDRESS <= SA AND "11111111111111111000"; --base address
Data <= D when (En1 = '1') else (others=>'Z');
D <=Data when (En2= '1') else (others=>'Z');

----------------STATE MACHINE----------------------------
PROCESS (RSET, BCLK)

VARIABLE RorW: STD_LOGIC;

BEGIN

IF (RSET='1') THEN

pr_state<=SILENT;

ELSIF (BCLK'EVENT AND BCLK='1' AND AEN ='0' AND
BASEADDRESS=address1) THEN-- AND AEN ='0') THEN
pr_state<=nx_state;

END IF;

CASE pr_state IS

WHEN state1 =>

IF(IOR='0') THEN
En2<='1';
En1<='0';
*********************************************
ELSIF(IOW='0') THEN
*********************************************
En1<='1';
En2<='0';
Else
En1<='0';
En2<='0';
*********************************************
END IF;

nx_state<= state2;

WHEN state2 =>

nx_state<= state3;

WHEN state3 =>

nx_state<= SILENT;

WHEN SILENT =>

D<= "ZZZZZZZZ";
DATA<= "ZZZZZZZZ";
En1<='0';
En2<='0';
nx_state<= state1;

END CASE;
END PROCESS;
END state_machine;

Hello,

I wrote this peice of code (a single process state machine) and I
have two INOUT Standard Vectors. When an IOR pin is high, one data bus
should write to the other and vice versa. When I try to simulate this
code in Quartus II, the data bus that should have info written to it
is left as a high impedence. I attempted to cut out any unnesicary
code to allow easier reading. I have surrounded the places I feel are
incorrect in *'s. Any help would be great because this is driving me a
little crazy.

Thank you

ENTITY singleprocess IS

PORT( SA: IN STD_LOGIC_VECTOR (19 downto 0); --system address
lines

D: INOUT STD_LOGIC_VECTOR (7 downto 0); --data bus
DATA: INOUT STD_LOGIC_VECTOR (7 downto 0));

END singleprocess;
----------------------------------------------------------
ARCHITECTURE state_machine OF singleprocess IS

TYPE state IS (state1, state2, state3, SILENT);
SIGNAL pr_state, nx_state: state;

CONSTANT address1: STD_LOGIC_VECTOR (19 downto 0) :=
X"002E8"; --declare base address vector for channel
CONSTANT interrupt: STD_LOGIC_VECTOR (10 downto 0) :=
"00000000001"; --declare interupt vector
SIGNAL FLAG: STD_LOGIC; --used to
inform the internal system an interrupt has been thrown
SIGNAL BASEADDRESS: STD_LOGIC_VECTOR (19 downto 0); --contains
the usable address

BEGIN

BASEADDRESS <= SA AND "11111111111111111000"; --base address

----------------STATE MACHINE----------------------------
PROCESS (RSET, BCLK)

VARIABLE RorW: STD_LOGIC;

BEGIN

IF (RSET='1') THEN

pr_state<=SILENT;

ELSIF (BCLK'EVENT AND BCLK='1' AND AEN ='0' AND
BASEADDRESS=address1) THEN-- AND AEN ='0') THEN
pr_state<=nx_state;

END IF;

CASE pr_state IS

WHEN state1 =>

IF(IOR='0') THEN
*********************************************
D<=DATA;
*********************************************
ELSIF(IOW='0') THEN
*********************************************
DATA<=D;
*********************************************
END IF;

nx_state<= state2;

WHEN state2 =>

IF(IOR='0') THEN
*********************************************
D<=DATA;
*********************************************
RorW:='0'; --IORC and IOWC unset during the
middle of the third clock cycle. This is used to hold vaule.

ELSIF(IOW='0') THEN
*********************************************
DATA<=D;
*********************************************
RorW:='1'; --IORC and IOWC unset during the
middle of the third clock cycle. This is used to hold vaule.

END IF;

nx_state<= state3;

WHEN state3 =>

IF(RorW='0') THEN
*********************************************
D<=DATA;
*********************************************
ELSIF(RorW='1') THEN
*********************************************
DATA<=D;
*********************************************
END IF;

nx_state<= SILENT;

WHEN SILENT =>

D<= "ZZZZZZZZ";
DATA<= "ZZZZZZZZ";

nx_state<= state1;

END CASE;
END PROCESS;
END state_machine;

I also forgot to add that I get the following error from Quartus if in
simulation when I set a particular bit ( in this case the lsb) high.

Warning: Found logic contention at time 693.0 ns on bus node "|
singleprocess|D[0]~result"
Info: Node "D[0]~output" has logic level of 0
Info: Node "D[0]" has logic level of 1
 
D

Dwayne Dilbeck

Oops! forgot to delete

D<= "ZZZZZZZZ";
DATA<= "ZZZZZZZZ";

from state silent. But you should have been able to get the idea.

Dwayne Dilbeck said:
Based on my assumptions on how you want the circuit to operate, I would
code it like so: (Note: There is likely to be type-Os and I have been
doing most of my coding in System Verilog lately so my VHDL is a little
rusty.)



ENTITY singleprocess IS

PORT( SA: IN STD_LOGIC_VECTOR (19 downto 0); --system address
lines

D: INOUT STD_LOGIC_VECTOR (7 downto 0); --data bus
DATA: INOUT STD_LOGIC_VECTOR (7 downto 0));

END singleprocess;
----------------------------------------------------------
ARCHITECTURE state_machine OF singleprocess IS

TYPE state IS (state1, state2, state3, SILENT);
SIGNAL pr_state, nx_state: state;

CONSTANT address1: STD_LOGIC_VECTOR (19 downto 0) :=
X"002E8"; --declare base address vector for channel
CONSTANT interrupt: STD_LOGIC_VECTOR (10 downto 0) :=
"00000000001"; --declare interupt vector
SIGNAL FLAG: STD_LOGIC; --used to inform the internal system an interrupt
has been thrown
SIGNAL BASEADDRESS: STD_LOGIC_VECTOR (19 downto 0);
BEGIN

signal en1,en2:bit:='0';

BASEADDRESS <= SA AND "11111111111111111000"; --base address
Data <= D when (En1 = '1') else (others=>'Z');
D <=Data when (En2= '1') else (others=>'Z');

----------------STATE MACHINE----------------------------
PROCESS (RSET, BCLK)

VARIABLE RorW: STD_LOGIC;

BEGIN

IF (RSET='1') THEN

pr_state<=SILENT;

ELSIF (BCLK'EVENT AND BCLK='1' AND AEN ='0' AND
BASEADDRESS=address1) THEN-- AND AEN ='0') THEN
pr_state<=nx_state;

END IF;

CASE pr_state IS

WHEN state1 =>

IF(IOR='0') THEN
En2<='1';
En1<='0';
*********************************************
ELSIF(IOW='0') THEN
*********************************************
En1<='1';
En2<='0';
Else
En1<='0';
En2<='0';
*********************************************
END IF;

nx_state<= state2;

WHEN state2 =>

nx_state<= state3;

WHEN state3 =>

nx_state<= SILENT;

WHEN SILENT =>

D<= "ZZZZZZZZ";
DATA<= "ZZZZZZZZ";
En1<='0';
En2<='0';
nx_state<= state1;

END CASE;
END PROCESS;
END state_machine;

Hello,

I wrote this peice of code (a single process state machine) and I
have two INOUT Standard Vectors. When an IOR pin is high, one data bus
should write to the other and vice versa. When I try to simulate this
code in Quartus II, the data bus that should have info written to it
is left as a high impedence. I attempted to cut out any unnesicary
code to allow easier reading. I have surrounded the places I feel are
incorrect in *'s. Any help would be great because this is driving me a
little crazy.

Thank you

ENTITY singleprocess IS

PORT( SA: IN STD_LOGIC_VECTOR (19 downto 0); --system address
lines

D: INOUT STD_LOGIC_VECTOR (7 downto 0); --data bus
DATA: INOUT STD_LOGIC_VECTOR (7 downto 0));

END singleprocess;
----------------------------------------------------------
ARCHITECTURE state_machine OF singleprocess IS

TYPE state IS (state1, state2, state3, SILENT);
SIGNAL pr_state, nx_state: state;

CONSTANT address1: STD_LOGIC_VECTOR (19 downto 0) :=
X"002E8"; --declare base address vector for channel
CONSTANT interrupt: STD_LOGIC_VECTOR (10 downto 0) :=
"00000000001"; --declare interupt vector
SIGNAL FLAG: STD_LOGIC; --used to
inform the internal system an interrupt has been thrown
SIGNAL BASEADDRESS: STD_LOGIC_VECTOR (19 downto 0); --contains
the usable address

BEGIN

BASEADDRESS <= SA AND "11111111111111111000"; --base address

----------------STATE MACHINE----------------------------
PROCESS (RSET, BCLK)

VARIABLE RorW: STD_LOGIC;

BEGIN

IF (RSET='1') THEN

pr_state<=SILENT;

ELSIF (BCLK'EVENT AND BCLK='1' AND AEN ='0' AND
BASEADDRESS=address1) THEN-- AND AEN ='0') THEN
pr_state<=nx_state;

END IF;

CASE pr_state IS

WHEN state1 =>

IF(IOR='0') THEN
*********************************************
D<=DATA;
*********************************************
ELSIF(IOW='0') THEN
*********************************************
DATA<=D;
*********************************************
END IF;

nx_state<= state2;

WHEN state2 =>

IF(IOR='0') THEN
*********************************************
D<=DATA;
*********************************************
RorW:='0'; --IORC and IOWC unset during the
middle of the third clock cycle. This is used to hold vaule.

ELSIF(IOW='0') THEN
*********************************************
DATA<=D;
*********************************************
RorW:='1'; --IORC and IOWC unset during the
middle of the third clock cycle. This is used to hold vaule.

END IF;

nx_state<= state3;

WHEN state3 =>

IF(RorW='0') THEN
*********************************************
D<=DATA;
*********************************************
ELSIF(RorW='1') THEN
*********************************************
DATA<=D;
*********************************************
END IF;

nx_state<= SILENT;

WHEN SILENT =>

D<= "ZZZZZZZZ";
DATA<= "ZZZZZZZZ";

nx_state<= state1;

END CASE;
END PROCESS;
END state_machine;

I also forgot to add that I get the following error from Quartus if in
simulation when I set a particular bit ( in this case the lsb) high.

Warning: Found logic contention at time 693.0 ns on bus node "|
singleprocess|D[0]~result"
Info: Node "D[0]~output" has logic level of 0
Info: Node "D[0]" has logic level of 1
 
D

Duane Clark

Matt said:
Hello,

I wrote this peice of code (a single process state machine) and I
have two INOUT Standard Vectors. When an IOR pin is high, one data bus
should write to the other and vice versa. When I try to simulate this
code in Quartus II, the data bus that should have info written to it
is left as a high impedence. I attempted to cut out any unnesicary
code to allow easier reading. I have surrounded the places I feel are
incorrect in *'s. Any help would be great because this is driving me a
little crazy.


ENTITY singleprocess IS

PORT( SA: IN STD_LOGIC_VECTOR (19 downto 0); --system address
lines

D: INOUT STD_LOGIC_VECTOR (7 downto 0); --data bus
DATA: INOUT STD_LOGIC_VECTOR (7 downto 0));
...

In general, you should code bidirectional pins something like this:

architecture ... is
signal D_O : STD_LOGIC_VECTOR (7 downto 0);
signal DATA_O : STD_LOGIC_VECTOR (7 downto 0);
begin

D <= D_O when IOR = '1' else "ZZZZZZZZ";
DATA <= DATA_O when IOR = '0' else "ZZZZZZZZ";
D_O <= DATA;
DATA_O <= D;

No need for that complicated state machine.
 
M

Matt

In general, you should code bidirectional pins something like this:

architecture ... is
   signal D_O    : STD_LOGIC_VECTOR (7 downto 0);
   signal DATA_O : STD_LOGIC_VECTOR (7 downto 0);
begin

  D <= D_O when IOR = '1' else "ZZZZZZZZ";
  DATA <= DATA_O when IOR = '0' else "ZZZZZZZZ";
  D_O <= DATA;
  DATA_O <= D;

No need for that complicated state machine.- Hide quoted text -

- Show quoted text -

There is a bit more going on in the different states that I have
omitted, so I still have to use the state machine :(.

Thank you all for your suggestions and corrections.
 
A

Andy

In general, you should code bidirectional pins something like this:

architecture ... is
signal D_O : STD_LOGIC_VECTOR (7 downto 0);
signal DATA_O : STD_LOGIC_VECTOR (7 downto 0);
begin

D <= D_O when IOR = '1' else "ZZZZZZZZ";
DATA <= DATA_O when IOR = '0' else "ZZZZZZZZ";
D_O <= DATA;
DATA_O <= D;

No need for that complicated state machine.

In general, I would argue the opposite. Rather than have a state
machine generate an enable that is then used in a separate concurrent
statement (or even a separate architecture) to create a tri-state
driver, just drive the data out as Z's from the state machine when
needed. Synthesis tools are plenty smart enough in this case to do
what you want, rather than you having to explicitly code tri-state
buffers. This is of course assuming that the state machine is driving
the data in the first place (deciding what data to drive when driven).
The synthesis tool is smart enough to infer the tri-state enable
signal and the tri-state buffers such that the circuit BEHAVIOR will
match that of the description.

In fact, when tri-state buffers first came out with optionally
registered enables, the recommended way to infer that registered
enable was to drive Z's from a clocked process.

Andy
 
D

Duane Clark

Matt said:
There is a bit more going on in the different states that I have
omitted, so I still have to use the state machine :(.

Well, you don't "have" to use the state machine for the tristating of
the outputs. If the signals and controls are a bit more complicated, I
personally would use the state machine to generate D_O/DATA_O and
D_EN/DATA_EN (where the _EN signals are tristate enables), and still use
concurrent statements for the actual tristating.

But I will admit that I tend to think of these kinds of things in terms
of hardware, not behaviorally.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top