0
\$\begingroup\$

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;
asked May 24, 2013 at 15:14
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

In VHDL (and HDLs in general) a for loop does not denote sequential execution like it does in a software programming language — it denotes the construction of multiple parallel instances of the hardware described in the body of the loop.

In your case, you have many assignments to the same variable BCD/bcd, and these are conflicting with each other. If you really intend to construct a system based on two shift registers (one binary, one bcd) that takes 14 clock periods to do the conversion, then you need to describe the hardware that way, and set up a state machine to control it.

On the other hand, if you really want to do it entirely combinatorially, then you need to create different intermediate variables (e.g., arrays that are indexed by the loop control variable) to hold the results at each stage.

answered May 24, 2013 at 16:10
\$\endgroup\$
2
  • \$\begingroup\$ Thank you for your answer! I do not insist to do it combinationally. The binary to BCD conversion I used was inspired from this website, with the only difference that I generated a 16-bit BCD number. It sais there that the code works, and is synthesisable. \$\endgroup\$ Commented May 24, 2013 at 16:30
  • 1
    \$\begingroup\$ Yes, but in that example, they used a function, while you turned it into a process -- completely different in terms of the synthesis process. \$\endgroup\$ Commented May 24, 2013 at 17:07

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.