FSM: next state precedence - verilog

When being in a state "a1" how can I show that the next arrows will have a precedence over each other, without having an overhead of extra states?
Full example:
We are at a1 state and signals x && y are asserted: we go to state b1
If that condition is not asserted but x && z is asserted then we go to state b2
If the above conditions are not asserted but x is asserted then we go to state b3
Visual concept:
In the above "FSM" we can't see that x && y is checked before the other two.
Code snippet:
always_comb begin
case (states)
a1: begin
if (x && y)
next_state = b1;
else if (x && z)
next_state = b2;
else if (x)
next_state = b3;
else
next_state = a1;
end
endcase
end

Since you tagged the question with SystemVerilog, I just wanted to mention an alternative way of describing your next state logic:
always_comb begin
case (states)
a1:
priority casez ({x,y,z})
3'b11?: next_state = b1; // x && y
3'b1?1: next_state = b2; // x && z
3'b1??: next_state = b3; // x
default: next_state = a1;
endcase
endcase
end
Also, the commonly used state diagram does not specify priority, so you need to completely specify the transition conditions as in xbug's answer. But I don't see why you can't extend this notation, for example, mark each arc with labels 1, 2, 3, and 4, where lower numbers indicate higher priority.

Ideally, you'd need to cover all the possible combinations of input events in each state to get a proper DFA (deterministic FSM).
However, you can get away by fully specifying the triggers in terms of input signals, and let your HDL default to "no transition". In that case:
transition from a1 to b1 may be triggered by x && y && !z
transition from a1 to b2 may be triggered by x && !y && z
transition from a1 to b3 may be triggered by x && !y && !z
(with ! denoting logical 'not').
With an alphabet of 3 symbols (your three input signals), you get 2^3 = 8 possible combinations in every state. Ask yourself: in your current design, what happens if all of x, y and z get asserted ? You need to be specific about that.
EDIT
Let me be more specific.
Let's consider A, B, C, ... H as events, each representing one possible combination of input signals, such as:
x y z
A 0 0 0
B 0 0 1
C 0 1 0
D 0 1 1
E 1 0 0
F 1 0 1
G 1 1 0
H 1 1 1
Then try to express your transitions in terms of A, B, C, ... H. If you can, the resulting FSM is suitable to your task. If you can't, you should probably rethink your logic.

Related

How to sample covergroup at the occurence of a certain sequence?

