Forum Discussion

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

Conversion uses all combinational logic

Hi,

I'm having trouble converting from an integer to an 8 bit std_logic_vector. It complies and gives an error that all my combinational logic nodes are used. I'm using a cyclone II FPGA chip.


type DATE_ARRAY is array(5 downto 0) of integer range 0 to 2100;
variable SC_Var : std_logic_vector(7 downto 0) := x"00";
        variable MN_Var : std_logic_vector(7 downto 0) := x"00";
        variable HR_Var : std_logic_vector(7 downto 0) := x"00";
        variable DT_Var : std_logic_vector(7 downto 0) := x"00";
        variable MO_Var : std_logic_vector(7 downto 0) := x"00";
        variable YR_Var : std_logic_vector(7 downto 0) := x"00";
        variable DW_Var : std_logic_vector(7 downto 0) := x"00";
date := ntpToRTC(timestamp_var);
                                SC_Var := std_logic_vector(to_unsigned(date(0),8));
                                MN_Var := std_logic_vector(to_unsigned(date(1),8));
                                HR_Var := std_logic_vector(to_unsigned(date(2),8)) or x"80";
                                DT_Var := std_logic_vector(to_unsigned(date(3),8));
                                MO_Var := std_logic_vector(to_unsigned(date(4),8));
                                YR_Var := std_logic_vector(to_unsigned(date(5),8));
                                DW_Var := "00000000";

The function I call fills the data with integers representing year, month, day... I also tried putting each conversion in a sepearate state and it made no difference.

Any help much appreciated

23 Replies

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

    With this change, all you have done it register each variable separately. It still uses the same number of resources. It cannot work out resource re-use from your code - a multiply instantiates a multiplier, a divide instantiates a divider. You will have to create a separate divider block and feed the separate values in at the specific times. This way you only use 1 divider/multipler/whatever

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

    Tricky, thank you very much for all your help. I'm a student and I mostly do software.

    Could I implement a multiplier as follows, and if I did would this only instantiate a single multiplier that I could use over and over via a state machine. So in state A, I input the operands, then in state B, I receive the processes output?

    process(a,b,clk)
    begin
    if clk'event and clk='1' then
    d<=a*b;
    c<=d;
    end if;
    end process;
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Quartus will use an exclusive multiplier instance for d <= a*c, at least in most cases. It should be considered, that multiplexing a "single multiplier" to different signals also costs a lot of logic cells and is not necessarily an advantage in terms of overall resource usage.

    In my opinion, sequential multiplexing is reasonable for a divider. As long as the utilized FPGA has free hardware multipliers, individual mutipliers are most likely the more economic variant. It may be slightly different with old FPGAs without hardware multipliers, e.g. Cyclone I. Looking at the resource usage of your original design, the large 31 and 32 bit wide dividers are causing most of the trouble.

    There are also options to code the problem more FPGA like, as the below example shows. The remaining two dividers for /100 and /400 are small and can be possibly accepted. To allow pipelining, the function needs to be rearranged as a component with clock input. Unfortunately, most resource usage is in the other functions.

    function getJulianDay (year: integer range 0 to 4095; 
      month: integer range 0 to 12; 
      day : integer range 0 to 31) return integer is
      variable y: integer range 0 to 8191;
      variable jd : integer range 0 to 2**22-1 := 0;
      type m_tab is array (1 to 12) of integer;
      constant am: m_tab := (1,1,0,0,0,0,0,0,0,0,0,0);
      constant m153: m_tab := (306,337,0,31,61,92,122,153,184,214,245,275);
    begin
      y := year + 4800 - am(month);
      jd := day + m153(month) + (365 * y);
      jd := jd + (y/4) - (y/100) + (y/400) - 32045;
      return(jd);
    end getJulianDay;