This page contains reference hardware and reference software that you can use to determine the calibration factors for your FPGA platform.
Hardware

The factor MaxFreqCalibrationModule for your FPGA is determined by synthesizing the following module on your FPGA, and finding the reciprocal of the critical path of this module after place and route. You will need this number for each FPGA that your system uses.

   module test(
       input [31:0] A,
       output reg [4:0] LZ,
       input clk
   );
   
   reg [31:0] LA;
   reg [4:0] Z;
   integer       i;
 
   always @(posedge clk) begin
       LA<=A;
       LZ<=Z;
   end
   
   always @(*) begin
       Z=0;
       for(i=0;i<=31;i=i+1) begin
           if (LA[i]) begin
               Z=Z+1;
           end
       end
   end
 
   endmodule
	
Software

The factor TimeCalibrationCodeHardCPU is found by compiling the following test program on your CPU and determine the execution time. While compiling and running this program, keep the following constraints in mind.

  • Choose an accurate time measurement method. We prefer you use a hardware-based clock-cycle counting mechanism for maximal accuracy. The sample code below provides several examples.
  • Compile your code to on-chip memories, and report the fastest possible execution time.
  • Compile your code with gcc -O2 optimization.
  //---------------------------------------------------------------------------     
  // MEMOCODE Hardware/Software Codesign Contest 2008                            
  // CPU calibration routines.                                                   
  //                                                                             
  // Instructions                                                                
  // 1. Select one of the methods below for time measurement                     
  //    (a) using a timer module (OPB Timer on EDK example given)                
  //    (b) using a CPU cycle counter (PPC and X86 examples given)               
  //    (c) least preferable - use software based on time.h                      
  // 2. Execute the test sequence below and collect all output of the program    
  // 3. Report the output of this program together along with the unit of time   
  //---------------------------------------------------------------------------  
                                                                                 
  // uncomment only one of the following four maacros                            
                                                                                 
  // #define USE_OPBTIMER_COUNTER                                                
  #define USE_PPC_COUNTER                                                        
  ///#define USE_X86_COUNTER                                                     
  // #define USE_SW_COUNTER                                                      
                                                                                 
  //---------------- using an OPB timer on Xilinx EDK                            
  #ifdef USE_OPBTIMER_COUNTER                                                    
  #include "xparameters.h"                                                       
  #include "xtmrctr.h"                                                           
  XTmrCtr T;                                                                     
  void clockstart() {                                                            
    XTmrCtr_Initialize(&T, XPAR_OPB_TIMER_0_DEVICE_ID);                          
    XTmrCtr_Reset(&T,0);                                                         
    XTmrCtr_Start(&T,0);                                                         
  }                                                                              
  void clockstop() {                                                             
    XTmrCtr_Stop(&T,0);                                                          
  }                                                                              
  unsigned long clockread() {                                                    
    return XTmrCtr_GetValue(&T,0);                                               
  }                                                                              
  #endif                                                                         
                                                                                 
  //---------------- using powerPC cycle counter                                 
  #ifdef USE_PPC_COUNTER                                                         
  long long ts_get_ll() {                                                        
         unsigned int upper, upper2;                                             
         unsigned int lower;                                                     
         unsigned long long ans;                                                 
         unsigned int x;                                                         
         // see PPC405 programmer's manual for explanation                       
         do {                                                                    
                 asm volatile ("mftbu %[arg]" : [arg] "=r" (upper) : );          
                 asm volatile ("mftb %[arg]" : [arg] "=r" (lower) : );           
                 asm volatile ("mftbu %[arg]" : [arg] "=r" (upper2) : );         
         } while (upper!=upper2);                                                
         ans=upper;                                                              
         ans=ans<<32;                                                            
         ans|=lower;                                                             
         return ans;                                                             
  }                                                                              
  long long t1, t2;                                                              
  void clockreset() {}                                                           
  void clockstart() {t1 = ts_get_ll();}                                          
  void clockstop()  {t2 = ts_get_ll();}                                          
  unsigned long clockread() {return (long) t2 - t1;}                             
  #endif                                                                         
                                                                                 
  //---------------- use on x86                                                  
  #ifdef USE_X86_COUNTER                                                         
  #include                                                             
  #include                                                              
  __inline__ uint64_t rdtsc() {                                                  
    uint32_t lo, hi;                                                             
    __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));                       
    return (uint64_t)hi << 32 | lo;                                              
  }                                                                              
  uint64_t t1, t2;                                                               
  void clockreset() {}                                                           
  void clockstart() {t1 = rdtsc();}                                              
  void clockstop()  {t2 = rdtsc();}                                              
  unsigned long clockread() {return t2 - t1;}                                    
  #endif                                                                         
                                                                                 
  //---------------- use for software-supported timekeeping (not recommended)    
  #ifdef USE_SW_COUNTER                                                          
  #include                                                               
  #include                                                              
  void clockreset() {}                                                           
  clock_t t1, t2;                                                                
  void clockstart() {t1 = clock();}                                              
  void clockstop () {t2 = clock();}                                              
  unsigned long clockread() {return t2 - t1;}                                    
  #endif                                                                         
                                                                                 
  //---------------------------------------------------------------------------  
                                                                                 
  unsigned rnstate = 1;                                                          
  unsigned accumulate() {                                                        
    unsigned a = 0;                                                              
    int i;                                                                       
    for (i=0; i<(1 << 20); i++) {                                                
      a += rnstate;                                                              
      rnstate = (rnstate >> 1) ^ (-(signed int)(rnstate & 1) & 0xd0000001u);     
    }                                                                            
    return a;                                                                    
  }                                                                              
                                                                                 
  int main() {                                                                   
    int i;                                                                       
    unsigned a;                                                                  
    for (i=0; i<3; i++) {                                                        
      clockstart();                                                              
      a  = accumulate();                                                         
      clockstop();                                                               
      xil_printf("Round %3d Chk %8x Ticks Elapsed %d\n", i, a, clockread());     
    }                                                                            
    return 0;                                                                    
  }