HDL Compiler:hdlin_preserve_sequential变量和preserve_sequential综合指令的使用

相关阅读

HDL Compilerhttps://blog.csdn.net/weixin_45791458/category_12893238.html?spm=1001.2014.3001.5482


综合指令(Synthesis Directives)是一些特殊注释,用于影响综合工具如何处理RTL代码,这些注释会被综合工具识别,但会被其他工具(如仿真器)忽略。关于综合指令相关概念的更多介绍,可以参考下面的博客。

HDL Compiler:综合指令https://chenzhang.blog.csdn.net/article/details/148695750 首先回顾一下不可读的概念:不可读是一种状态,单元(触发器、组合逻辑门)都可能位于这种状态,简单来说,不可读就是单元直接或间接没有驱动任何输出端口。当RTL代码中包含不可读或无驱动触发器/组合逻辑门时,HDL Compiler会把它们删除,因此并不会有不可读或无驱动触发器的推断报告,例1展示了不可读触发器的删除。

复制代码
// 例1
module unread(input a, b, c, clk, output z);
reg a_r1, a_r2;
wire d;

assign z = a_r1;
assign d = a_r2 & c;
always@(posedge clk) begin
    a_r1 <= a;
    a_r2 <= a & b;
end

endmodule

下面为HDL Compiler读取例1时产生的触发器推断报告,可以看出其中并未识别出不可读触发器a_r2_reg。

复制代码
==================================================================================
|    Register Name    |   Type    | Width | Bus | MB |  Set  | Reset | ST | Line |
==================================================================================
|      a_r1_reg       | Flip-flop |   1   |  N  | N  | None  | None  | N  |  6   |
==================================================================================

图1为此时的GTECH网表,可以看出一个触发器和两个与门都因为被认定为是直接/间接不可读状态而删除,只有触发器a_r1_reg以SEQGEN的形式存在。

图1 例1的GETCH网表

可以通过设置hdlin_preserve_sequential变量(默认值为none)控制是否保留不可读或无驱动触发器,如果将该变量设置为all或者true,触发器推断报告如下所示。

复制代码
==================================================================================
|    Register Name    |   Type    | Width | Bus | MB |  Set  | Reset | ST | Line |
==================================================================================
|      a_r1_reg       | Flip-flop |   1   |  N  | N  | None  | None  | N  |  6   |
|      a_r2_reg       | Flip-flop |   1   |  N  | N  | None  | None  | N  |  6   |
==================================================================================

图2为此时的GTECH网表,可以看出只有不可读触发器a_r2_reg后面的与门都因为被认定为是直接不可读状态而删除,不可读触发器a_r2_reg和其前面的与门(间接)都得到了保留。

图2 例1的GETCH网表

例1展示了不可读触发器的保留,如果无驱动触发器使用该方法保留下来了,会将无驱动引脚连接到常量0。

hdlin_preserve_sequential变量

当该变量被设置为all或者true时,保留所有不可读时序单元,不包括仅作为循环变量使用的不可读时序单元;当该变量被设置为all+loop_variables或者true+loop_variables时,保留所有不可读时序单元,包括仅作为循环变量使用的不可读时序单元;当该变量被设置为ff时,仅保留所有不可读触发器,不包括仅作为循环变量使用的不可读触发器;当该变量被设置为ff+loop_variables时,仅保留所有不可读触发器,包括仅作为循环变量使用的不可读触发器;当该变量被设置为latch时,仅保留所有不可读锁存器,不包括仅作为循环变量使用的不可读锁存器;当该变量被设置为latch+loop_variables时,仅保留所有不可读触发器,包括仅作为循环变量使用的不可读锁存器;

例2展示了仅作为循环变量使用的不可读触发器,其中i信号作为integer类型的变量作为for循环内的索引变量,默认不会被推断为触发器。

复制代码
// 例2
module test (input clk, rst, error);
parameter N = 4;
reg [N-1:0] fail;
integer i, j;

