Trying to blink LED in Verilog - verilog

I have a CPLD with a 50Mhz clock.
This is my code:
module FirstProject(clk, LED);
output LED;
input clk;
reg [32:0] count1;
reg LEDstatus;
assign LED = LEDstatus;
always # (posedge clk) begin
if (count1 < 10000000) begin
LEDstatus <= 0;
end
else begin
LEDstatus <= 1;
end
count1 <= count1 +1;
end
endmodule
I have no idea why this does not work. It deploys on CPLD, but light is always on
This code works on my cpld with the exact same pin assignments and timing constraints
http://www.fpga4fun.com/Opto2.html

The clock frequency is 50MHz, a On-Off loop is 2**33-1 (8589934591) cycles.
1/Hz = seconds
slowdown factor * 1/Hz = seconds to complete loop
This implies the LED is trying to flash at:
(8589934591 / 50000000) = 171s, slower than 1Hz
Anything over 25Hz would be not be perceived but that is not the issue here.
When the count is between 0 and 10000000 the light should be off:
10000000 / 50000000 = 0.2 Seconds
The off time is 0.2 seconds and the on time is about 170 seconds. It is likely that this ratio is very hard to observe. Switching to a 50/50 on/off ratio and a faster speed observation would be easier.
I would suggest making count1 24 bits wide and basing the output on the MSB of count1;
reg [23:0] count1;
always #(posedge clk) begin
LEDstatus <= count1[23];
count1 <= count1 + 1;
end

