FPGA 1-bit flashing light design [1241003385]
[Copy link]
1Blinking Light Design1. Project BackgroundLED (Light Emitting Diode), a solid-state semiconductor device that can convert electrical energy into visible light, can directly convert electricity into light. The heart of LED is a semiconductor chip, one end of the chip is attached to a bracket, one end is the negative pole, and the other end is connected to the positive pole of the power supply, so that the entire chip is encapsulated by epoxy resin. The semiconductor chip consists of two parts, one part is a Ptype semiconductor, in which holes dominate, and the other end is an Ntype semiconductor, which is mainly electrons. But when these two semiconductors are connected, a PN junction is formed between them. When the current acts on the chip through the wire, the electrons will be pushed to the P region, where the electrons and holes will recombine and then emit energy in the form of photons. This is the principle of LED light emission. The wavelength of light, that is, the color of light, is determined by the material that forms the PN junction. LED can directly emit red, yellow, blue, green, cyan, orange, purple, and white light. Initially, LED was used as an indicator light source for instruments and meters. Later, LEDs of various light colors were widely used in traffic lights and large-area display screens, producing good economic and social benefits. Take the 12-inch red traffic light as an example. In the United States, a long-life, low-light-efficiency 140-watt incandescent lamp was originally used as the light source, which produces 2,000 lumens of white light. After passing through the red filter, 90% of the light is lost, leaving only 200 lumens of red light. In the newly designed lamp, Lumileds uses 18 red LED light sources, including circuit losses, and consumes a total of 14 watts of power to produce the same light effect. Car signal lights are also an important application area for LED light sources. For general lighting, people need white light sources more. In 1998, the white light LED was successfully developed. This LED is made by packaging GaN chips and yttrium aluminum garnet (YAG). The GaN chip emits blue light (λp=465nm, Wd=30nm), and the YAG phosphor containing Ce3+ made by high temperature sintering is excited by the blue light and emits yellow light with a peak value of 550nm. The blue LED substrate is installed in a bowl-shaped reflective cavity and covered with a thin layer of resin mixed with YAG, about 200-500nm. Part of the blue light emitted by the LED substrate is absorbed by the phosphor, and the other part of the blue light is mixed with the yellow light emitted by the phosphor to obtain white light. For InGaN/YAG white LED, by changing the chemical composition of the YAG phosphor and adjusting the thickness of the phosphor layer, various colors of white light with a color temperature of 3500-10000K can be obtained. This method of obtaining white light through blue LED has a simple structure, low cost, and high technical maturity, so it is the most widely used. Ming Deyang's teaching board has a total of 8 green LED lights. Below is the schematic diagram of the LED lights. The left side LED6~LED13 is the silk screen of the board. The right side LED1~LED8 is the signal line name, which is invisible to readers on the board. One end of the LED light is connected to the high level 3.3V, and the other end is the signal line LED1~LED8. If LED1~LED8 is at a high level, the current will not flow, and the LED light will not emit light. If LED1~LED8 is at a low level, the current will flow, and the LED light will emit light. So whether the LED light emits light depends on the level of the signal LED1~LED8. Where are the signal lines LED1~LED8 connected to? Search the schematic document and you can find that these signals are connected to the pins of the FPGA. Below is the connection diagram between signal lines and FPGA pins. For example, the signal line LED1 is connected to the AA4 pin of the FPGA. Teaching board silk screen | | [/ td] [/tr] | | | | | | | | [align=left ]LED3 | | | [/td] [t d=111] | | | | [ align=left] LED6 | | | | | | | [align= left]LED8 | |
LED1~LED8 are connected to 8 pins of FPGA respectively, so the level of LED1~LED8, that is, whether the LED light will light up, depends on the output of FPGA pin. For example, FPGA pin AB14 is connected to LED7. To control the on and off of this light, FPGA only needs to output pin AB14 to low or high. When the output is high level, LED7 is off, and when the output is low level, LED7 is dark. All 8 LEDs can be controlled independently by FPGA. 2. Design goal This project uses 1 LED --- LED1 to realize the function of a flashing light. The working clock of the project is 50M, that is, the clock period is 20ns. When pin AA4 outputs a low level, LED1 lights up, and when it outputs a high level, LED1 lights up. The specific functional requirements are: every 1 second, light up for N seconds. The change of N seconds is: 1, 2, 3, ---, 9 seconds, and then cycle again. The following is a waveform: The board effect is shown in the figure below. For the demonstration video on the board, please visit the website: www.mdy-edu.com/xxxx. 3. Module design Let's first analyze the LED light on the board. To control the on and off of an LED light, the FPGA needs to generate a signal, assuming it is an LED, and this signal is connected to the LED light. To turn off the LED, FPGA outputs the signal led as 1; to turn on the LED, FPGA outputs the signal led as 0. In summary, our project requires three signals, clock clk, reset rst_n and output signal led. Let's analyze the functional requirements again. The changing pattern of the LED light is dark for 1 second and bright for N seconds. The change of N seconds is: 1, 2, 3, ---, 9 seconds, and then the cycle repeats. From the phenomenon into the signal, in fact, the signal is led = 1 for 1 second, then led = 0 for N seconds, where the change of N is: 1, 2, 3, ---, 9 seconds. The waveform diagram is as follows: The above figure is the waveform diagram of the change of led signal. At the first time, led=1 and lasts for 1 second, then led=0 and lasts for 1 second, for a total of 2 seconds; at the second time, led=1 and lasts for 1 second, then /font]led=0 and lasts for 2 seconds, a total of 3 seconds; and so on, the 9th time, led=1 and lasts for 1 second, then led=0 and lasts for 9 seconds, a total of 10 seconds. Then it repeats again. From the waveform, we can see that we need 1 counter to calculate the time, such as 2 seconds, 3 seconds, etc. The working clock of this project is 50MHz, that is, the period is 20ns. When the counter counts to 2_000_000_000/20=100_000_000, we know that 2 seconds have passed. Similarly, when the counter counts to 150_000_000, we know that 3 seconds have passed. When the counter counts to 500_000_000, it means that 10 seconds have passed. In addition, since the counter is counting continuously and never stops, it can be considered that the condition of adding 1 is always valid, which can be written as: assignadd_cnt==1. In summary, combined with the variable method, the code of the counter is as follows. Where x represents the number of the counter cnt0 to be counted. How to define this value will be considered later. Observing the waveform again, we find that there are words for the 1st, 2nd, and 9th times, which means that another counter is needed to indicate the number of times. The counter represents the number of times, so naturally it will add 1 after one is completed, because the condition for adding 1 can be end_cnt0. The counter needs to count 9 times in total. So the code is: With two counters, let's think about the changes of the output signal led. In summary, led has two change points: changing to 0 and changing to 1. The reason why it changes to 0 is that the count reaches 1 second, that is, when cnt0 counts to 1_000_000_000/20=50_000_000, the led changes to 0. The reason why it changes to 1 is that the counting time has expired, that is, end_cnt0. So the code of the led signal is as follows: Finally, let's think about the variable x.0pt], when we were discussing counters cnt0, we once said that "when the counter counts to 2_000_000_000/20=100_000_000, we know that 2 seconds have expired. By analogy, when the count reaches 150_000_000/20=100_000_000, we know that 2 seconds have expired. By analogy, when the count reaches 2, we know that 2seconds have expired. When you count _000, you know that 3 seconds is up. When you count to the 9th time, 500_000_000 means 10 seconds is up. You can see that the number of cnt0s to count is related to the number of times. The 1st, the 100_000_000th, the 2nd, the 150_000_000. That is, it is related to cnt1. Therefore, the code of x is as follows: This time, the main program has been completed. The next step is to complete module. Define the name of module as my_led. And we already know that this module has three signals: clk, rst_n and led. To this end, the code is as follows: Among them, clk and rst_n are input signals, led is the output signal, and the three signals are 1bit. Based on this information, we add the input and output port definitions. The code is as follows: Next, define the signal type. cnt0 is a signal generated by always, so the type is reg. The maximum value of cnt0 count is 500_000_000, which needs to be represented by 29 lines, that is, the bit width is 29 bits. Therefore, the code is as follows: add_cnt0 and end_cnt0 are both designed in the assign method, so the type is wire. And its value is 0 or 1, which can be represented by 1 line. Therefore, the code is as follows: cnt1 is a signal generated by always, so the type is reg. The maximum value of cnt1 count is 8, which needs to be represented by 4 roots, that is, the bit width is 4 bits. Therefore, the code is as follows: add_cnt1 and end_cnt1 are both designed using assign, so the type is wire. And its value is 0 or 1, 1 root line can be expressed. Therefore, the code is as follows: led is designed in the always way, so the type is reg. And its value is 0 or 1, 1 root line can be expressed. Therefore, the code is as follows: x is designed in the always way, so the type is reg. And its maximum value is 500_000_000, which requires 29 lines to represent. So the code is as follows: So far, the design of the entire code has been completed. The next step is to create a new project and put it on the board to check the phenomenon.0pt], I once said "When the counter counts to 2_000_000_000/20=100_000_000, we know that 2 seconds have passed. By analogy, when the counter counts to 150_000_000, we know that 3 seconds have passed. When the 9th time comes and the number reaches 500_000_000, it means the 10th second time is up. You can see that the number of cnt0s to be counted is related to the number of times. The 1st, the 100_000_000th, the 2nd, the 150_000_000. That is, it is related to cnt1. Therefore, the code of x is as follows: This time, the main program has been completed. The next step is to complete module. Define the name of module as my_led. And we already know that this module has three signals: clk, rst_n and led. To this end, the code is as follows: Among them, clk and rst_n are input signals, led is the output signal, and the three signals are 1bit. Based on this information, we add the input and output port definitions. The code is as follows: Next, define the signal type. cnt0 is a signal generated by always, so the type is reg. The maximum value of cnt0 count is 500_000_000, which needs to be represented by 29 lines, that is, the bit width is 29 bits. Therefore, the code is as follows: add_cnt0 and end_cnt0 are both designed in the assign method, so the type is wire. And its value is 0 or 1, which can be represented by 1 line. Therefore, the code is as follows: cnt1 is a signal generated by always, so the type is reg. The maximum value of cnt1 count is 8, which needs to be represented by 4 roots, that is, the bit width is 4 bits. Therefore, the code is as follows: add_cnt1 and end_cnt1 are both designed using assign, so the type is wire. And its value is 0 or 1, 1 root line can be expressed. Therefore, the code is as follows: led is designed in the always way, so the type is reg. And its value is 0 or 1, 1 root line can be expressed. Therefore, the code is as follows: x is designed in the always way, so the type is reg. And its maximum value is 500_000_000, which requires 29 lines to represent. So the code is as follows: So far, the design of the entire code has been completed. The next step is to create a new project and put it on the board to check the phenomenon.0pt], I once said "When the counter counts to 2_000_000_000/20=100_000_000, we know that 2 seconds have passed. By analogy, when the counter counts to 150_000_000, we know that 3 seconds have passed. When the 9th time comes and the number reaches 500_000_000, it means the 10th second time is up. You can see that the number of cnt0s to be counted is related to the number of times. The 1st, the 100_000_000th, the 2nd, the 150_000_000. That is, it is related to cnt1. Therefore, the code of x is as follows: This time, the main program has been completed. The next step is to complete module. Define the name of module as my_led. And we already know that this module has three signals: clk, rst_n and led. To this end, the code is as follows: Among them, clk and rst_n are input signals, led is the output signal, and the three signals are 1bit. Based on this information, we add the input and output port definitions. The code is as follows: Next, define the signal type. cnt0 is a signal generated by always, so the type is reg. The maximum value of cnt0 count is 500_000_000, which needs to be represented by 29 lines, that is, the bit width is 29 bits. Therefore, the code is as follows: add_cnt0 and end_cnt0 are both designed in the assign method, so the type is wire. And its value is 0 or 1, which can be represented by 1 line. Therefore, the code is as follows: cnt1 is a signal generated by always, so the type is reg. The maximum value of cnt1 count is 8, which needs to be represented by 4 roots, that is, the bit width is 4 bits. Therefore, the code is as follows: add_cnt1 and end_cnt1 are both designed using assign, so the type is wire. And its value is 0 or 1, 1 root line can be expressed. Therefore, the code is as follows: led is designed in the always way, so the type is reg. And its value is 0 or 1, 1 root line can be expressed. Therefore, the code is as follows: x is designed in the always way, so the type is reg. And its maximum value is 500_000_000, which requires 29 lines to represent. So the code is as follows: So far, the design of the entire code has been completed. The next step is to create a new project and put it on the board to check the phenomenon.0pt]" You can see that the number of cnt0 to be counted is related to the number of times. The 1st time, count 100_000_000, the 2nd t=宋体]times150_000_000. That is, it is related tocnt1. Therefore, the code ofx is as follows: This time, the main program has been completed. The next step is to complete the module. Define the name of module as my_led. And we already know that the module has three signals: clk, rst_n and led. To do this, the code is as follows: Among them, clk and rst_n are input signals, and led is the output signal, and all three signals are 1bit. Based on this information, we add the input and output port definitions. The code is as follows: Next, define the signal type. cnt0 is a signal generated by always, so the type is reg. The maximum value of cnt0 count is 500_000_000, which needs to be represented by 29 lines, that is, the bit width is 29 bits. Therefore, the code is as follows: add_cnt0 and end_cnt0 are both designed in the assign method, so the type is wire. And its value is 0 or 1, which can be represented by 1 line. Therefore, the code is as follows: cnt1 is a signal generated by always, so the type is reg. The maximum value of cnt1 count is 8, which needs to be represented by 4 roots, that is, the bit width is 4 bits. Therefore, the code is as follows: add_cnt1 and end_cnt1 are both designed using assign, so the type is wire. And its value is 0 or 1, 1 root line can be expressed. Therefore, the code is as follows: led is designed in the always way, so the type is reg. And its value is 0 or 1, 1 root line can be expressed. Therefore, the code is as follows: x is designed in the always way, so the type is reg. And its maximum value is 500_000_000, which requires 29 lines to represent. So the code is as follows: So far, the design of the entire code has been completed. The next step is to create a new project and put it on the board to check the phenomenon.0pt]" You can see that the number of cnt0 to be counted is related to the number of times. The 1st time, count 100_000_000, the 2nd t=宋体]times150_000_000. That is, it is related tocnt1. Therefore, the code ofx is as follows: This time, the main program has been completed. The next step is to complete the module. Define the name of module as my_led. And we already know that the module has three signals: clk, rst_n and led. To do this, the code is as follows: Among them, clk and rst_n are input signals, and led is the output signal, and all three signals are 1bit. Based on this information, we add the input and output port definitions. The code is as follows: Next, define the signal type. cnt0 is a signal generated by always, so the type is reg. The maximum value of cnt0 count is 500_000_000, which needs to be represented by 29 lines, that is, the bit width is 29 bits. Therefore, the code is as follows: add_cnt0 and end_cnt0 are both designed in the assign method, so the type is wire. And its value is 0 or 1, which can be represented by 1 line. Therefore, the code is as follows: cnt1 is a signal generated by always, so the type is reg. The maximum value of cnt1 count is 8, which needs to be represented by 4 roots, that is, the bit width is 4 bits. Therefore, the code is as follows: add_cnt1 and end_cnt1 are both designed using assign, so the type is wire. And its value is 0 or 1, 1 root line can be expressed. Therefore, the code is as follows: led is designed in the always way, so the type is reg. And its value is 0 or 1, 1 root line can be expressed. Therefore, the code is as follows: x is designed in the always way, so the type is reg. And its maximum value is 500_000_000, which requires 29 lines to represent. So the code is as follows: So far, the design of the entire code has been completed. The next step is to create a new project and put it on the board to check the phenomenon.0pt]The code is as follows: This time, the main program has been completed. The next step is to complete the module. Define the name of module as my_led. And we already know that this module has three signals: clk, rst_n and led. To this end, the code is as follows: Among them, clk and rst_n are input signals, led is the output signal, and the three signals are 1bit. Based on this information, we add the input and output port definitions. The code is as follows: Next, define the signal type. cnt0 is a signal generated by always, so the type is reg. The maximum value of cnt0 count is 500_000_000, which needs to be represented by 29 lines, that is, the bit width is 29 bits. Therefore, the code is as follows: add_cnt0 and end_cnt0 are both designed in the assign method, so the type is wire. And its value is 0 or 1, which can be represented by 1 line. Therefore, the code is as follows: cnt1 is a signal generated by always, so the type is reg. The maximum value of cnt1 count is 8, which needs to be represented by 4 roots, that is, the bit width is 4 bits. Therefore, the code is as follows: add_cnt1 and end_cnt1 are both designed using assign, so the type is wire. And its value is 0 or 1, 1 root line can be expressed. Therefore, the code is as follows: led is designed in the always way, so the type is reg. And its value is 0 or 1, 1 root line can be expressed. Therefore, the code is as follows: x is designed in the always way, so the type is reg. And its maximum value is 500_000_000, which requires 29 lines to represent. So the code is as follows: So far, the design of the entire code has been completed. The next step is to create a new project and put it on the board to check the phenomenon.0pt]The code is as follows: This time, the main program has been completed. The next step is to complete the module. Define the name of module as my_led. And we already know that this module has three signals: clk, rst_n and led. To this end, the code is as follows: Among them, clk and rst_n are input signals, led is the output signal, and the three signals are 1bit. Based on this information, we add the input and output port definitions. The code is as follows: Next, define the signal type. cnt0 is a signal generated by always, so the type is reg. The maximum value of cnt0 count is 500_000_000, which needs to be represented by 29 lines, that is, the bit width is 29 bits. Therefore, the code is as follows: add_cnt0 and end_cnt0 are both designed in the assign method, so the type is wire. And its value is 0 or 1, which can be represented by 1 line. Therefore, the code is as follows: cnt1 is a signal generated by always, so the type is reg. The maximum value of cnt1 count is 8, which needs to be represented by 4 roots, that is, the bit width is 4 bits. Therefore, the code is as follows: add_cnt1 and end_cnt1 are both designed using assign, so the type is wire. And its value is 0 or 1, 1 root line can be expressed. Therefore, the code is as follows: led is designed in the always way, so the type is reg. And its value is 0 or 1, 1 root line can be expressed. Therefore, the code is as follows: x is designed in the always way, so the type is reg. And its maximum value is 500_000_000, which requires 29 lines to represent. So the code is as follows: So far, the design of the entire code has been completed. The next step is to create a new project and put it on the board to check the phenomenon.Both add_cnt0 and end_cnt0 are designed in the assign method, so the type is wire. And its value is 0 or 1, which can be represented by 1 wire. Therefore, the code is as follows: cnt1 is a signal generated by always, so the type is reg. The maximum value of cnt1 count is 8, which needs to be represented by 4 wires, that is, the bit width is 4 bits. Therefore, the code is as follows: add_cnt1 and end_cnt1 are both designed in the assign way, so the type is wire. And its value is 0 or 1, 1 root line can be represented. Therefore, the code is as follows: led is designed in the always way, so the type is reg. And its value is 0 or 1, 1 root line can be represented. Therefore, the code is as follows: x is designed in the always way, so the type is reg. And its maximum value is 500_000_000, which requires 29 lines to represent it. Therefore, the code is as follows: So far, the design work of the entire code has been completed. The next step is to create a new project and put it on the board to check the phenomenon. Both add_cnt0 and end_cnt0 are designed in the assign method, so the type is wire. And its value is 0 or 1, which can be represented by 1 wire. Therefore, the code is as follows: cnt1 is a signal generated by always, so the type is reg. The maximum value of cnt1 count is 8, which needs to be represented by 4 wires, that is, the bit width is 4 bits. Therefore, the code is as follows: add_cnt1 and end_cnt1 are both designed in the assign way, so the type is wire. And its value is 0 or 1, 1 root line can be represented. Therefore, the code is as follows: led is designed in the always way, so the type is reg. And its value is 0 or 1, 1 root line can be represented. Therefore, the code is as follows: x is designed in the always way, so the type is reg. And its maximum value is 500_000_000, which requires 29 lines to represent it. Therefore, the code is as follows: So far, the design work of the entire code has been completed. The next step is to create a new project and put it on the board to check the phenomenon.
|