urbanzrim
Newbie level 4
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 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
Verilog code:
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 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
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: