当前位置: 首页 > news >正文

数字IC前端学习笔记:锁存器的综合

相关阅读

数字IC前端专栏https://blog.csdn.net/weixin_45791458/category_12173698.html?spm=1001.2014.3001.5482


        锁存器是一种时序逻辑,与寄存器相比面积更小,但它的存在会使静态时序分析(STA)变得更加复杂,因此懂得什么样的设计会综合出锁存器是很重要的,本文就将对此进行详细介绍。 

显式锁存器

        显式锁存器指的是在连续赋值语句或组合逻辑always结构中,将信号显式赋值给自己时出现的锁存器,一般显式锁存器是有意为之的。

连续赋值语句

最直观的锁存器

图1 D型锁存器

// 例1
module NonLatch1 (input wire d,input wire en,output wire q,output wire qbar
);wire set, rst;assign set =  !(en &  d);assign rst =  !(en & !d);assign q    = !(set & qbar);assign qbar = !(rst & q);endmodule

        图2是例1在Design Compiler 2024中的综合结果,可以看出,即使可以综合,综合工具并没有推断出D锁存器,而是综合为存在组合环(Combinational Loop)或者说反馈的结构。

图2 例1的综合结果

使用条件操作符

// 例2
module NonLatch2 (input wire d,input wire en,output wire q,output wire qbar
);assign q = en ? d : q;assign qbar = !q;
endmodule

        图3是例2的综合结果,可以看出,综合工具也没有推断出D锁存器,而是综合为存在组合环(Combinational Loop)或者说反馈的多路选择器。 

图3 例2的综合结果

always结构

        需要注意的是,这里指的是组合逻辑always结构,而不是边沿控制的时序逻辑always块,对于后者,综合工具会推断出触发器而不是锁存器。

使用条件操作符

// 例3
module Latch1 (input wire d,input wire en,output reg q,output reg qbar
);always @(*) beginq = en ? d : q;qbar = !q;endendmodule

        图4是例3的综合结果,可以看出,综合工具将其综合为D锁存器。 

图4 例3的综合结果

使用if-else语句

// 例4
module Latch2 (input wire d,input wire en,output reg q,output reg qbar
);always @(*) beginif (en) beginq = d; qbar = ~d;endelse beginq = q; qbar = qbar;endendendmodule

        图5是例4的综合结果,可以看出,综合工具将其综合为D锁存器,但与图4有一点区别,原因是发生了在优化过程中发生了相位反转和寄存器合并。  

图5 例4的综合结果

隐式锁存器

        隐式锁存器指的是在always结构中,没有将自己显式赋值给自己,但由于意料之外的因素出现的锁存器。

不完整的敏感列表

// 例5
module NonLatch3 (input wire a,input wire b,input wire c,output reg y
);always @(a) beginy = a & b & c;endendmodule

        例5使用组合逻辑always结构描述了一个三输入与门,但敏感列表中只有a而不含b和c,这导致了只有a发生变化时才会激活always结构。对于以前的综合工具,这会导致锁存器的产生;对于现在的综合工具,其对组合逻辑always结构的综合不依赖敏感列表,因此不会有锁存器产生,但这会导致前/后仿真的不一致,因为对于仿真工具根据敏感列表进行判断,因此行为就像是锁存器。

        图6是例5的综合结果,可以看出,综合工具将其综合为三输入与门。 

图6 例5的综合结果

        实际上,由于不完整的敏感列表带来的风险如此巨大,Verilog 2001标准新加了一个*通配符来形成一个完整的敏感列表。使用通配符意味着always结构中RHS表达式、函数和任务调用的参数、case语句的case expression和case item、if语句的expression信号将自动加入敏感列表,如例6所示。 

// 例6
module NonLatch4 (input wire a,input wire b,input wire c,output reg y
);always @(*) beginy = a & b & c;endendmodule

不完整的if语句

// 例7
module Latch3 (input wire a,input wire b,output reg y
);always @(*) beginif (a) y = b;endendmodule

        例7中的if语句缺少else分支,即当a为0时输出保持不变(这其实与例4等价,只不过例4是显式赋值),这是一个锁存器的行为,图7是例7的综合结果,可以看出,综合工具将其综合为D锁存器。 

图7 例7的综合结果

