+ Post New Thread
Results 1 to 7 of 7
  1. #1
    Newbie level 4
    Points: 1,044, Level: 7

    Join Date
    Oct 2012
    Posts
    7
    Helped
    0 / 0
    Points
    1,044
    Level
    7

    Timing constraints for clock domain crossing

    I'm developing a memory controller for asynchronous memory (as SRAM, MRAM, etc) and am facing some issue with properly constraining my design. I've prepared very simple design to depict my issue and attached it to the thread. Please keep in mind, that this is a modified chunk of a larger project.

    Design description:
    This simplifed design shows fetching data on input pads on every 20 MHz clock cycle. Faster clock, which frequency is 160 MHz, gives me resolution to latch data_i on each 1/8 of 20 MHz clock cycle. Data_i is latched on negative edge, when latch_sr[5] == 1. In total, we have 2x 8-bit registers for data latch, 1x 8-bit shift register for selecting the position of when data_i (changes asynchronous on input pads after 35 ns, relative to raising edge of clk_20 and is stable for 50 ns) is latched in data_latch register and two 1-bit registers for clk_20 positive edge detection. Clk_20 is sampled with clk_160 and itís positive edge will reset the latch_sr shift register. Clk_20 is main clock of the design and on the positive edge of the clock, data_i must to be present on data_o for further operations.

    Problem description:
    What worries me now is how to tell SmartTime with help of multicycle constraint (if this is the correct constraint), that data_i (through data_latch) will be present on data_o:D after cycle and a half (due to latching the data on negative edge of clk_160). As far as I can see, there is no atribute in set_multicycle_path for specifying clock domains. If I donít apply any of the constraint for this path, SmartTime wonít take this path as critical and will assume that there are no timing violations, but in practice Iíve calculated all the routes, and it shouldnít be OK.
    In my main project, there is also a big chunk of combinatorial logic between data_latch and data_o registers, which also delays the data path for 2-4 ns. Should this be taken to constraints consideration also?

    Is multicycle constraint for this path the correct approach? And if so, what is the correct definition of it?

    Iím using:
    Libero 11.8.2.4 (Classic constraint flow)
    IGLOO2 M2GL050T-FG484I

    Click image for larger version. 

Name:	blockdiag.png 
Views:	1 
Size:	80.7 KB 
ID:	145988

    Click image for larger version. 

