Is this a valid way to code a VHDL async reset? - vhdl

I have picked up some VHDL code to maintain that has a reset written in a way I'm not familiar with. I'm not sure if it's valid, and my simulator (Modelsim) is giving warnings that I wouldn't expect. Example of the pattern:
process(clk, reset_n)
begin
if reset_n = '0' then
counter <= (others=>'0');
end if;
if rising_edge(clk) then
case state is
when IDLE =>
if signal_a = signal_b then
state <= DATA;
end if;
when DATA =>
state <= IDLE;
when others =>
end case;
if state = DATA then
counter <= counter + 1;
else
counter <= (others => '0');
end if;
end if;
end process;
Modelsim warns that state, signal_a and signal_b are "read in the process but is not in the sensitivity list". I would not expect that as they are in a clocked block and the process is sensitive to the clock.
Is this a valid coding style for an async reset? I would expect to see elsif rising_edge(clk) instead, but understand this would cause problems here with the mix of other non-reset signals (state).

This pattern likely wont behave as you expect, and also likely wont synthesise (and if it does, it wont match the code).
This code has the clock overriding the reset. If reset is asserted ('0') then the counter will be reset, but if clk is running it will the run as if reset_n is '1'. This is because processes are only triggered by a 'event' on a signal in the sensitivity list, so the reset will only occur when reset_n changes to '0'. This doesnt usually matter in VHDL as the reset branch will have higher priority than the clock. So if it is clocked, the reset branch is taken. But here, because the reset has lower priority, it is as if reset_n is a negitive edge clock.
On the actual hardware, this is different. Sensitivity lists are normally ignored and the hardware is built from the code in the process. I would expect that this will fail to build either because it will complain about no logic matching the template, or dual edge flops are not allowed.
To fix this, either make the clock branch an elsif as you suggested, and you would also need to add state to the reset to avoid an accidental clock enable on state, or move the reset to the bottom of the process, where it will override the clock assignment properly, and allow you to have a mix of reset and non-reset registers in the same process.

Related

VHDL - FPGA implementation - Pulse trigger generated only once on mutiple button pushes

