Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16621 Discussions

"Error: Cannot hold value outside clock edge" ?

Altera_Forum
Honored Contributor II
3,723 Views

Hello,  

 

I am trying to compile a VHDL code written by another person. I am getting this error for a number of signals.  

 

 

--- Quote Start ---  

 

Error (10818): Can't infer register for "S_PLLValid" at DeviceControl.vhd(67) because it does not hold its value outside the clock edge  

 

--- Quote End ---  

 

 

 

The qu(at)rtus Help file apparently does not provide any details on this error.  

 

 

--- Quote Start ---  

Fix the problem identified by the message text. A future version of the qu(at)rtus II software will provide more extensive Help for this error message.  

--- Quote End ---  

 

 

 

Can anyone help what the reason is and how can the error be corrected?
0 Kudos
12 Replies
Altera_Forum
Honored Contributor II
1,656 Views

Maybe the VHDL wasn't written with the standard coding style for register inference. See http://www.alteraforum.com/forum/showthread.php?t=1025 for coding-style information.

0 Kudos
Altera_Forum
Honored Contributor II
1,656 Views

You should check all assignments to the signals marked in the error message. You'll usually find constructs that aren't synthesizable VHDL code, e. g. an asynchronus assignment acting in parallel to a clock synchronous assignment within the same process.

0 Kudos
Altera_Forum
Honored Contributor II
1,656 Views

 

--- Quote Start ---  

an asynchronus assignment acting in parallel to a clock synchronous assignment within the same process 

--- Quote End ---  

 

 

I think this IS the problem.. Here is the relevant part of the code  

 

process(Reset,Clock,RS232InInt,PLLValid ) . . . . . . elsif(PLLValid'Event and PLLValid='1') then I_PLLOutput<=CONV_INTEGER(PLL); S_PLLValid<='1'; elsif(S_PLLValid='1') then S_PLLValid<='0'; 

 

I tried to put the signals menioned in the error in the sensitivity list but that did not work. How do I change the code ?  

 

Thanks !
0 Kudos
Altera_Forum
Honored Contributor II
1,656 Views

try: 

 

if(Clock'Event and Clock='1') then 

if(PLLValid='1')then 

I_PLLOutput<=CONV_INTEGER(PLL); 

S_PLLValid<='1'; 

elsif(S_PLLValid='1') then 

S_PLLValid<= not S_PLLValid;
0 Kudos
Altera_Forum
Honored Contributor II
1,656 Views

Also, the present code was synthesized on a Xilinx Spartan II FPGA. I am trying it on a Altera Cyclone device which gives error. So its not a VHDL language error but a choice of compiler and the corresponding language construct ?

0 Kudos
Altera_Forum
Honored Contributor II
1,656 Views

 

--- Quote Start ---  

So its not a VHDL language error... 

--- Quote End ---  

 

 

You could have a language error even in code that can be synthesized by some tools. Synthesis tools vary in how much latitude they give for certain things that technically are not legal according to the language standard. 

 

 

--- Quote Start ---  

...but a choice of compiler and the corresponding language construct ? 

--- Quote End ---  

 

 

Code could be legal according to the standard but still not written in a good way for synthesis purposes. Following the recommended coding styles (most being applicable to all synthesis tools and some potentially being specific to a tool) avoids this situation.
0 Kudos
Altera_Forum
Honored Contributor II
1,656 Views

 

--- Quote Start ---  

I tried to put the signals menioned in the error in the sensitivity list but that did not work. 

--- Quote End ---  

 

 

 

The Quartus handbook chapter I referred you to through the other thread has several register examples. They all have only clock and asynchronous inputs like reset in the sensitivity list. 

 

The sensitivity list in the code you showed has something called "Clock" and also PLLValid, which is used in "PLLValid'Event and PLLValid='1'". PLLValid appears to be used as a clock. You should have only one clock in a process. This appears to be the problem markman was trying to solve with the suggested code change.
0 Kudos
Altera_Forum
Honored Contributor II
1,656 Views

Thanks for the replies.  

 

Another error is when I compile  

elsif (S_ReceiveParametersFromRS232='1' and RS232InInt'Event and RS232InInt='0' ) then 

 

I get the errors :  

 

 

--- Quote Start ---  

Error (10397): VHDL Event Expression error at ddfsControl.vhd(78): can't form clock edge from S'EVENT by combining it with an expression that depends on a signal besides S 

 

Error (10658): VHDL Operator error at ddfsControl.vhd(78): failed to evaluate call to operator ""and"" 

--- Quote End ---  

 

 

where apparently Quartus does not allow three signals 'and' together.  

 

I will go through the coding style guidelines chapter. However, the real challenge lies in re-writing the code.
0 Kudos
Altera_Forum
Honored Contributor II
1,656 Views

I again wonder if you have more than one clock in the process. Your elsif line is checking for the falling edge of RS232InInt, making that signal be a clock, but your first error message is about trying to use "S" as a clock. 

 

The register examples in the coding guidelines have nothing else ANDed in the "if" that does the clock edge detection. 

 

Another place for code examples is in the Quartus text editor at "Edit --> Insert Template". There are full designs containing registers, and there are multiple register examples in the "Insert Template" dialog box at "VHDL --> Logic --> Registers".
0 Kudos
Altera_Forum
Honored Contributor II
1,656 Views

Basically, the original author of these code had no concept of synchronous logic, to my opinion. There are edge sensitive expressions for various signals, mixed with level sensitive ones. We see now, that some constructs are not accepted by quartus, cause they are incompatible with the used synthesis rules. They may be rewritten easily, but that's probably only the tip of the iceberg. There's a high likelihood that you get occasional violation of timing requirements, resulting in unexpected logical behaviour. So, when rewriting the code, you should give it a more synchronous behaviour, as far as possible. 

 

In the example 

elsif (S_ReceiveParametersFromRS232='1' and RS232InInt'Event and RS232InInt='0' ) then 

a possible solution can't be given without knowing the other conditional expressions combined with the shown part. It may be sufficient to move the S_ReceiveParametersFromRS232='1' down by one level. A synchronous solution would se a clock'event as outermost level rather than RS232InInt'Event, as markman suggested in a different case. A synchronous edge detection instead of RS232InInt'Event may be necessary then. It looks more complex a first sight, but gives clearly defined behaviour.
0 Kudos
Altera_Forum
Honored Contributor II
1,656 Views

Just to summarize some basic facts that were essentially discussed by other posters: 

 

The initial code doesn't describe a valid register. You can't have an else or elsif condition that follows a rising_edge(clk) or (clk'event and clk = '1') if you want to synthesize the code. It basically says, "if there wasn't a clock edge..."  

 

Your second error occurs because AND is left associative in VHDL, so you wrote (A = '1' and B'EVENT) and B = '1'. The B'event must be combined with a level test involving only B to form a clock edge. You should use rising_edge(clk) anyway. QIS is smart enough to synthesize (rising_edge(clk) and enable = '1') as a clock edge with an enable condition. You don't necessarily need to use a nested if statement.  

 

Josh
0 Kudos
Altera_Forum
Honored Contributor II
1,656 Views

 

--- Quote Start ---  

QIS is smart enough to... 

--- Quote End ---  

 

 

 

For those who don't know the acronym, "QIS" is "Quartus II integrated synthesis".
0 Kudos
Reply