Difference between <= and >= in VHDL? - vhdl

Can someone please tell me the difference between <= and >= in VHDL?I know its greater than/less than or equal to sign.Can someone be precise and explain with a code of line how the execution takes place.I know usually for signal assignment we use <= but for example in state machines or whenever we use WHEN >= pops out.Can someone please tell me the difference?

There is a difference writing these in if-statements and elsewhere.
When using these in if-statements a mathematical operation is taking place. As you wrote a comparision is done, checking if value is great-or-equal, smaller-or-equal to the value you compare to.
When writing codes outside of the if-statements this are part of the VHDL syntax and has no mathematical meaning, it is just how the languagre is constructed.
signal_a <= signal_b -- Assign signal B to signal A
-- When something is A then do whats is inside when block
case something is
when A =>
-- Do some stuff
when others =>
-- Do other stuff
end case;

Related

Difference between process and "vanilla" VHDL

I'm practicing VHDL, and I have a fundamental question about "simple" statements which do not require a process.
I would like to know the difference between
c <= a and b;
Where the statement is not inside a process, just written after the architecture begin, and
process(a,b)
begin
c <= a and b;
end process;
Will these results produce the same thing?
Ty :)
Yes, the two descriptions are equivalent.
The concurrent signal assignment c <= a and b is evaluated at each update of any of the argument (a or b), and the process will also evaluate each time any of the arguments in the sensitivity list is updated (a or b).
In the simple example it not required to use a process, but for more complex expressions, the process has the advantage that control structures like if and for can be used, which is not directly possible in a concurrent signal assignment. Also, for sequential logic a process is required.
You can think of any VHDL one liner as an implied process with the arguments on the RHS of <= in the sensitivity list.
This is why both of the code snippets you wrote are practically equivalent.

VHDL block and guarded input - what does this code do?