解决方法1

        保持if语句完整且在每个分支中对所有信号的赋值,如例8所示。

// 例8
module NonLatch5 (input wire a,input wire b,output reg y
);always @(*) beginif (a) y = b;else   y = 1'b0;endendmodule

解决方法2

        在always结构的开头对所有信号赋初值,如例9所示。

// 例9
module NonLatch6 (input wire a,input wire b,output reg y
);always @(*) beginy = 1'b0;if (a) y = b;endendmodule

不完整的case语句

// 例10
module Latch4 (input wire [1:0] sel,input wire a,input wire b,output reg y
);always @(*) begincase (sel)2'b00: y = 1'b0;2'b01: y = 1'b1;endcase
endendmodule

        与例7类似,例10中的case语句缺少case item,即当sel[1]为1时输出保持不变,这是一个锁存器的行为,图8是例10的综合结果,可以看出,综合工具将其综合为D锁存器。 

图8 例10的综合结果

解决方法1

        保持case语句完整且在每个分支中对所有信号的赋值(或者干脆使用case default),如例11所示。

// 例11
module NonLatch7 (input wire [1:0] sel,input wire a,input wire b,output reg y
);always @(*) begincase (sel)2'b00: y = a;2'b01: y = b;2'b01: y = 1'b1;2'b01: y = 1'b0;// default: y = 1'b0;endcase
endendmodule

解决方法2

        在always结构的开头对所有信号赋初值,如例12所示。

// 例12
module NonLatch8 (input wire [1:0] sel,input wire a,input wire b,output reg y
);always @(*) beginy = 1'b0;case (sel)2'b00: y = a;2'b01: y = b;endcase
endendmodule

根本原因

        以上这些无意间综合出的锁存器产生的根本原因是出现了在某些情况下需要保持信号值不变的需求,而又使用了组合逻辑always结构,因此只能使用锁存器实现功能。

        思考一个问题:如果不使用本文提到的这些解决方法,不完整的if语句和case语句一定会综合出锁存器吗?例13会综合出锁存器吗?

// 例12
module Latch_or_Not (input wire sel,input wire a,input wire b,output reg y
);reg [1:0] sel_with_constraint;always @(*) beginif (sel) sel_with_constraint = 2'b00;else     sel_with_constraint = 2'b01;
endalways @(*) beginy = 1'b0;case (sel_with_constraint)2'b00: y = a;2'b01: y = b;endcase
endendmodule

        图9是例13的综合结果,如果这与你想的不一样,想想锁存器产生的根本原因,而不是孤立地看待if语句和case语句。

图9 例13的综合结果

相关文章:

  • 前端工程化和性能优化问题详解
  • 位移监测仪,精准测量,专业守护
  • 单调栈所有模版(2)
  • 制造单元智能化改造与集成技术平台成套实训设备
  • 7、三维机械设计、装配与运动仿真组件 - /设计与仿真组件/3d-mechanical-designer
  • 线程的生命周期·
  • 加密领域 AI Agent 的崛起:DeFAI 如何重塑金融
  • Webpack基本用法学习总结
  • Java EE初阶——初识多线程
  • 基于阿里云DataWorks的物流履约时效离线分析
  • 2025.05.07-淘天算法岗-第二题
  • UI设计公司兰亭妙微分享:汽车 MHI 设计的界面布局创新法则
  • CNG汽车加气站操作工岗位职责
  • Oracle版本、补丁及升级(12)——版本体系
  • 涨薪技术|0到1学会性能测试第56课- 堆与栈、GC回收机制
  • 深入探索 Python 的 QuTiP 5 库:量子计算与开放量子系统模拟的利器
  • Prometheus生产实战全流程详解(存储/负载/调度篇)
  • sklearn自定义pipeline的数据处理
  • stm32之USART
  • 【计算机主板架构】ATX架构
  • 中国象棋协会坚决支持司法机关依法打击涉象棋行业的违法行为
  • 市自规局公告收回新校区建设用地,宿迁学院:需变更建设主体
  • “仓促、有限”,美英公布贸易协议框架,两国分别获得了什么?
  • 105岁八路军老战士、抗美援朝老战士谭克煜逝世
  • 中消协点名新能源汽车行业:定金退款争议频发
  • 牛市早报|央行宣布降准降息,公募基金改革最新方案落地