Maker Pro
Maker Pro

VHDL Question: 'because it does not hold its value outside the clockedge'

M

Matt

Hello,

I am toying around with some GLUE logic to interface a 1655 to an
ISA bus. I have added my code below, however, when I try to synthesis
the code I recieve the following error:

"IRQ[0]" at isagluesimp,vhd (55) because is does not hold its value
outside the clock edge

I recieve that for all the IRQ lines in the IRQ vector. This error
goes away when I comment out the:

ELSIF (BCLK'EVENT AND BCLK='1' AND AEN='0' AND SA=address1 AND FLAG=
'0') THEN

line. ( I surrounded it in stars so it is more readable.




LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;

------------------------------------
ENTITY gluesimp IS

PORT( SA: IN STD_LOGIC_VECTOR (19 downto
0); --system address lines
D: INOUT STD_LOGIC_VECTOR (7 downto 0); --data bus
IRQ: OUT STD_LOGIC_VECTOR (10 downto 0); --IRQ
vector. Only one pin is used depending on the IRQ selected

IO16: OUT STD_LOGIC; --when
addressed, IO16# is asserted
RSET: IN STD_LOGIC; --when
asserted, system has reset, all values return to initial state
IOR: IN STD_LOGIC; --when
asserted, the system is doing an IO Read
IOW: IN STD_LOGIC; --when
asserted, the system is doing an IO Write
BCLK: IN STD_LOGIC; --bus clock
from CPU board (8.33MHz) used as clk signal
AEN: IN STD_LOGIC; --when
asserted, address is invalid (DMA read in progress)

----------UART SIGNALS--------------------------------------

ADD: OUT STD_LOGIC_VECTOR (2 downto 0); --A2, A1, A0
used to select internal register of 1655
CHIPSEL: OUT STD_LOGIC; --CSA, CSB, CSC,
CSD chipselect for 4 different channels (ACTIVE LOW)
DATA: INOUT STD_LOGIC_VECTOR (7 downto 0); --Data register
for both input and output to/from card
ISR: IN STD_LOGIC; --Interrupts
from the 4 channels. These will be anded together
RD: OUT STD_LOGIC; --Read strobe
WR: OUT STD_LOGIC; --Write strobe
RESET: OUT STD_LOGIC); --Reset
--INTN: OUT STD_LOGIC; --Configurable
depending on the type of interrupts used (MAY NOT BE USED)
--TXRDY: IN STD_LOGIC; --If TX FIFO
buffer is full, this will be set (ACTIVE LOW, MAY NOT BE USED)
--RXRDY: IN STD_LOGIC); --If RX FIFO
buffer is full, this will be set (ACTIVE LOW, MAY NOT BE USED)

END gluesimp;
------------------------------------

ARCHITECTURE behavior OF gluesimp IS

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 TRUEADDRESS: STD_LOGIC_VECTOR (11 downto 0); --contains
the usable address
SIGNAL TRUEDATA: STD_LOGIC_VECTOR (7 downto 0); --contains
the usable data
SIGNAL TEMP: STD_LOGIC_VECTOR (2 downto 0); --address
sent to the UART



BEGIN




PROCESS (BCLK, RSET, ISR)
BEGIN
FLAG <= ISR;

IF (RSET='1') THEN --RESET LOGIC

ADD <= "000";
CHIPSEL <= '0';
RESET <= '1';
RD <= '1';
WR <= '1';
IO16 <= 'Z';
D <= "ZZZZZZZZ";
IRQ <= "ZZZZZZZZZZZ";

------------------------------------------------------------------------------------------------------
**********************************************************************************************************
ELSIF (BCLK'EVENT AND BCLK='1' AND AEN='0' AND SA=address1 AND
FLAG= '0') THEN --I/O request from system
***********************************************************************************************************

IO16 <= '0'; --inform the system that this
is an 8-bit board
TEMP <= SA(2 downto 0); --takes the base address away
for easier use
TRUEDATA <= DATA;
CHIPSEL <= '1'; --selects a
port

IF (IOR = '1') THEN --It is a read

RD <= '1'; --tells UART that it is a read
command
ADD<= TEMP; --sends register address to UART
D <= TRUEDATA; --data from the UART is
placed on the ISA data bus

ELSIF (IOW = '1') THEN

WR <= '1'; --tells UART that it is a write
command
ADD <= TEMP; --sends register address to UART
DATA<= D; --data from the ISA BUS is sent
to the UART

END IF;



D <= "ZZZZZZZZ"; --silence on the bus
IO16 <= 'Z';
--------------------------------------------------------------------------------------------------------
ELSIF (FLAG = '1') THEN

IRQ <= interrupt;


IO16 <= '0'; --inform the system that this is
an 8-bit board
TEMP <= SA(2 downto 0); --takes the base address away
for easier use
CHIPSEL <= '1'; --selects a
port

IF (IOR = '1') THEN --It is a read