I have the following from a beginner's VHDL tutorial:
rising_edge: block(clk’event and clk = ‘1’)
begin
result <= guarded input or force after 10ns;
end block rising_edge
The explanatory text is
"Essentially I have a block called rising_edge, and it's a block with a guard condition which does the following, it checks that we have an event on the clock, and that the clock is equal to one, so we're effectively looking for the so called rising_edge. We're looking for the event where the clock goes from 0 to 1, and if it does, then we can conditionally assign the results, so you'll see that the result variable here says that it is a guarded input or force after 10 ns might seem a bit confusing, but consider it without the guarded keyword. All we're doing is we're assigning the result of the evaluation of input or force, and we're doing it in a guarded setup. So, in this case, the assignment of the signal result is only executed if the guard signal is actually true, and in our example it means that the assignment of the expression, which is input or force, will only happen on the rising_edge of the clock because that's on guard condition."
Now I've read this over and over and searched on the net but have come up blanks as to what this is actually doing. Can someone please gently explain its purpose?
A block is essentially a grouping of concurrent statements. In terms of practical usage, it is very similar to a process, only it has a limited scope wich allows component-style signal mapping(with port and port map). It can be used to improve readability(see this question) and really not much else. Blocks are resonably rarely used and frequently not synthesis supported(see here). To my (limited) knowledge, the use of blocks has no other advantage than readability.
Because your block statement contains a guard condition(clk'event and clk='1' is the guard condition here), it is a guarded block. Inside a guarded block, signals that are declared guarded (like in your example) will only be assigned if the guard condition evaluates to true
The entire statement that has been guarded(i.e. in your case input or force after 10ns) will only be executed when the guard condition evaluates to true, i.e. on the rising edge of clk. Thus, for all intents and purposes this block has the same behaviour as
process(clk)
begin
if clk'event and clk = '1' then
result <= input or force after 10ns;
end if;
end process;
I will say though, this is a terrible example. For one thing, as others have stated, the usage of block is very rare and they are generally only used in quite advanced designs. The usage of clk'event and clk = '1' has been discouraged since 1993(see here). It should also be mentioned again that the usage of rising_edge as a label is a terrible idea, as is the use of force for a signal name(in VHDL 2008, force is a reserved keyword that can be used to force a signal to a value).
Working from the idea that this is supposed to be a beginners tutorial, and with the lack of any explanation as to why such an unusual style has been used, a much more conventional implementation would be:
process : (clk)
begin
if (rising_edge(clk)) then
result <= input or force after 10 ns;
end if;
end process;
A couple of points to note:
This assumes that input and force are either signals, or inputs to the entity.
It is unusual to model signal assignment delays if your code is going to be implemented in a real hardware device.
The code in your question uses after 10ns;, which is not valid; you need a space between the value and the units (as in my code).
The code in your question uses rising_edge as an identifier, when this is actually already defined as a function, assuming you are including standard IEEE libraries newer than I believe VHDL93.
The code in your question uses force as a signal name, when this is also a reserved language keyword since VHDL2008.
My advice to you is to find a different tutorial. The quote you posted is not clearly written, and the code you posted appears to be sending you down a strange path. All I can think is that the tutorial is in fact very, very old.

Is it necessary to seperate combinational logic from sequential logic while coding in VHDL, while aiming for synthesis?

I am working on projects which requires synthesis of my RTL codes specifically for ASIC development. Given the case, how much important is it, to separate sequential logic from differential logic while designing my RTLs ? And if it is important, then what should be my approach while designing, as if how should I differentiate my design for sequential and combinational logic?
I generally will separate sequential and combinational as much as possible until it results in too much code (which is usually rare, and possibly an indication of a poor design), or when something just makes more sense (which again is rare, but happens).
This segregation usually aids in initial design, brain->rtl->synthesis (what you think you're making is actually what is synthesized), CDC evaluation for multiclock designs, verification, and other things as well. It's hard for me to give a great example of something bad versus something I would call good, but here is a stab at it.
Say I have a counter that I want to reset on a certain value. I could do this (which I tend to see from people who have a strong software and/or FPGA background)
always #(posedge clk or posedge reset) begin
if(reset) begin
count <= 0;
end else begin
if((count == reset_count_val) || (~enable)) count <= 0;
else count <= count + 1;
end
end
Or I would do this (which is what I would personally do):
//Combinational Path
assign count_in = enable ? ((count == reset_count_val) ? 4'd0 : count_in + 4'd1) : 4'd0;
//Sequential Path
always #(posedge clk or posedge reset) begin
if(reset) count <= 4'd0;
else count <= count_in;
end
The above I would agree is more typing, and to some, more difficult to read. It does however split up the circuit in a way that allows me to easier see what happens on each clock edge. I know that "count_in" is being setup prior to the posedge of clk. I can easily see (as well as anyone else looking at the code) that I would expect a MUX for the reset or addition of count based on the reset_count_val, with a final MUX for gating the count based on the enable signal. Now you could see the same with the first bit of code, however IMO it's not as clear. When you look at a sim, you can see what count_in looks like prior to the rising edge of the clk. This could aid you if the conditional statement for the count_in was rather complex.
Let's say you sent this through synthesis and place and route and you get a timing violation between the Q of the count reg and the D of the count reg (since you have a loopback based on the addition). It would generally be easier to see which path is causing the issue with the 2nd batch of code. This depends on the tool (Primetime more than likely). CDC could also be easier because let's say that reset_count_val is coming from a static registers in another clock domain. The tool may try to synthesize/elaborate the OR in the 1st batch of code thinking the reset_count_val and enable are somewhat related giving you a weird looking CDC violation. Again, sometimes it's hard to come up with an example that exercises all of the "why you shouldn't do this" type of cases.
As an example about splitting combinational and sequential, I inherited a design where someone had a state machine that was written with the combiational and sequential in the same block (always #(posedge clk) where the if/else's would get deep and have next state logic in it). I'm no genius, but after days of staring at that thing and running sims, I could just not figure out what it was doing. It was quite large as well. I simply redid the design, keeping the same algorithm, but splitting up the logic in the format I described here. Even with me adding some features, the size went down ~15%. Other engineers who had the same problem of being lost with the other design, could now understand what was going on with it. This won't always be the case, but more than often it is.
TLDR;
I try to be extremely descriptive when designing RTL that is to be used in an ASIC. The more abstract the code, the more likely it is to build something you don't want, or is more complex than needed. Verification is often much easier, particularly when you get to gate sims. While I am in the camp of "the less code the better" that is not always the case with verilog, especially on an ASIC.
In general, I would not hesitate to mix combinational with sequential logic. I come from an IC design background and have always mixed up combinational logic with sequential. I think that you are restricting yourself too much if you don't and are not fully using the power of your logic synthesiser.
For example, here is how I would design a simple, asynchronously-reset counter in VHDL:
process (Clock, Reset)
begin
if Reset = '1' then
Cnt <= (others => '0');
elsif Rising_edge(Clock) then
if Enable = '1' then
Cnt <= Cnt + 1;
end if;
end if;
end process;
This style of writing a counter in VHDL is ubiquitous. I personally can see no advantage to splitting the code up into two separate processes, one sequential the other combinational. I have just taught a room full of engineers to design a counter in exactly this way.
Here are some exceptions. I would split the combinational logic from the sequential logic if:
i) I were designing a state machine:
There is what I think is a really elegant way of coding a state machine, where you do split the combinational logic from the sequential:
Registers: process (Clock, Reset)
begin
if Reset = '1' then
State <= Idle;
elsif Rising_edge(Clock) then
State <= NextState;
end if;
end process Registers;
Combinational: process (State, Inputs)
begin
NextState <= State;
Output1 <= '0';
Output2 <= '0';
-- etc
case State is
when Idle =>
if Inputs(1) = '1' then
NextState <= State2;
end if;
when State2=>
Output1 <= '1';
if Inputs = "00" then
NextState <= State3;
end if;
-- etc
end case;
end process Combinational;
The advantage of coding a state machine like this is that the combinational process looks very like the state diagram. It is less error prone to write, less error prone to modify and less error prone to read.
ii) The combinational logic were complex:
For really big block of combinational logic, I would separate. The exact definition of "really big" is a matter of judgement.
iii) The combinational logic were on the Q output of a flip-flop:
Any signal driven in a sequential process infers a flip-flop. Therefore, if you wish to implement combinational logic that drives an output of an entity* then this combinational logic must be in a separate process.
*often not a good idea - be careful.
I would post it as comment if I could, as I am not writing full answer, but giving you a source, and also I don't fully refere to the question (I don't know anything about ASICs). But there is great pdf about this problem in general here. Generally, you don't have to completely separate sequential logic from differential logic, but it is helpful to write more readable and maintainable code.
Mixing sequential and combo condenses the code which almost always makes it easier to understand.
Separating makes ECOs easier.
Which you choose is a matter of personal style and organizational coding conventions and standards.

