Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
13 years ago

8bits to 7segments decoder

Hi, im trying to make a 8bits to 3digits 7segments decoder usind a double dabble, but there is something wrong with my code and i dont know what, can you help me?

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
  package my_pkg is 
        function to_bcd (bin : std_logic_vector(7 downto 0)) return std_logic_vector;
  end package my_pkg;
  package body my_pkg is 
    function to_bcd (bin : std_logic_vector(7 downto 0)) return std_logic_vector is
variable i : integer:=0;
variable bcd : std_logic_vector(11 downto 0) := (others => '0');
variable bint : std_logic_vector(7 downto 0) := bin;
begin
for i in 0 to 7 loop  
bcd(11 downto 1) := bcd(10 downto 0); 
bcd(0) := bint(7);
bint(7 downto 1) := bint(6 downto 0);
bint(0) :='0';
if(i < 7 and bcd(3 downto 0) > "0100") then 
bcd(3 downto 0) := bcd(3 downto 0) + "0011";
end if;
if(i < 7 and bcd(7 downto 4) > "0100") then 
bcd(7 downto 4) := bcd(7 downto 4) + "0011";
end if;
if(i < 7 and bcd(11 downto 8) > "0100") then  
bcd(11 downto 8) := bcd(11 downto 8) + "0011";
end if;
end loop;
return bcd;
end to_bcd;
  end package body my_pkg;
entity termometro is
port (
    clk: in std_logic;
    data: in std_logic_vector(7 downto 0);
    Di: out std_logic_vector (6 downto 0);
    Vtc:out std_logic_vector(3 downto 0));