RD <= '1'; --tells UART that it is a read
command
ADD<= TEMP; --sends register address to UART
D <= DATA; --data from the UART is placed
on the ISA data bus

ELSIF (IOW = '1') THEN

WR <= '1'; --tells UART that it is a write
command
ADD <= TEMP; --sends register address to UART
DATA<= D; --data from the ISA BUS is sent
to the UART

END IF;



IRQ <= "ZZZZZZZZZZZ";
D <= "ZZZZZZZZ"; --silence on the bus
IO16 <= 'Z';
END IF;


END PROCESS;

END behavior;








I thought this error occured if I tried to have another IF statment
using the NOT of a condition used in a previous NOT, but all my other
IF statements do not use the conditions of the line of code I
highlighted.

Any help would be great.
 
A

Allan Herriman

Hello,

I am toying around with some GLUE logic to interface a 1655 to an
ISA bus. I have added my code below, however, when I try to synthesis
the code I recieve the following error:

"IRQ[0]" at isagluesimp,vhd (55) because is does not hold its value
outside the clock edge

I recieve that for all the IRQ lines in the IRQ vector. This error
goes away when I comment out the:

ELSIF (BCLK'EVENT AND BCLK='1' AND AEN='0' AND SA=address1 AND FLAG=
'0') THEN

line. ( I surrounded it in stars so it is more readable.




LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;

------------------------------------
ENTITY gluesimp IS

PORT( SA: IN STD_LOGIC_VECTOR (19 downto
0); --system address lines
D: INOUT STD_LOGIC_VECTOR (7 downto 0); --data bus
IRQ: OUT STD_LOGIC_VECTOR (10 downto 0); --IRQ
vector. Only one pin is used depending on the IRQ selected

IO16: OUT STD_LOGIC; --when
addressed, IO16# is asserted
RSET: IN STD_LOGIC; --when
asserted, system has reset, all values return to initial state
IOR: IN STD_LOGIC; --when
asserted, the system is doing an IO Read
IOW: IN STD_LOGIC; --when
asserted, the system is doing an IO Write
BCLK: IN STD_LOGIC; --bus clock
from CPU board (8.33MHz) used as clk signal
AEN: IN STD_LOGIC; --when
asserted, address is invalid (DMA read in progress)

----------UART SIGNALS--------------------------------------

ADD: OUT STD_LOGIC_VECTOR (2 downto 0); --A2, A1, A0
used to select internal register of 1655
CHIPSEL: OUT STD_LOGIC; --CSA, CSB, CSC,
CSD chipselect for 4 different channels (ACTIVE LOW)
DATA: INOUT STD_LOGIC_VECTOR (7 downto 0); --Data register
for both input and output to/from card
ISR: IN STD_LOGIC; --Interrupts
from the 4 channels. These will be anded together
RD: OUT STD_LOGIC; --Read strobe
WR: OUT STD_LOGIC; --Write strobe
RESET: OUT STD_LOGIC); --Reset
--INTN: OUT STD_LOGIC; --Configurable
depending on the type of interrupts used (MAY NOT BE USED)
--TXRDY: IN STD_LOGIC; --If TX FIFO
buffer is full, this will be set (ACTIVE LOW, MAY NOT BE USED)
--RXRDY: IN STD_LOGIC); --If RX FIFO
buffer is full, this will be set (ACTIVE LOW, MAY NOT BE USED)

END gluesimp;
------------------------------------

ARCHITECTURE behavior OF gluesimp IS

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 TRUEADDRESS: STD_LOGIC_VECTOR (11 downto 0); --contains
the usable address
SIGNAL TRUEDATA: STD_LOGIC_VECTOR (7 downto 0); --contains
the usable data
SIGNAL TEMP: STD_LOGIC_VECTOR (2 downto 0); --address
sent to the UART



BEGIN




PROCESS (BCLK, RSET, ISR)
BEGIN
FLAG <= ISR;

IF (RSET='1') THEN --RESET LOGIC

ADD <= "000";
CHIPSEL <= '0';
RESET <= '1';
RD <= '1';
WR <= '1';
IO16 <= 'Z';
D <= "ZZZZZZZZ";
IRQ <= "ZZZZZZZZZZZ";

------------------------------------------------------------------------------------------------------
**********************************************************************************************************
ELSIF (BCLK'EVENT AND BCLK='1' AND AEN='0' AND SA=address1 AND
FLAG= '0') THEN --I/O request from system
***********************************************************************************************************

IO16 <= '0'; --inform the system that this
is an 8-bit board
TEMP <= SA(2 downto 0); --takes the base address away
for easier use
TRUEDATA <= DATA;
CHIPSEL <= '1'; --selects a
port

IF (IOR = '1') THEN --It is a read

RD <= '1'; --tells UART that it is a read
command
ADD<= TEMP; --sends register address to UART
D <= TRUEDATA; --data from the UART is
placed on the ISA data bus

