Forum Discussion

BrianHG's avatar
BrianHG
Icon for Occasional Contributor rankOccasional Contributor
5 years ago
Solved

Problem with 'altpll' phase parameter.

Hello, I trying to set 'altpll' parameter:

HPLL1.clk1_phase_shift = PHASE_ps,

Now, in my code, I made localparam 'DDR3_WDQ_PHASE_pss' =:

localparam int PHASE_degree = 90;

localparam int PHASE_ps = (((1000000 / ( CLK_KHZ_IN/1000 * CLK_IN_MULT / CLK_IN_DIV )) * PHASE_degree / 360) -1) ;
localparam string PHASE_ps_s1 = "499" ;
localparam PHASE_ps_s2 = "499" ;

HPLL1.clk1_phase_shift only seems to accept 'PHASE_ps_s2', a hard number written in quotes.

It wont even accept the string PHASE_ps_s1, and it sees the original 'PHASE_ps' as a "0".

How do I make the 'altpll' megafunction accept my calculated 'PHASE_ps'? All the other 'altpll' parameters like 'HPLL1.clk0_divide_by = CLK_IN_DIV' and 'HPLL1.clk0_multiply_by = CLK_IN_MULT' work fine.

  • BrianHG's avatar
    BrianHG
    5 years ago

    It looks like this is the only trick which will work:

    localparam DDR3_WDQ_PHASE_ps = (((1000000 / ( PLL1_in_KHz/1000 * CLK_IN_MULT / CLK_IN_DIV )) * DDR3_WDQ_PHASE / 360) -1) ;
    localparam DDR3_RDQ_PHASE_ps = (((1000000 / ( PLL1_in_KHz/1000 * CLK_IN_MULT / CLK_IN_DIV )) * DDR3_RDQ_PHASE / 360) -1) ;

    localparam int Altera_Dummy_String [0:399] = '{ // Seriously, this is the only way... I feel like an idiot making this public...
    "0000","0010","0020","0030","0040","0050","0060","0070","0080","0090","0100","0110","0120","0130","0140","0150","0160","0170","0180","0190",
    "0200","0210","0220","0230","0240","0250","0260","0270","0280","0290","0300","0310","0320","0330","0340","0350","0360","0370","0380","0390",

    ....... All the way up to 3990 .....

    localparam DDR3_WDQ_PHASE_pss = Altera_Dummy_String[DDR3_WDQ_PHASE_ps/10] ;
    localparam DDR3_RDQ_PHASE_pss = Altera_Dummy_String[DDR3_RDQ_PHASE_ps/10] ;

    Though this lowers my ps resolution to every 10ps, your so called string for some reason needs to be an INT parameter defined with numbers in quotes for ModelSim and Quartus to accept the results, hence my array 'localparam 'INT' Altera_Dummy_String [0:399] '.

    Simulation and results in the fitter's utilization report in the PLL section prove my calculated parameter referenced to the array 'DDR3_R/WDQ_PHASE_pss' takes proper effect.

    Really weird since the other 'STRING' parameters accept normal strings properly. It is only the PLL phase exclusively which requires an INT localparam with a number packaged in Quotes as if it were a string. Something is fishy with the way the coder decided to implement the phase feature as a non-standard string.

