Timers and LEDs in Verilog - verilog

I have a question about using timers and clocks in Verilog. I want to set up a custom reg to compare to an accumulator, which will control the state of an LED. The board uses inverse logic, so 0 is high on the LED. There are a few concepts I just need some clarification on. The clock is 100 MHz.
always #(posedge clk100 or negedge reset_)
begin
cust_LED_counter <= (cust_LED_counter<cust_LED_timer) ? cust_LED_counter + 1'b1 : 16'd0;
cust_LED_timer1 <= (cust_LED_counter == cust_LED_timer);
if(!reset_)
begin
cust_LED1 <= 'b0;
cust_LED_timer <= 'd0;
cust_LED_timer1 <= 'd0;
end
else
begin
cust_LED1 <= ~cust_LED_timer1;
end
end
For the accumulator, what is the action that resets it and allows for blinking to happen? Would it not hit the cust_LED_timer value and stay at that high reading?
I think I'm misunderstanding how a FPGA clock operates. Assuming this would cause a blinking action in the LED, it would mean some timer hit the upper limit and reset; however, I'm not sure if this would take place in the counter portion of the code, or instead would occur where the clock/reset is defined.
Also, based on how this layout looks it wouldn't be a uniform blink, in terms of equal time on and off. Is there a way to implement such a system for custom input?

Here's a simple module that should blink the LED with a 50-50 duty cycle for an arbitrary number of clocks (up to 2^26)
module blink(input clk, input rst, input [25:0] count_max, output LED);
reg [25:0] counter, next_count;
assign LED = counter < count_max >> 1;
always #(posedge clk or posedge rst)
begin
if (rst)
counter <= 0;
else
counter <= next_count;
end
always #* begin
if (counter < count_max - 1)
next_count = counter + 1;
else
next_count = 0;
end
endmodule // blink
Let me know if this doesn't compile! I don't have a verilog compiler where I'm writing this from at the moment!

Related

"ERROR: multiple drivers on net" when setting a register on both positive and negative edges

