statement is not synthesizable since it does not hold its value under NOT(clock-edge) condition - vhdl

statement is not synthesizable since it does not hold its value under NOT(clock-edge) condition
Try to reset =>0 signal u_txreq on u_txack edge and set =>1 it on CLK edge
process (CLK, u_reset_n, u_txack)
begin
if (u_reset_n='0')then
u_txreq<='0';
elsif rising_edge(CLK) then
u_txreq<='1';
elsif rising_edge(u_txack) then
u_txreq<='0';
end if;
end process;

For HDL code top be synthesizeable there must exist some hardware in the target library which implements the requested function.
At the moment there exists no hardware that at the same time supports:
1/ Reset a-synchronously on an active low signal. (if (u_reset_n='0'))
2/ Triggers on a rising edge (elsif rising_edge(CLK))
3/ Triggers on a second independent rising edge. (elsif rising_edge(u_txack)).
You have to re-write your code to use only ONE rising or falling clock edge.

Look at the my signals synchronization async u_txack with sync CLK:
if rising_edge(CLK) then
count<=count+B"00000001";
n1_txack <= u_txack;
if( n1_txack='0' AND u_txack='1')
then
u_txreq<='0';
count<=B"00000000";
end if;
if (count=B"00000010") then
u_txreq<='1';
end if;
end if;

Related

VHDL reset option in signal

Typically a clocked process can also have a reset trigger in sensitivity and can be used to initialize a value. However, it is my understanding that the following does the same.
signal mc_var: unsigned(40 downto 0) := (others =>'0'); -- value gets reset here.
my_counter: process (CLK)
IF (rising_edge(CLK)) THEN
mc_var <= mc_var + 1;
if mc_var = 10000000 then
mc_var <= others => '0');
end if;
END IF;
end process;
Does this function the same as using reset in the sensitivity?
No, initializing a value is not the same as providing a reset option.
A reset input allows to reset the circuit to a defined state after it has started running.
An initial value only sets the circuit to a defined state at the beginning, but then it can't be reset.
Plus: these initial values can be honored by logic synthesizers only on hardware targets that support power-on initializations (namely FPGAs). On ASIC-like targets they are frequently ignored.
This was originally posted by Renauld Pacalet as a comment to this answer.

Unable to determine signal value in VHDL

I am currently in the midst of an 12 hour debug session and I cannot, for the life of me, get passed this hump.
The way my code is setup, I have an 8 bit std_logic_vector mapped to 8 switches on the DE2-115 board. Each bit corrosponds to the logic level activated by the relative switch (0 or 1).
The goal is to have the board wait for any of the 8 switches to be activated before is starts the timer. This will be activated when the signal relative_time_enable is set to logic state of 1. Once the signal is set to 1 it will ultimately never be reset back to 0. This variable is initialized as shown:
signal relative_time_enable : STD_LOGIC := '0';
signal signal_in : STD_LOGIC_VECTOR(7 downto 0);
signal_in gets mapped to 'in' ports delclared in my entity, or rather, vice-versa. However it is said, signal_in corrosponds to the switches. Here is the code I have right now.
process(clk_1MHz_enable, signal_in)
begin
if(clk_1MHz_enable = '1') then
if(relative_time_enable = '0') and (signal_in /= "00000000")then
relative_time_enable <= '1';
end if;
end if;
end process;
I believe I have deduced the problem down to being that the if-statement is always coming up as true. Almost as though the signal_in is going through multiple states within the first cycles causing the value to immediately be set to 1, I couldn't find anything online that could point me to the right direction.
At this point, I have tried everything in order to determine what the values actually are including replacing "00000000" with "11111111", "UUUUUUUU", "ZZZZZZZZ", "XXXXXXXX" and all of them still get through.
I have also tried:
process(clk_1MHz_enable, signal_in)
begin
if(clk_1MHz_enable = '1') then
if(relative_time_enable = '0') and (signal_in /= "00000000")then
for i in 0 to 7 loop
if(signal_in(i) = '1') then
relative_time_enable <= '1';
end if;
end loop;
end if;
end if;
end process;
This method seems like it should 'double check' but somehow it keeps getting through and setting the value to 1 before any switches are activated. Also, I have signal_in displaying on the lCD and changes when I move switches and at startup, everything reads 00000000.
FYI: I have only been working with this FPGA and VHDL for 2 weeks so it's very possible that I missing something very fundamental. Also, I am not exactly 100% confident with my skills in ModelSIM and not sure how I would translate what I see into problems with code.
Any help would be greatly appreciated. If you need to see anymore of the code, just let me know I'll be happy to post whatever is needed. I just didn't put all of it up because there is a pretty lengthy state machine that controls the LCD which isn't relevant for this post.
Also, I should mention that the following code works as expected, but the problem with this code is that it resets relative_time_enable back to 0 which is a big no no. The only reason I am showing this is because it essentially does wait until a switch is active before starting the clock, but once I deactivate the switch, the clock stops running which is a problem.
process(clk_1MHz_enable, signal_in)
begin
if(clk_1MHz_enable = '1') then
if(relative_time_enable = '0') and (signal_in /= "00000000")then
relative_time_enable <= '1';
else
relative_time_enable <= '0';
end if;
end if;
end process;
Your test would work with a bit_vector because each bit would take either the '0' value or the '1' value. So, /= "00000000" would really mean: at least one bit is '1'. But as you are using an std_logic_vector, each bit can take 9 different values (std_logic is a 9-values enumerated type). So /= "00000000" does not mean that at least one bit is '1'. It can mean that one bit is set to 'U' or any other value different from '0'. At the beginning of a simulation signal_in is initialized with "UUUUUUUU" (U stands for Uninitialized). relative_time_enable is initialized with '0' because you declared it that way. So your test passes on the first rising edge of clk_1MHz_enable and relative_time_enable gets stuck at '1' almost immediately.
Assuming clk_1MHz_enable is a clock (strange name but why not), and you want an edge-triggered D-flip-flop, the following code solves this issue:
process(clk_1MHz_enable)
begin
if clk_1MHz_enable = '1' and clk_1MHz_enable'event then
for i in signal_in'range loop
if signal_in(i) = '1' then
relative_time_enable <= '1';
end if;
end loop;
end if;
end process;
And if you want a level-triggered latch instead of an edge-triggered D-flip-flop:
process(clk_1MHz_enable, signal_in)
begin
if clk_1MHz_enable = '1' then
for in in signal_in'range loop
if signal_in(i) = '1' then
relative_time_enable <= '1';
end if;
end loop;
end if;
end process;

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

