0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

教你如何书写高质量的Verilog代码?

冬至子 来源:小何的芯像石头 作者:五线谱是偶然来的 2023-06-27 11:16 次阅读

关于 Verilog HDL 的认知

常见认知(错误)

  • 很多语法规则与 C 语言相似,书写时可参考 C 语言
  • 追求代码的整洁简短
  • 着眼于代码书写,性能优化由综合器实现
  • 把 Verilog 代码当成了程序,把电路设计当成了编程

正确认知

HDL:hardware Description

  • HDL 语言仅是对已知硬件电路的文本表现形式编写前,对所需实现的硬件电路“ 胸有成竹
  • Verilog HDL 的基本功能之一是描述可综合的硬件电路。
  • 相比 C 语言,最显著的区别在于 HDL 语言具备以下硬件设计的基本概念:
    • 互连(Connectivity) : wire 型变量描述各个模块之间的端口与网线连接关系
    • 并发(concurrency) : 可以有效地描述并行的硬件系统
    • 时间(time) : 定义了绝对和相对的时间度量,可综合操作符具有物理延迟

Verilog HDL 用于可综合描述的语句

  • always
  • if-else
  • case
  • assign

这里课件上的 for 不可用于综合,这点不敢苟同

if-else 相关语句的硬件结果映射及优化

if-else 硬件结构

  • 映射的硬件结构: Multiplexing Hardware -> 多路选择器, 输出结果由输入的选择条件决定

图片

  • 重构 if-else 映射的硬件结构:减少了一个加法器,减少了硬件面积:

图片

trade-off :但是在这种情况下,电路的传播延迟 -> 数据通路的延迟没改变,但是控制通路的传播也变成了一个选择器和加法器之和,如果 aflag 到来延迟晚,则后一种电路没前者好的性能没这么好:

图片

单 if 语句-无优先级的判断结构

如以下代码:

always@(a or b or c or d or sel)begin
   z=0;
    if(sel[3])
        z=d;
    else if(sel[2])
        z=c;
    else if(sel[1])
        z=b;
    else if(sel[0])
        z=a;
end

硬件结构为:

图片

多 if 语句-具有优先级的判断结构

如以下代码:

always@(a or b or c or d or sel)begin
   z=0;
    if(sel[0])z=a;
    if(sel[1])z=b;
    if(sel[2])z=c;
    if(sel[3])z=d;
end

硬件结构为:

图片

最后一级选择信号具有最高的优先级,具有优先级的多选结构会消耗组合逻辑

  • 若某些设计中,有些信号要求先到达(如关键使能信号,选择信号等),而有些信号需要后到达(如慢速信号,有效时间较长的信号等),此时则需要采用此结构
  • 设计方法:最高优先级给最迟到达的关键信号

此处结合阻塞赋值与非阻塞赋值去想都是成立的

case-无优先级的判断结构

如以下代码:

always@(a or b or c or d or sel)begin
    case(sel)
        2'b00: z=d;
        2'b01: z=c;
        2'b10: z=b;
        2'b11: z=a;
       default: z=1'b0;
    endcase
end
  • 与单 if 语句的区别: 条件多为互斥
  • 多用于指令译码电路

慎用 Latch

综合器很难解释 latch,因此,除非特殊用途,一般避免引入 latch.

图片

一般只在异步电路与门控时钟中用到

  • latch 由电平触发,非同步控制.在使能信号有效时,latch 相当于通路,在使能信号无效时 latch 保持输出状态。DFF 由时钟沿触发,同步控制。
  • latch 容易产生毛刺(glitch),DFF 则不易产生毛刺。
  • latch 将静态时序分析变得极为复杂。
  • 一般的设计规则时:在绝大多数设计中避免产生 latch。latch 最大的危害在于 不能过滤毛刺 。这对于下一级电路时极其危险的。所以,只要能用 D 触发器的地方,就不用 latch。
  • 易引入 latch 的途径:使用不完备的条件判断语句

图片

所以防止产生非目的性 latch 的措施:

  • 使用完备的 if-else 语句
  • 为每个输入条件设计输出操作,为 case 语句设置 default 操作
  • 仔细检查综合器生成的报告,latch 会以 warning 的形式报告

利用综合器指令指定电路结构

