Generic binary to 7segment
This post is about my GitLab project Binary to 7segment.
It’s a generic 7-segment display driver constructed like image below, as its name implies it’s going to take N-bit binary and output 7-segment equivalent numbers by multiplexing each segment automatically.
You must set number of bits in binary input (BINARY_WIDTH
) and number of 7-segment display digits (DISPLAY_NUMBER
) and whether it is common anode or not (COMMON_ANODE
).
binary_to_7segment.vhdl
consists of four modules, each one will be explained separately.
module binary to bcd
In binary_to_bcd.vhdl
, you declare number of bits in binary by using BINARY_WIDTH
and number of equivalent BCD digits by using TOTAL_BCD_DIGIT
.
- The module uses the double dabble algorithm1 to convert binary into BCD in the following way:
- initializes the variables
- checks if BCD digit is greater than four if so then adds three to it
- shifts BCD left and copy MSB of binary input to BCD LSB
- shifts binary input left by 1 bit
the above steps will be repeated for each bit of binary input
Module output (bcd_out
) goes into generic mux to select each BCD digit for conversion.
BINARY_WIDTH
to a lower value if you don’t need to display the maximum number that can be displayed using BCD digits; otherwise, it will waste FPGA resources that you didn’t need.module generic mux
generic_mux.vhdl
2 is a generic multiplexer of TOTAL_MUX_INPUT
input of N_BIT_MUX
wide each and output of N_BIT_MUX
wide.
In order to make a generic mux from STD_LOGIC_VECTOR type, the function slv_to_generic_mux_type
is used.
The generic mux select pins (mux_select
) that are driven by common pin selector are used for multiplexing BCD digits in order to convert them to 7-segment digits.
module bcd to 7segment
The bcd_to_7segment.vhdl
converts a 4-bit BCD digit to 7-bit 7-segment pins and chooses 7-segment type, Whether it is a common anode or cathode (COMMON_ANODE
).
The selected assignment uses a common anode configuration.
The MSB of the module’s output is the G
segment and its LSB is the A
segment.
The last assignment just not the selected assignment data if COMMON_ANODE
is false for common cathode 7-segment displays.
module common pin selector
The module is common_pin_selector.vhdl
.
mux_select
output is responsible for multiplexing 7-segment digits using generic mux while simultaneously generating DISPLAY_NUMBER
common pin signals.
The first part of the module is a counter that increases at every rising edge of the multiplexing_clock
for mux_select
output.
The second part is a ring counter3 for common_pins_out
that one bit is active at a time (it depends on COMMON_ANODE
whether the bit is zero or one).
count up 7segment (example)
-
The example has three more generics:
-
DEBOUNCE_CLOCK_DIVIDER
: divide input clock by 2N for clock of the module that debouches the button when you press it. -
MULTIPLEXING_CLOCK_DIVIDER
: divide input clock by 2N for 7-segment display multiplexing speed. -
COUNT_TO
: maximum number that will be displayed on 7-segment display.
-
It’s an example of generating digits from zero up to COUNT_TO
and cycle again using ascending_binary_generator.vhdl
which is a counter.
There are two counters for generating clocks for other modules:
debounce_clock_generator.vhdl
for denouncing3 thepush_button
inpush_button_debounce.vhdl
andmultiplexing_clock_generator.vhdl
for multiplexing the 7-segment displays in common pin selector.
push_button_debounce.vhdl
module must have an input clock eight times faster than the button you are pressing because of the three flip-flops in it for debouncing.There are two testbenches:
count_up_7segment_tb.vhd
checks if four 7-segment digits (seven_segment_out
) andcommon_pins_out
have correct values only for common anode.count_up_7segment_tb_2.vhd
checks if is the number of buttons pressed displayed correctly on each 7-segment digit at the respectivecommon_pins_out
.