Synthesizing a counter with an asynchronous edge-triggered reset - verilog

I want to synthesize a clock counter with an asynchronous edge-triggered reset: the counter increments on every clk rising edge, and resets to 0 on the rising edge of a rst signal.
The counter reset to 0 must be edge-triggered since the rst signal may stay high indefinitely.
Here's what I have:
module clk_counter(input clk, input rst, output reg [7:0] count);
always # (posedge rst) begin
count <= 0;
end
always # (posedge clk) begin
if(count < 255) begin
count <= count + 1;
end
end
endmodule
I'm having trouble synthesizing the implementation since count is "connected to multiple drivers" according to the error message my synthesizer spits out. I suspect this is due to a race condition in the design: the value of count is uncertain if both rst and clk rise at the same time.
I believe the race condition can be solved if there is a way to prioritize the edge-triggered reset operation to occur before the typical counter increments.
Is there a way to prioritize between two edge-triggered operations?

The "Connected to multiple drivers" error is not a race condition - values cannot be assigned to the same net in multiple always blocks. Additionally, remember that HDL is not executed sequentially - placing an assignment earlier in a file won't give it any higher priority.
Instead, you'll need multiple sensitivities for your always block. Try this:
reg rst_prev;
always #(posedge clk)
rst_prev <= rst;
always #(posedge clk or posedge rst)
begin
if (rst)
begin
if (!rst_prev)
count <= 0;
end
else begin
if (count < 255)
count <= count + 1;
end
end
The main difference between this and the solution proposed by others is that as desired, it will only trigger on the edge of rst, since rst_prev will be 0, and rst will contain 1. However, this design is more sensitive to timing constraints (and more likely to have setup/hold violations) than the simpler designs.

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.

How to program a delay in Verilog?

