As part of my project for the Digital System Design course I have to use a component to display on the 7-segment display a INTEGER range 0 to 9999 (or a std_logic_vector(13 downto 0)). I used the double dabble algorithm to convert a 14 bit binary number into BCD and then extracted the 4 digits. I tested the component in Active-HDL and it works good, but once loaded on my Basys2 FPGA board, it displays the wrong numbers. For example, instead of "1770", I get "0064".
I am pretty sure that the problem is caused by something from the first process, where the BCD digits are generated, but I couldn't figure out what the problem is. Here is the code of the component:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity DISP_SOLD is
port (EN: in std_logic;
CLK_PLACA: in std_logic;
SUMA: in integer range 0 to 9999;
-- Cathodes
L18_CA: out std_logic;
F18_CB: out std_logic;
D17_CC: out std_logic;
D16_CD: out std_logic;
G14_CE: out std_logic;
J17_CF: out std_logic;
H14_CG: out std_logic;
-- Anodes
AN0_F17: out std_logic;
AN1_H17: out std_logic;
AN2_C18: out std_logic;
AN3_F15: out std_logic);
end DISP_SOLD;
architecture ARH of DISP_SOLD is
-- digit_pattern_array = current_BCD_digit
signal digit_pattern_array : std_logic_vector(6 downto 0) := "0000000";
signal current_segment : std_logic_vector(1 downto 0) := "00";
signal cathode_select : std_logic_vector(3 downto 0) := "0000";
-- count use for the clock divider
signal count : std_logic_vector(6 downto 0) := "0000000";
-- MUX_CLK is the clock resulting from the clock divider
signal MUX_CLK : std_logic;
signal cifra_mii: std_logic_vector(3 downto 0):="0000"; -- 1st digit
signal cifra_sute: std_logic_vector(3 downto 0):="0000"; -- 2nd digit
signal cifra_zeci: std_logic_vector(3 downto 0):="0000"; -- 3rd digit
signal cifra_unitati: std_logic_vector(3 downto 0):="0000"; -- 4th digit
begin
process(EN, SUMA)
variable BIN: std_logic_vector(13 downto 0);
variable BCD: std_logic_vector(15 downto 0):=(others => '0');
variable i: integer:=0;
variable CONVERTED: std_logic:='0';
begin
if EN='1' and CONVERTED='0' then
BIN := conv_std_logic_vector(SUMA, 14);
-- Convert Binary to BCD (Double Dabble algorithm)
for i in 0 to 13 loop
bcd(15 downto 1) := bcd(14 downto 0); --shifting the bits.
bcd(0) := bin(13);
bin(13 downto 1) := bin(12 downto 0);
bin(0) :='0';
if(i < 13 and bcd(3 downto 0) > "0100") then --add 3 if BCD digit is greater than 4.
bcd(3 downto 0) := bcd(3 downto 0) + "0011";
end if;
if(i < 13 and bcd(7 downto 4) > "0100") then --add 3 if BCD digit is greater than 4.
bcd(7 downto 4) := bcd(7 downto 4) + "0011";
end if;
if(i < 13 and bcd(11 downto 8) > "0100") then --add 3 if BCD digit is greater than 4.
bcd(11 downto 8) := bcd(11 downto 8) + "0011";
end if;
if(i < 13 and bcd(15 downto 12) > "0100") then --add 3 if BCD digit is greater than 4.
bcd(15 downto 12) := bcd(15 downto 12) + "0011";
end if;
end loop;
if SUMA /= 0 then
CONVERTED:='1';
end if;
cifra_mii <= BCD(15 downto 12);
cifra_sute <= BCD(11 downto 8);
cifra_zeci <= BCD(7 downto 4);
cifra_unitati <=BCD(3 downto 0);
end if;
end process;
-- CLK_PLACA: from 50MHz to MUX_CLK (~390Hz)
divizor_CLK: process(CLK_PLACA)
begin
if rising_edge(CLK_PLACA) then
count <= count + '1';
end if;
MUX_CLK <= count(6);
end process;
variable current_BCD_digit: std_logic_vector(3 downto 0);
begin
if rising_edge(MUX_CLK) then
current_segment <= current_segment + '1';
case current_segment is
when "00" => current_BCD_digit := cifra_mii;
cathode_select <= "1110";
when "01" => current_BCD_digit := cifra_sute;
cathode_select <= "1101";
when "10" => current_BCD_digit := cifra_zeci;
cathode_select <= "1011";
when "11" => current_BCD_digit := cifra_unitati;
cathode_select <= "0111";
when others => null;
end case;
case current_BCD_digit is
when "0000" => digit_pattern_array <= "0000001";
when "0001" => digit_pattern_array <= "1001111";
when "0010" => digit_pattern_array <= "0010010";
when "0011" => digit_pattern_array <= "0000110";
when "0100" => digit_pattern_array <= "1001100";
when "0101" => digit_pattern_array <= "0100100";
when "0110" => digit_pattern_array <= "0100000";
when "0111" => digit_pattern_array <= "0001111";
when "1000" => digit_pattern_array <= "0000000";
when "1001" => digit_pattern_array <= "0001100";
when others => null;
end case;
end if;
end process;
L18_CA <= digit_pattern_array(6);
F18_CB <= digit_pattern_array(5);
D17_CC <= digit_pattern_array(4);
D16_CD <= digit_pattern_array(3);
G14_CE <= digit_pattern_array(2);
J17_CF <= digit_pattern_array(1);
H14_CG <= digit_pattern_array(0);
AN0_F17 <= cathode_select(0) when EN='1' else '0';
AN1_H17 <= cathode_select(1) when EN='1' else '0';
AN2_C18 <= cathode_select(2) when EN='1' else '0';
AN3_F15 <= cathode_select(3) when EN='1' else '0';
end ARH;