Digital Design Using Digilent Fpga Boards Verilog
This FPGA tutorial will guide you how to control the 4-digit seven-segment display on Basys 3 FPGA Board. A display controller will be designed in Verilog for displaying numbers on the 4-digit 7-segment LED display of the Basys 3 FPGA. Full Verilog code for the seven-segment LED display controller will also be provided.
The Basys 3 FPGA has a common-anode 4-digit 7-segment LED display as shown in the following figure.
Seven anodes of the seven segments in a single LED are connected together to one common anode node while its cathodes are separate as shown in the following figure. DP-segment is to illuminate the dot so we omit the DP-segment for now since it is not contributing to the number value of the seven-segment display.
To illuminate LED segments such as A-G, anodes of these segments need to be at the 'high' logic level and cathodes should be at the 'low' logic level. Thus, the common anode node should be high to activate a single seven-segment LED display. The logic levels of cathodes can be varying from low (illuminated) to high(un-illuminated) to show different decimal values on a single 7-segment LED display as follows.
As shown in the figure above, we can display the numbers from zero to nine on the seven-segment LED display by turning on and off the seven segments of the single seven-segment LED display. For example, to show number "1" on the LED, the segments A, F, G, E, and D are un-illuminated or their cathodes should be high, and B-C segments are illuminated or their cathodes should be low. Similarly, we can obtain the following decoder table for displaying ten numbers on seven-segment LED display:
The table shows the needed cathode patterns for showing corresponding numbers on a single 7-segment LED display of the Basys 3 FPGA board.
For now, we know how to display numbers on a single seven-segment LED display on Basys 3 FPGA board. However, the cathodes of four seven-segment LEDs on Basys 3 are not separate but connected together as shown in the following figure.
Thus, to display 4 different numbers on the 4-digit seven-segment LED display, we have to control the cathodes (CA-CG) of the four seven-segment LEDs separately by activating the four seven-segment LEDs at different times. For example, when we activate LED 1 by driving A1 high and the other three LEDs (LED 2, LED 3, LED 4) are deactivated (A2, A3, and A4 not driven), the cathode pattern (CA-CG) will be used for displaying numbers on LED 1. Similarly, LED 2 - LED 4 can be displayed by using the same way at different times. As shown in the figure above, we can control activating four seven-segment LEDs by using 4 PNP transistors AN0-AN3. When a transistor is on or the Base terminal (W4, U4, V4, or U2) is low, the corresponding anode is driven high to activate or enable the corresponding seven-segment LED.
When a LED is deactivated after illuminating, it will darken. To avoid the displaying discontinuity perceived by the human eye, the four seven-segment LEDs should be continuously refreshed at about 1KHz to 60Hz or it should be refreshed at every 1ms to 16ms.
In this FPGA tutorial, a seven-segment LED display controller is designed for displaying numbers on the four-digit 7-segment LED display of the Basys 3 FPGA board. The following is the timing diagram for the seven-segment LED display controller on Basys 3 FPGA:
Below is an example timing diagram for displaying "1234" on the 4-digit 7-segment LED display of Basys 3 FPGA board with the refresh rate of 60Hz or period of 16ms:
Now, we know how to control and display numbers on the four-digit seven-segment LED display on Basys 3 FPGA. Next, let's design the 7-segment LED display controller.
The Basys 3 FPGA has a clock source of 100MHz and we need a 1ms-16ms refresh period or a 1KHz-60Hz refresh rate. I will choose a refresh period of 10.5ms (digit period = 2.6ms) so that we can use a 20-bit counter for creating the refresh period with the first 2 MSB bits of the counter for creating LED-activating signals (digit period of 2.6ms) as shown in the timing diagram above.
Below is an example Verilog code for creating the refresh signal and LED-activating signals:
reg [19 : 0] refresh_counter;
// the first 18-bit for creating 2.6ms digit period // the other 2-bit for creating 4 LED-activating signals
wire [1 : 0] LED_activating_counter;
// count 0 -> 1 -> 2 -> 3
// activates LED1 LED2 LED3 LED4 // and repeat always @(posedge clock_100Mhz or posedge reset) begin if(reset== 1) refresh_counter <= 0; else refresh_counter <= refresh_counter + 1; end assign LED_activating_counter = refresh_counter[19 : 18];
After that, we need to generate the anode signals (W4, V4, U4, U2) for the four-digit 7-segment LED display based on the LED-activating counter. The LED-activating counter will repeatedly count from zero to three for continuously activating and updating the four seven-segment LEDs.
Below is an example Verilog code for creating the anode signals and updating values of the four 7-segment LEDs on Basys 3 FPGA:
// anode activating signals for 4 LEDs // decoder to generate anode signals always @(*) begin case(LED_activating_counter) 2'b00 : begin Anode_Activate = 4'b0111; // activate LED1 and Deactivate LED2, LED3, LED4 LED_BCD = displayed_number[15 : 11]; // the first hex-digit of the 16-bit number end 2'b01 : begin Anode_Activate = 4'b1011; // activate LED2 and Deactivate LED1, LED3, LED4 LED_BCD = displayed_number[10 : 8]; // the second hex-digit of the 16-bit number end 2'b10 : begin Anode_Activate = 4'b1101; // activate LED3 and Deactivate LED2, LED1, LED4 LED_BCD = displayed_number[7 : 4]; // the third hex-digit of the 16-bit number end 2'b11 : begin Anode_Activate = 4'b1110; // activate LED4 and Deactivate LED2, LED3, LED1 LED_BCD = displayed_number[3 : 0]; // the fourth hex-digit of the 16-bit number end default : begin Anode_Activate = 4'b0111; // activate LED1 and Deactivate LED2, LED3, LED4 LED_BCD = displayed_number[15 : 11]; // the first hex-digit of the 16-bit number end endcase end
Last but not least, the example Verilog code for BCD to 7-segment decoder based on the decoder table above:
reg[6 : 0] LED_out; // Cathode patterns of the 7-segment LED display always @(*) begin case(LED_BCD) 4'b0000 : LED_out = 7'b0000001; // "0" 4'b0001 : LED_out = 7'b1001111; // "1" 4'b0010 : LED_out = 7'b0010010; // "2" 4'b0011 : LED_out = 7'b0000110; // "3" 4'b0100 : LED_out = 7'b1001100; // "4" 4'b0101 : LED_out = 7'b0100100; // "5" 4'b0110 : LED_out = 7'b0100000; // "6" 4'b0111 : LED_out = 7'b0001111; // "7" 4'b1000 : LED_out = 7'b0000000; // "8" 4'b1001 : LED_out = 7'b0000100; // "9" default : LED_out = 7'b0000001; // "0" endcase end
The design for 7-segment LED display controller is basically completed. Let's use the controller to display a 16-bit counting number on the four-digit seven-segment LED display of the Basys 3 FPGA board with the counting period of 1 second.
Full Verilog code of the seven-segment LED display controller for displaying counting numbers on Basys 3 FPGA:
// fpga4student.com: FPGA projects, Verilog projects, VHDL projects // FPGA tutorial: seven-segment LED display controller on Basys 3 FPGA module Seven_segment_LED_Display_Controller( input clock_100Mhz, // 100 Mhz clock source on Basys 3 FPGA input reset, // reset output reg [3 : 0] Anode_Activate, // anode signals of the 7-segment LED display output reg [6 : 0] LED_out// cathode patterns of the 7-segment LED display ); reg [26 : 0] one_second_counter; // counter for generating 1 second clock enable wire one_second_enable;// one second enable for counting numbers reg [15 : 0] displayed_number; // counting number to be displayed reg [3 : 0] LED_BCD; reg [19 : 0] refresh_counter; // 20-bit for creating 10.5ms refresh period or 380Hz refresh rate // the first 2 MSB bits for creating 4 LED-activating signals with 2.6ms digit period wire [1 : 0] LED_activating_counter;
// count 0 -> 1 -> 2 -> 3 // activates LED1 LED2 LED3 LED4 // and repeat always @(posedge clock_100Mhz or posedge reset) begin if(reset== 1) one_second_counter <= 0; else begin if(one_second_counter>= 99999999) one_second_counter <= 0; else one_second_counter <= one_second_counter + 1; end end assign one_second_enable = (one_second_counter== 99999999)? 1 : 0; always @(posedge clock_100Mhz or posedge reset) begin if(reset== 1) displayed_number <= 0; else if(one_second_enable== 1) displayed_number <= displayed_number + 1; end always @(posedge clock_100Mhz or posedge reset) begin if(reset== 1) refresh_counter <= 0; else refresh_counter <= refresh_counter + 1; end assign LED_activating_counter = refresh_counter[19 : 18]; // anode activating signals for 4 LEDs, digit period of 2.6ms // decoder to generate anode signals always @(*) begin case(LED_activating_counter) 2'b00 : begin Anode_Activate = 4'b0111; // activate LED1 and Deactivate LED2, LED3, LED4 LED_BCD = displayed_number/ 1000; // the first digit of the 16-bit number end 2'b01 : begin Anode_Activate = 4'b1011; // activate LED2 and Deactivate LED1, LED3, LED4 LED_BCD = (displayed_number % 1000)/ 100; // the second digit of the 16-bit number end 2'b10 : begin Anode_Activate = 4'b1101; // activate LED3 and Deactivate LED2, LED1, LED4 LED_BCD = ((displayed_number % 1000)% 100)/ 10; // the third digit of the 16-bit number end 2'b11 : begin Anode_Activate = 4'b1110; // activate LED4 and Deactivate LED2, LED3, LED1 LED_BCD = ((displayed_number % 1000)% 100)% 10; // the fourth digit of the 16-bit number end endcase end // Cathode patterns of the 7-segment LED display always @(*) begin case(LED_BCD) 4'b0000 : LED_out = 7'b0000001; // "0" 4'b0001 : LED_out = 7'b1001111; // "1" 4'b0010 : LED_out = 7'b0010010; // "2" 4'b0011 : LED_out = 7'b0000110; // "3" 4'b0100 : LED_out = 7'b1001100; // "4" 4'b0101 : LED_out = 7'b0100100; // "5" 4'b0110 : LED_out = 7'b0100000; // "6" 4'b0111 : LED_out = 7'b0001111; // "7" 4'b1000 : LED_out = 7'b0000000; // "8" 4'b1001 : LED_out = 7'b0000100; // "9" default : LED_out = 7'b0000001; // "0" endcase end endmodule
Pin constraint file for the four-digit seven-segment LED display on Basys 3 FPGA:
# Clock signal set_property PACKAGE_PIN W5 [get_ports clock_100Mhz] set_property IOSTANDARD LVCMOS33 [get_ports clock_100Mhz] set_property PACKAGE_PIN R2 [get_ports reset] set_property IOSTANDARD LVCMOS33 [get_ports reset] #seven-segment LED display set_property PACKAGE_PIN W7 [get_ports {LED_out[6]}] set_property IOSTANDARD LVCMOS33 [get_ports {LED_out[6]}] set_property PACKAGE_PIN W6 [get_ports {LED_out[5]}] set_property IOSTANDARD LVCMOS33 [get_ports {LED_out[5]}] set_property PACKAGE_PIN U8 [get_ports {LED_out[4]}] set_property IOSTANDARD LVCMOS33 [get_ports {LED_out[4]}] set_property PACKAGE_PIN V8 [get_ports {LED_out[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {LED_out[3]}] set_property PACKAGE_PIN U5 [get_ports {LED_out[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {LED_out[2]}] set_property PACKAGE_PIN V5 [get_ports {LED_out[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {LED_out[1]}] set_property PACKAGE_PIN U7 [get_ports {LED_out[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {LED_out[0]}]
set_property PACKAGE_PIN U2 [get_ports {Anode_Activate[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {Anode_Activate[0]}] set_property PACKAGE_PIN U4 [get_ports {Anode_Activate[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {Anode_Activate[1]}] set_property PACKAGE_PIN V4 [get_ports {Anode_Activate[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {Anode_Activate[2]}] set_property PACKAGE_PIN W4 [get_ports {Anode_Activate[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {Anode_Activate[3]}]
Now, create a new project in Vivado, choose the device part number of XC7A35T-1CPG236C for Artix-7 FPGA on Basys 3 FPGA board. Then, add the source and constraint files, and generate the bitstream. Program the FPGA using the bit stream and see how it works on the Basys 3 FPGA board.
Demo video for seven-segment LED display controller on Basys 3 FPGA board:
Here is the full VHDL code for seven-segment display on Basys 3 FPGA.
Recommended FPGA projects for students:
1. What is FPGA? How does FPGA work?
2. What is FPGA Programming?
3. How to load text file or image into FPGA
4. Image processing on FPGA using Verilog
5. License Plate Recognition on FPGA
6. Alarm Clock on FPGA using Verilog
7. Digital Clock on FPGA using VHDL
8. Traffic Light Controller on FPGA
9. Car Parking System on FPGA in Verilog
10. Verilog implementation of Microcontroller on FPGA
11. VHDL Matrix Multiplication on FPGA Xilinx
12. VHDL code for Microcontroller on FPGA
13. VHDL code for FIR Filter on FPGA
14. Single-Cycle MIPS processor on FPGA using Verilog
15. RISC Processor Design on FPGA using Verilog
16. PWM Generator on FPGA using VHDL
17. Tic Tac Toe Game on FPGA using Verilog
18. Pipelined MIPS Processor on FPGA in Verilog
19. Affordable Xilinx FPGA boards for beginners
20. Affordable Altera FPGA boards for beginners
21. Basys 3 FPGA OV7670 Camera
Digital Design Using Digilent Fpga Boards Verilog
Source: https://www.fpga4student.com/2017/09/seven-segment-led-display-controller-basys3-fpga.html
0 Response to "Digital Design Using Digilent Fpga Boards Verilog"
Publicar un comentario