9 Replies

  • Ash_R_Intel's avatar
    Ash_R_Intel
    Icon for Regular Contributor rankRegular Contributor

    Hi,

    Please note that clk1_phase_shift is of type STRING. You cannot pass an Integer value to it.

    For your application, the integer value should be converted to a string.


    You may use function like sprintf() to do that or any other method.


    Regards.


    • BrianHG's avatar
      BrianHG
      Icon for Occasional Contributor rankOccasional Contributor

      Ok, I tried this:

      localparam PHASE_ps_s2 = sprintf("%d",PHASE_ps);

      and for the PLL, I used the 'PHASE_ps_s2'.

      However, ModelSim reported this:

      # ** Error: BrianHG_DDR3_PLL.sv(131): External function 'sprintf' may not be used in a constant expression.
      # ** Error: BrianHG_DDR3_PLL.sv(131): Parameter value must be constant.

      Is there a way to tell the localparam that the 'sprintf("%d",PHASE_ps)' is a constant?

      The PHASE_ps is a localparam constant.

      Is there another way to pass my constant calculated integer PHASE_ps into a string?

      • BrianHG's avatar
        BrianHG
        Icon for Occasional Contributor rankOccasional Contributor

        Also, if I try:

        localparam string PHASE_ps_s2 = string'(((1000000 / ( CLK_KHZ_IN/1000 * CLK_IN_MULT / CLK_IN_DIV )) * PHASE_degree / 360) -1) ;

        I get this error:

        # ** Error: (vsim-8576) Override of parameter 'clk1_phase_shift' from '/BrianHG_DDR3_PLL_tb/DUT_DDR3_PLL/genblk3' has an incompatible value.
        # Time: 0 ps Iteration: 0 Region: /BrianHG_DDR3_PLL_tb/DUT_DDR3_PLL/genblk3 File: BrianHG_DDR3_PLL.sv

  • Ash_R_Intel's avatar
    Ash_R_Intel
    Icon for Regular Contributor rankRegular Contributor

    Hi,

    I think what you are trying to do is, control the phase of the output clock dynamically. In order to achieve this use the Dynamic Reconfiguration page of the wizard and tick the "Create optional inputs for dynamic phase reconfiguration". It will generate ports to control the phase of the output clock.


    The passing of a non-constant to a defparam might be a difficult or impossible path to pursue. I am not a Verilog expert though.


    Regards.


    • BrianHG's avatar
      BrianHG
      Icon for Occasional Contributor rankOccasional Contributor

      It looks like this is the only trick which will work:

      localparam DDR3_WDQ_PHASE_ps = (((1000000 / ( PLL1_in_KHz/1000 * CLK_IN_MULT / CLK_IN_DIV )) * DDR3_WDQ_PHASE / 360) -1) ;
      localparam DDR3_RDQ_PHASE_ps = (((1000000 / ( PLL1_in_KHz/1000 * CLK_IN_MULT / CLK_IN_DIV )) * DDR3_RDQ_PHASE / 360) -1) ;

      localparam int Altera_Dummy_String [0:399] = '{ // Seriously, this is the only way... I feel like an idiot making this public...
      "0000","0010","0020","0030","0040","0050","0060","0070","0080","0090","0100","0110","0120","0130","0140","0150","0160","0170","0180","0190",
      "0200","0210","0220","0230","0240","0250","0260","0270","0280","0290","0300","0310","0320","0330","0340","0350","0360","0370","0380","0390",

      ....... All the way up to 3990 .....

      localparam DDR3_WDQ_PHASE_pss = Altera_Dummy_String[DDR3_WDQ_PHASE_ps/10] ;
      localparam DDR3_RDQ_PHASE_pss = Altera_Dummy_String[DDR3_RDQ_PHASE_ps/10] ;

      Though this lowers my ps resolution to every 10ps, your so called string for some reason needs to be an INT parameter defined with numbers in quotes for ModelSim and Quartus to accept the results, hence my array 'localparam 'INT' Altera_Dummy_String [0:399] '.

      Simulation and results in the fitter's utilization report in the PLL section prove my calculated parameter referenced to the array 'DDR3_R/WDQ_PHASE_pss' takes proper effect.

      Really weird since the other 'STRING' parameters accept normal strings properly. It is only the PLL phase exclusively which requires an INT localparam with a number packaged in Quotes as if it were a string. Something is fishy with the way the coder decided to implement the phase feature as a non-standard string.

  • Ash_R_Intel's avatar
    Ash_R_Intel
    Icon for Regular Contributor rankRegular Contributor

    HI Brian,


    Understand your concern.


    Meanwhile, here is a workaround:

    localparam PHASE_ps = (((1000000 / ( CLK_KHZ_IN/1000 * CLK_IN_MULT /CLK_IN_DIV )) * PHASE_degree / 360) -1) ;

    localparam PHASE_ps_s2 = "0" + PHASE_ps;


    HPLL1.clk1_phase_shift = PHASE_ps_s2,


    This piece of code compiled correctly for me.


    However, if you are planning to control the phase of the output clock dynamically, I would still suggest you to do it through ports as mentioned earlier.


    Regards.


    • BrianHG's avatar
      BrianHG
      Icon for Occasional Contributor rankOccasional Contributor

      Hello Ash_R,

      I'm sorry, but in ModelSim, the result is a PLL with always 0 degrees phase shift.

      When I print the string with $warning, I get:

      *** True DDR3_WDQ_PHASE = p ps. ***

      The 'p' is actually has a weird extended ascii character just before it. It should read '90', no '*p'

      Same error in Quartus:

      Error (114000): Time value p and time unit are illegal

  • Ash_R_Intel's avatar
    Ash_R_Intel
    Icon for Regular Contributor rankRegular Contributor

    This thread will be transitioned to community support. If you have a new question, feel free to open a new thread to get the support from Intel experts. Otherwise, the community users will continue to help you on this thread. Thank you