Synthesis of two simulation identical designs - with and without second if in process for SET clk - verilog

I have got two identical (by means of simulation) flip flop process in verilog.
First is just a standard description of register with asynchronous reset (CLR) and clock (SET) with data in tied to 1:
always #(posedge SET, posedge CLR)
if (CLR)
Q <= 0;
else
Q <= 1;
second one is the same as above but with second if condition for SET signal:
always #(posedge SET, posedge CLR)
if (CLR)
Q <= 0;
else if (SET)
Q <= 1;
There is no differences between these two implementations of flip-flop in simulation. But what does the verilog standard says about this cases? Should these tests be equivalent as well as their netlists after synthesis process?

The "if (SET)" in your second example is redundant and would be optimized away n synthesis. Since the always block will only be entered on a posedge of SET or CLR, the else statement implies that a posedge of SET has occurred.
Incidentally, the first example is a much more accepted version for coding flip flops. I've yet to see the second version make it into a shipping design.

Related

Verilog race with clock divider using flops

I made a basic example on eda playground of the issue I got.
Let s say I have two clocks 1x and 2x. 2x is divided from 1x using flop divider.
I have two registers a and b. a is clocked on 1x, b is clocked in 2x.
b is sampling value of a.
When we have rising edge of 1x and 2x clocks, b is not taking the expected value of a but it s taking the next cycle value.
This is because of this clock divider scheme, if we make division using icgs and en it works fine.
But is there a way to make it work using this clock divider scheme with flops ?
EDA playground link : https://www.edaplayground.com/x/map#
module race_test;
logic clk1x = 0;
logic clk2x = 0;
always
#5ns clk1x = !clk1x;
int a, b;
always #(posedge clk1x) begin
a <= a+1;
clk2x <= !clk2x;
end
// Problem here is that b will sample postpone value of a
// clk2x is not triggering at the same time than clk1x but a bit later
// This can be workaround by putting blocking assignment for clock divider
always #(posedge clk2x) begin
b <= a;
end
initial begin
$dumpfile("test.vcd");
$dumpvars;
#1us
$stop;
end
endmodule
Digital clock dividers present problems with both simulation and physical timing.
Verilog's non-blocking assignment operator assumes that everyone reading and writing the same variables are synchronized to the same clock event. By using an NBA writing to clk2x, you have shifted the reading of a to another delta time*, and as you discovered, a has already been updated.
In real hardware, there are considerable propagation delays that usually avoid this situation. However, you are using the same D-flop to assign to clk2x, so there will be propagation delays there as well. You last always block now represents a clock domain crossing issue. So depending on the skews between the two clocks, you could still have a race condition.
One way of correcting this is using a clock generator module with an even higher frequency clock
always #2.5ns clk = !clk;
always #(posedge clk) begin
clk1x <= !clk1x;
if (clk1x == 1)
clk2x = !clk2x;
Of course you have solved this problem, but I think there is a better way.
The book says one can use blocking assignment to avoid race. But blocking assignemnt causes errors in synopsys lint check. So, one way to avoid race problem without lint error is to use dummy logic, like this
wire [31:0] a_logic;
wire dummy_sel;
assign dummy_sel = 1'b0;
assign a_logic = dummy_sel ? ~a : a;
always #(posedge clk2x) begin
b <= a_logic;
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

better way of coding a D flip-flop

Recently, I had seen some D flip-flop RTL code in verilog like this:
module d_ff(
input d,
input clk,
input reset,
input we,
output q
);
always #(posedge clk) begin
if (~reset) begin
q <= 1'b0;
end
else if (we) begin
q <= d;
end
else begin
q <= q;
end
end
endmodule
Does the statement q <= q; necessary?
Does the statement q <= q; necessary?
No it isn't, and in the case of an ASIC it may actually increase area and power consumption. I'm not sure how modern FPGAs handle this. During synthesis the tool will see that statement and require that q be updated on every positive clock edge. Without that final else clause the tool is free to only update q whenever the given conditions are met.
On an ASIC this means the synthesis tool may insert a clock gate(provided the library has one) instead of mux. For a single DFF this may actually be worse since a clock gate typically is much larger than a mux but if q is 32 bits then the savings can be very significant. Modern tools can automatically detect if the number of DFFs using a shared enable meets a certain threshold and then choose a clock gate or mux appropriately.
In this case the tool needs 3 muxes plus extra routing
always #(posedge CLK or negedge RESET)
if(~RESET)
COUNT <= 0;
else if(INC)
COUNT <= COUNT + 1;
else
COUNT <= COUNT;
Here the tool uses a single clock gate for all DFFs
always #(posedge CLK or negedge RESET)
if(~RESET)
COUNT <= 0;
else if(INC)
COUNT <= COUNT + 1;
Images from here
As far as simulation is concerned, removing that statement should not change anything, since q should be of type reg (or logic in SystemVerilog), and should hold its value.
Also, most synthesis tools should generate the same circuit in both cases since q is updated using a non-blocking assignment. Perhaps a better code would be to use always_ff instead of always (if your tool supports it). This way the compiler will check that q is always updated using a non-blocking assignment and sequential logic is generated.

