How to improve Fmax ? want to add some registers

Status
Not open for further replies.

adscrz

Member level 1
Joined
Jun 9, 2004
Messages
34
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Location
Unknow
Activity points
536
How to improve Fmax ?

I found some combination logic between two registers after compilation with below code, so the Fmax only 100.8MHz,

Could you give me some suggestion?

I want to add some registers , but I do know how to add it

Thanks.

// State Machine - Next State Assignment
always @(posedge sys_clk or negedge reset)
if (!reset)
begin
state <= verital_blank ;
clk_counter <= 16'h0 ;
line_counter <= 9'h0 ;
even_line <= 1'h0 ; even_row <= 1'h0 ;
end
else
begin
clk_counter <= clk_counter + 1 ;
case (state)
verital_blank: begin
//Vertical blanking :38,074 pixel clocks
even_line <= 1'h0 ; even_row <= 1'h0 ;
if ( clk_counter == 16'd38074 )
begin
state <= next_state;
clk_counter <= 16'h0 ;
end
end

frame_start_blank: begin
//Frame start blanking, R0x05-23 = 71 pixel clocks
even_line <= 1'h0 ; even_row <= 1'h0 ; //standard output
//even_line <= 1'h1 ; even_row <= 1'h0 ; //for C113 only
if ( clk_counter == 16'd70 )
begin
state <= next_state;
clk_counter <= 16'h0 ;
end
end

active_data: begin
//Active data time, R0x04 = 752 pixel clocks
even_row <= ~even_row ;
even_line <= even_line ;
//if ( clk_counter == 16'd751 )
if ( clk_counter == 16'd4 ) //for speed up testing
begin
state <= next_state;
clk_counter <= 16'h0 ;
line_counter <= line_counter + 1 ;
even_line <= ~even_line ;
if ( line_counter == 9'd479 )
begin
line_counter <= 9'h0 ;
end
end
end

horizontal_blank: begin
//Horizontal blanking, R0x05 = 94 pixel clocks
even_line <= even_line ; even_row <= 1'h0 ;
if ( clk_counter == 16'd93 )
begin
state <= next_state;
clk_counter <= 16'h0 ;
end
end

frame_end_blank: begin
//Frame end blanking, 23 (fixed) pixel clocks
even_line <= even_line ; even_row <= even_row ;
if ( clk_counter == 16'd22 )
begin
state <= next_state;
clk_counter <= 16'h0 ;
end
end

default: begin
clk_counter <= 16'h0 ;
even_line <= even_line ; even_row <= even_row ;
end
endcase
end
 

Re: How to improve Fmax ?

parallel_case verilog directive may improve Fmax.

state variable one-hot encoding (one bit per state) may improve Fmax.

case (state) /* synthesis parallel_case */

**broken link removed**
 
Last edited by a moderator:

How to improve Fmax ?

If i look at the first glance in to u r code, i believe u r clk_counter register timings are critical, if it is the case u can make a prescaled counter clk_counter and improve the timing. If not can put the critical path which u obtained from the synthesis, so that i can help you
 

Re: How to improve Fmax ?

Thanks for everyone's advice!

I try to add the following Verilog HDL synthesis attributes in Quartus II
But the Fmax is same: 207.68MHz !

It seem the parallel_case is not work in this case

case (state) // synthesis parallel_case

I will try to re-write the code,
Do you have any good code style for this code ?

Thank you!

Added after 3 hours 40 minutes:


Thanks!

I put the critical path in attached,

I want to re-write the code, pls input your suggestion
 

Re: How to improve Fmax ?

progressive clk count ?:
Code:
always @(posedge sys_clk or negedge reset)
begin
 if (!reset) clk_counter <= 16'h0;
 else
    if(clk_counter != (17'd38074 + 16'd70 + 16'd4 + ...))
        clk_counter <= clk_counter + 1'b1;
    else
        clk_counter <= 16'h0;
end

always @(posedge sys_clk or negedge reset)
begin
 if (!reset) state <= 16'h0;
 else
    begin
        case(clk_counter)   /* synthesis full_case parallel_case */
            17'h0:      state <= verital_blank;
            17'd38074:  state <= frame_start_blank;
            (17'd38074 + 16'd70)  state <= active_data;
            (17'd38074 + 16'd70 + 16'd4) state<= horizontal_blank;
            ..................
            (17'd38074 + 16'd70 + 16'd4 + ...)  state<= 
        endcase
    end
end
 

Re: How to improve Fmax ?


Hi, I re-write this code, but Fmax lower, from 208MHz --> 195MHz.

Code:
always @(posedge sys_clk or negedge reset)
  if (!reset) 
    begin
      state <= verital_blank ;
    end
  else 
    begin
      state <= next_state;
    end      
  

always @(posedge sys_clk or negedge reset)
  if (!reset) 
    begin
      clk_counter <= 16'h0 ;
    end
  else 
    begin
      clk_counter <= clk_counter + 1 ;
      case (state) // synthesis parallel_case 
        verital_blank: begin
        //Vertical blanking :38,074 pixel clocks
          if ( clk_counter > verital_blank_pixel )
            begin
              clk_counter <= 16'h0 ;
            end
        end
            
        frame_start_blank: begin
        //Frame start blanking, R0x05-23 = 71 pixel clocks
          if ( clk_counter > frame_start_blank_pixel )
            begin
              clk_counter <= 16'h0 ;
            end
        end

        active_data: begin
        //Active data time, R0x04 = 752 pixel clocks
          if ( clk_counter > active_data_pixel )
            begin
              clk_counter <= 16'h0 ;
            end
        end
            
        horizontal_blank: begin
        //Horizontal blanking, R0x05 = 94 pixel clocks
          if ( clk_counter > horizontal_blank_pixel )
            begin
              clk_counter <= 16'h0 ;
            end
        end

        frame_end_blank: begin
        //Frame end blanking, 23 (fixed) pixel clocks
          if ( clk_counter > frame_end_blank_pixel )
            begin
              clk_counter <= 16'h0 ;
            end
        end

        default: begin
          clk_counter <= 16'h0 ;
        end      
      endcase
    end
    

  always @( state , clk_counter, line_counter,even_row )
  begin  
    // default
    next_state  = state;
    line_counter = 9'h0 ;
    even_line = even_line ; even_row = even_row ;
    
    case (state)       
      // START : output verital_blank 
      verital_blank: begin //Vertical blanking :38,074 pixel clocks
        even_line = 1'b0 ; even_row = 1'b0 ;
        if ( clk_counter > verital_blank_pixel )
          begin
            next_state = frame_start_blank;
          end
        else
          begin
            next_state  = state;
          end
      end

      frame_start_blank: begin  //Frame start blanking, R0x05-23 = 71 pixel clocks
          even_line = 1'b0 ; even_row = 1'b0 ; //standard output
          //even_line = 1'b1 ; even_row = 1'b0 ; //for C113 only
          if ( clk_counter > frame_start_blank_pixel )
            begin
              next_state = active_data;
            end
          else
            begin
              next_state  = state;
            end
      end
      
      active_data: begin  //Active data time, R0x04 = 752 pixel clocks
          even_row  = ~even_row ; even_line = even_line ;
          if ( clk_counter > active_data_pixel )
            begin
              even_line <= ~even_line ;
              if ( line_counter == line_total )
                begin
                  next_state = frame_end_blank ;
                  line_counter = 9'h0 ;
                end
              else
                begin
                  next_state = horizontal_blank ;
                  line_counter = line_counter + 1 ;
                end
            end
          else
            begin
              next_state  = state;
            end
      end

      horizontal_blank: begin  //Horizontal blanking, R0x05 = 94 pixel clocks
          even_line = even_line ; even_row = 1'b0 ;
          if ( clk_counter > horizontal_blank_pixel )
            begin
              next_state = active_data;
            end
          else
            begin
              next_state  = state;
            end
      end
          
      frame_end_blank: begin  //Frame end blanking, 23 (fixed) pixel clocks
          even_line = 1'b0 ; even_row = 1'b0 ;
          if ( clk_counter > frame_end_blank_pixel )
            begin
              next_state = verital_blank ;
            end
          else
            begin
              next_state  = state;
            end        
      end

      default: begin
        next_state = verital_blank ;
        even_line = even_line ; even_row = even_row ;
      end      
    endcase
  end
 

Re: How to improve Fmax ?

progressive clk count ?:

No.



Code:
always @(posedge sys_clk or negedge reset) 
begin 
 if (!reset) 
 	clk_counter <= 16'h0; 
 else 
 	begin
    if(clk_counter != frame_end_blank_pixel) 
        clk_counter <= clk_counter + 1'b1; 
    else 
        clk_counter <= 16'h0; 
        
    if(clk_counter == 16'h0)
    	state <= verital_blank;        
    if(clk_counter == verital_blank_pixel)
    	state <= frame_start_blank;
    if(clk_counter == (verital_blank_pixel + frame_start_blank_pixel))
    	state <= active_data;       
    if(clk_counter == (verital_blank_pixel + frame_start_blank_pixel + active_data_pixel))  
      state <= frame_end_blank ;
    ............................
    end
end
 

Re: How to improve Fmax ?

adscrz said:

if not really necessary do not use async. reset
always @(posedge sys_clk or negedge reset)

you can increase Fmax changing some quartus settings:
Code:
 A. Settings -> 
        Analisys & Synth. Settings -> 
                Optimization Tech.: Speed
                Synth. Netlist Optym.: Perform gate-level reg. retimintg
  
 B.          -> Fitter Settings 
                    -> Fitter effort : Standard                                
                    -> More Settings
                           -> Placement Effort Multip.: 3
                           -> Router Effort Multip.:  3
                           -> Router Timing Opt. Level : Max
                    -> Physical Synth.Optimization
                           -> Perform register duplication
                           -> Perform reg. retiming

use: if ( clk_counter == frame_start_blank_pixel )
rather then:
if ( clk_counter > frame_start_blank_pixel )
it requires more logic to check a>b then find out if a==b;

create an extra 17 bits counter, let's say:
reg [16:0] vert_bl_px;
and change your code
Code:
    //  clk_counter <= 16'h0;   change to:
        clk_counter <= 16'h0;  vert_bl_px <= vertical_blank_pixel - 1;

    //  clk_counter <= clk_counter + 1 ; 
        clk_counter <= clk_counter + 1 ; vert_bl_px <= vert_bl_px - 1;

    //  if ( clk_counter > verital_blank_pixel ) 
    //    begin 
    //      next_state = frame_start_blank; 
    //    end 
        if ( vert_bl_px[16] ) 
          begin 
            next_state = frame_start_blank; 
          end

the point is that instead of logic to decode the number: '38074'
you can load this number [minus '1'] to a counter [and count down],
the counter's MSB indicates defined number of clocks passed,
in other words the counter itself is a decoder;
less logic should improve Fmax, and duplicated counter
should make router task easier;
Have fun;
---
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…