Hello everyone I wrote some VHDL code that implement a UART-TX from my FPGA to my desktop. To trigger data sending I use the signal(debounced ofc) coming from the on-board switch.
As long as the button is pressed data is being sent. Inevitably, for as quick as I can be pushing and releasing this switch, the FPGA sends many UART packet duplicates to the laptop. This is because i directly connected the button signal to the start bit of the UART-TX entity. Therefore, I removed this direct connection and instead use the button to actually generate a short bit pulse to trigger the UART-TX entity just once.
So I did this:
--start_deb is the start bit (debounced? coming from the switch
i_TX_DV_gen: process(start_deb, clk) is
variable counter: natural := 0;
begin
if rising_edge(start_deb) then
i_TX_DV <= '1';
end if;
if i_TX_DV = '1' and rising_edge(clk) then
counter := counter + 1;
if counter > 10_000 then
i_TX_DV <= '0';
counter := 0;
end if;
end if;
end process;
So the trigger bit to the UART entity is set to '1' when I press the button and then after a number of clock cycles (which I unsured smaller than the ones necessary to send one packet) it goes to '0' again avoiding the send any duplicates.
This works in simulation, I attached the waveform:
These are the signals description
clk:system clock
start_n: button signal (pressed when low)
start: not(start_n)
shift_input_n: button signal to select the next byte code.
o_TX_serial: serial output of the TX entity
packet: byte to be sent
i_TX_DV: trigger bit to start UART-TX trasmission
start_deb: start signal but debounced
The problem is that when I download it to my FPGA, the i_TX_DV is set to '1' only the first time.
[
To visualize this I used a FPGA-built-in LED, which produces a light burst every time the i_TX_DV is set to '1'( for its very short amount of time).
]
Therefore, the UART-TX entity is triggered only the first time I pressed the button. Apparently when on FPGA for some reason, i_TX_DV is not set to '1' anymore, or is set to '0' just right after.
I am using the fpga Crosslink-NX Family 8MG289C from Lattice Semiconductor.
Thank you guys, I thought of others ways to include it in a FSM and I ended up modifying the FSM of the UART-TX entity. Basically I don't go back to the idle state as long as the input start button is still pressed. This is a section of the FSM which contains the part I modified
when s_Cleanup =>
o_TX_Active <= '0';
r_TX_Done <= '1';
***if i_TX_DV = '1' then
r_SM_Main <= s_Cleanup;
else
r_SM_Main <= s_Idle;
end if;***
Anyway back at my original implementation, this was the netlist analyzer output for the pulse trigger generator:
It uses a register and a full adder to implement the counter. A register stores the value of i_TX_DV. The two multiplexer at the left are apparently used to either hold the value of the counter, updating it with the next value or "reset" it. The reset apparently is carried in this way: it comes from the d1 constant input data of bottom-left multiplexer wihch is tied to a 0. Therefore at the next clock cycle, when it holds the value it should be resetting itself. For some reason this still didn't work.
I apologize for my careless when writing the VHDL code, but when wiriting the code I just assumed that as long the simulation went well, the synthesis tool would have done the rest. Also I decided to not include too much code in order to be more coincise, because I had done several testing and made sure that all the other entities and modules were working correctly.

In VHDL, Can I use signal'event if signal is not a clock?

I am trying to clean up my VHDL code. I have a signal that is NOT a clk.
Can I write an event change monitor like the following and how do I get it to compile so it can be synthesized? (see code) I have tried several permutations but I cannot get it to compile. Will signal'event compile if signal is not a CLK and if so, how is it done? I see on the web and other literature that it can be done but all examples I see show CLK'event.
signal cntr: unsigned(15 downto 0) := (others => '0');
...
process(CLK):
begin
IF rising_edge(CLK) THEN
if (cntr'event) then
do something;
end if;
or...
if(cntr(0)'event) then
do something;
end if;
END IF;
end process;
I get the following and others
: can't synthesize condition that contains an isolated 'EVENT predefined attribute
rising_edge(CLK) is already an event, making your design synchronous, which is good. As said in comments, only clock signals should use that.
Looking at another even at that time doesn't make sense in synchronous designs, as the 2 signals won't change exactly at the same time, creating a race condition. Or actually a clock within a clock, and the synthesis error...
It may work in simulation, but don't rely on that fact.
The normal way to program in HDL languages is to save the previous value of the signal, on the same clock (for example cntr_d <= cntr) and to compare with that previous value. That allows to find if the signal went up (previously at 0, currently at 1), went down, changed (is different)...
And that method is perfectly fine for synthesis!

VHDL - how does "reset" work and how to use?

I am new to VHDL and am trying to understand how reset operates - specifically within the Xilinx Spartan6. I've looked over this site and others, a white paper or two, but my questions do not seem to be addressed (so I fear the issue is so basic that all is assumed!)
Anyway, I inherited some example code and have made significant changes to it and succeeded in getting some decent functionality but the use of reset mystifies me.
The code looks like this:
architecture Behavioral of BigProject is
...
signal reset : std_logic := 0;
...
begin
...
reset <= '0';
...
process(clk_1MHz, reset) is
begin
if reset = '1' then
foo_flag <= '0';
fsm_a <= FSM_FIRST_STATE;
elsif rising_edge(clk_1MHz) then
case fsm_a is
when FSM_FIRST_STATE =>
<do stuff>
when FSM_SECOND_STATE =>
<do other stuff>
when others =>
null;
end case;
end if;
end process;
What does my use of reset actually accomplish?
Thanks.
With respect to the Xilinx tools, initial values on signals are honored for power-on state. For example:
signal a : std_logic := '0';
signal b : std_logic := '1';
Signal a will have a power-on reset value of '0', and signal b will have a power-on reset value of '1'.
Now, this is generally NOT the case for ASIC's, and is not the case for Microsemi parts.
Also, it is highly recommended that you limit the resets to only those bits that actually need to be reset. For example, if you have a data path that does math operations on some data in a pipeline, do you need to reset the data itself? Resets have a cost in terms of logic (depending on the logic library, it may require a multiplexer), routing (the reset has to get everywhere it is necessary), and can be complex when releasing reset.
So, limit your resets as much as possible. If an external reset is not necessary, don't use one. And if it is required, limit it's use to essential bits.
Your reset actually accomplishes nothing ;) In your code the reset is tied to '0' and thus your clocked process is always in reset state.
Usually the reset signal is an input port. So someone outside of your module asserts the reset for clock cycle or more and then releases it. After that all your registers are (or should be) in knowns states and your design is ready to do what ever it does.
edit: sorry, the reset is active high, so the tie-0 in for your reset actually makes sure that the clocked process is not reset. Ever. So every time your design starts from unknown state. That would be the red x's you see in the simulation waveform.
signal reset : std_logic := ***'0'***;
In your code the reset is tied to '0' and thus your clocked process is always in reset state.
#Jarno: That's not correct. For a synthesized module for Altera this doesn't matter ... even if there would be a 1 for the reset.
If you synthesize the code you will see that the synthesizer ignores that value. Maybe you even get a warning that the init value is ignored.
[http://quartushelp.altera.com/14.0/mergedProjects/msgs/msgs/wvrfx2_vhdl_warning_initial_value_for_signal_is_ignored.htm][1]
PS: Sorry, I am not allowed to write comments, yet.

Using clock and enable

I was given a code for a D Flip-Flop with enable.
process(clk, en)
begin
if rising_edge(clk) then
if en = ‘1’ then
Q <= D;
end if;
end if;
end process;
I was told that I should not use if rising_edge(clk) and en = ‘1’ then .... Why?
Why isn't the if for the en = '1' before the if for clock since the clock is changing more often?
And is it necessary to specify that en in the process parenthesis process(clk, en)?
Some people believe that the VHDL compilers and synthesizers are not able to figure out that it's the same thing as you've shown here. I've never directly compared the output, but I'd be pretty sad if it mattered.
Changing more often doesn't really matter in hardware. In theory, it shouldn't matter. In practice, the compiler will probably incorrectly warn about your sensitivity list if you changed the order of the conditionals.
It is not.
Here is the answer to all 3 of your questions:
If you're coding sequential logic, it is wise to stick to a template. Here is one such template for sequential logic with no asynchronous reset, which all synthesis tools should understand:
process(clock) -- nothing else should go in the sensitivity list
begin
-- never put anything here
if 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;
So en should not be in the senstivity list and it should not be tested in the same if statement as the clock is tested.
If you think about it, there is another good reason why en should not be in the sensitivity list: the output of a flip-flop with no asyncrhonous reset only changes when the clock changes; it does not change when the D input changes.

Alternative way to implement state machines in VHDL

I have seen many state machines implemented like this one from Altera:
ARCHITECTURE a OF state_machine IS
TYPE STATE_TYPE IS (s0, s1, s2);
SIGNAL state : STATE_TYPE;
BEGIN
PROCESS (clk, reset)
BEGIN
IF reset = '1' THEN
state <= s0;
ELSIF (clk'EVENT AND clk = '1') THEN
CASE state IS
WHEN ...
An alterantive to that would be this:
ARCHITECTURE a OF state_machine IS
TYPE STATE_TYPE IS (s0, s1, s2);
BEGIN
PROCESS (clk, reset)
VARIABLE state : STATE_TYPE := s0;
BEGIN
IF reset = '1' THEN
state <= s0;
ELSIF (clk'EVENT AND clk = '1') THEN
CASE state IS
WHEN ...
What are the pros (if any) and cons of doing it the alternative way? I have only seen the alternative in one place and I'm guessing there must be some good reason for that.
I like to keep local things local, so if the state information is needed only within the process, I use a variable. In that case, I also like to declare the state type inside the process:
ARCHITECTURE a OF state_machine IS
BEGIN
PROCESS (clk, reset)
TYPE STATE_TYPE IS (s0, s1, s2);
VARIABLE state : STATE_TYPE := s0;
BEGIN
...
In the rare cases where I need to access the state of an FSM from another process (e.g. interactive state machines), I'll use a signal for storing the state.
The signal vs. variable decision if often a matter of taste. Some developers think that variables are evil and will never use them. Others (like me) use them whenever they can to keep local things local. As a bonus, since variables are more lightweight objects than signals, they also simulate faster.
Using a variable to hold state would mean you couldn't look at state with a waveform viewer.
There might be some synchronization issues with signal inputs used for branching, delta cycle mismatch in zero time models.
Any state machine outputs derived from state would require signals in any event - every concurrent statement has a process equivalent, a VHDL simulator executes processes, processes communicate via signals.
The only pluses that come to mind is that it would be a more compact model (code size) and execute a bit faster.
I often use a variable called state. It keeps the definition hidden, private to just the process that is using it. If you have 2 communicating state machines in one process, they can both have a variable called state local to themselves. Sometimes that works well. Other times it's confusing!
As with many code-style issues, you have to decide on the most readable way to do things. There's no functional reason not to use variables (of any sort, not just state variables).
One other thing you can do with a variable is read the intended next state at the end of the process, which can be useful when you need to reduce latency of outputs. Again, care is needed as you can create long chains of logic inadvertently which can slow the design down.
Variables are great if you are determining a partial sum or intermediate product that is to be used further down in your process in the same clock cycle. However if a variable is not driven every clock cycle then a latch will be inferred. Since you will want the state to be 'remembered' for the next clock cycle then you will get a latch if you use a variable without an assistant register signal. To clarify...
signal state_sig : state_type;
begin
process(clk, rst)
variable state : state_type := s0;
begin
if rst = '1' then
state_sig <= s0;
elsif rising_edge(clk) then
state := state_sig
case state is
when s0 =>
if blah = '0' then
state := s1;
end if;
....
....
end case;
if state = s1 then state := s2; end if;
state_sig <= state;
end if;
end process;
In the above example you are able to avoid going in the state s1 by modifying the state variable before it gets registered. A quick and dirty way of changing the state machine behaviour. However the state_sig signal must be used to 'remember' the state to avoid latch inferral.

Resources