Unsupported feature error - vhdl

I am trying to compile this piece of code in VHDL, using Altera 10.2, but I get this error:
Unsupported feature error: non-locally-static attribute names are not supported
I asked my instructor some help on this error message, but he said that my source code looked fine to him and it was supposed to compile correctly.
if ((ina'event AND ilvla=ilvlb) AND (ilvla=NOT ilvlc)) then
if (ilvla=lvla AND ilvlb=lvlb AND ilvlc=lvlc) then
ilvla <= '0';
ilvlb <= '0';
ilvlc <= '0';
clk <= '1';
else
ilvla <= (ilvlc AND ilvlb AND NOT ilvla) OR (ilvla AND NOT ilvlc) OR (ilvla AND NOT ilvlb);
ilvlb <= ilvlb XOR ilvlc;
ilvlc <= NOT ilvlc;
end if;
else
rst <= '1';
end if;
The error occurs on the first line with the if statement.

What are your intentions with 'event? Are you trying to create a flip-flop? If not, you should not be using 'event. If so, you missed on the basics of finding a rising edge. They are one of the following three:
if Clk = '1' and Clk'event then
if Clk'event and Clk = '1' then
if rising_edge(Clk) then -- *** Preferred for readability.
There really is no form that allows you to check for 'event of some signal and whether you are matching and/or not matching some other signal.
In addition, the structure you are using is inappropriate for a flip-flop. You are assigning a value within an else branch of the clock which is going to make tools unhappy. In addition synthesis tools are happiest if clock is only in the outer most if branches. The following two are common for flip-flops:
SimpleFF : process(Clk)
begin
if rising_edge(Clk) then
-- other stuff
end if ;
end process SimpleFF ;
AsyncResetFF : process(Clk, nReset)
begin
if nReset = '0' then
-- reset stuff
elsif rising_edge(Clk) then
-- other stuff
end if ;
end process SimpleFF ;
While you are writing code, you are creating hardware. Never forget this. Step one is to always draw a rough picture of what you want. In particular, identifying hardware elements, such as flip-flops, combinational logic, and arithmetic logic. Then write code that captures what is in the picture.

Related

VHDL Cannot Drive Load pins

Using the first snippet of code, I have been getting this error that a bunch of my signals drove no pins. I am pretty certain that this is because in the first snippet of code, the first if statement is never reached. Why would this be so? In the second snippet I modified the code, and all of my problems have been fixed. I made the change as an intuitive impulse, I have no idea why that fixed everything. Could someone explain maybe how the Synthesizer generates the circuit?
First Snippet:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity DataReg is
generic(N: integer := 8);
port(DIN: in std_logic_vector(N - 1 downto 0);
DOUT: out std_logic_vector(N - 1 downto 0);
CLK: in std_logic;
ENABLE: in std_logic;
RESET: in std_logic);
end DataReg;
architecture Behavioral of DataReg is
begin
process(CLK, ENABLE)
begin
if rising_edge(CLK) and ENABLE = '1' then
DOUT <= DIN;
end if;
if rising_edge(CLK) and RESET = '1' then
DOUT <= (others => '0');
end if;
end process;
end Behavioral;
Second snippet: (Fixed code)
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity DataReg is
generic(N: integer := 8);
port(DIN: in std_logic_vector(N - 1 downto 0);
DOUT: out std_logic_vector(N - 1 downto 0);
CLK: in std_logic;
ENABLE: in std_logic
RESET: in std_logic);
end DataReg;
architecture Behavioral of DataReg is
begin
process(CLK, ENABLE)
begin
if rising_edge(CLK) then
if ENABLE = '1' then
DOUT <= DIN;
elsif RESET = '1' then
DOUT <= (others => '0');
end if;
end if;
end process;
end Behavioral;
Because HDL code must be able to represent existing hardware. Therefore when you write RTL (Register Transfer Level) code you have to stick to certain structures. Even the second code you wrote is not correct.
I can't explain all the rules but basically, to use an edge (rising or falling) you can have only one signal. Not OR-es or And-es etc.:
if rising_edge(CLK) then
In such a clocked section your process can have one or two more sensitivity signals. Often there is an asynchronous reset in some exceptional cases there is also an asynchronous set. For those to work you have to place the condition before the clock. Therefore your code is wrong. Your ENABLE and RESET are only looked at when there is a clock edge. Thus putting ENABLE in the sensitivity list is superfluous. You might just as well leave it out.
Furthermore the ENABLE if is before the RESET. Thus if the ENABLE is high your RESET will be ignored. Probably not what you want!
The code for a clocked section is sooo terribly standard that I often copy a template I have laying around. (I always use asynchronous active low reset)
process(clk, reset_n)
begin
if (reset_n='0') then
elsif rising_edge(clk) then
end if; -- reset/clocked
end process;
First of all, the two pieces of code that you present are not even equivalent in the simulator because when ENABLE and RESET are both 1 on a clock edge, the first snippet results in DOUT being 00000000 whereas in the second one it evaluates to DIN.
It is my impression that the sensitivity lists (the part in parentheses after process) are ignored during synthesis by Xilinx Vivado. I consider them a relic from times when simulation tools could not afford deducing which variables should be monitored to determine when variables should be updated. I don't know what other synthesis tools do with them.
Anyway, you specified ENABLE in your sensitivity list, which means that you want to evaluate the process statements if ENABLE changes value. All if-statements evaluate to false unless a rising clock edges is taking place. Therefore, CLK alone in the sensitivity list is sufficient for simulation.
All that being said, you should restrict your code to formats that are explicitly recommended by the synthesis tool vendor. Synthesis tools can only implement a subset of everything that you can write in VHDL. For Vivado, you can find suggested code structure in the synthesis manual (This one is for Vivado 2017.3). On page 71, you will see that they recommend flip-flops of the form:
process(clk) is
begin
if rising_edge(clk) then
if clr = '1' then
dout <= "00000000";
elsif ce = '1' then
dout <= d_in;
end if;
end if;
end process;
You can rename the variables as needed of course. On page 69, you will also see that Xilinx recommends using synchronous implementations (putting everything inside the rising_edge if-statement) over asynchronous implementations. There is much more in the manual, for example about how to write shift registers or RAMs, which you should become familiar with if you want to write code to be synthesized with Vivado. Other vendors have similar documentation with recommended code.

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;

VHDL behavioural D Flip-Flop with R & S

Hi can any of you with more experience with VHDL Quartus II please set me right on this please.
I have the following Entity and behavioural Architecture for a D Flip-Flop with Set and Reset.
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
ENTITY Q1 IS
PORT (D,R,S,CLK : IN std_logic;
Q : OUT std_logic
);
END ENTITY Q1;
ARCHITECTURE behavioural OF Q1 IS
BEGIN
D_FF : PROCESS (CLK,R,S)
BEGIN
IF R = '0' THEN Q <= '0';
ELSIF S = '0' THEN Q <= '1';
ELSIF (rising_edge(CLK)) THEN Q <= D;
END IF;
END PROCESS D_FF;
END ARCHITECTURE behavioural;
When I compile the code using Quartus II I get the following error message :
Warning (335093): TimeQuest Timing Analyzer is analyzing 1 combinational loops as latches.
I think it is a warning for the incomplete output assignments of the R & S inputs, but when I make a D Flip-Flop latch with only the SET input this error message does not appear when compiled. This leaves me thinking maybe I made an error when writing the architecture? If anyone has any answers or useful info that would be much appreciated.
You have described a clock-edge triggered flip-flop (FF) with both an asynchronous reset and an asynchronous set. Only one of them is supported at the same time because AFAIK, all FFs on Altera FPGAs have only an asynchronous reset.
An asynchronous set is emulated on Altera FPGAs by inverting the FF data input and output and then resetting it to low instead of setting it to high. It looks like this:
Don't overlook the inverter on the D input of the FF. If S is low, then the FF itself is asynchronously reset, but due the negation of the Q output afterwars, it behaves as an asynchronous set of output Q of your entity Q1. If S is high, the FF stores the negated input at the rising clock-edge, which is again negated at the output. As you see, the asynchronous reset port of the FF is already used, and thus, cannot be used for an additional asynchronous reset of your entity Q1.
I recommend to use flip-flops with synchronous set and reset instead:
ARCHITECTURE sync_rs OF Q1 IS
BEGIN
D_FF : PROCESS (CLK)
BEGIN
IF (rising_edge(CLK)) THEN
IF R = '0' THEN Q <= '0';
ELSIF S = '0' THEN Q <= '1';
ELSE Q <= D;
END IF;
END IF;
END PROCESS D_FF;
END ARCHITECTURE sync_rs;
Flip flops in FPGA devices usually have either asynchronous set or reset, but not both, so Altera Quartus tries to make the requested circuit with latches instead of dedicated hardware.
However, for most cases that is not what you want, so instead use flip flops with either asynchronous reset or set, or use synchronous set and and reset as Martin Zabel suggested in his answer.
Note that asynchronous reset have an advantage over synchronous reset in high speed designs, since the asynchronous reset does not add any login in the main synchronous data path, which is usually the critical path for high-speed designs.
Finally, for asynchronous reset, it is a good habit to use two if separate statements, with reset last, so clocking is not dependent on assertion of reset. It is not an issue for a single bit flip flop, but if more signals are controlled in the same process, and reset does not apply to all signals, then clocking should not be dependent on reset for those signal without reset, since that will infer latches. Code like:
D_FF : PROCESS (CLK, R)
BEGIN
IF rising_edge(CLK) THEN
Q <= D;
END IF;
IF R = '0' THEN
Q <= '0';
END IF;
END PROCESS D_FF;
Thanks for the reply, I made the R & S inputs asynchronous on purpose. I have been working through a VHDL text book "Free Range VHDL" and have come across the following question in the Exercises:
The question asks for both inputs to be asynchronous. You say this can be emulated with Altera by inverting the input and output and resetting it to low instead of high. Can you expand on this a little? Thanks

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