You turn the LED off for 0.025% of the time so you might as well not be flashing it.
You probably want to reset your count to zero when it reaches 20000000 so that it's on and off half the time each. Or else toggle the state when it reaches 1000000 instead -
if (count1 == 33'd1000000) begin
LEDstatus <= !LEDstatus;
end

Related

Timers and LEDs in 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!

How do I setup a counter to count seconds using Verilog

I'm trying to make a second counter and millisecond counter using Verilog. The Problem is that whenever I run a simulation, the value of the second counter (clk_1sec) and millisecond counter (clk_1msec) is fixed to 0.
My Simulation shows proper result until 19th line of the code, but the simulation doesn't show the proper result of clk_1sec and clk_1msec (value of those two counters are fixed to 0)
module clk_gen(clk_5k, reset, loopcount, clk_1sec, clk_1msec);
input clk_5k, reset;
output [14:0] loopcount;
output clk_1sec, clk_1msec;
reg [14:0] loopcount;
reg clk_1sec, clk_1msec;
always #(posedge clk_5k or negedge reset)
begin
if (~reset)
begin
clk_1sec <= 0; clk_1msec <= 0; loopcount <= 0;
end
else
loopcount <= loopcount + 2'b10;
begin
if (loopcount += 13'b1001110001000)
clk_1sec = ~clk_1sec;
else if (loopcount += 3'b101)
clk_1msec = ~clk_1msec;
end
end
end
end
endmodule
Expected result is that clk_1sec should change its value when the value of loopcount is loopcount + 5000 (decimal) and clk_1msec should change its value when the value of loopcount is loopcount + 5 (decimal).
There are some misunderstandings in your code:
You are using blocking assignments inside clocked always. You should use only non blocking assignments.
You are using 13 bit constants to operate with a 15 bit register (loopcount). You should use 15 bit constants.
And above all, you are using an improper way to tell if the value of loopcount is multiple of 5 (to count miliseconds). Multiples of something that is not a power of two is difficult to implement in hardware. Either you should use a power of two clock signal (32.768 kHz is a common clock for these applications) or you should use a counter to count cycles to get miliseconds and another one to count miliseconds to get one second.
Assuming a 32.768 kHz clock, your module would go like this:
module clk_gen (
input wire clk32768,
input wire reset,
output reg [15:0] loopcount,
output wire clk_1sec,
output wire clk_1msec
);
assign clk_1sec = loopcount[15]; // 1 exact second (32768 counts)
assign clk_1msec = loopcount[5]; // not quite 1ms, but 0.97ms
always #(posedge clk32768 or negedge reset) begin
if (~reset)
loopcount <= 16'd0;
else
loopcount <= loopcount + 16'd1;
end
endmodule
If you need to stick with a 5KHz clock and/or need precise milisecond measurement (within the limits of your clock oscillator), then you can do as this:
module clk_gen (
input wire clk_5k,
input wire reset,
output reg clk_1sec,
output reg clk_1msec
);
reg [2:0] counter_cycles; // counts from 0 to 4 cycles => 1ms
reg [9:0] counter_msecs; // counts from 0 to 999 msecons => 1s
always #(posedge clk_5k or negedge reset) begin
if (~reset) begin
clk_1sec <= 1'b0;
clk_1msec <= 1'b0;
counter_cycles <= 3'd0;
counter_msecs <= 10'd0;
end
else begin
if (counter_cycles == 3'd4) begin
counter_cycles <= 3'd0;
clk_1msec <= ~clk_1msec;
if (counter_msecs == 10'd999) begin
counter_msecs <= 10'd0;
clk_1sec <= ~clk_1sec;
end
else begin
counter_msecs <= counter_msecs + 10'd1;
end
end
else begin
counter_cycles <= counter_cycles + 3'd1;
end
end
end
endmodule
You can edit/simulate this version at
https://www.edaplayground.com/x/3CjH
The problem is improper nesting of begin/end blocks with the first else. Your indentation does not match what the compiler sees. And I'm sure you meant == instead of +=

How to find middle point between 2 pulses in Verilog in an FPGA?

I'm trying to find the mid-point between hsync pulses in a video stream. There are many "pixel clocks" in between hsync pulses. How can I get a pulse or signal exactly at the midpoint between two hsync pulses? Basically I want to be able to find the horizontal center of the screen. Here is what I have:
reg [30:0] count;
reg [30:0] counter;
wire left;
always #(posedge pixclk)
begin
if (hsync == 1'b1)
begin
count = counter;
counter = 1'b0;
end
else
begin
counter = counter + 1;
end
end
assign left = (counter < (count / 2) ? 1'b1 : 1'b0);
First, I don't know if this is conceptually the right way to do this.
Second, if hsync is held low for more than one pixclk cycle, then count will always be zero. It will only work if the width of hsync pulse is exactly one clock cycle or less.
First: You should use non-blocking assignments in a clocked section. <=
In your case you tell me that you have an hsync which is longer then your pixel clock.
One way is to count pulses when the hsync is low and store the result when it is high. That would require a small two-state Fine-State-Machine (FSM)
However I personally find making Fine-State-Machines a burden to be avoided. So here is what I would do:
Detect the edge of the hysnc (when it goes high or when it goes low) and count between the edges. Here is the core of the code:
reg hsync_one_cycle_delayed;
always #(posedge pixclk)
begin
hsync_one_cycle_delayed <= hsync;
if (hsync==1'b1 && hsync_one_cycle_delayed==1'b0)
// We have a detected a rising edge on hsync
begin
count <= counter;
counter <= 31'h0;
end
else
counter <= counter + 1;
end
Some final notes:
It assume the hsync is synchronous to the pixel clock.
This code has no reset which seems to become the norm in FPGA code, but which I personally deplore.

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

How to make an LED blink in Verilog?

I have a FPGA board and I'm trying to make an led blink with a 30% timing margin of 60 seconds.
I have the clock set at 24 MHz
Here is the code I used from a tutorial website
reg [33:0] counter;
reg state;
assign ledg[0] = state;
always # (posedge clock) begin
counter <= counter + 1;
state <= counter[24]; //
end
There are 3 concerns I have about this code:
I don't understand why the counter was declared with the subscript [33:0]
I don't understand why the state is set to unblock when counter[24]
Upon using this code, my timing margin is off, i.e. when I timed the amount of blinks per 60 seconds, it was 0.73, which is off by .03 according to the requirements.
Thanks
I don't understand why the counter was declared with the subscript [33:0]
The subscript [33:0] means that your counter has 34 bits. This means it can count from 0 to 2^(34)-1, or 0 to 17179869183 in decimal.
I don't understand why the state is set to unblock when counter[24]
Upon using this code, my timing margin is off, i.e. when I timed the
amount of blinks per 60 seconds, it was 0.73, which is off by .03
according to the requirements.
state is assigned to the 24th bit of the counter. That means that whenever the 24th bit of the counter is equal to 1, the state will be '1' and the LED will turn on. Whenever the 24th bit of the counter is 0, the state will be 0 and the LED will turn off.
Note that the 24th bit of the counter toggles every 2^24 cycles, or 16,777,216 cycles. Remember that your clock is 24 MHz so that means the clock toggles 24,000,000 times per second. So if your LED state toggles every 16,777,216 cycles, that means it toggles (16,777,216/24,000,000) times per second or every 0.699 second - so it should be very close to the 0.7 that you are looking for.
//300MHz to 1Hz
module top(
input clk,
input reset,
output led
);
reg [27:0] counter;
reg led;
reg clkout;
always #(posedge clk) begin
if (counter == 0) begin
counter <= 149999999;
clkout <= ~clkout;
end else begin
counter <= counter - 1;
end
end
always #(posedge clkout) begin
if (reset == 0) begin
led <= 0;
end else begin
led <= ~led;
end
end

Resources