full-case

对如红绿灯等只有红绿黄三种情况下,采用 2bit 的状态编码则会产生分支赋值不完备的情况:

always@(a or b or c or sel)begin
    case(sel)
        2'b00: y=a;
        2'b01: y=b;
        2'b10: y=c;
    endcase
end

此时现实的状态已经完备了,但是从数字电路角度出发会有一个 2'b11 下的 latch

图片

此时使用 full-case:

  • full-case: 告诉综合器,当前 case 结构所列条件已完备
always@(a or b or c or sel)begin
    case(sel) // synopsys full_case
        2'b00: y=a;
        2'b01: y=b;
        2'b10: y=c;
    endcase
end

此时综合器结果:

图片

则不会推断出 latch

parallel_case

当 case 语句中的分支条件不互斥,则 case 语句存在优先级,如:

always@(irq)begin
    int = 3'b0;
    casez(irq)
        3'b1??: int[2]=1'b1;
        3'b?1?: int[1]=1'b1;
        3'b??1: int[0]=1'b1;
    endcase
end

综合器报告:

图片

使用 parallel-case 原语:告诉 DC,所有条件互斥,并行且无优先级

always@(irq)begin
    int = 3'b0;
    casez(irq) // synopsys parallel_case
        3'b1??: int[2]=1'b1;
        3'b?1?: int[1]=1'b1;
        3'b??1: int[0]=1'b1;
    endcase
end

合理使用 parallel case 约束,可以条件译码逻辑

图片

逻辑复制-均衡负载

通过逻辑赋值,降低关键信号的扇出,进而降低该信号的传播延迟,提高电路性能:

图片

trade-off: 资源消耗

资源共享-减少面积

若电路中存在较多公共单元,可以通过资源共享来减少面积:

图片

但一般共享会导致性能下降

资源顺序重排-降低传播延时

对到达延迟大的信号,可以重排其电路顺序以降低传播延时,提高性能:

图片

如图,假设 A 来得比较晚,就可以将其尽可能放在后面,隐藏他的延迟

":?"仅用于连线,always 用于逻辑运算

尽可能使用 always 来描述电路,assign 仅仅用来实现连线,如:

assign a = (b==1)?((c&&d)? 1'b1:1'b0):1'b0;

与 always 块描述的:

