better way of coding a D flip-flop - verilog

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.

Related

How do I drive a signal from 2 sources in system verilog

I'm trying to write a RTL model in which I monitor independent clock sources. These clock sources can have variable frequency (range 5 to 50MHz)
Let us say clk1 and clk2. I'm trying to drive a signal 'toggle' which is set '1' at every posedge of clk1 and is set to '0' at every negedge of clk2. I'm having trouble realizing this model.
I tried using 1 flop triggered at the positive edge of clk1 with inputs of this flop tied to 'high' and another flip flop triggered at the negative edge of clk2 with input tied to 'low'. I sent these outputs to a mux, but I have trouble figuring out how to drive the select signal of this mux
Here is my code snippet :
always_ff #(posedge clk1 or rstb) begin
if(!rstb) begin
flop1_out <= 0;
end else begin
flop1_out <= 1;
end
end
always_ff #(negedge clk2) begin
flop2_out <= 0;
end
assign toggle = sel ? flop1 : flop2;
So, as of now nothing is driving sel and trying to figure this out is where I'm having trouble
If I try to drive the same signal (toggle) from 2 different clock sources, I get an error saying that multiple drivers found for signal toggle, which makes sense.
Please let me know if you have any suggestions
EDIT: fixed a typo and removed rstb from the sensitivity list for flop2
assign rstn = clk2;
always # (posedge clk1 or negedge rstn)
if (~rstn)
toggle = 1'b0;
else
toggle <= 1'b1;
note: depending on the clock frequency and insertion delay relationships this circuit may become metastable. if you can tolerate delay, add a synchronizer on the output. better yet, if you can tolerate distortion, add a reset synchronizer on clk2 to clk1mx, where clk1mx is synchronous to clock1 but x times faster.

two clock ring counter with verilog

I'm trying to write a roll shift/ ring counter that takes two switches as the clocks in verilog.
My code is as follows:
module roll(CLK1, CLK2, LEDS);
input CLK1;
input CLK2;
output [3:0] LEDS;
reg [3:0] LEDS;
initial
begin
LEDS = 4'b0001;
end
always#(posedge CLK1 or posedge CLK2)
begin
if(CLK1)
begin
LEDS[3]<=LEDS[2];
LEDS[2]<=LEDS[1];
LEDS[1]<=LEDS[0];
LEDS[0]<=LEDS[3];
end
// Roll Right
if(CLK2)
begin
LEDS[3]<=LEDS[0];
LEDS[2]<=LEDS[3];
LEDS[1]<=LEDS[2];
LEDS[0]<=LEDS[1];
end
end
endmodule
I tried using two always blocks, but then figured out that I cannot do that. and when I have the posedge CLK2 in the always statement, the leds on my FPGA all stay on.
Remember Verilog is not a programming language it is a hardware description language.
And when coding for synthesis, you will only be successful if you write code that can be instantiated with actual gates. So writing an always block with sensitivity to edges of two different signals can't be synthesized unless the response to one of the two signals has the effect of a RESET or PRESET operation.
Your code also logically doesn't do what it seems you want to. Consider what your code says will happen if there is a rising edge on CLK2 when CLK1 is already high (or vice versa). Your lights will roll left and then immediately roll right gain, resulting in no change.
A more usual approach would be to have a clock running much faster than the UP and DOWN inputs are expected to change, and use that to drive the logic. For example
module roller(input clk, input rst, input UP, input DOWN, output reg LEDS[3:0]);
reg UP1, DOWN1;
always #(posedge clk or posedge rst)
if (rst) begin
LEDS[3:0] <= 4'b0001;
end
else
begin
UP1 <= UP;
DOWN1 <= DOWN;
if (UP & ~UP1) begin
LEDS[3:0] <= {LEDS[2:0], LEDS[3]};
end
else if (DOWN & ~DOWN1) begin
LEDS[3:0] <= {LEDS[0], LEDS[3:1]};
end
end
endmodule;
Notice that this gives priority to UP. If both UP and DOWN are asserted, the pattern will roll "up" rather than down. If you want a different behavior, you'd have to modify the code to achieve it.

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

verilog always #(posedge) failing in uart

I'm learning verilog and I think there is something that I must not understand about always #* and always (#posedge clk, ...)
Here is a piece of code supposed to send bits via uart. It fails at synthesization.
The error is
" The logic for does not match a known FF or Latch template. The description style you are using to describe a register or latch is not supported in the current software release."
(and 3 other errors for , and )
If I change the always #(...) by always #*, things fail in the next step ("implement design") because things are not connected.
In the book that I have, they implement an fsmd with an always (posedge clk) for the state, and always #* for the other logic, but I don't understand why this doesn't work.
On another forum, I read that the error could come from too complicated conditions. But I have simplified things too (not code the code here but basically I removed the case(state) and the ifs to have single line assignments with ? : or binary conditions, but it didn't work either)
I have seen this error before in other pieces of code that I wrote but I didn't get to the bottom of it, so if you could help me understand the general problem (with this uart thing as a support for a concrete example), I would be very happy.
Thanks
Thomas
P.S : Im using xilinx spartan 3e starter kit and xilinx ise 14.4
module UART_out #(parameter [3:0] NUM_BITS = 8)
(
input wire baud_clk,
input wire send_tick,
input wire[NUM_BITS-1:0] data_in,
output wire tx,
output wire debug_done
);
localparam
IDLE = 0,
TRANSMIT = 1;
reg[NUM_BITS:0] bits_to_send;
reg state;
reg out_bit;
reg[4:0] cnt;
always #(posedge baud_clk, posedge send_tick)
begin
case (state)
IDLE:
if (send_tick)
begin
bits_to_send <= {data_in, 0};
state <= TRANSMIT;
cnt <= 0;
end
TRANSMIT:
begin
if (cnt < NUM_BITS)
cnt <= cnt + 1;
else
state <= IDLE;
bits_to_send <= {1, bits_to_send[NUM_BITS:1]};
out_bit <= bits_to_send[0];
end
endcase
end
assign tx = (state == IDLE ? 1 : out_bit);
assign debug_done = (state == IDLE);
endmodule
The error:
The logic for does not match a known FF or Latch template. The description style you are using to describe a register or latch is not supported in the current software release.
Is referring to the fact that the synthesis tool does not have any hardware cells to use which match your description.
What hardware do you want from :
always #(posedge baud_clk, posedge send_tick)
This looks like you want a flip-flop with an enable signal. The enable signal (send_tick) should be 1 clock period wide. This is then used to select the path of logic on a clock edge. not as an alternative trigger.
I think that this is all you really need:
always #(posedge baud_clk) begin
case (state)
IDLE:
if (send_tick) begin
//...
end
//...
endcase
end
If send_tick is from another clock domain then you will need to do some clock domain crossing to turn it it to a clock wide pulse on the baud_clk.
You may be getting confused with blocks which have multiple triggers, they are normally a clk and reset. A negedge reset_n or posedge reset are often added for reset (initialisation) conditions.
If adding a reset :
always #(posedge baud_clk or negedge reset_n) begin
if (~reset_n) begin
//reset conditions
state <= IDLE;
//...
end
else begin
// Standard logic
end
end
You will notice that there is a very definite structure here, if reset else ... The synthesis tools recognise this as a flip-flop with an asynchronous reset. The data in the reset condition is also static, typically setting everything to zero.

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.

Resources