VHDL state machine differences (for synthesization)

I am taking a class on embedded system design and one of my class mates, that has taken another course, claims that the lecturer of the other course would not let them implement state machines like this:
architecture behavioral of sm is
type state_t is (s1, s2, s3);
signal state : state_t;
begin
oneproc: process(Rst, Clk)
begin
if (Rst = '1') then
-- Reset
elsif (rising_edge(Clk)) then
case state is
when s1 =>
if (input = '1') then
state <= s2;
else
state <= s1;
end if;
...
...
...
end case;
end if;
end process;
end architecture;
But instead they had to do like this:
architecture behavioral of sm is
type state_t is (s1, s2, s3);
signal state, next_state : state_t;
begin
syncproc: process(Rst, Clk)
begin
if (Rst = '1') then
--Reset
elsif (rising_edge(Clk)) then
state <= next_state;
end if;
end process;
combproc: process(state)
begin
case state is
when s1 =>
if (input = '1') then
next_state <= s2;
else
next_state <= s1;
end if;
...
...
...
end case;
end process;
end architecture;
To me, who is very inexperienced, the first method looks more fool proof since everything is clocked and there is less (no?) risk of introducing latches.
My class mate can't give me any reason for why his lecturer would not let them use the other way of implementing it so I'm trying to find the pros and cons of each.
Is any of them prefered in industry? Why would I want to avoid one or the other?
The single process form is simpler and shorter. This alone reduces the chance that it contains errors.
However the fact that it also eliminates the "incomplete sensitivity list" problem that plagues the other's combinational process should make it the clear winner regardless of any other considerations.
And yet there are so many texts and tutorials advising the reverse, without properly justifying that advice or (in at least one case I can't find atm) introducing a silly mistake into the single process form and rejecting the entire idea on the grounds of that mistake.
The only thing (AFAIK) the single-process form doesn't do well is un-clocked outputs. These are (IMO) poor practice anyway as they can be races at the best of times, and could be handled by a separate combinational process for that output only if you really had to.
I'm guessing there was originally some practical reason behind it; maybe a mid-1990s synthesis tool that couldn't reliably handle the single process form, and that made it into the original documentation that the lecturers learned from. Like those blasted non-standard std_logic_arith libraries. And so the myth has been perpetuated...
Those same lecturers would probably have a fit if they saw what can pass through a modern synthesis tool : integers, enumerations, record types, loops, functions and procedures updating signals (Xilinx ISE is now fine with these. Some versions of Synplicity have trouble with functions, but accept an identical procedure with an Out parameter).
One other comment : I prefer if Rst = '1' then over if (Rst = '1') then. It looks less like line noise (or C).
I agree with Brian on this. The only issue with the one process state machine is you cannot have un-clocked outputs, which is an issue if you need 0 latency on input to output. Otherwise the one process model helps to minimize bugs as it clearly relates the outputs to the state.
I was taught the two process model in school, but have discovered that the one process model is what is generally accepted in industry. I believe the reasoning for using the two process model in school is it gives students an understanding of how the placement of combinational logic relative to registers changes based on how the code is written (which IMO is very important when starting out) and what it means for their design. However simply forcing you to use the two process model with no explanation does not accomplish this.
the first method looks more fool proof since everything is clocked and there is less (no?) risk of introducing latches.
Yes, the first method where everything is clocked has no chance of introducing latches. It may introduce flipflops, but that's fine.
The 2nd method can introduce true asynchronous latches, which even in the best case are not very well handled by the back end FPGA tools I've used, and are not supported at all in some architectures, so would have to be built out of gates or lookup-tables.
In addition, if you get your sensitivity list wrong in the second process, your simulation can differ from your synthesis result! This is because synthesisers (for reasons I've given up trying to understand) treat the sensitivity list as if it were populated with all the signals you read (completely ignoring the VHDL language spec in the process) whereas the simulator will do exactly what you said.
Ugh. I hate the dual process state machine thing personally. He is probably an old guy and this was the most reliable way to do it 20 years ago. The tools understand your way and I personally like that approach better.
Your classmate is absolutely right. The problem here is that your question is not complete. The reason for your colleague's code to be better than yours is that people normally define the output values and the next state values in the same process, as shown below (this is the same as your own code, just with the output values added to it, which results in a "bad"code):
elsif (rising_edge(clk)) then
case state is
when s1 =>
--define outputs:
outp1 <= ...;
outp2 <= ...;
...
--define next state:
if (input = '1') then
state <= s2;
else
state <= s1;
end if;
when s2 =>
...
...
end case;
end if;
Recall that in an FSM the output is produced by the combinational logic section, therefore it is memoryless. However, in the code above, the output values get registered, which is not what the FSM must produce. Indeed, registering the outputs is a case-by-case decision EXTERNAL to the FSM (the outputs could be registered, for example, for glitch removal, which is a PARTICULAR, PLANNED decision, not a FORCED situation, as in the code above).

Behavioural logic sequential, code cannot work?

Basically I have the following code in my module. I want to change a number to it's 2's complement negative.
Eg. 100 becomes -100, and -200 becomes 200.
A shortcut I found is to read from the LSB until you reach a '1', then flip all the bits after it. I'm trying a implement a 32 bit converter using the least performance tradeoff (I heard num <= not(num) + 1 is quite resource heavy)
flipBit <= '0'; -- reset the flip bit
FOR i IN 0 TO 31 LOOP
IF flipBit = '1' THEN
tempSubtract(i) <= not Operand2(i);
ELSE
tempSubtract(i) <= Operand2(i);
END IF;
IF Operand2(i) = '1' THEN
flipBit <= '1';
END IF;
END LOOP;
However, all it does it to NOT the entire thing. Also, when I do num <= not(num)+1, the slow way, it gives me gibberish numbers too.
Can anyone tell me what's wrong? Thanks.
This is something the synthesis tool can probably do better than you, so I would recommend to simply use z <= -a;, where a and z are of type signed.
This will cause synthesis to optimize the negation for your target architecture, no matter what it is. For example, calculating not + 1 in an FPGA is very efficient.
You could just do: signal <= signal * -1 and the tools would synthesize it for you. That might not be the most efficient though. I don't think it would take up THAT much logic though. If you really need a more efficient solution you can do this:
Is there any reason you need to do this conversion you show above in 1 clock cycle? If you took 32 clocks to do it it would be easier and probably less resources. I would recommend that you remove your FOR loop, as it is causing most of the problems you are having.

Resources