How to split the sequential and the combinational in verilog - verilog

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.

Related

How to understand the blocking and non blocking statements in verilog?

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.

generate inside generate verilog + error near generate(veri - 1137)

Writing verilog code from quite a few days and one question I have is 'Can we write generate block inside generate block'? I am writing an RTL something like this:
Where 'n' is a parameter.
reg [DATA_WIDTH:0] flops [n-1:0];
generate
if (n > 0) begin
always #(posedge clk) begin
if (en) begin
flops[0] <= mem[addr];
end
end
generate
genvar i;
for (i = 1; i <= n ; i = i + 1) begin
always #(posedge clk) begin
flops[i] <= flops[i-1];
end
end
endgenerate
always #(flops[n - 1])
douta = flops[n - 1];
else
always #(posedge clk) begin
if (en) begin
primary_output = mem[addr];
end
end
end
endgenerate
While compiling the above code, I am getting :
ERROR: syntax error near generate (VERI-1137)
Not sure why. Purpose of this RTL is to create an pipeline of 'n' flops at the output side of the design.
Lets say n is 2, then circuit should become :
flop1-> flop2-> primary output of design
flop1 and flop2 are newly created flops.
You are a long long way from where you should be.
Verilog is not a programming language; it is a hardware description language. You model hardware as a network of concurrent processes. Each process models a small bit of hardware such as a counter, a state machine, a shift-register, some combinational logic... In Verilog, each process is coded as an always block. So, one always statement never ever can appear inside another; that makes no sense.
Secondly, generate is quite a specialised statement. You use it when you want either a large number or a variable number of concurrent processes. That is not a common thing to need, so generate is not common, but is useful when required. You don't need a generate statement to implement a parameterisable shift-register. And, because an always block is a concurrent statement it sits inside a generate statement, not the other way round.
I don't know what your design intent is exactly, to I suspect this code does not do exactly what you want. However, it does implement a parameterisable shift-register of length n and width DATA_WIDTH+1 (did you really mean that?), enabled by the en input:
module N_FLOPS #(n = 2, DATA_WIDTH = 8) (input [DATA_WIDTH:0] dina, input clk, en, output [DATA_WIDTH:0] douta);
reg [DATA_WIDTH:0] flops [n-1:0];
always #(posedge clk)
if (en)
begin : SR
integer i;
flops[0] <= dina;
for (i = 1; i <= n ; i = i + 1)
flops[i] <= flops[i-1];
end
assign douta = flops[n-1];
endmodule
http://www.edaplayground.com/x/3kuY
You can see - no generate statements required. This code conforms to this template, which suffices for any sequential logic without an asynchronous reset:
always #(posedge CLOCK) // or negedge
begin
// do things that occur on the rising (or falling) edge of CLOCK
// stuff here gets synthesised to combinational logic on the D input
// of the resulting flip-flops
end

How to handle data going from a clock domain to another clock domain whose clock is divide by 2 version of the first clock?

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

Shift Registers Verilog

