How would I do something like this without a synchronous error in vhdl? - vhdl

How would I do something like this without a synchronous error in vhdl?
process (shift_button)
variable x : STD_LOGIC;
begin
x := '0';
if falling_edge(shift_button) then
x := '1';
end if;
shift_button_let_go <= x;
end process;

I would first read the Xilinx support article about the error you're encountering:
http://www.xilinx.com/support/answers/14047.html
It basically states there is a certain template that XST expects when making synchronous design elements (note that falling_edge() will use the VHDL 'event attribute). I'm guessing that XST doesn't like how you are defining your clear of shift_button_let_go on the rising edge of shift_button.
You mentioned you want shift_button_let_go to go high for one clock cycle after shift_button goes low. If this is the case then you would want to use your clock in the process' sensitivity list instead of shift_button.
process (clk)
begin
if rising_edge(clk) then
shift_button_d <= shift_button;
if (shift_button_d = '1' and shift_button = '0') then -- Falling edge detect
shift_button_let_go <= '1';
else
shift_button_let_go <= '0';
end if;
end process;
NOTE This logic can suffer from meta stability issues if shift_button is not synchronous to clk and is not held stable for several clk cycles.

Related

VHDL finite state machine counter with start

i pretty new of vhdl and i'm trying to learn how to do a FSM with vhdl.
At moment i need a code that after a fixed count value, it give me back a pulse, in order to start a second FSM block. (I have a recurring signal every 100 kHz, i need to count it and release this signal after a fixed number of counts).
Actually it work as free run, every time that it see this signal, it start to count, but realy i want to add a "start" signal, so it must start to count this signal after it see this start signal.
at moment my working code is:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
entity counter is
Port (
signal_in : in STD_LOGIC := '0'; --segnale di start
clk : in STD_LOGIC; --clock di ingresso
reset : in STD_LOGIC; --ff reset
signal_out: out STD_LOGIC; --gate in uscita
count_val: in std_logic_vector (7 downto 0);
start : in STD_LOGIC := '0'
);
end counter;
architecture behavioral of counter is
type state_type is (idle, count_up);
signal state : state_type;
begin
process (reset, clk, signal_in, start)
variable index : integer :=0;
variable countlen: integer;
variable count_v: std_logic;
variable countlen2 : std_logic;
begin
countlen := to_integer(unsigned(count_val))-1;
if reset = '1' then
count_v := '0';
index := 0;
state <= idle;
else
--if start = '1' and
--if rising_edge(clk) then
if rising_edge(signal_in) then
case state is
when idle =>
count_v :='0';
index := 0;
if (signal_in = '1') then
state <= count_up;
else
state <= idle;
end if;
when count_up =>
if(index < countlen) then
state <=count_up;
index := index + 1;
elsif
index = countlen then
count_v := '1';
state <=idle;
end if;
when others => null;
end case;
end if;
end if;
signal_out <= count_v;
end process;
end Behavioral;
Any attempt to work with cose with "start = 1" will stop the count.
Please some one have some suggestion?
Kind REgards
Fulvio
Welcome om StackOverflow. Your specification is not 100% clear. What difference do you make between signal_in and start? According to your code and to your explanations, they both seem to act as a starter.
Moreover, there are several strange things with your code:
your process seems to be a synchronous one, with asynchronous reset. Its sensitivity list should contain only the clock and the reset. And its body should be:
process(clk, reset)
<variable declarations>
begin
<NOTHING HERE>
if reset = '1' then
<reset code>
elsif rising_edge(clk) then
<regular code>
end if;
<NOTHING HERE>
end process;
you are using signal_in as a clock and as a logic signal. This is extremely strange. Moreover, your if (signal_in = '1') then is always true (in the synthesis semantics) and thus useless.
You are initializing variables at declaration (index). This is not supported by some synthesizers and hardware targets. Moreover, even when supported, it works only at power up. If:
you intend to synthesize your code,
you want it to be portable across synthesizers and hardware targets,
you want to re-initialize signal and variables not only at power up but also when a reset input is asserted,
prefer a real explicit reset, instead, and guarantee that it is always asserted after power up (or at the beginning of a simulation) for proper first initialization.
you declare variable index with a full integer range, that is, 32 bits minimum, while 8 bits would suffice. This is a potential waste of hardware resources.
It is difficult to propose a solution without a clear and complete specification but assuming you want to count only after start has been asserted and only when signal_in is asserted, the following may be a starting point:
process (clk, reset)
variable index: natural range 0 to 255;
begin
if reset = '1' then
state <= idle;
signal_out <= '0';
index := 0;
elsif rising_edge(clk) then
case state is
when idle =>
signal_out <= '0';
index := 0;
if start = '1' then
state <= count_up;
end if;
when others =>
if signal_in = '1' then
if index = to_integer(unsigned(count_val)) - 1 then
state <= idle;
signal_out <= '1';
else
index := index + 1;
end if;
end if;
end case;
end if;
end process;
Note that this is really synchronous of your clock clk. I suspect that you made a very common mistake: as you wanted to increment your counter when signal_in is asserted you decided more or less to use signal_in as a clock. This is not a real synchronous and safe design. In a real safe synchronous design you do not use logic signals as clocks. You have well identified clocks and you use only these as clocks. In your case there is one single clock: clk. If you want to do something synchronously when a logic signal is asserted, wait for the rising edge of your clock and then test the logic signal and take appropriate actions.
thanks for your support.
Yes the point is that i need to "decimate" (or count) a signal.
This signal had a width of 50-100ns and it repeat itself with a frequency of 100 kHz.
so in my mind, this signal will go in to "signal in". My FPGA is an Actel proasic3 with a clock of 40 MHz.
In my setup this signal will be always on, but i don't want that my FSM will start to count as it see the first "signal in" but only when i send a "start" signal for the number of count that i indicate. (Realy they ask to me the possibility to decimate this signal up to 65000 count, so for sure i need to use a 16bit vector instead of 8bit).
The async reset is here "just in case" i need to reset the whole fsm in the middle of some data record.
Hope to be more clear now what this code should do.
For Old fart, yes indeed all my signal coming outside the fpga will be first synchronized with a simple 2 ff synchronizer with the FPGA clock

Switch on LED after receiving Ethernet packets

I'm a novice in VHDL programming and currently try to execute a program where the LED on the FPGA board should switch on after transmitting every 10 Ethernet packets which I generate from a Linux server. The code I've written is in the following which doesn't work properly. I'm trying to figure out the problem but still undone. Any help would be much appreciated.
---------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
---------------------------------------------
entity notification is
port (clk, reset, qdv: in std_logic;
LED: out std_logic
);
end notification;
architecture behavior of notification is
signal qdv_a: std_logic;
signal qdv_b: std_logic;
signal packet_count: std_logic_vector (3 downto 0);
begin
no_1: process(clk, reset)
begin
if (reset = '1') then
qdv_a <= '0';
elsif rising_edge (clk) then
qdv_a <= qdv;
end if;
end process no_1;
qdv_b <= qdv and (not qdv_a);
no_2: process(clk, reset)
begin
if (reset = '1') then
packet_count <= "0000";
elsif rising_edge (clk) then
if qdv_b = '1' then
if packet_count < "1010" then
packet_count <= packet_count + 1;
LED <= '0';
else
LED <= '1';
packet_count <= (others => '0');
end if;
end if;
end if;
end process no_2;
end behavior;
I am making assumptions based on your code:
1) You are trying to increment packet_count every time you see a rising edge on qdv,
2) The pulse width of qdv is longer than a period of the 25MHz clock (clk_25MHz) - 40ns and
3) You want an asynchronous reset. (Trying to decide which is better - a synchronous or asynchronous reset - is like trying to decide which is a better - a Mac or a PC.)
So,
If (1) and (2) are true, you need a synchronous edge detector:
signal qdv_d : std_logic;
signal qdv_r : std_logic;
...
process (clk_25MHz, reset)
begin
if reset = '1' then
qdv_d <= '0';
elsif rising_edge (clk_25MHz) then
qdv_d <= qdv;
end if;
end process;
qdv_r <= qdv and not qdv_d;
Please draw this out as a schematic so that you can see how it works.
Then, assuming (3), you need to sort out your main process. If you're coding sequential logic, you should stick to a template. Here is the template for sequential logic with an asynchronous reset, which all synthesis tools should understand:
process(clock, async_reset) -- nothing else should go in the sensitivity list
begin
-- never put anything here
if async_reset ='1' then -- or '0' for an active low reset
-- set/reset the flip-flops here
-- ie drive the signals to their initial values
elsif rising_edge(clock) then -- or falling_edge(clock)
-- put the synchronous stuff here
-- ie the stuff that happens on the rising or falling edge of the clock
end if;
-- never put anything here
end process;
Only clock and reset go in the sensitivity list, because the outputs of the sequential process (though they depend on all the inputs) only change when clock and/or reset change. On a real D-type flip-flop, reset takes priority over clock, so we test that first and do the resetting should reset be asserted. If there is a change on clock (when reset is not asserted) and that change is a rising edge, then do all the stuff that should happen on the rising edge of a clock (stuff that will get synthesised to combinational logic driving the D inputs of the flip-flops).
So, using that template, here is how I would write your main process:
process(clk_25MHz, reset)
begin
if reset = '1' then
packet_count <= "0000";
elsif rising_edge (clk_25MHz) then
if qdv_r = '1' then
if packet_count < "1010" then
packet_count <= packet_count + 1;
LED <= '0';
else
LED <= '1';
packet_count <= (others => '0');
end if;
end if;
end if;
end process;
Now we have a synchronous process which increments packet_count and drives the LED output. (What is q bringing to the party?)
Please
bear in mind that I haven't simulated any of this
don't just type it in without trying to understand how it works