always@(*) begin
    if(b==1'b1)
        if(c&&d == 1'b1)
      a=1'b1;
     else
            a=1'b0;
    else
        a=1'b0;
end

关于 assign 和三目运算符:

  • 仅用于信号连线
  • 难以阅读,且多层嵌套后很难被综合器解释

可综合风格对代码的要求

完整的 always 敏感信号列表

  • 所有的组合逻辑或所存的 always 结构必须由敏感信号列表.其中必须包括所有的输入信号
  • 原因: 综合过程将产生要给取决于除命案列表中所有其它值的结构,它将可能在行为仿真和门级仿真间产生潜在的失配.

每个 always 敏感信号列表对应一个时钟

  • 在综合过程中,每个 Verilog always 敏感信号列表只能对应一个时钟。
  • 原因:这是将每一个过程限制在单一寄存器类型的要求,有利于逻辑综合和时序分析

不允许 Wait 声明和# delay 声明

  • Wait 声明语句,无论时清楚还是含糊,都不能用于可综合设计。
  • 原因:从 RTL 级转换到 gate 级的综合工具一般都不支持 Wait 声明和# delay 声明,为了有效的综合,这些语句应该避免。
  • 例外:在不需要进行综合的行为模块中,如测试模块,表示行为的虚拟期间模块中可以使用。

在时序电路中必须使用非阻塞赋值(<=)

在组合逻辑中必须使用阻塞赋值(=)

模块划分

分开异步逻辑与同步逻辑

  • 建议分开异步逻辑与同步逻辑
  • 原因:简化综合时的问题,简化约束和编码难度
  • 例外:不可应用于非综合模块中(例如:总线模块,总线监视器或是模拟模块)除非他们被设计来综合仿真。

分开控制逻辑和存储器

  • 建议分开控制逻辑与存储器逻辑为独立模块
  • 原因:存储器一般由 memory compiler 生成,便于高层的存储器模块的使用和便于重新描述为不同的存储器类型。混用不利于综合,不利于方便更换工艺库和平台。
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 寄存器
    +关注

    关注

    31

    文章

    5322

    浏览量

    120022
  • 触发器
    +关注

    关注

    14

    文章

    1996

    浏览量

    61053
  • HDL语言
    +关注

    关注

    0

    文章

    46

    浏览量

    8912
  • dff
    dff
    +关注

    关注

    0

    文章

    26

    浏览量

    3400
  • 多路选择器
    +关注

    关注

    1

    文章

    22

    浏览量

    6517
收藏 人收藏

    评论

    相关推荐

    分享一些优秀的verilog代码 高质量verilog代码的六要素

    高质量verilog代码至少需要包含以下几个要素:可读性、功能、性能、标准化、稳定性、可定位。
    的头像 发表于 07-18 10:09 1112次阅读
    分享一些优秀的<b class='flag-5'>verilog</b><b class='flag-5'>代码</b> <b class='flag-5'>高质量</b><b class='flag-5'>verilog</b><b class='flag-5'>代码</b>的六要素

    何为高质量代码?如何写出高质量代码

    懂得“数据结构与算法” 写出高效的代码,懂得“设计模式”写出高质量代码
    发表于 08-02 09:44 781次阅读
    何为<b class='flag-5'>高质量</b>的<b class='flag-5'>代码</b>?如何写出<b class='flag-5'>高质量</b><b class='flag-5'>代码</b>?

    protel输出高质量gerber

    图文并茂一步一步手把手教你输出高质量的gerber傻瓜式教学。。。。[hide] [/hide]
    发表于 12-12 15:43

    高质量C++、C编程指南

    高质量C++、C编程指南
    发表于 08-06 11:58

    高质量C语言编程

    高质量c语言,精,精,精,精华
    发表于 07-22 13:48

    编写高质量C语言代码

    编写高质量C语言代码 编写高质量C语言代码 编写高质量C语言代码
    发表于 07-31 17:47

    【分享】verilog代码书写规范

    FPGA verilog代码书写规范,很好的借鉴
    发表于 05-21 11:36

    高质量编程

    干货,《495个C语言问题》、《华为内部程序设计编码规范》、《C语言:陷阱和缺陷》、《高质量C编程[林锐]》
    发表于 02-27 19:39

    Verilog HDL代码书写规范

    Verilog HDL代码书写规范
    发表于 09-30 08:55

    Verilog HDL代码书写规范

    本帖最后由 lee_st 于 2017-10-31 08:46 编辑 Verilog HDL代码书写规范
    发表于 10-21 20:53

    10个嵌入式小技巧 教你写出高质量代码

    由于物联网的发展,现在没人不知道嵌入式系统了,加上身边也有很多嵌入式的设备,所以这也让大家开始都转入到嵌入式门下,那么因为嵌入式毕竟是技术,所以下面也来给大家介绍下10个嵌入式技巧,教你怎么写高质量
    发表于 12-20 16:19

    Verilog代码书写规范

    Verilog代码书写规范 本规范的目的是提高书写代码的可读性、可修改性、可重用性,优化代码
    发表于 04-15 09:47 106次下载

    高质量代码的设计特点

    高质量的设计往往有一些共同的特点。如果你能达到这些对象,那么可以认为你的设计也是非常成功的。有些对象是互相矛盾的。但是这是设计的挑战所在,在相互矛盾的对象之间做出
    发表于 07-19 15:15 0次下载

    高质量Verilog代码有什么特点

    高质量verilog代码主要包含以下几个要素:可读性、功能、性能、标准化、稳定性、可定位。
    发表于 03-30 10:12 1935次阅读
    <b class='flag-5'>高质量</b><b class='flag-5'>Verilog</b><b class='flag-5'>代码</b>有什么特点

    如何编写高质量的Javascript代码

    这篇文章不仅仅从代码本身来考虑如何优化编码,也从代码的设计阶段来考虑,包括书写API文档,同事的review,使用JSLint。这些习惯都能帮助你编写更加高质量的、更易于理解的、可维护
    发表于 01-21 14:28 7次下载
    如何编写<b class='flag-5'>高质量</b>的Javascript<b class='flag-5'>代码</b>