module testbench;
bit [2:0] A;
bit [2:0] data[];
int i;
bit [2:0] b;
covergroup cov_grp;
c1 : coverpoint A {
bins b1 = {0,1,2};
bins b2 = {3,4,5};
bins b3 = {6,7};}
endgroup
sequence seq;
(b == 'd7);
endsequence
initial
begin
cov_grp cov_ins = new();
data = new[10];
for(i=0;i<8;i++)
begin
data[i] = $random;
A = data[i];
assert property #(seq) cov_ins.sample();
end
end
endmodule
I want to sample for the covergroup instance cov_ins when sequence seq occurs.
When b = 'd7 it should sample
...............................................................................................................................................................................................................................................................................................................
Just as your covergroup needs an event to trigger sampling, a sequence needs an event to know when to sample and evaluate the expression b = 'd7 (BTW, your testbench never sets b).
And it's not clear from your testcase why you even need to be using a sequence that is a simple Boolean expression. You could just write:
if (b == 'd7) cov_ins.sample();
But assuming your sequence is more complex, then you need a clock in your sequence and need to write something like
sequence seq;
#(posedge clk) (b == 'd7)[->1]; // when b transitions to 'b7
endsequence
covergroup cov_grp #seq; // instead of calling sample()
c1 : coverpoint A {
bins b1 = {0,1,2};
bins b2 = {3,4,5};
bins b3 = {6,7};}
endgroup

How can I assign a "don't care" value to an output in a combinational module in Verilog

Imagine we want to describe a combinational circuit that satisfy the following truth table:
a b | s0 s1 s2 s3
-----------------
0 0 | 1 d d d
0 1 | 0 1 d d
1 0 | 0 0 1 d
1 1 | 0 0 0 1
(where d stands for "don't care" value, that is, we don't care if the value of this output is 0 or 1)
If we go through traditional design, we can take advantage of these "don't cares" and assign to them the most convenient values so the resulting equations (and hence, the circuit) are the most simple ones. For example, we could change the previous truth table into this one:
a b | s0 s1 s2 s3
-----------------
0 0 | 1 1 1 1
0 1 | 0 1 0 1
1 0 | 0 0 1 1
1 1 | 0 0 0 1
And the final equations would be (using Verilog notation):
s0 = ~a & ~b;
s1 = ~a;
s2 = ~b;
s3 = 1;
(remember when you had to choose values for your outputs in a K-map so you would group as much cells as you can)
But what if I choose to design it using Verilog? I cannot do this:
module encoder (
input wire a,
input wire b,
output reg [3:0] s
);
always #* begin
case ({a,b})
2'b00 : s = 4'b1ddd;
2'b01 : s = 4'b01dd;
2'b10 : s = 4'b001d;
2'b11 : s = 4'b0001;
default: s = 4'bdddd;
endcase
end
endmodule
I was told at How to assign default values to outputs in a combinational always block... that I couldn't use x as an output either, only as input. And if I use z, the resulting circuit is even worse in terms of complexity and resources used, as tristate buffers are needed.
So I'm forced to choose at design time which values (1 or 0) I want to output, and these values don't have to yield the most optimized circuit:
module encoder (
input wire a,
input wire b,
output reg [3:0] s
);
always #* begin
case ({a,b})
2'b00 : s = 4'b1000;
2'b01 : s = 4'b0100;
2'b10 : s = 4'b0010;
2'b11 : s = 4'b0001;
default: s = 4'b0000;
endcase
end
endmodule
Which leads to these equations (ignoring the default clause for the moment):
s0 = ~a & ~b;
s1 = ~a & b;
s2 = a & ~b;
s3 = a & b;
Or this implementation (taken from the output of YOSIS 0.3.0 at EdaPlayGround):
Which may or may not be the best solution for a given target, but it is what we allow the synthesizer to infer given the outputs we want.
Using the XST synthesizer targetting a Spartan 3E-100k FPGA, the above module uses 2 slices and 4 LUTs.
I assume that Verilog (or any other HDL) should free the designer from having to do such choices, so the synthesizer can apply whatever optimizations are available if the designer allows it to choose the most convenient value for a given output and for a given set of inputs. If that would be the case, then the previous design could have been optimized to look like this:
Targetting the same FPGA as above, it uses 2 slices and 3 LUTs.
For this example, I've been able to make optimizations by hand, but consider a controller module with dozen of outputs to a datapath module. There could be output signals from the controller that may have a don't care value for a given state of the controller.
For example: controller outputs a signal to select from register A or register B, and another signal to enable load of register C, so register C can be loaded with either A or B, or keep its current value.
If load is 0, I don't really care about the value of select, so everytime in the controller description I output load = 0, I should be able to output a "don't care" to select.
So my questions are:
Is there any way to write a Verilog (not SystemVerilog) description so I can give "don't care values" to outputs from combinational blocks?
If not, is this a limitation in the language, or is it much a matter of "you should make your designs so 'don't care' values are not needed"?
ADDENDUM
To my surprise, XST recognizes `x` as a valid output. It's synthesizable and seems to behave the way I expected, resulting in the same circuit to be implemented with 2 slices and 3 LUTs. YOSIS, on the other way, seems to ignore it and produces the same output as the non optimized design.
Rectification: I've tested XST with another design: a circuit that produces this truth table:
a b | s0 s1 s2 s3
-----------------
0 0 | 0 d d d
0 1 | 1 0 d d
1 0 | 1 1 0 d
1 1 | 1 1 1 0
The corresponding Verilog module, written without don't cares, could be written in a number of ways, for example, this one:
module encoder (
input wire a,
input wire b,
output reg [3:0] s
);
always #* begin
case ({a,b})
2'b00 : s = 4'b0111;
2'b01 : s = 4'b1011;
2'b10 : s = 4'b1101;
2'b11 : s = 4'b1110;
default: s = 4'b1111;
endcase
end
endmodule
Which produces the worst result, in terms of minimization (2 slices, 4 LUTs in a Spartan 3E FPGA)
An optimized by hand version can be obtained by starting from this truth table:
a b | s0 s1 s2 s3
-----------------
0 0 | 0 0 0 0
0 1 | 1 0 1 0
1 0 | 1 1 0 0
1 1 | 1 1 1 0
It's easy to observe here that 3 from 4 outputs can be obtained without a single logic gate. Thus, XST reports 1 slice, 1 LUT (the only one needed to calculate s0)
module encoder (
input wire a,
input wire b,
output reg [3:0] s
);
always #* begin
case ({a,b})
2'b00 : s = 4'b0000;
2'b01 : s = 4'b1010;
2'b10 : s = 4'b1100;
2'b11 : s = 4'b1110;
default: s = 4'b1110; // yes, same output as above
endcase
end
endmodule
If use the dirty trick of using x as a "don't care":
module encoder (
input wire a,
input wire b,
output reg [3:0] s
);
always #* begin
case ({a,b})
2'b00 : s = 4'b0xxx;
2'b01 : s = 4'b10xx;
2'b10 : s = 4'b110x;
2'b11 : s = 4'b1110;
default: s = 4'bxxxx;
endcase
end
endmodule
The design synthesizes, but the result is not minimal. XST reports 1 slice, 2 LUTs.
The paper #Tim links in his comment is very clear about this matter: avoid using x in your designs. But according to this example, the language does not allow us to help the synthesizer to minimize a circuit.
Saving one or two LUTs may not be a great deal, but if the savings allow this module to stay within a slice, the P&R will have less work to place it wherever it wants.
When I use Quartus II ver 15.0, assiging "don't care" to output is OK and generated area-efficient circuit.
For example, if I synthesize this code, that :
module test1 (
input wire a,
input wire b,
output reg [3:0] s
);
always #* begin
case ({a,b})
2'b00 : s = 4'b1000;
2'b01 : s = 4'b0100;
2'b10 : s = 4'b0010;
2'b11 : s = 4'b0001;
default: s = 4'b0000;
endcase
end
endmodule
Quartus generated a circuit which uses 5 Logic Elements.
However, If I use "don't care" assignment in the code above:
module test1 (
input wire a,
input wire b,
output reg [3:0] s
);
always #* begin
case ({a,b})
2'b00 : s = 4'b1xxx;
2'b01 : s = 4'b01xx;
2'b10 : s = 4'b001x;
2'b11 : s = 4'b0001;
default: s = 4'b0000;
endcase
end
endmodule
a circuit which uses only 2 Logic Elements is generated. It's interesting that although the total logic elements are less used, the generated circuit seems to be more complex.
I was wondering whether the generated circuit is correct. So I ran Quartus's simulator with the circuit which uses "don't care". The result is the simplest circuit we want.
I would think that supplying x to an output would do the trick -- "unknown" should do exactly what you want. I believe you can wire it directly as an output, but if that's forbidden, you could generate it by wiring both 1 and 0 to the output.

Verilog Muliple if else not working as expected

I am using three buttons on the Altera DE0 Board.
I declare it as
input [2:0] Button;
reg [2:0] y;
parameter [2:0] S0 = 3'b000, S1 = 3'b001, S2 = 3'b010, S3 = 3'b011, S4 = 3'b100, S5 = 3'b101;
I have a nested if-else statement based on the values of the three buttons
always#(negedge (&Button))
//if(&Button == 0)
begin
if(Button == 3'b011) // Button 2 is pressed
begin
if(y == S0)
begin
y = S1;
end
end
else if(Button == 3'b101) // Button 1 is pressed
begin
if (y == S1)
begin
y = S2;
end
else if (y == S2)
begin
y = S3;
end
end
else if(Button == 3'b110) //This is the check on button 0, but this conditional statement does not work.
begin
if(y == S2)
begin
y = S3;
end
end
end
assign z = (y == S0); // z,z1,z2,z3 are LED's on the board
assign z1 = (y == S1);
assign z2 = (y == S2);
assign z3 = (y == S3);
When I use the first two buttons of the if-else statement (button == 3'b011 and button == 3'b101) labeled BUTTON2 and BUTTON1 on the DE0 board, the code works and y changes to the proper value as expected.
But when I try the third button in the if-else, Button == 3'b011, labeled BUTTON0 on the DE0, nothing happens, y does not get the expected value. I used 2 different DE0 boards and the same issue arises.
I think it has something to do with the
always#(negedge (&button))
in that the third button press is just not being detected. But when I use code like
always#(negedge button[0] or negedge button[1] or negedge button[2])
other issues arise that I haven't been able to resolve.
You need to think about what hardware you are trying to model. always #(negedge or more generally edge triggered always blocks, are used to imply flip-flops which are generally driven by a clock and reset.
Data signals can be used as clocks as you would in a Frequency Divider. However your use of a unary & a combinatorial reduction operator will result in a glitchy clock in real hardware.
I mentioned thinking about what hardware you are implying because you have this construct:
always#(negedge button[0] or negedge button[1] or negedge button[2])
Which has no equivalent in hardware.
You may find this Altera FSM example helpful. You likely what to implement edge detection from this question so you only change state once per button press.

Using '<=' operator in verilog

Can any one explain me the reason why this particular module doesn'twork when we use '<=' instead of '='
module TestCell(x0, x1, y0, y1, z);
input x0, x1, y0, y1;
output z;
reg z;
reg a1, a2, a3, a4;
always #(x0 or x1 or y0 or y1) begin
a1 <= ~(x0 & y1);
a2 <= ~(y0 & x1);
a3 <= ~(a2 | a1);
a4 <= a2 & a1;
z <= ~(a4 | a3);
end
endmodule
And what we should ensure in order to use '<=' in verilog.
As Cthulhu has said = is blocking, That implies the statement will be evaluated before moving on to the next line of code.
always #* begin
a = b & c;
d = e & f;
g = a & d ;
end
The above example is the same as :
always #* begin
g = b & c & e & f;
end
However if we switch to using <= Then they are no longer the same in simulation, the g will be the OLD a AND OLD b. Since this is a combinatorial block, ie not regularly triggered or evaluated like a flip-flop, you will get odd results from simulation.
Correct use of the <= non-blocking assignment is in implying flip-flop.
always #(posedge clk or negedge rst_n) begin
if (!rst_n) begin
a <= 1'b0;
d <= 1'b0;
g <= 1'b0;
end
else begin
a <= b & c;
d <= e & f;
g <= a & d ;
end
end
In the Flip-Flop example above g takes the value of a and d from last clk cycle not the current evaluation.
In your example you have used always #(sensitivity list), that is a combinatorial circuit and = would be the correct usage. I would also recommend switching to always #* if your simulator allows it. The * is a wildcard and removes the need for manually entering the sensitivity list.
I think that is is worth remembering that synthesis tools will base their results on the statement following the always # If it is edge based they will use a type of flip-flop if it is combinatorial they will place combinatorial logic. The use of = or <= only has an effect in simulation. Using the wrong type means your simulation will not match the synthesised hardware.
In the case of combinational logic there is "=" for assignment, and for the sequential block we have the "<=" operator.
"=" is blocking assignment and "<=" is nonblocking assignment.
"=" executes code sequentially inside a begin / end, whereas nonblocking "<=" executes in parallel.
More

Size of arithmetic operation result in Verilog

I am making a signed comparator in Verilog. Here is the code:
module signedComparator(a0, a1, a2, b0, b1, b2, G, E, L);
input a0, a1, a2, b0, b1, b2;
output reg G, E, L;
always#(a0 or a1 or a2 or b0 or b1 or b2)
begin
if(a2 == 0 && b2 == 0) //both a and b >= 0
begin
L <= {a1,a0} < {b1,b0};
G <= {a1,a0} > {b1,b0};
E <= {a1,a0} == {b1,b0};
end
else if(a2 == 1 && b2 == 0) //a negative, b >= 0
begin
L <= 1;
G <= 0;
E <= 0;
end
else if(a2 == 0 && b2 == 1) //a >= 0, b negative
begin
L <= 0;
G <= 1;
E <= 0;
end
else //both a and b negative
begin
L <= (~{a1,a0} + 1) > (~{b1,b0} + 1);
G <= (~{a1,a0} + 1) < (~{b1,b0} + 1);
E <= (~{a1,a0} + 1) == (~{b1,b0} + 1);
end
end
endmodule
I am wondering, when adding vectors, what is the length of the intermediate result? I am concerned about the last case (L <= (~{a1,a0} + 1) > (~{b1,b0} + 1);). When adding 1 to ~{a1,a0}, is the result three bits in length for the comparison, or will {1,1} + 1 = {0,0}? Is there documentation somewhere for what the data type of intermediate results in verilog will be? This is hard to search for since I don't yet know the proper terminology.
I'm assuming this is for synthesis and have a few comments about your code. You seem to be using individual bits as inputs to the module and then using concatenation to make vectors later on. You can avoid this by declaring ports as signed vectors and doing a comparison directly.
input signed [2:0] a,b;
...
if(a == b)
...
else if(a > b)
...
else
...
Also, you are using non-blocking assignments to model combinational logic. These will work in the code you posted but really shouldn't be used in this manner. They work much better modeling synchronous logic via a clocked process. There's a good paper that summarizes a good coding style for synthesis.
I am wondering, when adding vectors, what is the length of the intermediate result?
The spec has a table for this as it depends on the operands and context.
An integer : Unsized constants are at least 32-bits
{a,b} : sizeof(a) + sizeof(b)
~{a} : sizeof(a)
a + b : max(sizeof(a),sizeof(b))
Thus your comparison operands will both be (at least) 32-bits. You can explicitly assign a constant size by using a tick before the value.
4'b1 // 0001 Binary 1
4'd1 // 0001 Decimal 1
4'd8 // 1000 Decimal 8
1'b1 // 1 Binary 1
'b1 // The same as 1, tick here only specifies dec/oct/bin format
Is there documentation somewhere for what the data type of
intermediate results in verilog will be?
By far the best resource I've found for details like this is the spec itself, IEEE 1364.

Resources