end termometro;
architecture behavior of termometro is
    signal bcd1, bcd2, bcd3: std_logic_vector(3 downto 0);
    type segs is(se0, se1, se2);
    signal seg_atual, prox_seg: segs;
    signal S1, S2, S3: std_logic_vector(6 downto 0);
    begin
        bcd1<=to_bcd(3 downto 0);
        bcd2<=to_bcd(7 downto 4);
        bcd3<=to_bcd(11 downto 7);
    
    process(bcd1, bcd2, bcd3)
    begin
    WITH bcd1 SELECT
    S1 <= "1111110" when "0000",
            "0110000" when "0001",
            "1101101" when "0010",
            "1111001" when "0011",
            "0110011" when "0100",
            "1011011" when "0101",
            "0100000" when "0110",
            "1110000" when "0111",
            "1111111" when "1000",
            "1111011" when "1001",
            "0000000" when others;
    WITH bcd2 SELECT
    S1 <= "1111110" when "0000",
            "0110000" when "0001",
            "1101101" when "0010",
            "1111001" when "0011",
            "0110011" when "0100",
            "1011011" when "0101",
            "0100000" when "0110",
            "1110000" when "0111",
            "1111111" when "1000",
            "1111011" when "1001",
            "0000000" when others;
    WITH bcd3 SELECT
    S1 <= "1111110" when "0000",
            "0110000" when "0001",
            "1101101" when "0010",
            "1111001" when "0011",
            "0110011" when "0100",
            "1011011" when "0101",
            "0100000" when "0110",
            "1110000" when "0111",
            "1111111" when "1000",
            "1111011" when "1001",
            "0000000" when others;
    
    end process;
    
    process(clk) is
    begin
        if(clk = '1' and clk'event) then
            seg_atual<=prox_seg;
        end if;
    end process;
    
    process (S1, S2, S3) is
        begin    
                case seg_atual is
                    when se0=>
                        Di <= S1;
                        Vtc<= "0001";
                        prox_seg <= se1;
                    when se1 =>
                        Di <= S2;
                        Vtc<= "0010";
                        prox_seg <= se2;
                    when se2 =>
                        Di <= S3";
                        Vtc<= "0100";
                        prox_seg <= se3;
                end case;
            end process;
    
end behavior;
    

7 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    What is the 'something' that is wrong with your code?

    --- Quote End ---

    it says that is something wrong with de syntax but there isnt, so i coment this part and then other error apears but none of them are usefull

    the compiler doesn't seems to know what's wrong with the code, the syntax itself is correct, i triplecheck it

    the thing is, i dont know what is this something, thats why im asking for help xD
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Well my suggestion is to read the error message and to fix whatever it is saying is wrong with your code.

    Without the error messages themselves it is difficult to give more help.

    There is at least an error that I can see in your code. You used a with...select construction, that is a concurrent statement and can't be placed in a process. Either put it outside or use a case statement.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Between the 'end package body my_pkg;' and the following entity you have to (re-)declare all used libraries (including the above defined package)

    Your FSM is not fully elaborated (missing state se3.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Did both things but still not working

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_arith.all;
      package my_pkg is 
    		function to_bcd (bin : std_logic_vector(7 downto 0)) return std_logic_vector;
      end package my_pkg;
      
      library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_arith.all;
      package body my_pkg is 
        function to_bcd (bin : std_logic_vector(7 downto 0)) return std_logic_vector is
    variable i : integer:=0;
    variable bcd : std_logic_vector(11 downto 0) := (others => '0');
    variable bint : std_logic_vector(7 downto 0) := bin;
    begin
    for i in 0 to 7 loop  
    bcd(11 downto 1) := bcd(10 downto 0); 
    bcd(0) := bint(7);
    bint(7 downto 1) := bint(6 downto 0);
    bint(0) :='0';
    if(i < 7 and bcd(3 downto 0) > "0100") then 
    bcd(3 downto 0) := bcd(3 downto 0) + "0011";
    end if;
    if(i < 7 and bcd(7 downto 4) > "0100") then 
    bcd(7 downto 4) := bcd(7 downto 4) + "0011";
    end if;
    if(i < 7 and bcd(11 downto 8) > "0100") then  
    bcd(11 downto 8) := bcd(11 downto 8) + "0011";
    end if;
    end loop;
    return bcd;
    end to_bcd;
      end package body my_pkg;
    entity termometro is
    port (
    	clk: in std_logic;
    	data: in std_logic_vector(7 downto 0);
    	Di: out std_logic_vector (6 downto 0);
    	Vtc:out std_logic_vector(3 downto 0));
    end termometro;
    architecture behavior of termometro is
    	signal bcd1, bcd2, bcd3: std_logic_vector(3 downto 0);
    	type segs is(se0, se1, se2);
    	signal seg_atual, prox_seg: segs;
    	signal S1, S2, S3: std_logic_vector(6 downto 0);
    	begin
    		bcd1<=to_bcd(3 downto 0);
    		bcd2<=to_bcd(7 downto 4);
    		bcd3<=to_bcd(11 downto 7);
    	
    	WITH bcd1 SELECT
    	S1 <= "1111110" when "0000",
    			"0110000" when "0001",
    			"1101101" when "0010",
    			"1111001" when "0011",
    			"0110011" when "0100",
    			"1011011" when "0101",
    			"0100000" when "0110",
    			"1110000" when "0111",
    			"1111111" when "1000",
    			"1111011" when "1001",
    			"0000000" when others;
    	WITH bcd2 SELECT
    	S1 <= "1111110" when "0000",
    			"0110000" when "0001",
    			"1101101" when "0010",
    			"1111001" when "0011",
    			"0110011" when "0100",
    			"1011011" when "0101",
    			"0100000" when "0110",
    			"1110000" when "0111",
    			"1111111" when "1000",
    			"1111011" when "1001",
    			"0000000" when others;
    	WITH bcd3 SELECT
    	S1 <= "1111110" when "0000",
    			"0110000" when "0001",
    			"1101101" when "0010",
    			"1111001" when "0011",
    			"0110011" when "0100",
    			"1011011" when "0101",
    			"0100000" when "0110",
    			"1110000" when "0111",
    			"1111111" when "1000",
    			"1111011" when "1001",
    			"0000000" when others;
    	
    	process(clk) is
    	begin
    		if(clk = '1' and clk'event) then
    			seg_atual<=prox_seg;
    		end if;
    	end process;
    	
    	process (S1, S2, S3) is
    		begin	
    				case seg_atual is
    					when se0=>
    						Di <= S1;
    						Vtc<= "0001";
    						prox_seg <= se1;
    					when se1 =>
    						Di <= S2;
    						Vtc<= "0010";
    						prox_seg <= se2;
    					when se2 =>
    						Di <= S3";
    						Vtc<= "0100";
    						prox_seg <= se3;
    				end case;
    			end process;
    	
    end behavior;
    	
    

    the following error occured:

    Error (10500): VHDL syntax error at termometro.vhd(126) near text "";" end of line inside a string

    Error (10500): VHDL syntax error at termometro.vhd(126) near text "";"; expecting ";"

    same as before

    tried change the syntax but still nothing
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Take some time, look at the error. It is on line 126. Look closely, your compiler is trying to help you. See lines 118 and 122 for reference.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Take some time, look at the error. It is on line 126. Look closely, your compiler is trying to help you. See lines 118 and 122 for reference.

    --- Quote End ---

    i wasn't the main problem, but i already solved it

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_unsigned.all;
        
      package my_pkg is 
            function to_bcd (bin : std_logic_vector(7 downto 0)) return std_logic_vector;
      end package my_pkg;
      
      package body my_pkg is 
        function to_bcd (bin : std_logic_vector(7 downto 0)) return std_logic_vector is
         variable aux: std_logic_vector (20 downto 0);
         variable bcd: std_logic_vector(11 downto 0);
      begin 
      aux := (OTHERS=>'0');
      aux(8 downto 1) := bin(7 downto 0); 
     
      for i in 0 to 7 loop 
       if aux(12 downto 9) > 4 then  
           aux(12 downto 9) := aux(12 downto 9) + 3; 
       end if; 
       if aux(16 downto 13) > 4 then  
           aux(16 downto 13) := aux(16 downto 13) + 3; 
       end if; 
       aux(20 downto 1) := aux(19 downto 0); 
      end loop; 
     
     bcd := aux(20 downto 9);
     return bcd;
    end to_bcd;
      end package body my_pkg;
    library ieee;
    use ieee.std_logic_1164.all;
    library work;
    use work.my_pkg.all;
    entity termometro is
    port (
        data: in std_logic_vector(7 downto 0);
        Di: out std_logic_vector (6 downto 0);
        Vtc:out std_logic_vector(2 downto 0); -- como soh usarar 3 displays nao precisa colocar energia nos 4
        clk: in std_logic
        );
    end termometro;
    architecture behavior of termometro is
        signal bcd1, bcd2, bcd3: std_logic_vector(3 downto 0);
        signal aux: std_logic_vector(11 downto 0);
        type segs is(se0, se1, se2);
        signal seg_atual, prox_seg: segs;
        signal S1, S2, S3: std_logic_vector(6 downto 0);
        begin
            aux <= to_bcd(data);
            bcd1<=aux(3 downto 0);
            bcd2<=aux(7 downto 4);
            bcd3<=aux(11 downto 8);
        
        WITH bcd1 SELECT
        S1 <= "1111110" when "0000",
                "0110000" when "0001",
                "1101101" when "0010",
                "1111001" when "0011",
                "0110011" when "0100",
                "1011011" when "0101",
                "0100000" when "0110",
                "1110000" when "0111",
                "1111111" when "1000",
                "1111011" when "1001",
                "0000000" when others;
        WITH bcd2 SELECT
        S2 <= "1111110" when "0000",
                "0110000" when "0001",
                "1101101" when "0010",
                "1111001" when "0011",
                "0110011" when "0100",
                "1011011" when "0101",
                "0100000" when "0110",
                "1110000" when "0111",
                "1111111" when "1000",
                "1111011" when "1001",
                "0000000" when others;
        WITH bcd3 SELECT
        S3 <= "1111110" when "0000",
                "0110000" when "0001",
                "1101101" when "0010",
                "1111001" when "0011",
                "0110011" when "0100",
                "1011011" when "0101",
                "0100000" when "0110",
                "1110000" when "0111",
                "1111111" when "1000",
                "1111011" when "1001",
                "0000000" when others;
        
        process(clk) is
        begin
            if(clk = '1' and clk'event) then
                seg_atual<=prox_seg;
            end if;
        end process;
        
        process (S1, S2, S3) is
            begin    
                    case seg_atual is
                        when se0=>
                            Di <= S1;
                            Vtc<= "001";
                            prox_seg <= se1;
                        when se1 =>
                            Di <= S2;
                            Vtc<= "010";
                            prox_seg <= se2;
                        when se2 =>
                            Di <= S3;
                            Vtc<= "100";
                            prox_seg <= se0;
                    end case;
                end process;
        
    end behavior;