Search code examples
vhdl

ERROR:HDLCompiler:806 - Line 35: Syntax error near "function". Cannot find syntax error


I just had this code synthesized and working an hour ago. I am using a double dabble method to display the digits that are counting on the 7 seg display on my FPGA board. I added the seven.seg.display function, commented it out, and now it won't synthesize. I'm at my wits end trying to figure out what this syntax error could be but I just can't do it anymore. I literally changed nothing and it won't work. Please help me.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity main is
Port ( reset : in  STD_LOGIC;
       clock : in  STD_LOGIC;
       LED : out  STD_LOGIC_VECTOR(7 downto 0)
          );
end main;


function to.bcd(bin: std_logic_vector(7 downto 0));
  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 0):= 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;

--function seven.seg.display(bin: std_logic_vector(6 downto 0));
--  variable bcd: std_logic_vector(11 downto 0):= (others => '0');
--   variable segment: std_logic_vector(6 downto 0):= bin;
--
--begin
--  case  bcd(11 downto 8) is
--      when "0000"=> segment <="0000001";  -- 0
--      when "0001"=> segment <="1001111";  -- 1
--      when "0010"=> segment <="0010010";  -- 2
--      when "0011"=> segment <="0000110";  -- 3
--      when "0100"=> segment <="1001100";  -- 4 
--      when "0101"=> segment <="0100100";  -- 5
--      when "0110"=> segment <="0100000";  -- 6
--      when "0111"=> segment <="0001111";  -- 7
--      when "1000"=> segment <="0000000";  -- 8
--      when "1001"=> segment <="0000100";  -- 9
--      when others=> segment <="1111111";  -- -
--  end case;
--  case  bcd(7 downto 4) is
--      when "0000"=> segment <="0000001";  -- 0
--      when "0001"=> segment <="1001111";  -- 1
--      when "0010"=> segment <="0010010";  -- 2
--      when "0011"=> segment <="0000110";  -- 3
--      when "0100"=> segment <="1001100";  -- 4 
--      when "0101"=> segment <="0100100";  -- 5
--      when "0110"=> segment <="0100000";  -- 6
--      when "0111"=> segment <="0001111";  -- 7
--      when "1000"=> segment <="0000000";  -- 8
--      when "1001"=> segment <="0000100";  -- 9
--      when others=> segment <="1111111";  -- -
--  end case;
--  case  bcd(3 downto 0) is
--      when "0000"=> segment <="0000001";  -- 0
--      when "0001"=> segment <="1001111";  -- 1
--      when "0010"=> segment <="0010010";  -- 2
--      when "0011"=> segment <="0000110";  -- 3
--      when "0100"=> segment <="1001100";  -- 4 
--      when "0101"=> segment <="0100100";  -- 5
--      when "0110"=> segment <="0100000";  -- 6
--      when "0111"=> segment <="0001111";  -- 7
--      when "1000"=> segment <="0000000";  -- 8
--      when "1001"=> segment <="0000100";  -- 9
--      when others=> segment <="1111111";  -- -
--  end case;
--
--return bcd;
--end seven.seg.display;

architecture Behavioral of main is
    signal counter: std_logic_vector(7 downto 0);
    signal prescaler: std_logic_vector(25 downto 0);

begin
    CounterProcess: process(clock)
    begin
        if rising_edge(clock) then
            if (reset = '1') then
                prescaler <= (others => '0');
                counter <= (others => '0');
            else
                if prescaler < "1011111010111100001000000" then
                    prescaler <= std_logic_vector(unsigned(prescaler) + 1);
                else
                    prescaler <= (others => '0');
                    counter <= std_logic_vector(unsigned(counter) + 1);
                end if;
            end if;
        end if;
    end process;

    LED <= counter;

end Behavioral;

Solution

  • Your function isn't a primary unit. The easiest place for it to be declared is in the architecture declarative region.

    As the first answer pointed out the function didn't have a return type declaration or the keyword is, and an identifier can't have a period in it, a period is a delimiter.

    Because you didn't include another use clause I converted the three "+" adds to unsigned (from numeric_std). As your second answer attempts to articulate you could use a use clause enabling access to package std_logic_unsigned instead, but that would require you to change the "+" in counterprocess unless you added a use clause as a subprogram (function) declarative item.

    And there was an error with:

    bint(7 downto 0) := bint(6 downto 0);
    

    Should be:

    bint(7 downto 1) := bint(6 downto 0);
    

    apparently.

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
    
    entity main is
        port ( 
            reset: in   std_logic;
            clock: in   std_logic;
            led:   out  std_logic_vector(7 downto 0)
        );
    end entity;
    
    architecture behavioral of main is
        signal counter: std_logic_vector(7 downto 0);
        signal prescaler: std_logic_vector(25 downto 0 );
    
        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) := 
                        std_logic_vector (unsigned(bcd(3 downto 0)) + "0011");
                end if;
                if i < 7 and bcd(7 downto 4) > "0100" then
                    bcd(7 downto 4) := 
                        std_logic_vector(unsigned(bcd(7 downto 4)) + "0011");
                end if;
                if i < 7 and bcd(11 downto 8) > "0100" then
                    bcd(11 downto 8) := 
                        std_logic_vector(unsigned(bcd(11 downto 8)) + "0011");
                end if;
            end loop;
            return bcd;
        end function;
    begin
    counterprocess: 
        process(clock)
        begin
            if rising_edge(clock) then
                if (reset = '1') then
                    prescaler <= (others => '0');
                    counter <= (others => '0');
                else
                    if prescaler < "1011111010111100001000000" then
                        prescaler <= std_logic_vector(unsigned(prescaler) + 1);
                    else
                        prescaler <= (others => '0');
                        counter <= std_logic_vector(unsigned(counter) + 1);
                    end if;
                end if;
            end if;
        end process;
    
        led <= counter;
    
    end architecture;
    

    This wouldn't have worked with the commented out 'function', either.

    Your VHDL specification now analyzes and elaborates. It hasn't been tested for functionality. The to_bcd double dabble function looks like its from the VHDL Guru blog.