I am very new to HDL language. I have a question about how to program a shift register. (i know i shift to the other direction). Why does the book use wire[N-1:0] r_next? what's drawback of my implementation?
thanks
my first try is as following
module lesson04#(parameter N=8)(
input wire clk, reset,
input wire data,
output wire out
);
reg [N-1: 0] r_reg;
always #(posedge clk or negedge reset)
begin
if(!reset)
r_reg =0;
else
r_reg[0]=data;
r_reg = r_reg<<1;
end
assign out =r_reg[N-1];
endmodule
but the book gives:
module lesson04#(parameter N=8)(
input wire clk, reset,
input wire data,
output wire out
);
reg [N-1: 0] r_reg;
wire[N-1:0] r_next;
always #(posedge clk or negedge reset)
begin
if(!reset)
r_reg =0;
else
r_reg <= r_next;
end
assign r_next= {data, r_reg[N-1:1]};
assign out =r_reg[N-1];
endmodule
First of all, don't forget your begin-ends around sections of code:
else begin
r_reg[0]=data;
r_reg = r_reg<<1;
end
Without this, only r_reg[0]=data will be in the else clause of the if statement. This will work, but is considered bad style due to the blocking statements in a sequential logic description...
Second, for modeling sequential blocks, use nonblocking assignments (<=) or your calculations may 'fall through' (google nonblocking vs blocking for more info). Your example may very well work (did you try it in a simulator?) but if things get more complicated and more variables are added things can break.
always #(posedge clk or negedge reset)
begin
if(!reset)
r_reg <= 0;
else begin // This is horrible! Don't write code like this!
r_reg[0] = data; // blocking
r_reg <= r_reg<<1; // non-blocking
end
end
For the above reason, it is sometimes recommended that combo logic is separated from sequential logic so that you can write nonblocking assignments to registers in sequential blocks, and blocking in combo blocks and never have to worry about the scheduling.
To code in this way, you need to calculate what the next output should be using the current state, hence the r_next bus in the answer. I think it tends to help the synthesis tool out too if all the flip-flops are separated from surrounding combo logic in this way.
Also, if your reset is active low (ie LOW resets ) it should be named as such, eg resetb or reset_n.
Your implementation produces quite a different output from the book's. You should prove this to yourself by constructing a simple testbench to drive your inputs and run a simulation. You will see that the book's output shifts the input data by a single clock cycle, whereas your output shifts the input data by eight clock cycles.
By the way you have indented your always block, I am led to believe that it is not what you wanted. This is how your block really behaves:
always #(posedge clk or negedge reset)
begin
if(!reset) begin
r_reg =0;
end else begin
r_reg[0]=data;
end
r_reg = r_reg<<1;
end
I always explicitly use the begin/end keywords in if/else statements to avoid this confusion.
The way it simulates, r_reg is always 0 because you clobber the 1st assignment (r_reg[0]=data;) with the 2nd (r_reg = r_reg<<1;). Another difference is that the book assigns data to the MSB of the shift register, but you assign it to the LSB.
If you are using decent linting and synthesis tools, you would probably get a bunch of warnings for your code. This would alert you to make some changes.

Verilog code simulates but does not run as predicted on FPGA

I did a behavioral simulation of my code, and it works perfectly. The results are as predicted. When I synthesize my code and upload it to a spartan 3e FPGA and try to analyze using chipscope, the results are not even close to what I would have expected. What have I done incorrectly?
http://pastebin.com/XWMekL7r
Your problem is with lines 13-16, where you set initial values for state registers:
reg [OUTPUT_WIDTH-1:0] previousstate = 0;
reg [OUTPUT_WIDTH-1:0] presentstate = 1;
reg [6:0] fib_number_cnt = 1;
reg [OUTPUT_WIDTH-1:0] nextstate = 1;
This is an equivalent to writing an "initial" statement assigning these values, which isn't synthesizable -- there is no such thing as a default value in hardware. When you put your design inside an FPGA, all of these registers will take on random values.
Instead, you need to initialize these counters/states inside your always block, when reset is high.
always #(posedge clk or posedge reset)
if (reset) begin
previousstate <= 0;
presentstate <= 1;
... etc ...
end
Answer to the follow-up questions:
When you initialize code like that, nothing at all happens in hardware -- it gets completely ignored, just as if you've put in a $display statement. The synthesis tool skips over all simulation-only constructs, while usually giving you some kind of a warning about it (that really depends on the tool).
Now, blocking and non-blocking question requires a very long answer :). I will direct you to this paper from SNUG-2000 which is probably the best paper ever written on the subject. It answers your question, as well as many others on the topic. Afterward, you will understand why using blocking statements in sequential logic is considered bad practice, and why your code works fine with blocking statements anyway.
http://cs.haifa.ac.il/courses/verilog/cummings-nonblocking-snug99.pdf
More answers:
The usual "pattern" to creating logic like yours is to have two always blocks, one defining the logic, and one defining the flops. In the former, you use blocking statements to implement logic, and in the latter you latch in (or reset) the generated value. So, something like this:
wire some_input;
// Main logic (use blocking statements)
reg state, next_state;
always #*
if (reset) next_state = 1'b0;
else begin
// your state logic
if (state) next_state = some_input;
else next_state = 1'b0;
end
// Flops (use non-blocking)
always #(posedge clock)
if (reset) state <= 1'b0;
else state <= next_state;
Note that I'm using a synchronous reset, but you can use async if needed.
Lines 13-16 are correct. "reg [6:0] fib_number_cnt = 1;" is not the same as using "initial" statement. Read Xilinx synthesis guide for more detailed description of how to initialize the registers.

Resources