How to count the number of flip-flops generated or used in the Verilog code without using any tool?
You count the number of bits on the LHS of non-blocking assignments inside an always # (pos/neg_edge ...). (The 'non-blocking' adjective is superfluous as you should only have non-blocking assignments inside an # (pos/neg_edge clock) section.)
The following code produces 12 registers:
reg [7:0] my_byte1,my_byte2;
...
always #(posedge clock)
begin
my_byte1 <= something_which_is_8_bits_wide;
my_byte2[3:0]<= something_else_which_is_4_bits_wide;
end
Related
I am trying to form a T flip-flop in Verilog. I am studying verilog from "Digital System Design with FPGA: Implementation using verilog and vhdl" and the code for T flip-flop is here below:
module t_flip_flop(t,clk,clr,q,qn);
input t,clk,clr;
output reg q,qn;
always #(posedge clk or negedge clr)
begin
if(clr==0)
q<=0;qn<=1;
else
q<=q^t;
qn<=~(q^t);
end
I understand the xor part that we use this because of the toggle operation. I tried to form it without using "clr", but it didn't work. (I am using "clr" as clear input which is for resetting the flip-flop). Can't I do it without using "clr"?
I tried to change code like this below:
module t_flip_flop(t,clk,q,qn);
input t,clk;
output reg q,qn;
always #(posedge clk)
if(t)
begin
q<=q^t;
qn<=~(q^t);
end
But in the simulation, I get "x" for both q and qn in Vivado. I was expecting to get the same results as the code with "clr".
The clr signal is used to properly initialize q and qn.
You declared q as a reg type. In Verilog simulations, reg is initialized to x (the "unknown" value).
Consider your code without clr. At time 0, q=x. Let's say the posedge of clk is at 10ns and t=1 at that time. The assignment:
q<=q^t;
is evaluated like:
q <= x ^ 1;
Verilog evaluates x ^ 1 as x. Since x could be 0 or 1, we don't know if the expression is 1^1 or 0^1, which means that we don't know what the result of the expression should be. This means that q will remain x for the rest of the simulation. There will be no way to change its value.
Using the clr signal fixes that problem. Typically, at the start of simulation (time=0), you would set clr=0 so that q is assigned a known value (0). That prevents the x.
Even if you didn't start with clr=0, as soon as you do set clr=0 at a later time, that will resolve the x.
All of this applies to the qn signal as well.
I have a systemverilog module with a LOT of input signals of varying sizes. I want to optionally register them before use. Here is my desired criteria for the code that does this optional registering:
I should only need to write out the assignments once (no duplicate code)
I should not need to use any macros (I don't want scoping issues)
Here's a minimal reproducible example of my current solution:
module optional_register #(
parameter bit REGISTER_INPUTS=1
)(
input wire clk,
input wire a_in,
input wire b_in,
input wire c_in,
input wire d_in,
output logic a_out,
output logic b_out,
output logic c_out,
output logic d_out
);
function assign_inputs();
a_out <= a_in;
b_out <= b_in;
c_out <= c_in;
d_out <= d_in;
endfunction
generate if (REGISTER_INPUTS) begin
always_ff # (posedge clk)
assign_inputs();
end else begin
always_comb
assign_inputs();
end endgenerate
endmodule
This code synthesizes correctly in Vivado 2020.2 with both the registers on and off. But I am worried that the non-blocking assignments in the function are technically invalid, according to The IEEE Std for Verilog (1364-2001), section "10.3.4 Function rules" which states:
A function shall not have any nonblocking assignments.
So my concern is that this won't work in other synthesizers, and may cause unexpected behavior in simulation. Can anyone speak to this?
Any other ideas?
This is SystemVerilog code, you should be using the IEEE 1800-2017 LRM.
Nonblocking assignments are allowed inside function as long as LHS target is not a variable with an automatic lifetime. Do not use NBA to assign to argument outputs or the return value of a function with a static lifetime because their current values get copied out before the NBA updates happens.
You should declare your function with no return value.
function void assign_inputs();
Using NBAs in combinational logic is not the best for simulation performance, but is usually OK functionality wise.
I understood the basic difference between blocking and non-blocking statements in Verilog. But still it is not possible for me to understand what's happening & when and where to use blocking and non-blocking statements. For example, consider simple d ff code:
module dff (clk, reset,d, q, qb);
input clk;
input reset;
input d;
output q;
output qb;
reg q;
assign qb = ~q;
always #(posedge clk or posedge reset)
begin
if (reset) begin
// Asynchronous reset when reset goes high
q <= 1'b0;
end else begin
// Assign D to Q on positive clock edge
q <= d;
end
end
endmodule
But if I write the very same logic using two-segment coding technique:
module dff(input wire d,
clk,
reset,
en,
output wire q);
reg q;
reg r_reg, r_next;
always #(posedge clk, posedge reset)
if(reset)
r_reg<=1'b0;
else
r_reg<=r_next;
always #*
if(en)
r_reg=d;
else
r_reg=r_next;
assign q<=r_reg;
endmodule
Now, in this code, I just didn't understand why are using <= in the first always block and why they are using = in 2nd always block. I also know that in combinational logic circuit = is advised to use & in sequential <= this is advised to use. But still, I couldn't be able to find out the answer to the usage of blocking and non-blocking statements. Can you please help me!?
Blocking/non-blocking assignments is a simulation artifact only. Contrary to the believe, verilog does not describe hardware. Verilog describes desired behavior of the hardware trying to fit it into an event-driven simulation scheme.
Here is a simple example of a shift register which employs 2 flops:
always #(posedge clk)
out1 = in;
always #(posedge clk)
out2 = out1;
Now, what would the output of the out2 be? Since we are dealing with simulation, then it depends on the order in which these 2 statements are executed. Either it will be the old value of out1, or the new one (actually the value of in);.
In hardware there is no such mess. It will flop the value which existed at the posedge time, the old value of out1 (well, unless there are unusual delays in clocks).
In order to match this behavior, the non-blocking assignment was introduced. Verilog simulation is done in simulation ticks. Every tick is as long as there are events which could cause re-evaluation of other blocks. The non-blocking assignments are scheduled to be executed at the end of such a tick with current rhs values ( in reality there are several scheduling zones). So, consider the following:
always #(posedge clk)
out1 <= in;
always #(posedge clk)
out2 <= out1;
In the above example the all assignments will happen at the end of the tick. 'out2` will be assigned a value which existed at the time of the <=, so, it will be the old value of out1. Now, it does not matter in which order they are executed.
So, the top-level recommendation is to use blocking assignments (=) for combinational logic and use non-blocking assignments (<=) for all outputs of state devices, flops and latches. Note that some temporary variables inside state devices, which are only used there internally should also be assigned with blocking. Also, never use non-blocking assignments in clock trees.
I am trying to make a counter in verilog and I want to know how to split the sequential part from the combinational one.
I have this module, it works fine, but I don't know how to split it?
module counter4bits(
input clk_i,
input rst_n_i,
input enable_i,
input up_down_i,
output reg[3:0] val_o);
always#(posedge clk_i) begin
if (rst_n_i == 1)
val_o <= 0;
else if(enable_i == 1)
val_o <= val_o + 1;
end
endmodule
One way is to make always #(*) blocks for the combinational parts using blocking assignments (=), and make always #(posedge clk_i) blocks for the sequential parts using non-blocking assignments (<=) to simple reg.
The blocking assignment (=) in combinational gives faster simulation and predictable behavior even if explicit sensitivity lists line #(rst_n_i or enable_i or ...) are used instead of #(*). The non-blocking assignment (<=) in sequential logic gives the expected flip-flop behavior where the next value depends on the previous value.
The code will then look like:
module counter4bits(
... input/output with no change
reg [3:0] val_nxt; // Not flip-flop but used in always #(*) thus reg
always #(*) begin
if (rst_n_i == 1)
val_nxt = 0;
else if(enable_i == 1)
val_nxt = val_o + 1;
end
always #(posedge clk_i)
val_o <= val_nxt;
endmodule
Why do you want to split the combinational and sequential logic.
The code you have written is good style for the power optimization.
With your style of code the tool can understand the flip flop value will change on enable_i hence the tools are intelligent enough to put a clock gate for flop using enable_i which will reduce the power.
I have the following code.
module tb;
reg clk;
reg clk_2;
reg [15:0] from_flop;
reg [15:0] to_flop;
initial begin
clk = 0;
clk_2 = 0;
from_flop = 1;
end
always #10 clk = ~clk;
always #(posedge clk) begin
clk_2 <= ~clk_2;
end
always #(posedge clk) begin
from_flop <= from_flop + 1;
end
always #(posedge clk_2) begin
to_flop <= from_flop;
end
endmodule
However, at time instant 10ns, from_flop and to_flop both get value = 2. This is contrary to what I was expecting. I was expecting from_flop to change from 1 to 2 at 10ns, and to_flop to change from x to 1 at 10ns.
Why is this happening and how to code such that this doesn't happen?
Usually assignments in a sequential block are use non-blocking (<=) assignments. The one notable except is for generating derived clocks, which should use blocking (=) assignments. Blocking assignments in sequential blocks are legal; but you need to know what you are doing or you will get a functional mismatch between RTL simulation and circuit. That said, you still needed to error on the side of caution when using this approach.
A flip-flop has has a clock to Q delay, there for any derived clocks will have a phase offset from its parent clock. Some synthesizing tools may compensate the offset for you, however you will need to specify all cases where this should happen to the synthesizer; it will not figure it out for you. This means you should not create derived clocks sporadically across the design. All derived clocking signals need to be generated from one dedicated module; this keeps it manageable.
In most cases you should not create any derived clock. Instead, sample every other clock by adding an extra flip-flop.
always #(posedge clk) begin
from_flop <= from_flop + 1;
if (transfer_n==1'b0) begin
to_flop <= from_flop;
end
transfer_n <= ~transfer_n;
end
This strategy keeps the design in one clock domain which usually makes synthesis easier with better timing. The area impact from the extra flop in minimal can easily be less then the area penalty from the added buffers needed to keep the derived clocks aligned.
The problem is this line:
clk_2 <= ~clk_2;
You are using a non-blocking assignment, when perhaps you wanted a blocking assignment:
clk_2 = ~clk_2;
Non-blocking assignments are scheduled after blocking assignments, so the always #(posedge clk) begin will always be clocked before always #(posedge clk_2) begin.
Obviously, this isn't synthesisable code. So, this is a simulation (scheduling) issue. If you are going to synthesise something with this functionality, consider very carefully how you generate the divided clock.
http://www.edaplayground.com/x/AyQ