During synthesis, should I care about the "found latch" warnings if I actually want the latches?

say I have the following state machine:
....
if state_a then
output_a <= '0';
next_state <= state_b;
elsif state_b then
output_a < '0';
if cond then
output_b <= '1';
next_state <= state_a;
else
next_state <= state_b;
end if;
end if;
......
I don't want output_b to change except when being assigned again in state_b. However, when I try to synthesise this code, most synthesis tools will say something along this line:
warning: found 1-bit latch for signal "output_b". latches aren't
recommended for FPGA design because it might result in timing
problems.
Should I worry about this at all? If so, why and what are the alternatives?
Following Xilinx:
If latch inference is intended, you can safely ignore this message. However, some inefficient coding styles can lead to accidental latch inference. You should analyse your code to see if this result is intended.
Some techniques to avoid latch inference:
Make sure any "if / else if" statements have a concluding "else" clause,
Assign to all the same outputs in each case,
Include all possible cases in the case statement (but be aware that WHEN OTHERS clause always works, but can create extraneous logic).
if you have incomplete if/elsif or case statement in a clocked process, it's absolutely harmless.
if rising_edge(clk)
if a then
out <= b;
end if;
end if;
It means that you have flip-flop with some sort of feedback, or, like in this case, you have flip-flop with clock enable pin used, which is even better.
If you have incomplete if/elsif or case statement in not clocked process - it's a latch and it's in most cases:
something you don't really want;
something that point out on a poor design and can be avoided with redesign.
If you complete your little example, someone can help you redesign it. Now it is not enough information.
The problem you have stems from the FSM coding style you're (presumably) using. As other pointed it is not possible to guess what you want the code to do, since you did not provide enough code to figure that out, so I present one possible interpretation, assuming you really wanted to change output_a somehow and that one time (after reset) latching of output_b should happen at the same time FSM state transitions.
Using 2 processes per FSM style, we have code that is not giving latch warnings:
----
signal CLK, RESET, cond : std_logic;
type state_t is (a,b);
signal state, state_next : state_t;
signal ouput_a, output_b, output_b_next : std_logic;
----
FSM_clock: process(all)
begin
if rising_edge(CLK) then
if RESET then
state <= a;
output_b <= '0';
else
state <= state_next;
output_b <= output_b_next;
end if;
end if;
end process;
FSM_next: process(all)
begin
state_next <= state;
output_b_next <= output_b;
output_a <= '0';
case state is
when a =>
state_next <= b;
when b =>
output_a <= '1';
if cond then
output_b_next <= '1';
state_next <= a;
else
state_next <= b;
end if;
end case;
end process;