I'm trying to make a morse code display using an led. I need a half second pulse of the light to represent a dot and a 1.5 second pulse to represent a dash.
I'm really stuck here. I have made a counter using an internal 50MHz clock on my FPGA. The machine I have to make will take as input a 3 bit number and translate that to a morse letter, A-H with A being 000, B being 001 and so on. I just need to figure out how to tell the FPGA to keep the led on for the specified time and then turn off for about a second (that would be the delay between a dot pulse and a dash pulse).
Any tips would be greatly appreciated.
Also, it has to be synthesizable.
Here is my code. It's not functioning yet. The error message it keeps giving me is:
Error (10028): Can't resolve multiple constant drivers for net "c3[0]"
at part4.v(149)
module part4 (SELECT, CLK, CLOCK_50, RESET, led);
input [2:0]SELECT;
input RESET, CLK, CLOCK_50;
output reg led=0;
reg [26:0] COUNT=0; //register that keeps track of count
reg [1:0] COUNT2=0; //keeps track of half seconds
reg halfsecflag=0; //goes high every time half second passes
reg dashflag=0; //goes high every time 1 and half second passes
reg [3:0] code; //1 is dot and 0 is dash. There are 4 total
reg [1:0] c3; //keeps track of the index we are on in the code.
reg [3:0] STATE; //register to keep track of states in the state machine
reg done=0; //a flag that goes up when one morse pulse is done.
reg ending=0; //another flag that goes up when a whole morse letter has flashed
reg [1:0] length; //This is the length of the morse letter. It varies from 1 to 4
wire i; // if i is 1, then the state machine goes to "dot". if 0 "dash"
assign i = code[c3];
parameter START= 4'b000, DOT= 4'b001, DASH= 4'b010, DELAY= 4'b011, IDLE=
4'b100;
parameter A= 3'b000, B=3'b001, C=3'b010, D=3'b011, E=3'b100, F=3'b101,
G=3'b110, H=3'b111;
always #(posedge CLOCK_50 or posedge RESET) //making counter
begin
if (RESET == 1)
COUNT <= 0;
else if (COUNT==8'd25000000)
begin
COUNT <= 0;
halfsecflag <= 1;
end
else
begin
COUNT <= COUNT+1;
halfsecflag <=0;
end
end
always #(posedge CLOCK_50 or posedge RESET)
begin
if (RESET == 1)
COUNT2 <= 0;
else if ((COUNT2==2)&&(halfsecflag==1))
begin
COUNT2 = 0;
dashflag=1;
end
else if (halfsecflag==1)
COUNT2= COUNT2+1;
end
always #(RESET) //asynchronous reset
begin
STATE=IDLE;
end
always#(STATE) //State machine
begin
done=0;
case(STATE)
START: begin
led = 1;
if (i) STATE = DOT;
else STATE = DASH;
end
DOT: begin
if (halfsecflag && ~ending) STATE = DELAY;
else if (ending) STATE= IDLE;
else STATE=DOT;
end
DASH: begin
if ((dashflag)&& (~ending))
STATE = DELAY;
else if (ending)
STATE = IDLE;
else STATE = DASH;
end
DELAY: begin
led = 0;
if ((halfsecflag)&&(ending))
STATE=IDLE;
else if ((halfsecflag)&&(~ending))
begin
done=1;
STATE=START;
end
else STATE = DELAY;
end
IDLE: begin
c3=0;
if (CLK) STATE=START;
else STATE=IDLE;
end
default: STATE = IDLE;
endcase
end
always #(posedge CLK)
begin
case (SELECT)
A: length=2'b01;
B: length=2'b11;
C: length=2'b11;
D: length=2'b10;
E: length=2'b00;
F: length=2'b11;
G: length=2'b10;
H: length=2'b11;
default: length=2'bxx;
endcase
end
always #(posedge CLK)
begin
case (SELECT)
A: code= 4'b0001;
B: code= 4'b1110;
C: code= 4'b1010;
D: code= 4'b0110;
E: code= 4'b0001;
F: code= 4'b1011;
G: code= 4'b0100;
H: code= 4'b1111;
default: code=4'bxxxx;
endcase
end
always #(posedge CLK)
begin
if (c3==length)
begin
c3<=0; ending=1;
end
else if (done)
c3<= c3+1;
end
endmodule
I have been reading your code and there are many issues:
The code is not formatted.
You did not provide a test-bench. Did you write one?
"Can't resolve multiple constant drivers for net" Search on stack exchange for the error message. It has been asked many times.
Use always #(*) not e.g. always #(STATE) you are missing signals like i, halfsecflag, ending. But see point 6: You want the STATE in a clocked section.
Where you use always #(posedge CLK) you must use non-blocking assignments: <=.
There are many places where you use always #(posedge CLK) where you want to use always #(*) (e.g. where you set length and code) Opposite you want to use a posedge CLK where you work with your STATE.
Use one clock and one clock only. Do not use CLK and CLOCK_50. Use either one or the other.
Take care of your vector sizes. This 8'd25000000 is wrong as you can no fit 25000000 in 8 bits.
Your usage of halfsecflag is excellent! I have see many times where people think they can use always #(halfsecflag) which is a recipe for disaster!
Below you find a small piece of your code which I have re-written.
All assignments are non-blocking <=
halfsecflag is essential to operate the code only every half a second, so I put that by itself in a separate if at the top. I would use that throughout the code.
All register are reset, both COUNT2 and dashflag.
dashflag was set to 1 but never set back to 0. I fixed that.
I specified the vector sizes. It makes the code "Lint proof".
Here is it:
always #(posedge CLOCK_50 or posedge RESET)
begin
if (RESET == 1'b1)
begin
COUNT2 <= 2'd00;
dashflag <= 1'b0;
end // reset
else if (halfsecflag) // or if (halfsecflag==1'b1)
begin
if (COUNT2==2'd2))
begin
COUNT2 <= 2'd0;
dashflag <=1'b1;
end
else
begin
COUNT2 <= COUNT2+2'd1;
dashflag <=1'b0;
end
end // clocked
end // always
Start fixing the rest of your code the same way. Write a test-bench, simulate and trace on a waveform display where things go wrong.
Normally you would build the finite state machine to produce the output. That machine would have some stages, like reading the input, mapping it to a sequence of morse code element, shifting out the elements to output buffer, waiting for conditions to move to the next morse element. You will need some timer that would produce one morse time unit intervals, and depending on the FSM stage you will wait one, three or seven time units. The FSM will spin in the waiting stage, it doesn't "magically" sleeps in some fpga-produced delay, there's no such things.
Okay a year later, I know exactly what one should do if they want to create a delay in their verilog program! Essentially, what you should do is create a timer using one of the clocks on your FPGA. For me on my Altera DE1-SoC, the timer I could use is the 50MHz clock known as CLOCK_50. What you do is make a timer module that triggers on the positive (or negative, doesn't matter) edge of the 50MHz clock. Set up a count register that holds a constant value. For example, reg [24:0] timer_limit = 25'd25000000; This is a register that can hold 25 bits. I've set this register to hold the number 25 million. The idea is to flip a bit every time the value in this register is exceeded. Here's some pseudocode to help you understand:
//Your variable declarations
reg [24:0] timer_limit = 25'd25000000; //defining our timer limit register
reg [25:0] timer_count = 0; //See note A
reg half_sec_clock;
always#(posedge of CLOCK_50) begin
if timer_count >= timer_limit then begin
reset timer_count to 0;
half_sec_clock = ~half_sec_clock; //toggle your half_sec_clock
end
Note A: Setting it to zero may or may not initialize count, it's always best to include a reset function that clears your count to zero because you don't know what the initial state is when you're dealing with hardware.
This is the basic idea of how to introduce timing into your hardware. You need to use an onboard clock on your device, trigger on the edge of that clock and create your own slower clock to measure things like seconds. The example above will give you a clock that triggers periodically every half second. For me, this allowed me to easily make a morse code light that could flash on either 1 half second count, or 3 half seconds. My best advice to you beginners is to work in a modular fashion. For example build your half second clock and then test it out to see if you can get a light on your FPGA to toggle once every half second (or whatever interval you want). :) I really hope this is the answer that helps you. I know this is what I was looking for when I originally posted this question so long ago.

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

Entries in Verilog always sensitivity list

Can't find anything on this, it doesn't fit in well with keywords. Somewhere I came across a statement that it's bad practice to put some things in an always block sensitivity list. Things other than clk and other related internal signals within the device can, according to the statement, cause routing inefficiencies.
I find it convenient when coding relatively slow applications to generate subdivided clock signals, and use these in always blocks.
For Example:
reg Counter [12:0] ;
reg SlowClk ;
always # (posedge clk)
begin
Counter <= Counter + 13'h1 ;
SlowClk <= Counter[12] ;
end
always # (posedge SlowClk)
Note: My text entry has one statement per line, if the lines are concatenated in the final post, that's due to the website.
Is there anything wrong with this?
Yes this is indeed a bad practice. So you can do something different to get the SlowClk edge.
You can take a wire, to detect the SlowClk positive edge.
wire got_SlowClk_posedge;
Now to detect, SlowClk, positive edge, you need to have it's current and next clock values (Current Clock Value should be 0 & Next Clock Value should be 1) But fortunately, in your case, SlowClk, next clock value is the current value of Counter[12]. So you can use it.
assign got_SlowClk_posedge = Counter[12] & ~SlowClk;
So now your 2nd always block may look like this :
// Instead of #(posedge SlowClk)
always #(posedge clk)
begin
if(got_SlowClk_posedge)
begin
// Your code for positive edge of SlowClk
end
end
Nothing is wrong in this. If design required divided clock we must have to do this.
but best practice is to use en signal for clock divider so that you can use same clock in every always block. And yes its good to use reset in clcok diveder
(any sequential ckt required reset).
reg Counter [12:0] ;
reg SlowClk ;
reg div_clk ;
wire en;
always # (posedge clk)
begin
if(!reset)
Counter <= 13'h0;
else
Counter <= Counter + 13'h1;
end
assign en = (Counter ==13'h0)? 1'b1 : 1'b0;
always # (posedge clk)
begin
if(!reset)
div_clk = 1'b0;
else(en)
div_clk <= ~div_clk;
end

Delay using Verilog for PR controller

i want to shift a signal by fixed number of clock cycles. I receive the signal from adc. kindly let me know how to implement this
HINT: Not a full answer
A 8 bit flip-flop in verilog might look like:
reg [7:0] a;
always #(posedge clk, negedge rst_n) begin
if (~rst_n) begin
// Active Low Reset condition
a <= 'b0;
end
else begin
a <= input_eight_bit;
end
end
To delay for multiple clock cycles you need multiple flip-flops feeding from one to the next. This creates a pipe line or delay line.

Resources