Forum Discussion

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

Learning VHDL

Hi, I am starting learning VHDL. Y have tried different exercises like chronometers. But now, I am trying to do a Real Time Clock. I hace been following this manual http://www.vhdlcodes.com/2011/01/rtc-on-fpga-with-manual-set.html but when I try to compile, it gives me an error which I don't know how to solve.

The error is... "Error (12002): Port "rsts" does not exist in macrofunction "c1"

Firstly, It is the first time that I try to compile a project which have several files. It has 5 .hdl files. Y only have added its to the project when I was creating the project. Could it be the error???

Y attach the main code:

library ieee;use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity DigiClock is
port( 
      clkm: in std_logic;
      rst,setm,seth: in std_logic;
        z: in std_logic;
      op: out std_logic;
      op0,op1,op2,op3: out std_logic_vector(6 downto 0)
      );
      
end DigiClock;
architecture clock of DigiClock is
component sec_clk
Port ( 
           clks : in std_logic;
              rsts : in std_logic;
           ops  : out std_logic
     );
    end component;
component min_clk
Port ( 
           clkmi : in std_logic;
           rst : in std_logic;
           opm  : out std_logic
     );
    end component;
    
component manu_clk
Port ( 
           set       : in  std_logic;
           clk       : in std_logic;
           opu       : out std_logic
         );
    end component;
    
component seg7
port(m: in integer range 0 to 10;
     num: out std_logic_vector(6 downto 0));
end component;
signal mflag: std_logic;
signal sflag: std_logic;
signal a: integer range 0 to 10;
signal b: integer range 0 to 6;
signal c: integer range 0 to 10;
signal d: integer range 0 to 3;
signal x: std_logic;
signal hrt: std_logic;
signal u: std_logic;
signal v: std_logic;
signal rstsec: std_logic;
signal mi: std_logic;
signal hr: std_logic;
begin
c1: sec_clk  port map(clkm,rstsec,sflag);
c2: min_clk  port map(sflag,rst,mflag);
c3: manu_clk port map(setm,clkm,mi);
c4: manu_clk port map(seth,clkm,hr);
op<=sflag;
clockmin: process(x,rst)
variable m0: integer range 0 to 10:=0;
variable m1: integer range 0 to 6:=0;
begin
     a<=m0;
     b<=m1;
     hrt<= '1' and u;
     
     if rst='0' then
     m0:=0;
     m1:=0;
            
     elsif falling_edge(x) then
        
     if  m0/=9 then
         m0:= m0+1;
         u<='0';
        elsif  m0=9 and  m1/=5  then
         m0:=0;
         m1:= m1+1;
         u<='0';
        elsif  m0=9 and  m1=5 then
         m0:=0;
         m1:=0;
         u<='1';
        end if;  
        end if;    
    
    end process clockmin;
     
     selecter: process(z,clkm)
     
     begin
         if rising_edge(clkm) then
             if z  = '0' then
                 x<=mi;
                 v<=hr;
                 rstsec<='0';
             else
                 x<=mflag;
                 v<=hrt;
                 rstsec<='1';
             end if;
         end if;
    end process selecter;
     
     clockhr: process(v,rst)
    variable m2: integer range 0 to 10:=2;
    variable m3: integer range 0 to 3:=1;
    begin
     
     c<=m2;
    d<=m3;
     
     if rst = '0' then
     m2:=2;
    m3:=1; 
     
     elsif rising_edge(v) then
     if m2/=9 and m3=0 then
     m2:=m2+1;
     elsif m2=9 and m3=0 then
     m2:=0;
     m3:=m3+1;
     elsif m2/=2 and m3=1 then
     m2:=m2+1;
     elsif m2=2 and m3=1 then
     m2:=1;
     m3:=0;
     end if;
     
     end if;
     end process clockhr;
     
     
    
    z0: seg7 port map(a,op0);
    z1: seg7 port map(b,op1);
    z2: seg7 port map(c,op2);
    z3: seg7 port map(d,op3);
    
end clock;

and the macrofunction c1:

library IEEE; use IEEE.STD_LOGIC_1164.ALL;
 use IEEE.numeric_std.all;
 
 entity sec_clk is
    Port ( 
           clks             : in  std_logic;
           ops       : out std_logic
    );
 end sec_clk;
 
 architecture RTC of sec_clk is
   constant max_count : natural := 24000000;
   
 begin
       
    -- compteur de 0 ‡ max_count
    compteur : process(clks)
        variable count : natural range 0 to max_count;
    begin
        if rising_edge(clks) then
            if count < max_count/2 then
                ops    <='1';
                count := count + 1;
            elsif count < max_count then
                ops    <='0';
                count := count + 1;
            else
                count := 0;
                ops   <='1';
            end if;
        end if;
    end process compteur; 
 end RTC;

I have added the first macrofunction, but I think that it gives error with the four macrofunctions. I attach the total of the files (5).

Thanks!!

1 Reply

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

    The sec_clk entity doesnt have a rsts port, but the component declaration inside DigiClock does have a rsts port. Hence you have a missmatch.

    This is a good demonstration of why component declarations can cause problems. When the source of an entity is in VHDL, then a component declaration is not needed, and errors like the one that has occured here will be picked up much sooner in the compiler. You can use direct instantiation instead:

    
    c1: entity work.sec_clk port map(clkm,rstsec,sflag);
    

    And some other comments on your code:

    1. Positional association in port maps is generally frowned on. It is much easier to maintain, less error prone and easier for others to follow with named association

    
    c1: sec_clk  port map
    (clks => clkm,
     ops => sflag);
    

    2. As a beginner, I highly recommend you do NOT use variables. they can cause odd behaviour when you were least expecting it to. Only use signals for expected behaviour

    3. Inside a clocked process, NEVER put anything outside the reset or clocked part of the process.

    
    process(clk,reset)
    begin
       --- NEVER PUT CODE HERE
      if reset = '1' then
        -- async reset goes here
      elsif rising_edge(clk) then
        -- Logic goes here
      end if;
      -- NEVER PUT ANYTHING HERE EITHER
    end process;
    

    4. Do not use any generated logic as a clock, use it as a clock enabled instead and use a single clock for the whole design. Doing so will lead to timing problems.

    
    process(clk)
    begin
      if rising_edge(clk) then
        if en = '1' then
          -- logic only activated when enable is set
        end if;
      end if;
    end process;
    

    5. Do no mix rising and falling edges in the same design. Stick to a single edge (and conventionally, people using rising_edge). Mixtures of clock edges can make timing much harder

    6. Another convention is that active low signals be named something like sig_n or nSig, to make it easier for others to understand it is an active low signal. You have labelled your reset rst, but it is active low. Many engineers would prefer it to be called rst_n. But this leads to another convention - most FPGA engineers like signals to be active high.

    7. You only need clk and any async resets in the sensitivity list. Anything inside the clk branch does NOT need to be in the sensitivity list (and could cause simulation slow-down, but this is unlikely nowadays).

    8. Comment your code, explaining WHY you have done something that way, not HOW (they should understand the how from the code!)