ELSIF (IOW = '1') THEN

WR <= '1'; --tells UART that it is a write
command
ADD <= TEMP; --sends register address to UART
DATA<= D; --data from the ISA BUS is sent
to the UART

END IF;



D <= "ZZZZZZZZ"; --silence on the bus
IO16 <= 'Z';
--------------------------------------------------------------------------------------------------------
ELSIF (FLAG = '1') THEN

IRQ <= interrupt;


IO16 <= '0'; --inform the system that this is
an 8-bit board
TEMP <= SA(2 downto 0); --takes the base address away
for easier use
CHIPSEL <= '1'; --selects a
port

IF (IOR = '1') THEN --It is a read

RD <= '1'; --tells UART that it is a read
command
ADD<= TEMP; --sends register address to UART
D <= DATA; --data from the UART is placed
on the ISA data bus

ELSIF (IOW = '1') THEN

WR <= '1'; --tells UART that it is a write
command
ADD <= TEMP; --sends register address to UART
DATA<= D; --data from the ISA BUS is sent
to the UART

END IF;



IRQ <= "ZZZZZZZZZZZ";
D <= "ZZZZZZZZ"; --silence on the bus
IO16 <= 'Z';
END IF;


END PROCESS;

END behavior;








I thought this error occured if I tried to have another IF statment
using the NOT of a condition used in a previous NOT, but all my other
IF statements do not use the conditions of the line of code I
highlighted.

Any help would be great.


Some comments:

You really should follow the synthesisable code templates that the
synthesiser vendor provided in the documentation.



2. This is the sensitivity list:

PROCESS (BCLK, RSET, ISR)

The flip flop template has a sensitivity list which contains the
clock, the async reset (or set) input and nothing else. Remove ISR
from the sensitivity list of this process, and make the assignment

FLAG <= ISR;

on a line of its own outside the process.


3. Your flip flop model seems confused. Here's my cut-down version
of your code:


PROCESS (BCLK, RSET)
BEGIN
IF (RSET='1') THEN
IRQ <= "ZZZZZZZZZZZ";
ELSIF (BCLK'EVENT AND BCLK='1' AND AEN='0' AND SA=address1 AND
FLAG= '0') THEN
-- Make no assignment to IRQ here
ELSIF (FLAG = '1') THEN
IRQ <= interrupt;
IRQ <= "ZZZZZZZZZZZ";
END IF;
END PROCESS;


Perhaps you meant to have the line
IRQ <= interrupt;
where I put the comment
-- Make no assignment to IRQ here
?



4. Are you aware that the part after
ELSIF (FLAG = '1') THEN
will behave differently in synthesis and simulation?
The simulator will execute it on the falling edge of the clock if FLAG
is '1', and the synthesiser will produce an error message. Did you
really mean to code for a falling edge flip flop? (It does this
because BCLK is in the sensitivity list, and the only way to get to
that code is if there is an event (i.e. an edge) on BCLK that isn't a
rising edge, and FLAG is '1'.)

I'm guessing (without trying to understand your application at all)
that it should look something like this:


PROCESS (BCLK, RSET)
BEGIN

IF RSET='1' THEN
IRQ <= "ZZZZZZZZZZZ";
ELSIF rising_edge(BCLK) THEN
if AEN='0' AND SA=address1 AND FLAG= '0' THEN
IRQ <= interrupt;
ELSIF FLAG = '1' THEN
IRQ <= "ZZZZZZZZZZZ";
else
-- make no change to IRQ
END IF;
END IF;
END PROCESS;

At least it will be synthesisable.


5. Finally, this is off-topic for s.e.d. Please try comp.lang.vhdl
next time.

Regards,
Allan
 
F

Frank Buss

Matt said:
TEMP <= SA(2 downto 0); --takes the base address away
for easier use
CHIPSEL <= '1'; --selects a
port

IF (IOR = '1') THEN --It is a read

RD <= '1'; --tells UART that it is a read
command
ADD<= TEMP; --sends register address to UART

Allan has already given some useful hints. One more: Looks like you are
assuming that you can use the value of TEMP within the same clock cylce.
This is wrong. ADD becomes the TEMP value from the previous clock cycle.
Use variables, if you just want placeholders for signal slides.

Another good newsgroup for posting such questions is comp.arch.fpga.
 
M

Matt

Allan has already given some useful hints. One more: Looks like you are
assuming that you can use the value of TEMP within the same clock cylce.
This is wrong. ADD becomes the TEMP value from the previous clock cycle.
Use variables, if you just want placeholders for signal slides.

Another good newsgroup for posting such questions is comp.arch.fpga.

Allan and Frank,

Thank you for the responses and sorry about posting in the wrong
group. I had to tweak my sensitivity list and many of the errors
disapeared. I contiuned to play with my loops and finally got the
whole thing working.

Thank you for your comments,
Matt
 
Top