Sir, Thank you so much for writing and breaking this code line-by-line. You are a gentleman and a scholar! You are making learning FPGAs not impossible!
Great video thanks. I found the hard way about 7 segment display on basys3 when i first started playing a month ago. so i ended up reversing the pattern by putting the 'a' on the right hand side and 'g' on the left. I am new to verilog and FPGA :-).
@@dajoma36 Dude I copied your code and ran it on my basys3 and it works beautifully. after correcting a few typo mistakes "Mhz" instead of "MHz" it runs perfect. Thank you!
Well, with any test bench you use reg to drive the inputs and wire to capture outputs. In the case of the seven segment display the outputs are 4 anodes and 7 cathodes, input is the clock.
Thanks! As for the refresh rate: It refers to how quickly the display updates or cycles through different digits or characters to maintain the illusion of continuous, stable information. Each anode is turned on, one after the other in sequential order, at a certain refresh rate / frequency. The human eye has limitations in perceiving high-frequency changes. A higher refresh rate generally results in smoother and more flicker-free displays when showing rapidly changing information, such as on the 7-segment displays. Rapidly cycling through the anodes repeatedly while changing the 7-bit segment value for each anode gives the illusion that the display is showing a stable number. If you slow the refresh rate way down, to let's say 10Hz, you will see how each anode is turned on then off, one after another, continuously. You should try it. Hope this helps.
Hello. The purpose of the 10 Hz clock is only for the demonstration of the 7 segment displays. Just so I could show you a counter. I could have used 1Hz, but that would have been slower.
@@danielafajardo9961 For a refresh of 2ms, the counter should count to 200,000 before switching to next digit. The period of a 100MHz clock is 1/100,000,000 which equals 10ns(10 x 10^-9 seconds). To achieve a period of 2ms, 10ns x 200,000 = 2ms. So, for a 2ms period per digit, the counter would count from 0 to 199,999 and then reset. This will achieve a total display refresh period of 2ms per digit x 4 digits = 8ms. Thank you for pointing this out. My calculation in the video is just dumb luck, I guess. I have updated the description for this video to explain better how to calculate the refresh period.
@@dajoma36 Oh, thank you for your explanation! Yes, I was asking cause I'm trying to implement a counter myself by applying what you explained in the video but without copying your code, just to see if I'm understanding well. Unfortunately, I don't have an fpga board so I'm not sure if it's working or not haha. but now I got how the refresh rate works, thank you!!!!
Hi, I seem to be getting a NSTD-1 and UCIO-1 errors when following this method step by step while trying to generate the bit-stream at the end. Any idea why that could happen? I checked the forums and I did find entries on those errors but I could not make head or tails of what they actually meant
Usually if problem with bitstream, then FPGA pin assignment is in error. Double check all files, especially XDC, to ensure they are correct. Sorry, this is all I got.
@@dajoma36 Thanks for the reply. So I had copied my project files from one location to another and opened the project from the latter location. Apparently, that caused all the errors. The errors went away as soon as I made a new project and redid everything.
Very simple to do. You don't need to loop through the anodes, you just turn on the ones you want to use by driving a 0 to them. For instance, if you use 3 digits to the right, send 1000 to the 4-bit anode. For the 9, just set the 7-bit seg value that is the pattern for displaying a 9.
@@dajoma36 but then won't it work as a counter ? I want to keep displaying a certain value without any change. The value isn't a user defined value and it will be the output of some calculations.
@@navaneethkrishnannampoothi2317 Hm. I'm trying to understand what you mean. Maybe look into the 7-segment display clock. The value that is displayed is dependent upon a counter value. If you mean something like displaying the value of a sensor, which is the result of a calculation, check out the video on I2C, which explains how to display the numerical result of the sensor. Hope this helps, if not, maybe provide more detail about what you are trying to do.
Hi bro u r videos are actually superb i am doing project real time clk(hr:min:sec) using 7 segment display and also i need to convert 24 hrs format into 12 hrs pls help to do this
Oh. After reading your comment again, I see that I may not have understood. Converting a 24 hours into 12 hours? I believe you would need another signal, for AM / PM. You could have one signal, like a reg, and if it is 0 consider it AM, and 1 consider it PM. Every 12 hours flip it. Is this what you meant?
Depends on how you order your segments. If from a - g, then you will have to change, as I did in the video. If you order from g - a, then you don't. As R. Vass mentioned in another comment on this video.
Use this testbench to check it in simulation `timescale 1ns / 1ps module testbench; reg clk_100MHz, reset; reg up; reg down; wire[6:0] seg; wire[2:0] digit;
top counter(clk_100MHz,reset,up,down,seg,digit);
always begin clk_100MHz = 1'b1; #10; clk_100MHz = 1'b0; #10; end initial begin up = "0"; down = "0";reset = "1"; #15; reset = "0"; #20; up = "1"; down = "0"; #20; up = "0"; down = "0"; #20; up = "1"; down = "0"; #20; up = "0"; down = "0"; #20; up = "1"; down = "0"; #20; up = "0"; down = "0"; #20; up = "1"; down = "0"; #20; up = "0"; down = "0"; #20; up = "1"; down = "0"; #20; up = "0"; down = "0"; #20; up = "1"; down = "0"; #20; up = "0"; down = "0"; #20; up = "1"; down = "0"; #20; up = "0"; down = "0"; #20; up = "1"; down = "0"; #20; up = "0"; down = "0"; #20; up = "1"; down = "0"; #20; up = "0"; down = "0"; #20; up = "1"; down = "0"; #20; up = "0"; down = "0"; #20; up = "1"; down = "0"; #20; up = "0"; down = "0"; #20; up = "1"; down = "0"; #20; up = "0"; down = "0";
#20; up = "0"; down = "0";reset = "1"; #15; reset = "0"; #20; up = "0"; down = "1"; #20; up = "0"; down = "0"; #20; up = "0"; down = "1"; #20; up = "0"; down = "0"; #20; up = "0"; down = "1"; #20; up = "0"; down = "0"; #20; up = "0"; down = "1"; #20; up = "0"; down = "0"; #20; up = "0"; down = "1"; #20; up = "0"; down = "0"; #20; up = "0"; down = "1"; #20; up = "0"; down = "0"; #20; up = "0"; down = "1"; #20; up = "0"; down = "0"; #20; up = "0"; down = "1"; #20; up = "0"; down = "0"; #20; up = "0"; down = "1"; #20; up = "0"; down = "0"; #20; up = "0"; down = "1"; #20; up = "0"; down = "0"; #20; up = "0"; down = "1"; end endmodule but sec and digit stay at a fixed value without changing, is my testbench wrong?
Sir, Thank you so much for writing and breaking this code line-by-line. You are a gentleman and a scholar! You are making learning FPGAs not impossible!
great video. I was stuck on how to control the seven segments individually and this was the only video i found that explained it
Great stuff - Most informative - Thanks for putting it out - Cheers :)
Great video thanks. I found the hard way about 7 segment display on basys3 when i first started playing a month ago. so i ended up reversing the pattern by putting the 'a' on the right hand side and 'g' on the left. I am new to verilog and FPGA :-).
I wouldn't say you did it in a "hard way", you just solved the problem in a different way. Props for figuring that out!
@@dajoma36 Dude I copied your code and ran it on my basys3 and it works beautifully. after correcting a few typo mistakes "Mhz" instead of "MHz" it runs perfect. Thank you!
@@Avionics2 Glad to hear it worked for you and that I am able to share what I know and teach others some stuff.
Hello, can you explain how can we simulate (seven segment led display) using testbench. For this very code.
Well, with any test bench you use reg to drive the inputs and wire to capture outputs. In the case of the seven segment display the outputs are 4 anodes and 7 cathodes, input is the clock.
Wonderful Video, Can you pls explain that what is the use of Refreshing Rate or Refreshing Period?
Thanks! As for the refresh rate:
It refers to how quickly the display updates or cycles through different digits or characters to maintain the illusion of continuous, stable information. Each anode is turned on, one after the other in sequential order, at a certain refresh rate / frequency. The human eye has limitations in perceiving high-frequency changes. A higher refresh rate generally results in smoother and more flicker-free displays when showing rapidly changing information, such as on the 7-segment displays. Rapidly cycling through the anodes repeatedly while changing the 7-bit segment value for each anode gives the illusion that the display is showing a stable number. If you slow the refresh rate way down, to let's say 10Hz, you will see how each anode is turned on then off, one after another, continuously. You should try it. Hope this helps.
@@dajoma36 Alright, Thanks for Explaining it more clearly!
14 bits binary to its 4 digits:
module bin2dec_digits(
input clk_10Hz,
input [13:0] in,
output reg [3:0] ones, tens, hundreds, thousands
);
always @(posedge clk_10Hz) begin
ones
Thanks for sharing.
Cool!
Variable 'digit' should not be used in output port connection
what does this error mean? Im getting this error in top module?
I don't know.
Simply change its data type from reg to wire
Im trying to figure out how to turn on one DP for one digit in the 7 segment display, so far im having no luck still
You can either use 8 bits for the segments with the 8th bit being the DP signal. Or, you can drive the DP as it's own signal.
Hello. I didn't understand why we need a 10 Hz clock. Could someone explain that to me, please?
Hello. The purpose of the 10 Hz clock is only for the demonstration of the 7 segment displays. Just so I could show you a counter. I could have used 1Hz, but that would have been slower.
@@dajoma36 Oh, I see. Thank you!!!
@@danielafajardo9961 You're welcome.
@@danielafajardo9961 For a refresh of 2ms, the counter should count to 200,000 before switching to next digit. The period of a 100MHz clock is 1/100,000,000 which equals 10ns(10 x 10^-9 seconds). To achieve a period of 2ms, 10ns x 200,000 = 2ms. So, for a 2ms period per digit, the counter would count from 0 to 199,999 and then reset. This will achieve a total display refresh period of 2ms per digit x 4 digits = 8ms.
Thank you for pointing this out. My calculation in the video is just dumb luck, I guess. I have updated the description for this video to explain better how to calculate the refresh period.
@@dajoma36 Oh, thank you for your explanation! Yes, I was asking cause I'm trying to implement a counter myself by applying what you explained in the video but without copying your code, just to see if I'm understanding well. Unfortunately, I don't have an fpga board so I'm not sure if it's working or not haha. but now I got how the refresh rate works, thank you!!!!
Hey great video, but i am stuck at one issue, i think maybe you can help me?
btw i have put an email to you! Hoping to hear back soon!
Hi, I seem to be getting a NSTD-1 and UCIO-1 errors when following this method step by step while trying to generate the bit-stream at the end. Any idea why that could happen? I checked the forums and I did find entries on those errors but I could not make head or tails of what they actually meant
Sorry, I have no idea. If the errors are from bitstream generation, then it may be a problem with Vivado.
Usually if problem with bitstream, then FPGA pin assignment is in error. Double check all files, especially XDC, to ensure they are correct. Sorry, this is all I got.
@@dajoma36 Thanks for the reply. So I had copied my project files from one location to another and opened the project from the latter location. Apparently, that caused all the errors. The errors went away as soon as I made a new project and redid everything.
@@deathmaster4035 Glad to hear you got it figured out.
Bro can you say how to show a constant number on the LED. For Example I have to keep showing the number 999
Very simple to do. You don't need to loop through the anodes, you just turn on the ones you want to use by driving a 0 to them. For instance, if you use 3 digits to the right, send 1000 to the 4-bit anode. For the 9, just set the 7-bit seg value that is the pattern for displaying a 9.
@@dajoma36 In this case all the LEDs will show the same value. What if I want to show different values on all the LEDs ?
@@navaneethkrishnannampoothi2317 Well, then you do what I did in the video.
@@dajoma36 but then won't it work as a counter ? I want to keep displaying a certain value without any change. The value isn't a user defined value and it will be the output of some calculations.
@@navaneethkrishnannampoothi2317 Hm. I'm trying to understand what you mean. Maybe look into the 7-segment display clock. The value that is displayed is dependent upon a counter value. If you mean something like displaying the value of a sensor, which is the result of a calculation, check out the video on I2C, which explains how to display the numerical result of the sensor. Hope this helps, if not, maybe provide more detail about what you are trying to do.
Hi bro u r videos are actually superb i am doing project real time clk(hr:min:sec) using 7 segment display and also i need to convert 24 hrs format into 12 hrs pls help to do this
For a 24 hour clock, just have your hours counter count from 1 to 24, instead of 1 to 12. Everything else should be the same, I think.
You will need to make the hours counter 5 bits, instead of 4. And, thanks for your comments on my vids.
Oh. After reading your comment again, I see that I may not have understood. Converting a 24 hours into 12 hours? I believe you would need another signal, for AM / PM. You could have one signal, like a reg, and if it is 0 consider it AM, and 1 consider it PM. Every 12 hours flip it. Is this what you meant?
@@dajoma36 brother can u share me ur mail id i will share my question wat are exactly specifications they mentioned
@@sankasuvarna1764 You can find my email on my ABOUT page. I will try to help you if I can.
You do not need to reverse endianness or reverse the indices in the xdc. They will still connect to the correct outputs.
Depends on how you order your segments. If from a - g, then you will have to change, as I did in the video. If you order from g - a, then you don't. As R. Vass mentioned in another comment on this video.
Use this testbench to check it in simulation
`timescale 1ns / 1ps
module testbench;
reg clk_100MHz, reset;
reg up;
reg down;
wire[6:0] seg;
wire[2:0] digit;
top counter(clk_100MHz,reset,up,down,seg,digit);
always begin
clk_100MHz = 1'b1;
#10; clk_100MHz = 1'b0;
#10;
end
initial begin
up = "0"; down = "0";reset = "1";
#15; reset = "0";
#20; up = "1"; down = "0";
#20; up = "0"; down = "0";
#20; up = "1"; down = "0";
#20; up = "0"; down = "0";
#20; up = "1"; down = "0";
#20; up = "0"; down = "0";
#20; up = "1"; down = "0";
#20; up = "0"; down = "0";
#20; up = "1"; down = "0";
#20; up = "0"; down = "0";
#20; up = "1"; down = "0";
#20; up = "0"; down = "0";
#20; up = "1"; down = "0";
#20; up = "0"; down = "0";
#20; up = "1"; down = "0";
#20; up = "0"; down = "0";
#20; up = "1"; down = "0";
#20; up = "0"; down = "0";
#20; up = "1"; down = "0";
#20; up = "0"; down = "0";
#20; up = "1"; down = "0";
#20; up = "0"; down = "0";
#20; up = "1"; down = "0";
#20; up = "0"; down = "0";
#20; up = "0"; down = "0";reset = "1";
#15; reset = "0";
#20; up = "0"; down = "1";
#20; up = "0"; down = "0";
#20; up = "0"; down = "1";
#20; up = "0"; down = "0";
#20; up = "0"; down = "1";
#20; up = "0"; down = "0";
#20; up = "0"; down = "1";
#20; up = "0"; down = "0";
#20; up = "0"; down = "1";
#20; up = "0"; down = "0";
#20; up = "0"; down = "1";
#20; up = "0"; down = "0";
#20; up = "0"; down = "1";
#20; up = "0"; down = "0";
#20; up = "0"; down = "1";
#20; up = "0"; down = "0";
#20; up = "0"; down = "1";
#20; up = "0"; down = "0";
#20; up = "0"; down = "1";
#20; up = "0"; down = "0";
#20; up = "0"; down = "1";
end
endmodule
but sec and digit stay at a fixed value without changing, is my testbench wrong?
Can I see the module you are testing? What is up and down for?
Never seen anyone use "0" and "1" for numbers. Maybe a new thing in Verilog? Try using only the integers 0 and 1, with no quotations.