Strange spikes in the signal ModelSim VHDL

I'm working on a final project for school and this is my first time working with VHDL in Quartus and ModelSIM. It's supposed to be a control for an elevator that services three floors. I have these strange spikes in a few signals, and I can't seem to find their source.
The one problem I have is a spike in a signal that feeds to an up/down counter that shows the current floor. When it stops at a floor, it ends up counting one additional time and going either one floor too high or one floor too low, while the next floor display seems to show the same floor just fine until another floor is called. The next floor display comes from an FSM, while the current floor display is from an up/down counter.
It's a bit complex to post everything here, so I'm just going to post the waveform for now in case someone's come across this signal spike thing and it ends up being a minor error/easy fix.!
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity FSM_Elevador is
port (Up_Down, Igual, Reset, Clock: in std_logic;
Andar_Dif: out std_logic
);
end FSM_Elevador;
architecture FSM_beh of FSM_Elevador is
type Elev_States is (Start, Wait_State, Pulse_State);
signal Current_State, Next_State: Elev_States;
signal RST, CLK, Sig_Andar_Dif, Cont_Mesmo_Andar: std_logic;
begin
RST <= Reset;
CLK <= Clock;
process(RST, CLK)
begin
if RST = '0' then
Current_State <= Start;
elsif CLK'event and CLK = '1' then
Current_State <= Next_State;
end if;
end process;
process(Current_State, Igual)
begin
case Current_State is
when Start =>
Next_State <= Wait_State;
when Wait_State =>
if Igual = '1' then
Next_State <= Wait_State;
Sig_Andar_Dif <= '0';
else
Next_State <= Pulse_State;
Sig_Andar_Dif <= '1';
end if;
when Pulse_State =>
if Igual = '1' then
Sig_Andar_Dif <= '0';
Next_State <= Wait_State;
else
Sig_Andar_Dif <= '0';
Next_State <= Pulse_State;
end if;
end case;
end process;
Andar_Dif <= Sig_Andar_Dif;
end FSM_beh;
fru1tbat: I use the Elev_pulse to make the counter go up or down once, and yes it enters the counter as a clock. It was suggested by the professor.
Edit: sorry that was the wrong code earlier. Andar_Dif is what sends out the signal that ends up going to the component that has Elev_Pulse
Get rid of the reassignment of Clock and Reset to CLK and RST and just use the signals from the port directly. That is creating a delta cycle delay which is the cause of these kind of spikes. It looks like you have resets with different delays in the design which can also complicate matters. If the removal of the indirection doesn't clear things up you need to scrutinize the ordering of when events are generated on signals and when they are processed.
The outputs from your state machine are unregistered which is also potentially involved. Consider reworking the FSM so that all outputs are registered. This is a better design practice in general as it ensures that you don't have unknown combinational delays affecting downstream logic.

