在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 1054|回复: 6

[求助] synopsys dc 综合问题

[复制链接]
发表于 2023-5-30 09:45:26 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
家人们问大家个问题,我的设计代码有一些用到了vivado的原语库如IDDR和ODDR,这些是vivado提供的仿真模型,而且我现在已经通过验证了。但是到后面会需要使用synopsys dc对所有的rtl代码进行综合的,那这些原语到时候应该如何处理?是要寻找替换方案吗?还是工具会有一些特殊的方式啊,希望大家不吝赐教。
发表于 2023-5-30 10:41:49 | 显示全部楼层
看看你用的library有相关的stdcell没
 楼主| 发表于 2023-5-30 11:35:44 | 显示全部楼层
本帖最后由 freemanhans 于 2023-5-30 11:36 编辑


qq524788633 发表于 2023-5-30 10:41
看看你用的library有相关的stdcell没





  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright (c) 1995/2005 Xilinx, Inc.
  3. // All Right Reserved.
  4. ///////////////////////////////////////////////////////////////////////////////
  5. //   ____  ____
  6. //  /   /\/   /
  7. // /___/  \  /    Vendor : Xilinx
  8. // \   \   \/     Version : 8.1i (I.13)
  9. //  \   \         Description : Xilinx Timing Simulation Library Component
  10. //  /   /                  Dual Data Rate Input D Flip-Flop
  11. // /___/   /\     Filename : IDDR.v
  12. // \   \  /  \    Timestamp : Thu Mar 11 16:44:06 PST 2005
  13. //  \___\/\___\
  14. //
  15. // Revision:
  16. //    03/23/04 - Initial version.
  17. //    03/11/05 - Added LOC parameter, removed GSR ports and initialized outpus.
  18. //    12/20/05 - Fixed setup and hold checks.
  19. //    04/28/06 - Added c_in into the sensitivity list (CR 219840).
  20. //    05/29/07 - Added wire declaration for internal signals
  21. //    04/16/08 - CR 468871 Negative SetupHold fix
  22. //    05/06/08 - CR 455447 add XON MSGON property to support async reg
  23. //    12/03/08 - CR 498674 added pulldown on R/S.
  24. //    12/13/11 - Added `celldefine and `endcelldefine (CR 524859).
  25. //    08/23/13 - PR683925 - add invertible pin support.
  26. //    10/22/14 - Added #1 to $finish (CR 808642).
  27. // End Revision

  28. `timescale  1 ps / 1 ps

  29. `celldefine

  30. module IDDR (Q1, Q2, C, CE, D, R, S);
  31.    
  32.     output Q1;
  33.     output Q2;
  34.    
  35.     input C;
  36.     input CE;
  37.     input D;
  38.     input R;
  39.     input S;

  40.     parameter DDR_CLK_EDGE = "OPPOSITE_EDGE";   
  41.     parameter INIT_Q1 = 1'b0;
  42.     parameter INIT_Q2 = 1'b0;
  43.     parameter [0:0] IS_C_INVERTED = 1'b0;
  44.     parameter [0:0] IS_D_INVERTED = 1'b0;
  45.     parameter SRTYPE = "SYNC";

  46. `ifdef XIL_TIMING

  47.     parameter LOC = "UNPLACED";
  48.     parameter MSGON = "TRUE";
  49.     parameter XON = "TRUE";

  50. `endif



  51.     pulldown P1 (R);
  52.     pulldown P2 (S);

  53.     reg q1_out = INIT_Q1, q2_out = INIT_Q2;
  54.     reg q1_out_int, q2_out_int;
  55.     reg q1_out_pipelined, q2_out_same_edge_int;
  56.     reg notifier, notifier1, notifier2;
  57.     wire notifier1x, notifier2x;

  58.     wire c_in,delay_c;
  59.     wire ce_in,delay_ce;
  60.     wire d_in,delay_d;
  61.     wire gsr_in;
  62.     wire r_in,delay_r;
  63.     wire s_in,delay_s;
  64.    
  65.     tri0 GSR = glbl.GSR;
  66.    
  67.     assign gsr_in = GSR;
  68.     assign Q1 = q1_out;
  69.     assign Q2 = q2_out;
  70.    
  71.     wire nr, ns, ngsr;
  72.     wire ce_c_enable, d_c_enable, r_c_enable, s_c_enable;
  73.     wire ce_c_enable1, d_c_enable1, r_c_enable1, s_c_enable1;
  74.     not (nr, R);
  75.     not (ns, S);
  76.     not (ngsr, GSR);

  77.     and (ce_c_enable, ngsr, nr, ns);
  78.     and (d_c_enable, ngsr, nr, ns, CE);
  79.     and (s_c_enable, ngsr, nr);


  80. `ifdef XIL_TIMING

  81.     assign notifier1x = (XON == "FALSE") ?  1'bx : notifier1;
  82.     assign notifier2x = (XON == "FALSE") ?  1'bx : notifier2;

  83.     assign ce_c_enable1 = (MSGON =="FALSE") ? 1'b0 : ce_c_enable;
  84.     assign d_c_enable1 = (MSGON =="FALSE") ? 1'b0 : d_c_enable;
  85.     assign r_c_enable1 = (MSGON =="FALSE") ? 1'b0 : ngsr;
  86.     assign s_c_enable1 = (MSGON =="FALSE") ? 1'b0 : s_c_enable;

  87. `endif

  88.    
  89.     initial begin

  90.    if ((INIT_Q1 != 0) && (INIT_Q1 != 1)) begin
  91.        $display("Attribute Syntax Error : The attribute INIT_Q1 on IDDR instance %m is set to %d.  Legal values for this attribute are 0 or 1.", INIT_Q1);
  92.        #1 $finish;
  93.    end
  94.    
  95.        if ((INIT_Q2 != 0) && (INIT_Q2 != 1)) begin
  96.        $display("Attribute Syntax Error : The attribute INIT_Q1 on IDDR instance %m is set to %d.  Legal values for this attribute are 0 or 1.", INIT_Q2);
  97.        #1 $finish;
  98.    end

  99.        if ((DDR_CLK_EDGE != "OPPOSITE_EDGE") && (DDR_CLK_EDGE != "SAME_EDGE") && (DDR_CLK_EDGE != "SAME_EDGE_PIPELINED")) begin
  100.        $display("Attribute Syntax Error : The attribute DDR_CLK_EDGE on IDDR instance %m is set to %s.  Legal values for this attribute are OPPOSITE_EDGE, SAME_EDGE or SAME_EDGE_PIPELINED.", DDR_CLK_EDGE);
  101.        #1 $finish;
  102.    end
  103.    
  104.    if ((SRTYPE != "ASYNC") && (SRTYPE != "SYNC")) begin
  105.        $display("Attribute Syntax Error : The attribute SRTYPE on IDDR instance %m is set to %s.  Legal values for this attribute are ASYNC or SYNC.", SRTYPE);
  106.        #1 $finish;
  107.    end

  108.     end // initial begin
  109.    
  110.          
  111.     always @(gsr_in or r_in or s_in) begin
  112.    if (gsr_in == 1'b1) begin
  113.        assign q1_out_int = INIT_Q1;
  114.        assign q1_out_pipelined = INIT_Q1;
  115.        assign q2_out_same_edge_int = INIT_Q2;
  116.        assign q2_out_int = INIT_Q2;
  117.    end
  118.    else if (gsr_in == 1'b0) begin
  119.        if (r_in == 1'b1 && SRTYPE == "ASYNC") begin
  120.       assign q1_out_int = 1'b0;
  121.       assign q1_out_pipelined = 1'b0;
  122.       assign q2_out_same_edge_int = 1'b0;
  123.       assign q2_out_int = 1'b0;
  124.        end
  125.             else if (r_in == 1'b0 && s_in == 1'b1 && SRTYPE == "ASYNC") begin
  126.       assign q1_out_int = 1'b1;
  127.       assign q1_out_pipelined = 1'b1;
  128.       assign q2_out_same_edge_int = 1'b1;
  129.       assign q2_out_int = 1'b1;
  130.        end
  131.        else if ((r_in == 1'b1 || s_in == 1'b1) && SRTYPE == "SYNC") begin
  132.       deassign q1_out_int;
  133.       deassign q1_out_pipelined;
  134.       deassign q2_out_same_edge_int;
  135.       deassign q2_out_int;
  136.        end      
  137.        else if (r_in == 1'b0 && s_in == 1'b0) begin
  138.       deassign q1_out_int;
  139.       deassign q1_out_pipelined;
  140.       deassign q2_out_same_edge_int;
  141.       deassign q2_out_int;
  142.        end
  143.    end // if (gsr_in == 1'b0)
  144.     end // always [url=home.php?mod=space&uid=1801890]@[/url] (gsr_in or r_in or s_in)
  145.    
  146.       
  147.     always @(posedge c_in) begin
  148.     if (r_in == 1'b1) begin
  149.        q1_out_int <= 1'b0;
  150.        q1_out_pipelined <= 1'b0;
  151.        q2_out_same_edge_int <= 1'b0;
  152.    end
  153.    else if (r_in == 1'b0 && s_in == 1'b1) begin
  154.        q1_out_int <= 1'b1;
  155.        q1_out_pipelined <= 1'b1;
  156.        q2_out_same_edge_int <= 1'b1;
  157.    end
  158.    else if (ce_in == 1'b1 && r_in == 1'b0 && s_in == 1'b0) begin
  159.             q1_out_int <= d_in;
  160.        q1_out_pipelined <= q1_out_int;
  161.        q2_out_same_edge_int <= q2_out_int;
  162.    end
  163.     end // always @ (posedge c_in)
  164.    
  165.    
  166.     always @(negedge c_in) begin
  167.    if (r_in == 1'b1)
  168.        q2_out_int <= 1'b0;
  169.    else if (r_in == 1'b0 && s_in == 1'b1)
  170.        q2_out_int <= 1'b1;
  171.    else if (ce_in == 1'b1 && r_in == 1'b0 && s_in == 1'b0)
  172.        q2_out_int <= d_in;
  173.     end
  174.    
  175.    
  176.     always @(c_in or q1_out_int or q2_out_int or q2_out_same_edge_int or q1_out_pipelined) begin
  177.    case (DDR_CLK_EDGE)
  178.        "OPPOSITE_EDGE" : begin
  179.                         q1_out <= q1_out_int;
  180.                         q2_out <= q2_out_int;
  181.                          end
  182.        "SAME_EDGE" : begin
  183.                          q1_out <= q1_out_int;
  184.                          q2_out <= q2_out_same_edge_int;
  185.                      end
  186.        "SAME_EDGE_PIPELINED" : begin
  187.                               q1_out <= q1_out_pipelined;
  188.                                      q2_out <= q2_out_same_edge_int;
  189.                                end
  190.        default : begin
  191.                        $display("Attribute Syntax Error : The attribute DDR_CLK_EDGE on IDDR instance %m is set to %s.  Legal values for this attribute are OPPOSITE_EDGE, SAME_EDGE or SAME_EDGE_PIPELINED.", DDR_CLK_EDGE);
  192.                 $finish;
  193.        end
  194.    endcase // case(DDR_CLK_EDGE)
  195.     end // always @ (q1_out_int or q2_out_int or q2_out_same_edge_int or q1_out_pipelined or q2_out_pipelined)
  196.    

  197. `ifndef XIL_TIMING

  198.     assign delay_c =  C;
  199.     assign delay_ce = CE;
  200.     assign delay_d =  D;
  201.     assign delay_r = R;
  202.     assign delay_s = S;

  203. `endif
  204.     assign c_in = IS_C_INVERTED ^ delay_c;
  205.     assign ce_in = delay_ce;
  206.     assign d_in = IS_D_INVERTED ^ delay_d;
  207.     assign r_in = delay_r;
  208.     assign s_in = delay_s;

  209.    
  210. //*** Timing Checks Start here

  211. `ifdef XIL_TIMING
  212.    
  213.     always @(notifier or notifier1x) begin
  214.    q1_out <= 1'bx;
  215.     end
  216.    
  217.     always @(notifier or notifier2x) begin
  218.    q2_out <= 1'bx;
  219.     end

  220. `endif
  221.    
  222. `ifdef XIL_TIMING
  223.    wire c_en_n;
  224.    wire c_en_p;
  225.    wire ce_c_enable1_n,d_c_enable1_n,r_c_enable1_n,s_c_enable1_n;
  226.    wire ce_c_enable1_p,d_c_enable1_p,r_c_enable1_p,s_c_enable1_p;
  227.    assign c_en_n = IS_C_INVERTED;
  228.    assign c_en_p = ~IS_C_INVERTED;
  229.    assign ce_c_enable1_n = ce_c_enable1 && c_en_n;
  230.    assign ce_c_enable1_p = ce_c_enable1 && c_en_p;
  231.    assign d_c_enable1_n = d_c_enable1 && c_en_n;
  232.    assign d_c_enable1_p = d_c_enable1 && c_en_p;
  233.    assign r_c_enable1_n = r_c_enable1 && c_en_n;
  234.    assign r_c_enable1_p = r_c_enable1 && c_en_p;
  235.    assign s_c_enable1_p = s_c_enable1 && c_en_p;
  236.    assign s_c_enable1_n = s_c_enable1 && c_en_n;
  237. `endif

  238.     specify
  239.    
  240.    (C => Q1) = (100:100:100, 100:100:100);
  241.    (C => Q2) = (100:100:100, 100:100:100);
  242.    (posedge R => (Q1 +: 0)) = (0:0:0, 0:0:0);
  243.    (posedge R => (Q2 +: 0)) = (0:0:0, 0:0:0);
  244.    (posedge S => (Q1 +: 0)) = (0:0:0, 0:0:0);
  245.    (posedge S => (Q2 +: 0)) = (0:0:0, 0:0:0);
  246. `ifdef XIL_TIMING
  247.     (R => Q1) = (0:0:0, 0:0:0);
  248.    (R => Q2) = (0:0:0, 0:0:0);
  249.    (S => Q1) = (0:0:0, 0:0:0);
  250.    (S => Q2) = (0:0:0, 0:0:0);

  251.    $period (negedge C, 0:0:0, notifier);
  252.    $period (posedge C, 0:0:0, notifier);
  253.    $recrem (negedge R, negedge C, 0:0:0, 0:0:0, notifier2, c_en_n, c_en_n);
  254.    $recrem (negedge R, posedge C, 0:0:0, 0:0:0, notifier1, c_en_p, c_en_p);
  255.    $recrem (negedge S, negedge C, 0:0:0, 0:0:0, notifier2, c_en_n, c_en_n);
  256.    $recrem (negedge S, posedge C, 0:0:0, 0:0:0, notifier1, c_en_p, c_en_p);
  257.    $recrem ( posedge R, negedge C, 0:0:0, 0:0:0, notifier2, c_en_n, c_en_n);
  258.    $recrem ( posedge R, posedge C, 0:0:0, 0:0:0, notifier1, c_en_p, c_en_p);
  259.    $recrem ( posedge S, negedge C, 0:0:0, 0:0:0, notifier2, c_en_n, c_en_n);
  260.    $recrem ( posedge S, posedge C, 0:0:0, 0:0:0, notifier1, c_en_p, c_en_p);
  261.    $setuphold (negedge C, negedge CE &&& (ce_c_enable1_n!=0), 0:0:0, 0:0:0, notifier2, , , delay_c, delay_ce);
  262.    $setuphold (negedge C, negedge D  &&& (d_c_enable1_n!=0),  0:0:0, 0:0:0, notifier2, , , delay_c, delay_d);
  263.    $setuphold (negedge C, negedge R  &&& (r_c_enable1_n!=0),  0:0:0, 0:0:0, notifier2, , , delay_c, delay_r);
  264.    $setuphold (negedge C, negedge S  &&& (s_c_enable1_n!=0),  0:0:0, 0:0:0, notifier2, , , delay_c, delay_s);
  265.    $setuphold (negedge C, posedge CE &&& (ce_c_enable1_n!=0), 0:0:0, 0:0:0, notifier2, , , delay_c, delay_ce);
  266.    $setuphold (negedge C, posedge D  &&& (d_c_enable1_n!=0),  0:0:0, 0:0:0, notifier2, , , delay_c, delay_d);
  267.    $setuphold (negedge C, posedge R  &&& (r_c_enable1_n!=0),  0:0:0, 0:0:0, notifier2, , , delay_c, delay_r);
  268.    $setuphold (negedge C, posedge S  &&& (s_c_enable1_n!=0),  0:0:0, 0:0:0, notifier2, , , delay_c, delay_s);
  269.    $setuphold (posedge C, negedge CE &&& (ce_c_enable1_p!=0), 0:0:0, 0:0:0, notifier1, , , delay_c, delay_ce);
  270.    $setuphold (posedge C, negedge D  &&& (d_c_enable1_p!=0),  0:0:0, 0:0:0, notifier1, , , delay_c, delay_d);
  271.    $setuphold (posedge C, negedge R  &&& (r_c_enable1_p!=0),  0:0:0, 0:0:0, notifier1, , , delay_c, delay_r);
  272.    $setuphold (posedge C, negedge S  &&& (s_c_enable1_p!=0),  0:0:0, 0:0:0, notifier1, , , delay_c, delay_s);
  273.    $setuphold (posedge C, posedge CE &&& (ce_c_enable1_p!=0), 0:0:0, 0:0:0, notifier1, , , delay_c, delay_ce);
  274.    $setuphold (posedge C, posedge D  &&& (d_c_enable1_p!=0),  0:0:0, 0:0:0, notifier1, , , delay_c, delay_d);
  275.    $setuphold (posedge C, posedge R  &&& (r_c_enable1_p!=0),  0:0:0, 0:0:0, notifier1, , , delay_c, delay_r);
  276.    $setuphold (posedge C, posedge S  &&& (s_c_enable1_p!=0),  0:0:0, 0:0:0, notifier1, , , delay_c, delay_s);
  277.    $width (negedge C, 0:0:0, 0, notifier);
  278.    $width (negedge R, 0:0:0, 0, notifier);
  279.    $width (negedge S, 0:0:0, 0, notifier);
  280.    $width (posedge C, 0:0:0, 0, notifier);
  281.    $width (posedge R, 0:0:0, 0, notifier);
  282.    $width (posedge S, 0:0:0, 0, notifier);

  283. `endif

  284.    specparam PATHPULSE$ = 0;
  285.    
  286.     endspecify


  287. endmodule // IDDR

  288. `endcelldefine




复制代码
你好这是代码,来自vivado目录下的的unisims文件夹,您看一下这里面应该是有stdcell的吧
发表于 2023-5-30 12:13:17 | 显示全部楼层


freemanhans 发表于 2023-5-30 11:35
你好这是代码,来自vivado目录下的的unisims文件夹,您看一下这里面应该是有stdcell的吧
...


这个只是仿真模型,用于行为仿真的。FPGA里ODDR这种其实是硬资源,是直接做到PAD上的。如果你要做半定制的ASIC实现,需要确定一下厂商提供的单元库中有没有相同功能的标准单元
 楼主| 发表于 2023-5-30 13:57:37 | 显示全部楼层


lzhj21 发表于 2023-5-30 12:13
这个只是仿真模型,用于行为仿真的。FPGA里ODDR这种其实是硬资源,是直接做到PAD上的。如果你要做半定制 ...


也就是说,我无法直接使用这些进行综合,需要寻找可替换的的单元,厂商的话是不是就比如andes这种啊,因为我们公司和andes有合作。或者如果这些原语的功能没那么复杂,我也是可以手写功能代码替换的吧,当然前提是仿真能够通过。
发表于 2023-5-30 16:24:30 | 显示全部楼层


freemanhans 发表于 2023-5-30 13:57
也就是说,我无法直接使用这些进行综合,需要寻找可替换的的单元,厂商的话是不是就比如andes这种啊,因 ...


对,Xilinx提供的这些仅仅是用来仿真的模型,没法综合。所谓的厂商是提供给你们标准单元库的公司,例如代工厂。直接用手写功能代码替换的话可能会有些问题,因为像是ODDR这种原语会涉及到双边沿采样,手写代码的话做后端的时候可能需要特别处理一些,例如要求走线等长之类的,不然时序上会出问题,这个我也没有具体的去弄过,不知道行不行。
 楼主| 发表于 2023-5-30 17:48:42 | 显示全部楼层
本帖最后由 freemanhans 于 2023-5-31 15:12 编辑


lzhj21 发表于 2023-5-30 16:24
对,Xilinx提供的这些仅仅是用来仿真的模型,没法综合。所谓的厂商是提供给你们标准单元库的公司,例如代 ...


哦谢谢啦,双边沿采样提醒了我,手写确实有风险,我大致了解了

双边采样就是上升沿和下降沿均采样,我从网上查看了了解到下降沿采样在综合时候不会优化所以不推荐。那么我能否将时钟取反,就相当于还是用上升沿在采样,这样做有什么不妥吗,或者说会有什么隐患?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /3 下一条

×

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-4-23 20:34 , Processed in 0.024442 second(s), 6 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表