24 bit counter state machine

I am trying to create a counter in verilog which counts how many clock cycles there have been and after ten million it will reset and start again.
I have created a twenty four bit adder module along with another module containing twenty four D Flip flops to store the count of the cycles outputted from the adder.
I then want to have a state machine which is in the count state until ten million cycles have passed then it goes to a reset state.
Does this sound right? The problem is I am not sure how to implement the state machine.
Can anyone point me to a website/book which could help me with this?
thanks
As Paul S already mentioned, there is no need for a state machine if you want your counter to keep counting after an overflow. You can do something like this (untested, might contain typos):
module overflow_counter (
clk,
reset,
enable,
ctr_out
);
// Port definitions
input clk, reset, enable;
output [23:0] ctr_out;
// Register definitions
reg [23:0] reg_ctr;
// Assignments
assign ctr_out = reg_ctr;
// Counter behaviour - Asynchronous active-high reset
initial reg_ctr <= 0;
always # (posedge clk or posedge reset)
begin
if (reset) reg_ctr <= 0;
else if (enable)
begin
if (reg_ctr == 10000000) reg_ctr <= 0;
else reg_ctr <= reg_ctr + 1;
end
end
endmodule
Of course, normally you'd use parameters so you don't have to make a custom module every time you want an overflowing counter. I'll leave that to you ;).
[Edit] And here are some documents to help you with FSM. I just searched Google for "verilog state machine":
EECS150: Finite State Machines in Verilog
Synthesizable Finite State Machine Design Techniques
I haven't read the first paper, so I can't comment on that. The 2nd one shows various styles of coding FSMs, among which the 3 always blocks style, which I highly recommend, because it's a lot easier to debug (state transitions and FSM output are neatly separated). The link seems to be down, so here is the cached Google result.
You don't need a state machine. You already have state in the counter. All you need to do is detect the value you want to wrap at and load 0 into your counter at that point
In pseudo-code:
if count == 10000000 then
nextCount = 0;
else
nextCount = count + 1;
...or...
nextCount = count + 1;
if count == 10000000 then
resetCount = 1;
State machines are not too tricky. Use localparam (with a width, don't forget the width, not shown here because it is just one bit) to define labels for your states. Then create two reg variables (state_reg, state_next). The _reg variable is your actual register. The _next variable is a "wire reg" (a wire that can be assigned to inside a combinational always block). The two things to remember are to do X_next = X_reg; in the combinational always block (and then the rest of the combinational logic) and X_reg <= X_next; in the sequential always block. You can get fancy for special cases but if you stick to these simple rules then things should just work. I try not to use instantiation for very simple things like adders since Verilog has great support for adders.
Since I work with FPGAs, I assign initial values to my registers and I don't use a reset signal. I'm not sure but for ASIC design I think it is the opposite.
localparam STATE_RESET = 1'b0, STATE_COUNT = 1'b1;
reg [23:0] cntr_reg = 24'd0, cntr_next;
reg state_reg = STATE_COUNT, state_next;
always #* begin
cntr_next = cntr_reg; // statement not required since we handle all cases
if (cntr_reg == 24'd10_000_000)
cntr_next = 24'd0;
else
cntr_next = cntr_reg + 24'd1;
state_next = state_reg; // statement required since we don't handle all cases
case (state_reg)
STATE_COUNT: if (cntr_reg == 24'd10_000_000) state_next = STATE_RESET;
endcase
end
always #(posedge clk) begin
cntr_reg <= cntr_next;
state_reg <= state_next;
end
I found this book to be very helpful. There is also a VHDL version of the book, so you can use both side-by-side as a Rosetta Stone to learn VHDL.

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