VHDL driving signal from different processes

I have a little problem with following VHDL code:
process (zbroji)
begin
if rising_edge(zbroji) then
oduzima <= '0';
ucitanPrvi <= '1';
broj1 <= ulaz_broj;
end if;
end process;
process (oduzmi)
begin
if rising_edge(oduzmi) then
oduzima <= '1';
ucitanPrvi <= '1';
broj1 <= ulaz_broj;
end if;
end process;
The problem is that signal ucitanPrvi always has value X. If I don't try to set it's value in two processes, then I don't have any problems ... So I know that I mustn't drive one signal from multiple processes, but I don't know how to write this differently ...
Does anyone have an idea how I could resolve this problem ?
Thanks !
EDIT: Thank you all guys for replying :) Now I understand why I can't drive one signal from multiple processes (at least in the way I wanted it to work).
If you want to synthesize your design for a real FPGA or ASIC, you are going to have to think of VHDL in terms of real hardware (wires, flip flops, gates, etc.). Also, if you want to perform a real rising edge detect in hardware, you will need a system clock that drives a flip flop. Given your original code sample, it doesn't seem that zbroji or oduzmi are system clocks, but just std_logic signals. I wrote this code example assuming basic functionality from your example, hopefully, you can take my code and comments and accomplish what you need.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity example is
port (Reset : in std_logic;
SysClk : in std_logic;
zbroji : in std_logic;
oduzmi : in std_logic;
ulaz_broj : in std_logic;
oduzima : out std_logic;
ucitanPrvi : out std_logic;
broj1 : out std_logic
);
end example;
architecture Behavioral of example is
-- Delayed version of input signals (1 clock cycle delay)
signal zbroji_d : std_logic;
signal oduzmi_d : std_logic;
signal zbrojiRE : std_logic;
signal oduzmiRE : std_logic;
begin
-- Generate 1 clock cycle delayed version of
-- signals we want to detect the rising edge
-- Assumes active high reset
-- Note: You should only use the rising_edge macro
-- on an actual global or regional clock signal. FPGA's and
-- ASICs place timing constraints on defined clock signals
-- that make it possible to use rising_edge, otherwise, we have
-- to generate our own rising edge signals by comparing delayed
-- versions of a signal with the current signal.
-- Also, with any respectable synthesizer / simulator using
-- rising_edge is almos exactly the same as (clk'event and clk='1')
-- except rising_edge only returns a '1' when the clock makes a
-- valid '0' to '1' transition. (see link below)
EdgeDetectProc : process (Reset, SysClk)
begin
if Reset = '1' then
zbroji_d <= '0';
oduzmi_d <= '0';
elsif rising_edge(SysClk) then
zbroji_d <= zbroji;
oduzmi_d <= oduzmi;
end if;
end process EdgeDetectProc;
-- Assert risinge edge signals for one clock cycle
zbrojiRE <= '1' when zbroji = '1' and zbroji_d = '0' else '0';
oduzmiRE <= '1' when oduzmi = '1' and oduzmi_d = '0' else '0';
-- Assumes that you want a single cycle pulse on ucitanPrvi on the
-- rising edege of zbroji or oduzmi;
ucitanPrvi <= zbrojiRE or oduzmiRE;
-- Based on your example, I can't tell what you want to do with the
-- broj1 signal, but this logic will drive broj1 with ulaz_broj on
-- either the zbroji or oduzmi rising edge, otherwise '0'.
broj1 <= ulaz_broj when zbrojiRE = '1' else
ulaz_broj when oduzmiRE = '1' else
'0';
-- Finally, it looks like you want to clear oduzima on the rising
-- edge of zbroji and assert oduzima on the rising edge of
-- oduzmi
LatchProc : process (Reset, SysClk)
begin
if Reset = '1' then
oduzima <= '0';
elsif rising_edge(SysClk) then
if zbrojiRE = '1' then
oduzima <= '0';
elsif oduzmiRE = '1' then
oduzima <= '1';
end if;
end if;
end process LatchProc;
end Behavioral;
The previous code assumes you have a system clock. In a simulator like ModelSim (free student edition), you can generate a 100 MHz clock with non-synthesizable testbench code like this...
ClockProc : process
begin
SysClk <= '0';
wait for 5 ns;
SysClk <= '1';
wait for 5 ns;
end process ClockProc;
In an actual FPGA/ASIC implementation, you will probably want to use an external oscillator that you run into your chip, drive the signal into a DCM (Digital clock manager), which will output a very clean clock signal to all of your VHDL logic, so you can have a glitch free design.
And finally, here is a great explanation on the differences between rising_edge and
(clk'event and clk='1')
http://vhdlguru.blogspot.com/2010/04/difference-between-risingedgeclk-and.html
Hope that helps.
If you drive a std_logic signal from more than one process (and remember that a continuous assignment outside of a process also creates an implied process!) then all but one of them must be driving Z onto the signal. To a first approximation, the resolution function (that decides what the final value should be) will produce Xs unless this happens.
I'm not sure how best to change your code - you need to decide when a particular process should not drive the signal and have it drive a Z at that point.
The full definition of how the multiple drivers are resolved is defined in the ieee.std_logic_1164 package and covers all possibilities, such as a 1 and an L driving etc. The IEEE get shirty about copyright, so I'm not going to post even an excerpt here, but you'll be able to find it in the source libraries of your simulator.
Driving signals from multiple processes is a bad idea unless you really know what you're doing. You can re-write this code in a single process like this.
process (zbroji, oduzmi)
begin
if rising_edge(zbroji) then
oduzima <= '0';
ucitanPrvi <= '1';
broj1 <= ulaz_broj;
end if;
if rising_edge(oduzmi) then
oduzima <= '1';
ucitanPrvi <= '1';
broj1 <= ulaz_broj;
end if;
end process;
Note that if you do this, and you get a rising edge on both zbroji & oduzmi then oduzima will get the value 1 as it happens last in the process. Before you'd have been trying to set it to 0 and 1 at the same time. That would simulate to X, and probably wouldn't synthesize. If it did synthesize you'd be connecting power and ground together in a CMOS design.
An alternative method is to have each process drive it's own version of the signal, and then resolve them externally with what ever function you like (or another process). In this case I used or:
process (zbroji)
begin
if rising_edge(zbroji) then
ucitanPrvi_1 <= '1';
end if;
end process;
process (oduzmi)
begin
if rising_edge(oduzmi) then
ucitanPrvi_2 <= '1';
end if;
end process;
ucitanPrvi <= ucitanPrvi_1 or ucitanPrvi_2;
Unless zbroji and oduzmi are seperate clocks this is my recommended implementation
This registers the zbroji and oduzmi and checks if the value in the register is the opposite of the original signal. This should only occur when zbroji/oduzmi go from 0 to 1 and the register has not yet updated the change in signal.
process (clk)
begin
if rising_edge(clk) then
if zbroji = '1' and zbroji_old = '0' then
oduzima <= '0';
ucitanPrvi <= '1';
broj1 <= ulaz_broj;
elif oduzmi = '1' and oduzmi_old = '0' then
oduzima <= '1';
ucitanPrvi <= '1';
broj1 <= ulaz_broj;
end if;
zbroji_old <= zbroji;
oduzmi_old <= oduzmi;
end if;
end process;
Also it appears that ucitanPrvi and broj1 are always the same thing. Either the signals are useless, this was orignally a typo or you are creating "update" pulses in which case you need the statement
ucitanPrvi <= '0'
broj1 <= (others=>'0') -- assumed reset?
following the if(rising_edge(clk) statement
When you're changing same signal value from multiple process, the simulator will be creating multiple signal drivers for this. The output of them will essentially will be unresolved. Think of it as the output of multiple gates connected together, what do you expect?
To overcome this, what you need to implement is, a resolution function, that drivers the output to signal.
http://www.csee.umbc.edu/portal/help/VHDL/misc.html#resf
If you have any doubts, let me know.

Resources