how many flip-flips would this code produce when synthesized? - verilog

I'm trying to understand how many flip-flips would this code produce when synthesized?
I've got 2 test cases with non-blocking and blocking assignment code.
Test 1.
wire aclk;
wire [1:0] a;
reg [1:0] c;
reg [1:0] b;
always #(posedge aclk)
begin
b <= a + 1;
c = b;
end
Test 2.
wire aclk;
wire [1:0] a;
reg [1:0] c;
reg [1:0] b;
always #(posedge aclk)
begin
b = a + 1;
c <= b;
end
The Test 1 has 4 FFs and Test 2 has 2 FFs.
I can't understand how does it make a difference I just switching the code.
Thanks for letting me know at all.

They are functionally different. Non blocking assignment evaluate the right hand side and then continue to the next statement, storing into the left hand side isn't done until all other statements are evaluated first. Blocking statements evaluate the right hand side and store it into the left hand side immediately.
Test1 is doing this:
evaluate (a+1)
store b into c , BEFORE (a+1) is stored into b!!!
store (a+1) into b
Test2 is doing this:
evaluate (a+1)
store (a+1) into b
store b into c
Like toolic mentioned, you generally used non-blocking statements in sequential logic. Most people also recommend not mixing non-blocking and blocking statements in the same begin-end block.

Related

Verilog - Changing a reg in sensitivity list in Always block

reg A,B,C;
always #(*)begin
//some other computations
C=B;
//some other computations
A=C;
end
always #(posedge clk)begin
B<=A;
end
Hi there,
In the code above, at the posedge of clk reg A changes the value of reg B and that starts the process of first always block since B is in the sensitivity list. My question is what will be happening at the line "C=B" since reg C is also in the sensitivity list? Will that start the process of the first loop again and causes an infinite loop?
I check that on simulation and it works fine. But I don't know want would happen on hardware.
My guess is it will not cause a problem. Since Verilog only creates a LUT to mimic the algorithm inside of the always block, that will not cause a problem on hardware. However, I am not sure so I would like to ask.
Thank you,
Remember that procedural code executes one statement at a time. Your code is effectively interpreted the same as
initial begin
#(B or C) // wait for a change on B or C
C = B;
A = C;
#(B or C) // wait for a change on B or C
C = B;
A = C;
#(B or C) // wait for a change on B or C
C = B;
A = C;
...
end
The assignment to C happens, but any change to C has already happened before you get to the next #. Synthesis interprets C as an intermediate value.

Using wire and assign vs. wire in Verilog

Is there any difference between
wire A = B & C;
and
wire A;
assign A = B & C;
?
I do not think so but I have seen code using the latter and I wonder if that was done for a reason.
They are functionally the same in your example. There are slight differences when adding a delay to a wire declaration.
wire #5 A = B & C;
wire A;
assign #5 A = B & C;
In the first form, the delay gets added to all other net drivers. You can also use SDF back annotation to modify the wire delay.
In the second form, the delay applies to only that continuous assignment, and you cannot use SDF back annotation to modify the delay.
My observation is that most people use the second form in RTL to keep the declarations and functionality separated.

Verilog - re-using register value on always posedge

Consider the following code:
Module Test (B, A, CLK)
Input A, CLK;
Output B;
Reg RA;
Always #(Posedge CLK)
Begin
RA=A;
B=RA;
End
EndModule
Would that work properly to move the input to the register and then to the output on every positive edge? Can it be created with circuits?
It depends what you are trying to do...
If you just want a single flip-flop, the simplest way is to declare reg B; then you can write always #(posedge CLK) B <= A;. There is no need for another signal.
If (for some style reason) you want to separate the flip-flop from the output, you can wire them together with a continuous assignment assign B = RA;. The circuit would be the same.
If you want two flip-flops (2-stage pipeline), your code is almost correct but remember to declare reg B; and use <= for both updates (they can be written in either order).
If RA is some sort of temporary variable for describing your intentions to the tools, then Yes; you can write to it with = and use its value in the same process (do not try to access it from any other process). This is occasionally useful for e.g. accumulating things in loops, but here it would just be confusing and error-prone!
To synthesize real hardware you would typically also have a reset signal and would need to use it in the proper way for each flip-flop.
To answer your question, yes, what you've written (conceptually) will work. In terms of syntax, here's something that will compile and do what you're thinking. Note that I've declared your output B a register and used nonblocking assignments for the registers.
module Test (
input wire CLK,
input wire A,
output reg B
);
reg RA;
always #(posedge CLK) begin
RA <= A;
B <= RA;
end
endmodule

Verilog: Interface Module Input With a Reg

In the following code:
wire a;
reg b;
assign a = b;
ModuleName foo(a, other wire inputs, ... , wire outputs);
Assume that they are part of a top level module.
I wanted to run an always# block but make changes in the input of a module instantiated in this module.
always#(*) b = c^d; //Some Logic
The thing is, they are wires and cannot be on the LHS in an always# block. Can I make changes to band expect to see them in a i.e. the input of the Module foo.
Yes. Every time you change b, a will change too. That is what an assign statement does. Remember this is hardware. The statement
assign a = b;
means 'drive wire a with whatever value reg b has for all time'.

Memory code errors in Verilog

I write Verilog program to simulate memory transfer to Temp , but i got a lot of errors, help please.
wire [64:0] temp,mem [0:256];
wire [15:0] w0, w1, w2, w3;
wire [7:0] block_nr;
integer i ;
for ( i=0; i <3; i = i + 1) begin
temp = mem [i];
data_mem [i] = {block_nr, w0,w1, w2, w3 };
block_nr = block_nr +1;
end
5There are many errors in your code. Here are some:
a) Instead of this:
wire [64:0] temp,mem [0:256];
perhaps you mean this?
wire [64:0] mem [0:256]; // this might be a reg, too, one cannot tell from your code snippet
reg [64:0] temp;
i) I don't think you meant temp to be a 65x257 array as well as mem? And did you mean "64"? Or "63"? Or (see below) "71"? And did you mean "256"? Or "255"?
ii) You cannot assign to a wire from inside a procedural block.
b) This needs to be a reg, too, because (again) you cannot assign to a wire from inside a procedural block.
reg [7:0] block_nr;
c) This code needs to go inside a procedural block, either initial or always. Which depends on your design intent - I cannot tell this from your snippet of code. Let's assume initial:
initial begin
for ( i=0; i <3; i = i + 1) begin
temp = mem [i];
data_mem [i] = {block_nr, w0,w1, w2, w3 }; // what is "data_mem"? Did you mean "mem"?
// if you did mean "mem", did you notice that "{block_nr, w0,w1, w2, w3 }" is 72 bits wide?
block_nr = block_nr +1;
end
end
If this is intended to be synthesised, the you cannot use initial. If you do intend to synthesise this, you are a long way from a working solution.
I must emphasise, however, that these are merely suggestions. It is not possible to completely correct errors in code whose design intent is not known.

Resources