I´m trying to verify four buttons. When one of them are pushed I need to check if the corresponding led are lit. So, I did the code, where a process checks which button has been pressed and compares the values with the value of the led (lit or not). The problem occurs when I want to increase the variable that controls the amount of hits (successes) of the player.
Remembering that "acertos" is a signal of the type std_logic_vector(3 downto 0)
process(pb0,pb1,pb2,pb3)
variable erro_int : STD_LOGIC;
begin
if (clk_game = '0') then
erro_int:='0';
if rising_edge(pb0) then
if pb0 /= led(0) then
erro_int:='1';
end if;
elsif rising_edge(pb1) then
if pb1 /= led(1) then
erro_int:='1';
end if;
elsif rising_edge(pb2) then
if pb2 /= led(2) then
erro_int:='1';
end if;
elsif rising_edge(pb3) then
if pb3 /= led(3) then
erro_int:='1';
end if;
else
acertos <= acertos+1;
end if;
end if;
end process;
See Error (10818): Can't infer register for “E” at clk200Hz.vhd(29) because it does not hold its value outside the clock edge which demonstrates the exact same Error case. Normally you'd also be encouraged to use the vendor as a resource for their error messages as well.
The error case here is expressing that the acertos assignment is not taking place inside a conditional assignment statement dependent on a signal event used as a clock.
However this isn't the end to potential problems you'll likely encounter with the process you've shown us from some design specification.
There's the question of whether signals pb0, pb1, pb2 and pb3 are de-bounce filtered. See Wentworth Institute of Technology Department of Electronics and Mechanical ELEC 236 Logic Circuits Switch Debounce Design, where the first scope trace shows a normally pulled high, momentary switch connecting to ground switch input. The issue is contact bounce. The web page talks about some solutions.
De-bounce would allow you to use your button inputs as clocks but there are other issues in your process.
For instance some vendors won't accept multiple clocks in the same process statement, your design specification may not be portable.
There isn't a recognized sequential event inferring storage element construct that allows multiple clocks for the same storage element (erro_int). Because there is no passage of simulation time expressed by successive if statements without inter-dependencies you might expect that perhaps only the last one get's expressed as hardware.
You could combine all the push buttons into a single signal:
button_press <= not (not pb0 and not pb1 and not pb2 and not bp3);
Where any button pressed can cause an edge event when transitioning from no buttons pressed.
If you de-bounce this say using a counter and testing for successive events you could use it as the sole clock.
Let's assume for the following it's de-bounced. Setting a default value in the process statement for erro_out would give you a process that looks something like:
process(button_press)
variable erro_int: std_logic;
begin
if (clk_game = '0') then
erro_int:='0';
if rising_edge(button_press) then
if pb0 /= led(0) or pb1 /= led(1) or pb1 /= led(2) or pb3 /=pb3 then
erro_int:= '1';
end if;
acertos <= acertos + 1;
end if;
end process;
(And I looked up the translation of acertos - hits, not necessarily valid hits, I take it this is a game.)
This still doesn't solve the issue that erro_int is a local variable. If it's used elsewhere it wants to be a declared as a signal. If you change the process to:
...
signal erro_int: std_logic; -- defined say as an architecture declarative item
...
process(button_press)
begin
if (clk_game = '0') then
erro_int <='0';
if rising_edge(button_press) then
if pb0 /= led(0) or pb1 /= led(1) or pb1 /= led(2) or pb3 /=pb3 then
erro_int <= '1';
end if;
acertos <= acertos + 1;
end if;
end process;
You can use it externally. The reason why this works is that a process only has a single driver for a signal and the last assignment at the current simulation time is the one that takes effect (there's only one assignment to the current simulation time).
And of course if you use a clock to de-bounce you could use button_press as an enable if it were gated to only last one clock.

VHDL - FSM Control

I'm a beginner and I need a little help . My "current_s" is changing whenever rising edge of the clock detected. But, I want it to change only once when "Dot" or "Dash" is '1'.
I tried to create a signal like: Go_s<=Dot or Dash;
And then tried to use its rising_edge to enable the process, but I've been told that it's not a good idea. But I can't think anything else.
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
-------------------------------------------------------------------------------
Entity Let5 is
Port(
Clk: in std_logic;
Reset: in std_logic;
Dot: in std_logic;
Dash: in std_logic;
one_spc: in std_logic;
three_spc: in std_logic);
END Let5;
-------------------------------------------------------------------------------
Architecture Let5_a of Let5 is
-------------------------------------------------------------------------------
Type state is (Start, A, B, A_1, A_2, B_1, B_2);
Signal current_s: state;
-------------------------------------------------------------------------------
BEGIN
---------------------------------------------------------------------------------
PROCESS(Clk, Reset)
BEGIN
IF(Reset='1')Then
current_s<=Start;
ELSIF(Clk='1' and Clk'event)Then
Case current_s is
When Start =>
IF(Dot='1')Then
current_s<=A;
ELSIF(Dash='1')Then
current_s<=B;
END IF;
When A =>
IF(Dot='1')Then
current_s<=A_1;
ELSIF(Dash='1')Then
current_s<=A_2;
END IF;
When B =>
IF(Dot='1')Then
current_s<=B_1;
ELSIF(Dash='1')Then
current_s<=B_2;
END IF;
When OTHERS => current_s <= Start;
END Case;
END IF;
END PROCESS;
-------------------------------------------------------------------------------
END Let5_a;
Simulation:
Add an conditional update of current_s inside the clocked process, using:
...
elsif (Clk='1' and Clk'event) then
if (Dot = '1') or (Dash = '1') then
case current_s is
...
Then current_s is updated only when the condition (Dot = '1') or (Dash = '1') is TRUE.
It is correct what you have been told, that you should not make an additional signal Go_s checking for rising edge of this, since this is not the way to implement standard synchronous designs. Instead use a signal clock and make updates on rising edge, for example using rising_edge(Clk) instead of Clk='1' and Clk'event, and then make the updated conditional to whatever signal required. FPGAs and tools are made to implement this kind of design.
Actually it ought to work reading Dot or Dash in the way you do now; I suspect something else is the problem.
If Dot is high for three consecutive clock cycles...
in the first, you get to State A.
in the second, you get to State A1.
in the third, ... there is no handler for State A1 so the "when others" clause takes you back to Start.
I suspect you actually want to remain in State A1 (or even State A) until either :
Dot is no longer 1, or:
Dash is 1
and to accomplish this (remain in State A1 instead of retriggering) you need:
When A1 =>
if Dot = '0' then
current_s <= Start;
elsif Dash = '1' then
current_s <= A_2;
end if;
Treat states Bn similarly for Dash.
If I'm misinterpreting and you actually want to remain in State A longer, it should now be clear how to make that happen instead.
Your code has a number of problems, and they are NOT related to Dot and Dash, because it is OK to have one with higher priority than the other. The present state changes at every clock cycle because that is exactly what you told the circuit to do when Dot and/or Dash is '1'. Note that in the states start, A, and B the machine changes to a state that is not in this list (start, A, B), so the WHEN OTHERS statement causes it to return to the start state at the next clock edge, with this repeated indefinitely.
My suggestion is that you draw the intended state transition diagram very carefuly, after which re-writing the code should be straightforward, especially because this is a relatively simple problem.

What is the correct implementation of handling asynchronous signals in an FSM?

We are implementing an Ethernet MAC controller in VHDL..
To start of, here is a code snippet of my code..
-- next state
PROCESS(p_state, phy_start, phy_ctr, phy_clk)
BEGIN
CASE p_state IS
WHEN sIDLE =>
IF(phy_start = '1' or rising_edge(phy_start)) THEN
n_state <= sPRE;
ELSIF(phy_start'event AND phy_start='0') THEN
n_state <= n_state;
ELSE
n_state <= sIDLE;
END IF;
............
The problem is that my professor told me I associated phy_start as the clock signal where in the rising_edge() must be only associated to only one clock which is phy_clk. What I want to happen is when phy_start asserts, it would go to sPRE state at the next clock cycle. The assertion is done in the rising edge of the clock. I have tried
PROCESS(p_state, phy_start, phy_ctr, phy_clk)
BEGIN
CASE p_state IS
WHEN sIDLE =>
IF(phy_start = '1') THEN
n_state <= sPRE;
ELSIF(phy_start'event AND phy_start='0') THEN
n_state <= n_state;
ELSE
n_state <= sIDLE;
.............
but it does not enter the phy_start = '1' because it happened in the transition.. (there is what we call the setup time in which the data must be stable in that duration in order to be read correctly). What is the correct implementation then? Or I have no choice but to assert the phy_start for 2 clock cycles if the assertion happens in the rising edge, or phy_start must be asserted in the falling edge of the clock. ALso, what is the correct set of sensitivity list for the next state logic?
If everything is clocked under phy_clk, you should never use rising_edge() or 'event on other signals. These are associated to the clocks, not the signals.
If you want to detect when a signal clocked on phy_clk rises, you should proceed like this:
process(phy_clk,nreset)
begin
if nreset = '0' then
phy_start_d <= '0';
elsif phy_clk = '1' and phy_clk'event then
phy_start_d <= phy_start;
end if;
end process;
phy_start_p <= phy_start and not phy_start_d;
the phy_start_p signal is set to 1 only when phy_start rises, and it's totally synchronous with phy_clk;
If phy_start is created synchronously by another process, then you have no problem.
Just read it in your other synchronous process, and compare against a value you stored from the last clock cycle, to detect when the signal has changed from 0 to 1:
process (phy_clk)
variable last_start : std_logic := '0';
begin
if rising_edge(phy_clk) then
if phy_start = '1' and last_start = '0' then
-- do something in here
end if;
last_start := phy_start;
end if;
end process;
There has been a related question with answers recently, which you can find at:
how many processes i need to monitor two signals?
It is useful to keep in mind that VHDL is for describing hardware (design), so
the synthesis tool can convert the description to fit the available hardware,
which is typically flip flops (sequential design) and gates (combinatorial
design). The synthesis tools does typically have some recommendations for
writing VHDL, so the translation to hardware will work smoothly.
For flip flops with asynchronous reset (rst) and rising edge clock (clk), with
next value generated by optional gates, the VHDL is typically:
-- Template for flip flops
process (clk, rst) is
begin
if rising_edge(clk) then
-- Flip flops outputs updated on rising edge of clk
end if;
if rst = '1' then
-- Flip flops outputs assigned with constant value when rst is '1'
end if;
end process;
Only rst and clk should be in the sensitivity list, so other signals used
in expressions in the process should not be included. Any expressions used to
generate the value for the flip flop will be converted to gates by the tool.
Only rising edge clock should be used for flip flop, unless there is a good
reason to use falling edge clock, or even both edges, since using only a single
edge will make it easier to do the timing constraining.
If asynchronous reset is not used, then leave out the rst from the
sensitivity list and remove the related if statement.
For pure gates the VHDL is typically, assuming use of VHDL-2008:
-- Template for gates
process (all) is
begin
-- Gates outputs updated based
end process;
or for simple expression just drop the process and write:
my_signal <= my_expression;
So back to the specific code, then it is possible to write this as a single
process with phy_clk as clock:
PROCESS (phy_clk)
BEGIN
IF RISING_EDGE(phy_clk) THEN
CASE p_state IS
WHEN sIDLE =>
p_state <= ... -- New value for state based on signals
When it is required to react on changes in signals, like phy_start going from
'0' to '1', then a signal with a single cycle delayed version of phy_start
can be made, for example phy_start_ff, and the an expression can be written
in the code like:
if (phy_start_ff = '0') and (phy_start = '1') then -- phy_start from 0 to 1
..

Resources