I was following a tutorial on SPI master in Verilog. I've been debugging this for about three hours now and cannot get it to work.
I've been able to break down the issue into a minimum representative issue. Here are the specifications:
We have two states, IDLE and COUNTING. Then, on the clock positive edge, we check:
If the state is IDLE, then the counter register is set to 0. If while in this state the dataReady pin is high, then the state is set to COUNTING and the counter is set to all 1s.
If the state is COUNTING, the state remains COUNTING as long as counter is not zero. Otherwise, the state is returned to IDLE.
Then, we count on the negative edge:
On the negative edge of clock if state is COUNTING, then decrement counter.
Here's the code I came up with to fit this specification:
// look in pins.pcf for all the pin names on the TinyFPGA BX board
module top (
input CLK, // 16MHz clock
input PIN_14,
output LED, // User/boot LED next to power LED
output USBPU // USB pull-up resistor
);
// drive USB pull-up resistor to '0' to disable USB
assign USBPU = 0;
reg [23:0] clockDivider;
wire clock;
always #(posedge CLK)
clockDivider <= clockDivider + 1;
assign clock = clockDivider[23];
wire dataReady;
assign dataReady = PIN_14;
parameter IDLE = 0, COUNTING = 1;
reg state = IDLE;
reg [3:0] counter;
always #(posedge clock) begin
case (state)
IDLE: begin
if (dataReady)
state <= COUNTING;
end
COUNTING: begin
if (counter == 0)
state <= IDLE;
end
endcase
end
always #(negedge clock) begin
if (state == COUNTING)
counter <= counter - 1;
end
always #(state) begin
case (state)
IDLE:
counter <= 0;
COUNTING:
counter <= counter;
endcase
end
assign LED = counter != 0;
endmodule
With this, we get the error:
ERROR: multiple drivers on net 'LED' (LED_SB_DFFNE_Q.Q and LED_SB_DFFNE_Q_1.Q)
Why? There is literally only one assign statement on the LED.
First of all it would not be easy to come up with a synthesizable model in such a case. But, you do not need any negedge logic to implement your model. Also you made several mistakes and violated many commonly accepted practices.
Now about some problems in your code.
By using non-blocking assignment in the clock line you created race condition in the simulation which will probably cause incorrect simulation results:
always #(posedge CLK)
clockDivider <= clockDivider + 1; // <<< this is a red flag!
assign clock = clockDivider[23];
...
always #(posedge clk)
you incorrectly used nbas in your always block
always(#state)
... counter <= conunter-1; // <<< this is a red flag again!
your state machine has no reset. Statements like reg state = IDLE; will only work in simulation and in some fpgas. It is not synthesizable in general. I suggest that you do not use it but provide a reset signal instead.
Saying that, i am not aware of any methodology which would use positive and negative edges in such a case. So, you should not. All your implementation can be done under the posedge, something like the following. However
always #(posedge clock) begin
if (reset) begin // i suggest that you use reset in some form.
state <= IDLE;
counter <= 0;
end
else begin
case (state)
IDLE: begin
if (dataReady) begin
state <= COUNTING;
counter <= counter - 1;
end
end
COUNTING: begin
if (counter == 0)
state <= IDLE;
else
counter <= counter - 1;
end
endcase
end
end
I hope i did it right, did not test.
Now you do not need the other two always blocks at all.

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.

Adding delay to the output in Verilog

I need to add a synthesizable delay in my code to get an output. My code is:
module square_wave(clk,rst,dac_out);
input clk;
input rst;
output reg dac_out;
reg [3:0] counter; //
always #(posedge clk)
begin
if (rst == 1'b1 || counter == 4'b1111) // period, count from 0 to n-1
counter <= 0;
else
counter <= counter + 1'b1;
if (rst == 1'b0 && counter < 4'b0110) // duty cycle, m cycles high
dac_out = 1'b1;
else
dac_out = 1'b0;
end
endmodule
This gives me an output where 6 out of the 15 times of the initial clock cycle, it will be 1, and otherwise 0. So far, it is good. But the other signal I need, TG, needs to be kinda twice of this signal. Meaning in 15 cycles, it should be 1 2 times.
So, what I need to do is delay my output signal by 6 or 7 or 8 times the original clock cycle so that I get a delayed signal, which I can then add to my original output to get what I need. Please refer to the image attached. I am unable to figure out the synthesizable delay. Any help will be appreciated. Thanks.
Please look at this pic to help
You can use a shift register to delay your output the required number of cycles. Then OR the original output with the delayed output
module square_wave(
input clk, rst,
output regdac_out,
output TG);
reg [3:0] counter;
reg [7:0] shifter;
always #(posedge clk)
if (rst == 1'b1 || counter == 4'b1111) // period, count from 0 to n-1
counter <= 0;
else begin
counter <= counter + 1'b1;
shifter <= {shifter, dac_out};
if (rst == 1'b0 && counter < 4'b0110) // duty cycle, m cycles high
dac_out <= 1'b1;
else
dac_out <= 1'b0;
end
assign TG = dac_out || shifter[7];
endmodule
If that's not what you want, you need to give us a much better idea of what the waveform looks like. You picture does not help.
You may add delays by instantiating a delay buffer from the standard cell library if you want custom delays (i.e. delay != N(1/clk)). But please note that you may have to add dont_touch option while synthesizing because the tool may optimize the delay buffer since there is no logic in the data path of the buffer (capacitors are used to delay the signal).
Or you may use D-Flops shown below to delay (here delay value = N(1/clk))your signal.
always#(posedge clk)
begin
data1_d1 <= data1; //Delay data1 by one clock (clk)
data1_d2 <= data1_d1; //Delay data1 by two clocks (clk)
end

gate control clock generation

Here is the code first...
always#(posedge clk)
begin
if(cstate==idle) rclk<=1;
else rclk<=0;
end
always#(negedge clk)
rclk<=0;
What I want to achieve is this: every time at the rising edge of clock signal, if the signal cstate equals idle(4'b0000), the the rclk goes to one, else to zero, at the same time, every time the falling edge of clk will set the rclk to zero. THIS CODE IS NOT SYNTHESIZABLE since the compiler gives the error " the rclk signal is driven by multiple drivers".
How can I achieve the same function by other techniques?
It looks like you want a clock gate cell. Based on a 1 cycle wide enable signal generate a clock pulse which has the same high time as the input clock.
A naive way of doing this might be :
assign rclk = (cstate==idle) ? clk : 1'b0 ;
Which could easily be synthesised assign rclk = (cstate==idle) & clk ;
cstate == idle is going to glitch which is why it would normally be used by a flip-flop allowing the answer to settle before being used.
Using a clock gate cell stops you from creating glitches on the (rclk) clock line. It is common to instantiate your libraries clock gate cell in the rtl for this. In RTL it might be similar to :
reg result;
always #(posedge clk or negedge rst_n) begin
if (~rst_n) begin
result <= 1'b0;
end
else begin
result <= (cstate == idle);
end
end
assign rclk = (result) ? clk : 1'b0 ;
This means result will be stable for each clock cycle, not allowing glitches through from the comparator.
Expanded answer
I have included my example again below with waveform, I have replaced your state comparison with a simple counter which overflows to reset itself. Not the comparison is matching to 2'b10; which means the clock appears on the following count (2'b11). If the clock was to appear in exactly the same time your comparison matched then you have no glitch suppression on your clock and will likely generate unreliable hardware.
reg [1:0] counter = 0;
always #(posedge clk)
counter <= counter+1;
reg result;
wire result_a = (counter == 2'b10 );
always #(posedge clk or negedge rst_n) begin
if (~rst_n) begin
result <= 1'b0;
end
else begin
result <= result_a;
end
end
assign rclk = (result) ? clk : 1'b0 ;

My Verilog behavioral code getting simulated properly but not working as expected on FPGA

I wrote a behavioral program for booth multiplier(radix 2) using state machine concept. I am getting the the results properly during the program simulation using modelsim, but when I port it to fpga (spartan 3) the results are not as expected.
Where have I gone wrong?
module booth_using_statemachine(Mul_A,Mul_B,Mul_Result,clk,reset);
input Mul_A,Mul_B,clk,reset;
output Mul_Result;
wire [7:0] Mul_A,Mul_B;
reg [7:0] Mul_Result;
reg [15:0] R_B;
reg [7:0] R_A;
reg prev;
reg [1:0] state;
reg [3:0] count;
parameter start=1 ,add=2 ,shift=3;
always #(state)
begin
case(state)
start:
begin
R_A <= Mul_A;
R_B <= {8'b00000000,Mul_B};
prev <= 1'b0;
count <= 3'b000;
Mul_Result <= R_B[7:0];
end
add:
begin
case({R_B[0],prev})
2'b00:
begin
prev <= 1'b0;
end
2'b01:
begin
R_B[15:8] <= R_B[15:8] + R_A;
prev <= 1'b0;
end
2'b10:
begin
R_B[15:8] <= R_B[15:8] - R_A;
prev <= 1'b1;
end
2'b11:
begin
prev <=1'b1;
end
endcase
end
shift:
begin
R_B <= {R_B[15],R_B[15:1]};
count <= count + 1;
end
endcase
end
always #(posedge clk or posedge reset)
begin
if(reset==1)
state <= start;
else
begin
case(state)
start:
state <= add;
add:
state <= shift;
shift:
begin
if(count>7)
state <= start;
else
state <=add;
end
endcase
end
end
endmodule
You have an incomplete sensitivity list in your combinational always block. Change:
always #(state)
to:
always #*
This may be synthesizing latches.
Use blocking assignments in your combinational always block. Change <= to =.
Good synthesis and linting tools should warn you about these constructs.
Follow the following checklist if something does work in the simulation but not in reality:
Did you have initialized every register? (yes)
Do you use 2 registers for one working variable that you transfer after each clock (no)
(use for state 2 signals/wires, for example state and state_next and transfer after each clock state_next to state)
A Example for the second point is here, you need the next stage logic, the current state logic and the output logic.
For more informations about how to proper code a FSM for an FPGA see here (go to HDL Coding Techniques -> Basic HDL Coding Techniques)
You've got various problems here.
Your sensitivity list for the first always block is incomplete. You're only looking at state, but there's numerous other signals which need to be in there. If your tools support it, use always #*, which automatically generates the sensitivity list. Change this and your code will start to simulate like it's running on the FPGA.
This is hiding the other problems with the code because it's causing signals to update at the wrong time. You've managed to get your code to work in the simulator, but it's based on a lie. The lie is that R_A, R_B, prev, count & Mul_Result are only dependent on changes in state, but there's more signals which are inputs to that logic.
You've fallen into the trap that the Verilog keyword reg creates registers. It doesn't. I know it's silly, but that's the way it is. What reg means is that it's a variable that can be assigned to from a procedural block. wires can't be assigned to inside a procedural block.
A register is created when you assign something within a clocked procedural block (see footnote), like your state variable. R_A, R_B, prev and count all appear to be holding values across cycles, so need to be registers. I'd change the code like this:
First I'd create a set of next_* variables. These will contain the value we want in each register next clock.
reg [15:0] next_R_B;
reg [7:0] next_R_A;
reg next_prev;
reg [3:0] next_count;
Then I'd change the clocked process to use these:
always #(posedge clk or posedge reset) begin
if(reset==1) begin
state <= start;
R_A <= '0;
R_B <= '0;
prev <= '0;
count <= '0;
end else begin
R_A <= next_R_A;
R_B <= next_R_B;
prev <= next_prev;
count <= next_count;
case (state)
.....
Then finally change the first process to assign to the next_* variables:
always #* begin
next_R_A <= R_A;
next_R_B <= R_B;
next_prev <= prev;
next_count <= count;
case(state)
start: begin
next_R_A <= Mul_A;
next_R_B <= {8'b00000000,Mul_B};
next_prev <= 1'b0;
next_count <= 3'b000;
Mul_Result <= R_B[7:0];
end
add: begin
case({R_B[0],prev})
2'b00: begin
next_prev <= 1'b0;
end
.....
Note:
All registers now have a reset
The next_ value for any register defaults to it's previous value.
next_ values are never read, except for the clocked process
non-next_ values are never written, except in the clocked process.
I also suspect you want Mul_Result to be a wire and have it assign Mul_Result = R_B[7:0]; rather than it being another register that's only updated in the start state, but I'm not sure what you're going for there.
A register is normally a reg, but a reg doesn't have to be a register.

Resources