Name:	tbdiag.png 
Views:	0 
Size:	26.7 KB 
ID:	145989

    Verilog code:
    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    
    module top_des(
        clk_osc_i,
        rst_i,
     
        data_i,
        data_o
        
    );
    input clk_osc_i, rst_i;
    input [7:0] data_i;
    output [7:0] data_o;
     
    reg [7:0] latch_sr;
    reg [7:0] data_latch;
    reg [7:0] data_o;
     
    // Internal PLL
    ccc_gen ccc_gen_u
    (
        // Inputs
        .CLK0_PAD(clk_osc_i),
        // Outputs
        .GL0(clk_20),
        .GL1(clk_160),
        .LOCK(ccc_lock)
    );
     
    reg r1, r2;
    always @ (posedge clk_160) begin
        r1 <= clk_20;
        r2 <= r1;
    end
     
    assign pos_edge = r1 & !r2;
     
    always @ (posedge clk_160 or negedge rst_i) begin
        if(!rst_i || !ccc_lock) begin
            latch_sr <= 8'd1;
        end
        else begin
            if(pos_edge) begin
                latch_sr <= 8'd1;
            end
            else begin
                latch_sr <= {latch_sr[6:0], latch_sr[7]};
            end
        end
    end
     
    always @ (negedge clk_160 or negedge rst_i) begin
        if(!rst_i || !ccc_lock) begin
            data_latch <= 8'd0;
        end
        else begin
            if(latch_sr[5]) begin
                data_latch <= data_i;
            end
        end
    end
     
    always @ (posedge clk_20 or negedge rst_i) begin
        if(!rst_i || !ccc_lock) begin
            data_o <= 8'd0;
        end
        else begin
            data_o <= data_latch;
        end
    end
     
    endmodule
    Last edited by andre_teprom; 14th April 2018 at 02:40. Reason: upload picture from external website

    •   Alt10th April 2018, 07:31

      advertising

        
       

  2. #2
    Full Member level 4
    Points: 1,498, Level: 8

    Join Date
    Oct 2015
    Posts
    237
    Helped
    35 / 35
    Points
    1,498
    Level
    8

    Re: Timing constraints for clock domain crossing

    ---------
    always @ (posedge clk_160 or negedge rst_i) begin
    if(!rst_i || !ccc_lock) begin
    latch_sr <= 8'd1;
    ---------
    Mixing reset with external clock is not good. Please use only reset signal.

    ---------
    always @ (posedge clk_160) begin
    r1 <= clk_20;
    r2 <= r1;
    end

    assign pos_edge = r1 & !r2;
    ---------
    Detect edge of a clock signal is also not recommended.
    Please make counter and enable signal instead.
    To improve one's brain, the doors are needed over the keys.



  3. #3
    Newbie level 4
    Points: 1,044, Level: 7

    Join Date
    Oct 2012
    Posts
    7
    Helped
    0 / 0
    Points
    1,044
    Level
    7

    Re: Timing constraints for clock domain crossing

    Thank you for answering.
    I am completely aware of that. This design was created only to show you signal relations on pre-synthesis level.
    Please focus only on timings.



    •   Alt10th April 2018, 09:23

      advertising

        
       

  4. #4
    Full Member level 4
    Points: 1,498, Level: 8

    Join Date
    Oct 2015
    Posts
    237
    Helped
    35 / 35
    Points
    1,498
    Level
    8

    Re: Timing constraints for clock domain crossing

    Quote Originally Posted by urbanzrim View Post
    Thank you for answering.
    I am completely aware of that. This design was created only to show you signal relations on pre-synthesis level.
    Please focus only on timings.
    If you have the wrong/inappropriate design in logic,
    its timing is meaningless.
    To improve one's brain, the doors are needed over the keys.


    1 members found this post helpful.

  5. #5
    Advanced Member level 5
    Points: 20,362, Level: 34
    barry's Avatar
    Join Date
    Mar 2005
    Location
    California, USA
    Posts
    3,931
    Helped
    846 / 846
    Points
    20,362
    Level
    34

    Re: Timing constraints for clock domain crossing

    Quote Originally Posted by urbanzrim View Post
    Thank you for answering.
    I am completely aware of that. This design was created only to show you signal relations on pre-synthesis level.
    Please focus only on timings.
    'I don't care if my house is on fire, please tell me what color I should paint the walls.'


    1 members found this post helpful.

    •   Alt10th April 2018, 16:42

      advertising

        
       

  6. #6
    Newbie level 4
    Points: 1,044, Level: 7

    Join Date
    Oct 2012
    Posts
    7
    Helped
    0 / 0
    Points
    1,044
    Level
    7

    Re: Timing constraints for clock domain crossing

    Thank you both for your thorough answers.
    If you would read the article at least once, you'd see what really I am asking.

    - - - Updated - - -

    Pasting corrected code and asking again:
    Is multicycle constraint correct approach for constraining data path? If is it so, how can I define the relation between negative edge of one clock and positive edge of another in SmartTime?

    Code:
    `timescale 1ns/100ps
    
    module top_des(
        clk_osc_i,
        rst_i,
    
        data_i,
        data_o
        
    );
    input clk_osc_i, rst_i;
    input [7:0] data_i;
    output [7:0] data_o;
    
    reg [7:0] latch_sr;
    reg [7:0] data_latch;
    reg [7:0] data_o;
    
    // Internal PLL
    ccc_gen ccc_gen_u
    (
        // Inputs
        .CLK0_PAD(clk_osc_i),
        // Outputs
        .GL0(clk_20),
        .GL1(clk_160),
        .LOCK(ccc_lock)
    );
    
    always @ (posedge clk_160 or negedge rst_i) begin
        if(!rst_i) begin
            latch_sr <= 8'd1;
        end
        else begin
            latch_sr <= {latch_sr[6:0], latch_sr[7]};
        end
    end
    
    always @ (negedge clk_160 or negedge rst_i) begin
        if(!rst_i) begin
            data_latch <= 8'd0;
        end
        else begin
            if(latch_sr[2]) begin
                data_latch <= data_i;
            end
        end
    end
    
    always @ (posedge clk_20 or negedge rst_i) begin
        if(!rst_i) begin
            data_o <= 8'd0;
        end
        else begin
            data_o <= data_latch;
        end
    end
    
    endmodule
    Click image for larger version. 

Name:	tbdiag (1).png 
Views:	1 
Size:	22.9 KB 
ID:	145990



  7. #7
    Full Member level 4
    Points: 1,498, Level: 8

    Join Date
    Oct 2015
    Posts
    237
    Helped
    35 / 35
    Points
    1,498
    Level
    8

    Re: Timing constraints for clock domain crossing

    Multicycle constraint is targetted on a ( or a set ) of timing path.
    Within 1 clock domain, a timing path is check with 1 cycle for setup and 0 for hold ( as default ).

    You worry sounds like you want to tell the tool the latency of data through your design.
    It is different with multicycle path constraint.

    If you design have no problem on timing without multicycle constraint,
    you can go ahead without adding multicycle constraint.

    If you want to make a multicycle constraint, you need to analyze the functional waveform.
    If the endpoint ( of a timing path ) onlly need to capture the data at more than 1 clock trigger-edge,
    you can consider to set the multicycle for setup.

    In your case, you have this combination in logic ( which is my understanding )
    data_i -> latch
    latch -> data_o
    There is no data_i --> data_o logic path. So you can not specify multicycle from data_i to data_o directly.
    To improve one's brain, the doors are needed over the keys.



--[[ ]]--