0
\$\begingroup\$

Problem

I'm developing a simple LED blinking system in Quartus Prime Lite 18.1 to be instantiated on a DE0-Nano development board that makes use of the Cyclone IV E generation of Intel FPGAs. To do so I am defining a block in VHDL. This block accepts a 10MHz clock signal and a switch input and causes an onboard LED to flash at either 1 or 2 Hz. Here is the VHDL description.

-- Library declaration

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

-- Entity declaration

entity BlinkerTest is
    port(
            clk_10MHz: in std_logic;
            switch_1: in std_logic;
            clk_out: out std_logic
            );
end entity;

architecture behave of BlinkerTest is

-- Signal declaration

signal clk_1Hz: std_logic := '0';
signal clk_2Hz: std_logic := '0';
signal scaler: integer range 0 to 5000000;
signal second_scaler: integer range 0 to 2500000;

begin

-- Process used to scale down the 10 MHz frequency from the PLL to a 1Hz rate. 

    clk_process: process(clk_10MHz, switch_1) is
    begin
        if(rising_edge(clk_10MHz)) then
            if (NOT(switch_1) AND (scaler  < 5000000)) then
                scaler <= scaler + 1;
            else if switch_1 AND (second_scaler < 2500000) then
                second_scaler <= second_scaler + 1;
        else 
            if NOT(switch_1) then
                scaler <= 0;
                clk_1Hz <= NOT(clk_1Hz);    
                clk_out <= clk_1Hz;             
            else if switch_1 then 
                second_scaler <= 0;
                clk_2Hz <= NOT(clk_2Hz);
                clk_out <= clk_2Hz;
            end if; 
        end if;
    end if;
    end clk_process;
    


end behave;

I am making some sort of error in my description and I continue to provoke the following errors.


Error (10500): VHDL syntax error at BlinkerTest.vhd(49) near text "clk_process";  expecting "if"
Error (10500): VHDL syntax error at BlinkerTest.vhd(53) near text "behave";  expecting "if"
Info (12021): Found 0 design units, including 0 entities, in source file blinkertest.vhd


May you help me write this description correctly?

\$\endgroup\$
3
  • 1
    \$\begingroup\$ You are creating more levels of nested if than you think, and you need more end if statements to close them out. That's why the parser is still expecting another end if when it gets to the end of the process. Try using elsif rather than else if. \$\endgroup\$
    – Dave Tweed
    Feb 15 at 11:53
  • 1
    \$\begingroup\$ Of course, if the second if is simply testing the opposite condition from the first if, it isn't needed at all. Just use a bare else. \$\endgroup\$
    – Dave Tweed
    Feb 15 at 11:58
  • 1
    \$\begingroup\$ Count your end ifs. \$\endgroup\$ Feb 15 at 13:06

1 Answer 1

3
\$\begingroup\$

The syntax problem is because you have entered else if, possibly instead of the VHDL elsif, which leaves unbalanced if and end if pairs.

More to the point, though, it looks like somewhat confused VHDL. I think what you were trying to do was:

  pGenerateClock : process(RST, CLK_10MHZ) is
  begin
    if (RST = '1') then
      clk         <=  '0';
      scaler      <=   0 ;

    elsif rising_edge(CLK_10MHZ) then

      if (scaler = 0) then

        clk       <=  not clk;

        if (SWITCH_1 = '0') then
          scaler  <=  5000000 - 1;
        else
          scaler  <=  2500000 - 1;
        end if;

      else

        scaler    <=  scaler - 1;

      end if;

    end if;
  end process pGenerateClock;

Don't use the terms 'out' and 'in' within signal, port and variable names. It most often makes things more confusing, as at some point outputs are connected to inputs.

Also, don't use your generated 'home-made' clock clk as an input clock for any FPGA circuitry.

Always take clocks from reliable external clock sources (clock modules etc.) or internal PLLs driven by these inputs. You can use a common 1-CLK wide prescaler signal to enable circuitry at the slower rate you want and save gates on prescaling counters everywhere.

Here, this prescaler would be generated by modifying the above process, removing clk and replacing it with tick1sec:

      if (scaler = 0) then

        tick1sec  <=  '1';
        ...

      else

        tick1sec  <=  '0';

        scaler    <=  scaler - 1;

      end if;

Then your remaining circuitry would be clocked by CLK_10MHZ and contain logic like this example:

  pSlow : process(RST, CLK_10MHZ) is
  begin
    if (RST = '1') then
      secondsCtr   <=  0;

    elsif rising_edge(CLK_10MHZ) then

      if (tick1sec = '1') then

        if (secondsCtr = 59) then
          secondsCtr  <=  0;
        else
          secondsCtr  <=  secondsCtr + 1;
        end if;

      end if;

    end if;
  end process pSlow;
\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.