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.
Related
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.
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!
I am trying to make a new design. I design it with two processes which are synchronous and asynchronous. I generally give reset in the asynchronous process which is shown first code snippet. However, someone just told me that is a mistake. In her knowledge, I should give the reset statement in the synchronous process. I also checked the schematic for the first one and saw it is connected correctly to flip-flop's resets.
sync_proc : process(clk_i)
begin
if(rising_edge(clk_i)) then
do smt..
end if;
end process sync_proc;
async_proc : process(some signals)
begin
if(reset_i = '1') then
reset smt..
else
do smt..
end if;
end process sync_proc;
Above is my code and below is what she suggested.
sync_proc : process(clk_i)
begin
if(reset_i = '1') then
reset smt..
else(rising_edge(clk_i)) then
do smt..
end if;
end process sync_proc;
I am wondering that, is there any differences between these states? If so, what are they?
Think of a VHDL process as a little bit of software that models a little bit of hardware. With your approach, you have two little bits of hardware driving the same signal, ie a short circuit. With her (correct) approach, you have one little bit of hardware (a flip-flop) driving one signal.
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.
A lot of the FSMs I see in VHDL work by setting a variable "next_state" in the FSM logic and then assign this seperately to the state variable outside of the process.
If there anything wrong with simply writing "state <= state_five;" to set the next state instead?
I'm presuming there is a reason that so many people use a separate next state variable instead of directly assigning to the state as I see it all the time, but as far as I can tell there is no difference except that it makes the code longer and more complicated looking.
Have I missed something? Or is it just a question of style? And if so why is that style better, it seems unnecessary to me.
"Is there anything wrong with simply writing state <= state_five;?"
Nothing whatsoever - PROVIDED the state assignment is done in a clocked process.
This leads to the neat simple reliable "single process state machine" style, instead of the unreliable (because it's easy to get the sensitivity lists wrong) two-process style that is taught in WAY too many textbooks and online tutorials.
Search for "single process state machine" and you should be able to find good example material and further discussion.
Historical note : there may have been some synthesis tools in the previous century that had problems with the single-process style; but that's no reason to avoid it now.
The reason why some people always write two-process state machines (that is, one synchronous process and one concurrent process) is probably mostly because they learned to do it that way in school, like others have said.
However, in some cases this coding style can actually be better than having a single synchronous process. In short it allows you to mix synchronous and concurrent assignments in the same context. Consider the following two pieces of code, both accomplishing the same thing:
Two-process state machine:
process (clk)
begin
if rising_edge(clk) then
state <= state_next;
end if;
end process;
process (all)
begin
state_next <= state;
case state is
when s_idle =>
if req_i = '1' then
fifo_read <= '1'; -- Concurrent assignment
state_next <= s_check_data; -- "Synchronous" assignment
end if;
when s_check_data =>
if fifo_out = x"1234" then
(...)
end if;
(...)
end case;
end process;
One-process state machine:
process (clk)
begin
if rising_edge(clk) then
case state is
when s_idle =>
if req_i = '1' then
fifo_read <= '1';
state <= s_wait_for_data;
end if;
when s_wait_for_data =>
state <= s_check_data;
when s_check_data =>
-- Data word from FIFO now available.
if fifo_out = x"1234" then
(...)
end if;
(...)
end case;
end if;
end process;
Notice the extra state in the second example. Because there is no way to make concurrent assignments in synchronous processes in VHDL (I wish there was!), a register will be added to the fifo_read signal, delaying it by one cycle. While this example is simple enough, always sticking to one-process state machines can sometimes cause the code to become quite confusing and hard to follow for this reason. It can also cause your state machine to spend more resources in hardware and even make the code longer. Neither style is always the right choice, but I usually prefer the one-process variant.
Or even use a variable:
state := state_five
Using a variable to store the state means that it remains completely local to the process and doesn't pollute the namespace of the whole architecture.
It also means that if you are in the habit of using printf (sorry report) to track the progress of state machines when debugging (which is sometimes preferable to a waveform viewer), you can report the intended next state at the end of the state machine process, which can be handy.
Added:
As noted in the comments, the variable assignment occurs "instantly" (to be clear - this doesn't cause the case statement to immediately switch to the next state though!)
This effect can be used to advantage (occasionally) if you need an output a cycle early - by assigning to said signal based on the next state at the end of the process. If I end up needing to do that I tend to have an explicit next_state variable which I use for everything except the case statement and the state := next_state; (which is right at the end of the clocked process). It demonstrates to the code reviewers that you intended to do it this way!