Sign In

Don't have a Xilinx account yet?

  • Choose to receive important news and product information
  • Gain access to special content
  • Personalize your web experience on Xilinx.com

Create Account

Username

Password

Forgot your password?
XClose Panel
Xilinx Home
Reply
Visitor
anoopjveliyath@gmail.com
Posts: 2
Registered: ‎05-11-2012
0
Accepted Solution

Error in ise 13.2: "Place 1018" and "weird" behaviour when it is converted to warning and code is implemented and executed

 

Hi,

 

My code is basically meant to generate a single ramp from a DAC by programming the DAC by SPI communication using FPGA : SPARTAN XC3S250E. Ise 13.2 was used to implement it. Basically what the code does is, it continuously sends the digital data to the DAC and we get the ramp output from the data. I have two modes of operation, free running ramp and handshake mode ramp. In free running ramp, one by one, we continuously send the digital data to the DAC, and each new digital data= previous digital data+ step size(where step size is a 16 bit register whose value is given by register write). In free running mode, the code executes perfectly fine. The issue is seen in the handshake mode.

 

In the hand shake mode, the FPGA receives an external SOC(Start of conversion) signal, in the form of a pulse, and only when this pulse is detected, the digital data to be sent to the DAC is updated, ie, incremented by stepsize, and then sent to the DAC by SPI. So, in the free running code, i made a modification such that the data updation and SPI sending block is triggered when a flag bit becomes=1'b1, and this flag bit becomes "1" always at the posedge of SOC, and is made zero after the data sending is over. pin "IO_L11N_3_10" is used for this purpose as an input pin. But with this, while implementing, an error is displayed, as follows:

 

“ERROR:Place:1018 - A clock IOB / clock component pair have been found that are not placed at an optimal clock IOB /

   clock site pair. The clock component <EOC_BUFGP/BUFG> is placed at site <BUFGMUX_X1Y1>. The IO component <EOC> is

   placed at site <P34>.  This will not allow the use of the fast path between the IO and the Clock buffer. If this sub

   optimal condition is acceptable for this design, you may use the CLOCK_DEDICATED_ROUTE constraint in the .ucf file to

   demote this message to a WARNING and allow your design to continue.

However, the use of this override is highly

   discouraged as it may lead to very poor timing results. It is recommended that this error condition be corrected in

   the design. A list of all the COMP.PINs used in this clock placement rule is listed below. These examples can be used

   directly in the .ucf file to override this clock rule.

   < NET "EOC" CLOCK_DEDICATED_ROUTE = FALSE; >”

 

Seems it was taking SOC for a clock signal, since we were using its posedge as a trigger. Initially I just copied “ NET "EOC" CLOCK_DEDICATED_ROUTE = FALSE; “ into the UCF file as advised, and the bit file was generated successfully. But while executing the code some weird results were obtained. For instance, in the free running mode, each dac update was done as : count<=count+stepsize, where “count” is the data sent to DAC for update . In free running mode it was running fine, when we made changes to stepsize, the output varied accordingly. But when the EOC posedge trigger condition was included, for all the other things unchanged, we were getting junk values at output, in the place of a smooth ramp. Also, when i hard coded it to count<=count+1’b1, the ramp was generated, but after reaching maxcode, if extra SOC pulses were given, again it showed glitches at output, whereas ideally once reaching maxcode, it should stay there without any more sending of data no matter how many extra SOC’s we give. It works fine in the free runnign mode In short the code wasn’t functioning as per the expectation and simulated results, when we used the SOC edge triggered mode.

 

The particular block that is causing the trouble is given below, with comments in green explaining its purpose. Please note here in the code the "EOC" is actually the SOC signal mentioned above.

 



always @ (posedge EOC)
EOC_posedge<=~EOC_posedge; // at each posedge of EOC, EOC_posedge, which is used as a flag, is toggled