always @(posedge clk or posedge rst)
if (rst) 
    fail <= {N-1{1'b0}};
else
for ( i = 0; i < N; i = i + 1 )
    fail[i] <= fail[i] | error;

endmodule

当hdlin_preserve_sequential变量被设置为none时,所有不可读触发器fail_reg[i]都被删除了;当hdlin_preserve_sequential变量被设置为all时,触发器推断报告如下所示,GETCH网表如图3所示;

复制代码
==================================================================================
|    Register Name    |   Type    | Width | Bus | MB |  Set  | Reset | ST | Line |
==================================================================================
|      fail_reg       | Flip-flop |   4   |  Y  | N  | None  | Async | N  |  7   |
==================================================================================

图3 例2的GETCH网表

当hdlin_preserve_sequential变量被设置为all+loop_variables时,触发器推断报告如下所示,GETCH网表如图4所示。

复制代码
==================================================================================
|    Register Name    |   Type    | Width | Bus | MB |  Set  | Reset | ST | Line |
==================================================================================
|      fail_reg       | Flip-flop |   4   |  Y  | N  | None  | Async | N  |  7   |
|        i_reg        | Flip-flop |  32   |  Y  | N  | None  | None  | N  |  7   |
==================================================================================

图4 例2的GETCH网表

preserve_sequential综合指令

hdlin_preserve_sequential变量只能进行粗粒度的控制,如果想要更细粒度的控制,可以使用preserve_sequential综合指令。需要强调,preserve_sequential综合指令只能用于保留有可能被推断出的时序单元,对于组合逻辑的保留是间接的。

例3展示了该综合指令的使用方法。

复制代码
// 例3
module mydesign (input  in1, in2, in3, input clk, output out);
reg sum1;
reg sum2 /* synopsys preserve_sequential */;
wire save;

always @ (posedge clk) begin
    sum1 <= in1 | in2;
    sum2 <= in1 & in2 & in3; // 该组合逻辑会被保留(间接)
end

assign out = ~sum1;
assign save = sum1 & sum2; // 该组合逻辑不会被保留,因为它位于被保留触发器sum2_reg后面

endmodule

此时的触发器推断报告如下所示,GETCH网表如图5所示。

复制代码
==================================================================================
|    Register Name    |   Type    | Width | Bus | MB |  Set  | Reset | ST | Line |
==================================================================================
|      sum1_reg       | Flip-flop |   1   |  N  | N  | None  | None  | N  |  6   |
|      sum2_reg       | Flip-flop |   1   |  N  | N  | None  | None  | N  |  6   |
==================================================================================

图5 例3的GETCH网表

例4展示了该综合指令的使用方法。

复制代码
// 例4
module mydesign (input  in1, in2, in3, input clk, output out);
reg sum1;
reg sum2, save /* synopsys preserve_sequential */;

always @ (posedge clk) begin
    sum1 <= in1 | in2;
    sum2 <= in1 & in2 & in3; // 该组合逻辑会被保留(间接)
end

assign out = ~sum1;

always @ (posedge clk) begin
    save = sum1 & sum2; // 该组合逻辑也会被保留(间接),因为save信号被定义为reg类型且添加了综合指令
end

endmodule

此时的触发器推断报告如下所示,GETCH网表如图6所示。

复制代码
==================================================================================
|    Register Name    |   Type    | Width | Bus | MB |  Set  | Reset | ST | Line |
==================================================================================
|      sum1_reg       | Flip-flop |   1   |  N  | N  | None  | None  | N  |  6   |
|      sum2_reg       | Flip-flop |   1   |  N  | N  | None  | None  | N  |  6   |
|      save_reg       | Flip-flop |   1   |  N  | N  | None  | None  | N  |  13  |
==================================================================================

图6 例4的GETCH网表

Design Compiler NXT在2022版本推出了report_transformed_registers命令,该命令可以报告工具在优化过程中对寄存器(包括触发器和锁存器)进行的所有变换,详细内容可以参考下面的博客。

SDC命令详解:使用report_transformed_registers命令进行报告https://blog.csdn.net/weixin_45791458/article/details/158101563?sharetype=blogdetail&sharerId=158101563&sharerefer=PC&sharesource=weixin_45791458&spm=1011.2480.3001.8118 不管是使用hdlin_preserve_sequential变量还是preserve_sequential综合指令,它只能影响HDL Compiler在读取RTL代码时的行为,对于Design Compiler在综合时对于不可读触发器的优化,可以参考下面的博客。

Design Compiler:不可读单元的移除https://blog.csdn.net/weixin_45791458/article/details/157099538?ops_request_misc=%257B%2522request%255Fid%2522%253A%252227bdd50e3fb6d8469484e6eb17894502%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=27bdd50e3fb6d8469484e6eb17894502&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-157099538-null-null.nonecase&utm_term=Design%20Compiler%EF%BC%9A%E4%B8%8D%E5%8F%AF%E8%AF%BB&spm=1018.2226.3001.4450

相关推荐
日晨难再13 小时前
SDC命令详解:使用report_transformed_registers命令进行报告
数字ic
ll56782 天前
数字IC后端实现之OCC电路分段时钟树综合实战解析
数字ic·时钟树综合·occ电路·分段时钟树
日晨难再3 天前
SDC命令详解:使用write_environment命令进行输出
数字ic
日晨难再5 天前
SDC命令详解:使用write_app_var命令进行输出
数字ic
日晨难再8 天前
DSO.ai:基于AI的搜索优化型EDA工具介绍
人工智能·数字ic
日晨难再19 天前
物理约束命令:创建芯片(Die)区域和核心(Core)区域
数字ic
日晨难再24 天前
Design Compiler:触发器的复制(set_register_replication命令)
数字ic
日晨难再1 个月前
Design Compiler:不可读单元的移除
数字ic
日晨难再1 个月前
SDC命令详解:使用write_parasitics命令进行输出
数字ic