Forum Discussion

SparkyNZ's avatar
SparkyNZ
Icon for Contributor rankContributor
5 years ago
Solved

Can you force synthesis of registers?

bit [ 11 : 0 ] colorRGB[ 7 : 0 ];
bit [ 11 : 0 ] tempRGB;
..
tempRGB = colorRGB[ dataH ];
..
dataR = tempRGB[ 11 : 8 ];

When the above code is synthesized, tempRGB does not appear in the RTL Viewer. It has been optimized/removed from the synthesized design.

Is there a way to force Quartus into synthesizing registers? ie. Is there a keyword I can use so that tempRGB must appear in my design?

  • Hi,


    You may change to below:

    if( ( hcount >= hdat_begin ) && ( hcount <= hdat_last ) )

    begin

    if( hcount[ 0 ] == 0 )

    begin

    tempRGB <= colorRGB[ dataH ];


    end

    else

    begin

    tempRGB <= colorRGB[ dataL ];

    end


    dataR <= tempRGB[ 11 : 8 ];

    dataG <= tempRGB[ 7 : 4 ];

    dataB <= tempRGB[ 3 : 0 ];

    end


    Thanks

    Best regards,

    KhaiY


21 Replies

  • sstrell's avatar
    sstrell
    Icon for Super Contributor rankSuper Contributor

    Use the "preserve" or "keep" synthesis attributes to prevent logic from being optimized away. See the built-in help for the appropriate syntax.

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

    Hi,


    You may change to below:

    if( ( hcount >= hdat_begin ) && ( hcount <= hdat_last ) )

    begin

    if( hcount[ 0 ] == 0 )

    begin

    tempRGB <= colorRGB[ dataH ];


    end

    else

    begin

    tempRGB <= colorRGB[ dataL ];

    end


    dataR <= tempRGB[ 11 : 8 ];

    dataG <= tempRGB[ 7 : 4 ];

    dataB <= tempRGB[ 3 : 0 ];

    end


    Thanks

    Best regards,

    KhaiY


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

      That solution is NOT going to produce the exact same result however.

      Changing the assignment from blocking (=) to non-blocking (<=) is going to cause a one-clock pipeline delay to occur.

      tempRGB will be assigned in clock state 'N+0'

      dataR/DataG/dataB will get that value in clock state 'N+1'

      This may or may not be significant, depending on the desired behavior.

      • SparkyNZ's avatar
        SparkyNZ
        Icon for Contributor rankContributor

        @ak6dn, yeah its 7pm and my brain is too flat to try it out but I hear you. I would have thought the blocking assignments would have required more clock cycles.. or do you mean that because it's "continuous" now that it may take an extra cycle to stabilise, so to speak?

        I've never felt comfortable with using non-blocking assignments in conjunction with if() statements because they don't behave the same as a software if() statement (and I'm a software developer).

        Still, there are 3 things here:

        1) I need to be able to see values in SignalTap so I can make sense of my bugs

        2) I need to understand what Quartus does to help and what it does to hinder

        3) I should get my design working properly - but that can wait until the weekend

        and possible 4) I really need to get my brain around how non-blocking assignments and if() statements work. Any tutorial material I find seems contradictory or poorly written for my brain to absorb. I kind of got the impression that non-blocking assignments are effectively evaluated at the end of the clock cycle.. but then that does that mean that the if() conditions use the value at the start of the clock cycle.. or are the if() statements themselves continuous in nature like any logic gate would be?

    • SparkyNZ's avatar
      SparkyNZ
      Icon for Contributor rankContributor

      Wow. That was the culprit!

      I know everyone keeps saying "use non blocking assignments" but I didn't think blocking assignments would cause me this much trouble.

      I will definitely be making notes about this. As soon as I changed my code as you'd suggested @KhaiChein_Y_Intel , tempRGB appeared in the RTL Viewer.

      Thanks @ak6dn for the additional info. I had a look at my .map.rpt file and tempRGB was nowhere to be found - so it was getting removed long before with no evidence that it had been removed whatsoever.

      It's really difficult trying to debug what has gone wrong in the process when there is no track record. @KhaiChein_Y_Intel , if possible could we make a suggestion to the developers to log something in the report for cases such as this? If you attach my project to a ticket, I am sure they will find it easy to recreate. Any message would do such as 'Removed "tempRGB" because you keep using blocking assignments'

      So I have a solution, thank you - but I still don't know why was removed (without a trace).

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

        It was removed because it never really existed as a physical register.

        In coding verilog, you can use register variables to simplify computations WITHOUT ever creating a real register.

        thus:

        wire W1,W2,W3,W4;
        reg R1,R2,R3;
        always @(posedge clk)
            begin
            R1 = W1+W2;
            R2 = W3+W4;
            R3 = R1+R2;
            end

        will only create a single real register R3. R1 and R2 don't really need to exist, they are transient. It is really the same as if you wrote:

        wire W1,W2,W3,W4;
        reg R1,R2,R3;
        always @(posedge clk)
            begin
            R3 = (W1+W2)+(W3+W4);
            end

        But this will be very different:

        wire W1,W2,W3,W4;
        reg R1,R2,R3;
        always @(posedge clk)
            begin
            R1 <= W1+W2;
            R2 <= W3+W4;
            R3 <= R1+R2;
            end

        because R1 and R2 will be computed in time state 'N', but R3 won't get the sum until time state 'N+1'.