always@(posedge sclk_int)//This block is used to send the 24 bits of configuration command to the FPGA by SPI
begin                                             protocol.Block starts here
    
    
     if (dactest_start_reg[0])
    begin
if(comndordata==1'b0)
begin      
    dac_data<=conf;  
        
        if (count_bit_spi == 0)
        begin
            if(delay_count==delay)
            begin    
            syncbar_int <= 1'b1;
            
            done_spi <=1'b1;
            count_bit_spi <= 5'd24;
            comndordata<=1'b1;
            delay_count<=16'b0;
            SOC_int <= 1'b1;
            no_of_times<=24'd0;
             EOC_posedge_cnt_inside<=~EOC_posedge_cnt_inside;
            end
            else
            begin
            syncbar_int <= 1'b1;
            delay_count<=delay_count+1;
            SOC_int <= 1'b0;
            end
       end
        else if (count_bit_spi == 5'd24)
        begin
        sdin_int <= dac_data [ count_bit_spi-1 ] ;
            syncbar_int <=1'b0;
            
            count_bit_spi <= count_bit_spi - 1;
            done_spi <=1'b0;
            SOC_int <= 1'b0;
       end
        else
        begin
            sdin_int <= dac_data [ count_bit_spi - 1] ;
            syncbar_int <= 1'b0;
            SOC_int <= 1'b0;
            count_bit_spi <= count_bit_spi - 1;
            done_spi <= 1'b0;
            
        end
    
    

end                                                      //Block ends here
    //SEND DATA
 else if(((comndordata==1'b1)&&(no_of_times<=24'd2))||((comndordata==1'b1)&&(EOC_posedge==EOC_posedge_cnt_inside)))        //This block sends the data to the DAC corresponding to which     
begin                                                                                      we should get the analog output. Block starts here
 
 
 if (ramp_stop==1'b0)
    begin
    dac_data<=dac_out;  
        
        if (count_bit_spi == 0)
        begin
            if(delay_count==delay)
            begin    
            syncbar_int <= 1'b1;
            
            done_spi <=1'b1;
            count_bit_spi <= 5'd24;
            delay_count<=16'b0;
            SOC_int <= 1'b1;
            no_of_times<=no_of_times+1;
            //EOC_posedge<=1'b0;
            //if (no_of_times>24'd1)
            if (no_of_times>24'd2)  
                EOC_posedge_cnt_inside<=~EOC_posedge_cnt_inside;    //This is another flag, and this is toggled when
                                                                                                                                 the last bit of SPI data has been sent.
       end
        else
            begin
            syncbar_int <= 1'b1;
            delay_count<=delay_count+1;
            SOC_int <= 1'b0;
            //EOC_posedge_cnt_inside=EOC_posedge;
            end
       end
        else if (count_bit_spi == 5'd24)
        begin
        sdin_int <= dac_data [ count_bit_spi-1 ] ;
            syncbar_int <=1'b0;
        SOC_int <= 1'b0;
            count_bit_spi <= count_bit_spi - 1;
            done_spi <=1'b0;
            //EOC_posedge_cnt_inside=EOC_posedge;
       end
        else
        begin
            sdin_int <= dac_data [ count_bit_spi - 1] ;
            syncbar_int <= 1'b0;
        SOC_int <= 1'b0;
            count_bit_spi <= count_bit_spi - 1;
            done_spi <= 1'b0;
            //EOC_posedge_cnt_inside=EOC_posedge;
        end
    end
    end
    end
    else if(dactest_start_reg[0]==1'b0)
    begin
        sdin_int <=1'b0;
        syncbar_int <=1'b1;
        done_spi<=1'b0;
        count_bit_spi<=5'd24;
        comndordata<=1'b0;
    SOC_int <= 1'b0;
        //EOC_posedge_cnt_inside=~EOC_posedge;
        EOC_posedge_cnt_inside<=EOC_posedge;

        no_of_times<=24'd0;
        //dac_data<=dac_out_2;
    end
end                                                                           //Block ends here
    
    
always @ (posedge done_spi)        //This is actually the block where the dac data is updated each time as the     

                                                                   done_spi bit goes high, ie, when each time the SPI data transfer gets over. It  

                                                                    should keep on updating the dac data, indicated by "count", 

                                                                    as count<=count+stepsize1, where stepsize1 is user programmed by register 

                                                                   write to FPGA.Also it must check if the "count" has reached or exceeded the   

                                                                  limit for max code and then stop the SPI data sending. Block begins here
begin
   
                     
        if (no_of_times<=24'd2)
          begin  
         count<=dac_out_2;
dac_out<= count;
 end
          else
        
        begin
        dac_out<= count;
                    count<=count+stepsize1;
         
            
            end
        
        if((count==dac_out_1)||((count>dac_out_1)&&((count-dac_out_1)<8'hFF)))
            begin
            ramp_stop<=1'b1;
            count<=dac_out_2;
            
            end
            else
            ramp_stop<=1'b0;
        
          
                
         end  //Block ends here
      
      In the free running mode, we just remove the portion of the code above given in blue font. Then it is seen that the code executes fine. But when that portion is included, ie, when operating in handshake mode with SOC(EOC in code), it is seen that some random data is what which is sent to the dac, and instead of getting a ramp, we get just some glitches and unpredictable values in dac output. Also, when the portion given in red font is made count<=count+1'd1, we get a ramp. But when it is count<=count+stepsize1, even when we give stepsize1 as 01H by register write, what we get is unpredictable behaviour. But in free running mode, ie, on the removal of the blue font section, even with count<=count+stepsize1, it works fine.

 

Then I checked the SOC pulse width which was 280nS, and since the SCLK clock period is just 33ns, it was clear we didn’t actually need to use the SOC posedge as trigger, we can use its high level, which can be easily detected at SCLK edge. When I made the code SOC level triggered, ie , eliminated the use of SOC posedge completely, the code works perfectly.

Also the above mentioned error wasn’t displayed while generating the program file, as we’d expect.

 

So something strange seems to happen whenever we use SOC posedge as trigger, which i cant understand. Can you please shed some light on this?

 

 

Thanks,

Anoop    
  
    

        


 

 

 

Expert Contributor
eteam00
Posts: 7,505
Registered: ‎07-21-2009
0

asynchronous inputs will cause problems.

[ Edited ]

You are making the classic mistake of inexperienced digital logic designers:  ignoring the consequences of asynchronous inputs to synchronous logic.

 

  • Consider eliminating all the clocks in your design except one.
  • Do not use asynchronous inputs as clocks, even for edge detection.
  • Use the one remaining clock to detect edges (if needed) of asynchronous inputs.

 

From the New Users Forum README thread, post #2, Design Fundamentals section:

 

Here are some threads which discuss how to handle asynchronous inputs:  link#1 link#2 link#3

 

-- Bob Elkind

SIGNATURE:
README for newbies is here: http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

Summary:
1. Read the manual or user guide. Have you read the manual? Can you find the manual?
2. Search the forums (and search the web) for similar topics.
3. Do not post the same question on multiple forums.
4. Do not post a new topic or question on someone else's thread, start a new thread!
5. Students: Copying code is not the same as learning to design.
6 "It does not work" is not a question which can be answered. Provide useful details (with webpage, datasheet links, please).
7. You are not charged extra fees for comments in your code.
8. I am not paid for forum posts. If I write a good post, then I have been good for nothing.
Visitor
anoopjveliyath@gmail.com
Posts: 2
Registered: ‎05-11-2012
0

Re: asynchronous inputs will cause problems.

Bob,

 

Thanks for the reply. Yes, since this edge detection was causing problems, i had instead removed the edge detection part for EOC, and just used the posedge of the clock alone to detect when EOC went high first, then it was working perfectly fine. Thanks a lot

 

 

Thanks,

Anoop