Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Timing constraints for clock domain crossing

Status
Not open for further replies.

urbanzrim

Newbie level 4
Newbie level 4
Joined
Oct 2, 2012
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,346
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

blockdiag.png

tbdiag.png

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 a moderator:

---------
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.
 

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.
 

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.
 
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.'
 
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

tbdiag (1).png
 

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.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top