EmbDev.net

Forum: FPGA, VHDL & Verilog HELP! Error messages in Quartus! "Can't infer register"


Author: Afkar Osman (Company: nanyang polytechnic) (afkarsosman)
Posted on:
Attached files:

Rate this post
0 useful
not useful
Hi!

Im having some error when compiling on my Quartus, what Im trying to 
drive a simple character to my DE2 Altera Board (Cyclone II 
EP2C35F672C6N) LCD.

The Errors are as attached.
Note that this was originally from a previous student, my teacher asked 
me to use his coding to modify it so that i can just display Characters, 
Numbers to the LCD. This previous student's codes was to make a clock 
with the display "00:00:00".

Big advance thanks for any help.

Here are my codes.
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY LCD_Main IS 
  PORT ( clk : IN std_logic;
      iRST_N : IN std_logic;
          SW : IN std_logic_vector(17 downto 0);
       reset : IN std_logic;
      switch : IN std_logic;
     switch2 : IN std_logic;
     
    LCD_DATA : OUT std_logic_vector(7 downto 0);
      LCD_RW : OUT std_logic;
      LCD_ON : OUT std_logic;
    LCD_BLON : OUT std_logic;
      LCD_RS : OUT std_logic;
      LCD_EN : OUT std_logic:='0' 
       );
END LCD_Main;

ARCHITECTURE LCDBody of LCD_Main is
  
  CONSTANT LCD_INITIAL:std_logic_vector(7 downto 0):="00000000";
  CONSTANT LCD_LINE1:std_logic_vector(7 downto 0):= "00000100";
  CONSTANT LCD_CH_LINE:std_logic_vector(7 downto 0):=LCD_LINE1+16;
  CONSTANT LCD_LINE2:std_logic_vector(7 downto 0):=LCD_LINE1+16+1;
  CONSTANT LUT_SIZE:std_logic_vector(7 downto 0):=(LCD_LINE2+50)+1;
  
  SIGNAL LUT_DATA:std_logic_vector (11 downto 0):=x"000";--In hex    
--  SIGNAL count2 : integer range 0 to 65535 := 0;
  SIGNAL LUT_INDEX:std_logic_vector(7 downto 0):="00000000";
  SIGNAL mLCD_DONE:std_logic:='0';
 -- SIGNAL mLCD_ST:std_logic_vector(5 downto 0):="000000";
  SIGNAL mLCD_ST:std_logic_vector(1 downto 0):="00";
  SIGNAL mDLY:std_logic_vector(27 downto 0):=x"0000000";--In hex
  SIGNAL mLCD_Start:std_logic:='0';
  SIGNAL mLCD_DATA:std_logic_vector(7 downto 0):="00000000";
  SIGNAL mLCD_RS:std_logic:='0';
  SIGNAL sclk:std_logic:='0';
  SIGNAL startcount : integer range 0 to 1:=0;
  SIGNAL D1,D2,D3,D4,D5,D6 : std_logic_vector (11 downto 0):=x"130";

  COMPONENT LCD_controller IS
       PORT( iCLK,iRS,iRST_N,istart : IN std_logic;
                              iDATA : IN std_logic_vector(7 downto 0);
                              oDone : OUT std_logic;
                           LCD_DATA : OUT std_logic_vector(7 downto 0);
                             LCD_RW : OUT std_logic;
                             LCD_RS : OUT std_logic;
                             LCD_EN : OUT std_logic
           );
  END COMPONENT LCD_controller;
  
  COMPONENT clk_div IS
         PORT ( iCLK: IN std_logic;
                sclk: OUT std_logic
               );
  END COMPONENT clk_div; 
  
  BEGIN      
       U0:LCD_controller 
       PORT MAP(
                  iCLK => clk,
                   iRS => mLCD_RS,
                iRST_N => iRST_N,
                istart => mLCD_START,
                 iDATA => mLCD_DATA,
                 oDone => mLCD_DONE,
              LCD_DATA => LCD_DATA,
                LCD_RW => LCD_RW,
                LCD_RS => LCD_RS,
                LCD_EN => LCD_EN
                );
                
        U1:clk_div 
        PORT MAP( iCLK => clk,
                  sclk => sclk
                 ); 
                       
    LCD_ON <= '1';
    LCD_BLON <= '1';
    
always : process(clk)
    Begin
      
      IF(switch2 = '1' AND switch2'event) THEN
      startcount <= startcount + 1;
      END IF;
      
         IF(startcount = 1) THEN
      If(sclk = '1' and sclk'event)THEN
      
----------LCD Line 1--------------

        IF(reset = '0')THEN
          LUT_INDEX <= "00000000";
          --mLCD_ST <= "000000";
          mLCD_ST <= "00";
          --mDLY <= x"0000000";
          mLCD_DATA <= "00000000";
          mLCD_START <= '0';
          mLCD_RS <= '0';
          
          startcount <= 0;
          D1 <= x"130";
          D2 <= x"130";
          D3 <= x"130";
          D4 <= x"130";
          D5 <= x"130";
          D6 <= x"130";
          
        ELSIF(rising_edge(clk))THEN
          IF(LUT_INDEX < LUT_SIZE)THEN
            case mLCD_ST is
              when "00" => mLCD_DATA <= LUT_DATA(7 downto 0);
                          mLCD_RS   <= LUT_DATA(8);
                          mLCD_START<= '1';
                          mLCD_ST   <= "01";
              
              when "01" => IF(mLCD_DONE = '1') THEN
                          mLCD_START <= '0';
                          mLCD_ST    <= "10";
                       END IF;
                          
              when "10" => IF(switch = '1')THEN
                        IF(LUT_DATA = x"080")THEN
                          mLCD_ST <= "11";
                        END IF;
                       END IF; 
                            
               when "11" => LUT_INDEX <= LUT_INDEX + 1;
                       mLCD_ST   <= "00";
            end case;
          ELSE
            IF(sclk = '1')THEN
              LUT_INDEX <= LCD_INITIAL;
            END IF;
          END IF;
        END IF;
      END IF;
      END IF;
END PROCESS always;    



----READING OF LCD COMMAND----
check:process(LUT_INDEX)
      begin

  case LUT_INDEX is  
   when LCD_INITIAL+0=>LUT_DATA<=(x"030");
   when LCD_INITIAL+1=>LUT_DATA<=(x"00C");         
 --  when LCD_INITIAL+2=>LUT_DATA<=(x"001");          
   when LCD_INITIAL+2=>LUT_DATA<=(x"006");           
   when LCD_INITIAL+3=>LUT_DATA<=(x"080");
   
   

   
   when LCD_LINE1 + 1 => LUT_DATA<=(x"130");
   when LCD_LINE1 + 2 => LUT_DATA<=(x"130");
   when LCD_LINE1 + 3 => LUT_DATA<=(x"130");
   when LCD_LINE1 + 4 => LUT_DATA<=(D6);
   when LCD_LINE1 + 5 => LUT_DATA<=(D5);
   when LCD_LINE1 + 6 => LUT_DATA<=(x"13a");
   when LCD_LINE1 + 7 => LUT_DATA<=(D4);
   when LCD_LINE1 + 8 => LUT_DATA<=(D3);
   when LCD_LINE1 + 9 => LUT_DATA<=(x"13a");
   when LCD_LINE1 + 10=> LUT_DATA<=(D2);
   when LCD_LINE1 + 11=> LUT_DATA<=(D1);
--   when LCD_LINE1 + 12=> LUT_DATA<=(x"130");
--   when LCD_LINE1 + 13=> LUT_DATA<=(x"130");
--   when LCD_LINE1 + 14=> LUT_DATA<=(x"130");
--   when LCD_LINE1 + 15=> LUT_DATA<=(x"130");
--   when LCD_LINE1 + 16=> LUT_DATA<=(x"130");  
   when others => LUT_DATA <= (x"000");

   end case;   

  end process check; 
end LCDBody;

Author: P. K. (pek)
Posted on:

Rate this post
1 useful
not useful
A clocked process has just one active edge and depends on just one 
single clock.

Yours doesn't:

> If(sclk = '1' and sclk'event)THEN
> ...
>   ELSIF(rising_edge(clk))THEN

As there are no registers with dual clock inputs, the tool is not able 
to infer them.

: Edited by User
Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
1 useful
not useful
Afkar O. wrote:
> always : process(clk)
Additionally the simulation result is incorrect due to the incomplete 
sensitivity list.

>  IF(switch2 = '1' AND switch2'event) THEN
>    startcount <= startcount + 1;
>  END IF;
A bouncing asynchronous input signal never ever must be used this way. 
Instead synchronize the switch to the one and only "clk" and then add an 
edge detection to that synchronized signal.

For simplicity a beginners design MUST have only one clock. All actions 
in the design have to be synchronous to that one "clk". All the rest is 
done by clock enable signals.

See how ALL the other designs are made. They all look like this:
  process (reset, clock)
  begin
    if reset = '1' then
      -- set the reset conditions
    elsif rising_edge(clk)
      -- do what has to be done
      if startcount = 1 then 
        -- here startcount=1 is a clock enable
      end if;
    end if
  end process;
If your design has another structure its wrong in >>99% of all possible 
cases.

And the structure of your design is absolutely strange like this:
  always : process(clk)
  Begin
    IF(switch2 = '1' AND switch2'event) THEN  -- this is a clock!
      .... 
    END IF;
      
    IF(startcount = 1) THEN -- this is a clock enable outside a clocked block
      If(sclk = '1' and sclk'event)THEN
        IF(reset = '0')THEN
          -- some kind of synchronous reset          
        ELSIF(rising_edge(clk))THEN -- a clock "inside" a clock?
          .... 
            IF(sclk = '1')THEN -- this here is unnecessary because here sclk MUST be '1' (see the condition 5 lines above)
              ...
            END IF;
          ...
        END IF;
      END IF;
    END IF;
  END PROCESS always;  
Do you see the difference?

: Edited by Moderator
Author: Afkar Osman (Company: nanyang polytechnic) (afkarsosman)
Posted on:

Rate this post
0 useful
not useful
Hi Mr. Lothar Miller,

I understand where am i going wrong now. Im going to try and change the 
codes and try again. Thank you for your help! I really appreciate it!

If there are any questions I'll be sure to post it here.

Regards,
Afkar O.

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [vhdl]VHDL code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig
Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.