ASIC-WORLD Verilog(16)综合

 写在前面

        在自己准备写一些简单的verilog教程之前,参考了许多资料----Asic-World网站的这套verilog教程即是其一。这套教程写得极好,奈何没有中文,在下只好斗胆翻译过来(加点自己的理解)分享给大家。

        这是网站原文:Verilog Tutorial

        这是系列导航:Verilog教程系列文章导航


什么是逻辑综合( logic synthesis )?

        逻辑综合是将高层次的设计描述转换为优化后的门级设计的过程。逻辑综合会使用一个标准的单元库,它有许多简单的单元,例如像与门或门非门等基本的逻辑门、加法器、多路选择器、存储单元和触发器。标准单元组合起来则被称为技术库。通常,这种技术库以晶体管的尺寸(0.18u,90纳米)而为人所知。

        电路描述是用硬件描述语言(HDL)编写的,例如如Verilog。设计师应该首先理解架构描述,然后他才应该考虑设计限制,如时间、面积、可测试性和功率等。

        我们将在最后一章的Verilog教程中,看到一个典型的大型设计流程的例子。        

在Verilog发明之前的设计方法

        正如你必须在大学里所经历的一样,一切(所有的数字电路)都是手动设计的。绘制卡诺图、优化逻辑、绘制原理图等。这就是工程师们早期设计数字逻辑电路的方法。好吧,如果只设计几百个门的话这方法也还行。

hdl与逻辑综合的影响

        高级设计不太容易出现人为错误,因为设计是在一个较高的抽象层级上进行描述的。高层次的设计是在不对设计约束过于关注的情况下完成的。从高层次设计转换到门级设计是通过综合工具,使用各种算法优化整体设计来实现的。这就消除了设计和次优化设计中不同设计风格的问题。逻辑综合工具允许技术独立设计。对于技术独立的描述,设计重用是可能的。

我们在这里讨论什么?

        对于Verilog来说,其综合流程也与其他语言相同。接下来的文章,我们要看的是特定代码是如何转化为门级电路的。"delay"就是一个例子。我们无法综合delay,但是当然我们可以通过添加缓冲器来增加特定信号的delay。但这也会变得过于依赖于综合目标技术了。
        首先,我们将聚焦在无法综合的构造,下表显示了无法被综合的构造。


无法被综合的构造

构造类型

说明

initial

只能用于testbenches

events

只能用于testbenches

real

不支持

time

不支持

force and release

不支持

assign and deassign

不能用于reg,只能用于wire

fork join

使用非阻塞赋值可以达到同样的效果

primitives

仅仅支持门级原语

table

不支持

示例:无法被综合的构造

        任何包含上述构造的代码都是不可综合的,但是在可综合的构造中,糟糕的编码也可能会引起综合问题。我就见过某个工程师的代码中,触发器的敏感列表居然同时是时钟的上升沿和下降沿。

        另一种常见的错误类型是,一个reg变量被多个always块所驱动。这也肯定会引起综合错误。

    
示例1:Initial 语句

module synthesis_initial(
clk,q,d);
input clk,d;
output q;
reg q;initial beginq <= 0;
end always @ (posedge clk)
beginq <= d;
end endmodule

示例2:Delays语句

        a = #10 b;        //这句代码仅在仿真时有效

        综合工具通常会忽略这些构造,只是假设上面的语句中没有#10,因此综合工具会将上面的代码简单地视为 

        a = b;

与X 和 Z的比较总是被忽略

        似乎所有新的硬件设计工程师都有一个共同的问题--他们通常倾向于将变量与x和z进行比较。实际上这是最糟糕的事情,请避免与X和Z相比较。将您的设计限制在0和1这两个状态。仅在芯片的IO端口才使用三态(tri-state)。


可以被综合的构造

        Viilog是这样一种简单的语言--您很容易就可以编写出很容易实现和被映射到门级电路的代码。使用 if和case语句的代码很简单,使用综合工具不会引起很多麻烦。但是,如果你喜欢花哨的代码风格,并且喜欢有一些麻烦,好吧,你也别怕,不过你最好在有了一定经验后再使用它们。使用高层次的构造是很有趣的,而且很省时间。

        建模任何逻辑的最常见方法是使用assign语句或always块。assign语句只可用于组合逻辑;而always块则可以用于组合逻辑和时序逻辑。

构造类型

关键词或描述

端口

input, inout, output

参数

parameter

模块定义

module

信号和变量

wire, reg, tri

例化

module instances / primitive gate instances

函数和任务

function , task

过程语句

always, if, else, case, casex, casez

过程块

begin, end, named blocks, disable

数据流

assign

循环语句

for, while, forever

逻辑电路建模

        根据我们在数字设计中所学到的内容,我们知道只有两种类型的数字电路。一种是组合逻辑电路,另一种是时序逻辑电路。只有很少的规则需要遵循,就可以获得良好的综合输出和避免意外发生。

使用assign语句的组合逻辑电路

        可以使用assign和always块来实现组合逻辑电路。使用assign语句在Viilog中编写简单的组合电路非常简单,就像下面的例子中所描述的那样。

assign Y=(A&MP;B)|(C);

示例1:三态缓冲器(Tri-state buffer)

module tri_buf (a,b,enable);input a;output b;input enable;wire b;assign b = (enable) ? a : 1'bz;endmodule

示例2:多路选择器(Mux)

module mux_21 (a,b,sel,y);input a, b;output y;input sel;wire y;assign y = (sel) ? b : a;endmodule

示例3:简单拼接

module bus_con (a,b);input [3:0] a, b;output [7:0] y;wire [7:0] y;assign y = {a,b};endmodule

示例4:带进位的1位加法器

module addbit (
a      , // first input
b      , // Second input
ci     , // Carry input
sum    , // sum output
co       // carry output
);
//Input declaration
input a;
input b;
input ci;
//Ouput declaration
output sum;
output co;
//Port Data types
wire  a;
wire  b;
wire  ci;
wire  sum;
wire  co;
//Code starts here
assign {co,sum} = a + b + ci;endmodule // End of Module addbit

示例5:乘2电路

module muliply (a,product);input [3:0] a;output [4:0] product;wire [4:0] product;assign product  = a << 1;endmodule

示例6:3-8译码器

module decoder (in,out);
input [2:0] in;
output [7:0] out;
wire [7:0] out;
assign out  =  	(in == 3'b000 ) ? 8'b0000_0001 : 
(in == 3'b001 ) ? 8'b0000_0010 : 
(in == 3'b010 ) ? 8'b0000_0100 : 
(in == 3'b011 ) ? 8'b0000_1000 : 
(in == 3'b100 ) ? 8'b0001_0000 : 
(in == 3'b101 ) ? 8'b0010_0000 : 
(in == 3'b110 ) ? 8'b0100_0000 : 
(in == 3'b111 ) ? 8'b1000_0000 : 8'h00;endmodule

使用always块的组合逻辑电路

        在使用always语句建模时,如果不小心的话,有可能会综合出来一个锁存器。(似乎没有人喜欢设计中的锁存器,尽管它们速度更快,而且采用的晶体管也较少。这是因为时序分析工具总是有锁存器的问题,锁存器启用时的故障是另一个问题)。

        用always语句消除锁存器的一个简单方法是始终在always代码的开头将0驱动到等式的左侧变量,如下文代码所示。

示例:用always语句实现的3-8译码器

module decoder_always (in,out);
input [2:0] in;
output [7:0] out;
reg [7:0] out;always @ (in)
beginout = 0;case (in)3'b001 : out = 8'b0000_0001;3'b010 : out = 8'b0000_0010;3'b011 : out = 8'b0000_0100;3'b100 : out = 8'b0000_1000;3'b101 : out = 8'b0001_0000;3'b110 : out = 8'b0100_0000;3'b111 : out = 8'b1000_0000;endcase
endendmodule

时序逻辑电路

        时序逻辑电路是利用always块的敏感列表中的边缘敏感元素实现的。时序逻辑只能使用always块来实现。通常我们使用非阻塞赋值来进行实现时序逻辑电路。

示例:简单的触发器

module flif_flop (clk,reset, q, d);
input clk, reset, d;
output q;
reg q;always @ (posedge clk )
beginif (reset == 1) beginq <= 0;end else beginq <= d;end
endendmodule

Verilog编码风格

        如果你看看上面的代码,你会发现我强加了一个看起来很酷的编码风格。

  • 信号和变量要使用有意义的名称
  • 不要把水平和边缘敏感的元素混合在同一个always块中
  • 避免将上升沿触发和下降沿触发的触发器混合在一起
  • 使用括号优化逻辑结构
  • 简单的组合逻辑使用连续赋值语句
  • 时序逻辑使用非阻塞赋值,组合逻辑使用阻塞赋值
  • 不要将阻塞赋值和非阻塞赋值的混合在同一个always块中
  • 别对同一变量的进行多次赋值
  • 明确地定义"if-else语句"或"case语句"

  • 📣您有任何问题,都可以在评论区和我交流📃!
  • 📣本文由 孤独的单刀 原创,首发于CSDN平台🐵,博客主页:wuzhikai.blog.csdn.net
  • 📣您的支持是我持续创作的最大动力!如果本文对您有帮助,还请多多点赞👍、评论💬和收藏⭐!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/119530.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Centos 6.5 升级到Centos7指导手册

一、背景 某业务系统因建设较早&#xff0c;使用的OS比较过时&#xff0c;还是centos6.5的系统&#xff0c;因国产化需要&#xff0c;需将该系统升级到BClinux 8.6&#xff0c;但官方显示不支持centos 6.x升级到8&#xff0c;需先将centos6.5升级到centos7的最新版&#xff0c…

【100天精通Python】Day53:Python 数据分析_NumPy数据操作和分析进阶

目录 1. 广播 2 文件输入和输出 3 随机数生成 4 线性代数操作 5 进阶操作 6 数据分析示例 1. 广播 广播是NumPy中的一种机制&#xff0c;用于在不同形状的数组之间执行元素级操作&#xff0c;使它们具有兼容的形状。广播允许你在不显式复制数据的情况下&#xff0c;对不同…

合宙Air724UG LuatOS-Air LVGL API控件--容器 (Container)

容器 (Container) 容器是 lvgl 相当重要的一个控件了&#xff0c;可以设置布局&#xff0c;容器的大小也会自动进行调整&#xff0c;利用容器可以创建出自适应成都很高的界面布局。 代码示例 – 创建容器 cont lvgl.cont_create(lvgl.scr_act(), nil) lvgl.obj_set_auto_re…

北京APP外包开发需要注意的问题

开发APP的过程中&#xff0c;由于开发APP需要投入大量的时间、精力和资源&#xff0c;所以在开始前一定要做好充足的准备和规划。您需要注意以下重点&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1…

如何熟练使用vector?

&#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;推荐专栏1: &#x1f354;&#x1f35f;&#x1f32f;C语言初阶 &#x1f43b;推荐专栏2: &#x1f354;&#x1f35f;&#x1f32f;C语言进阶 &#x1f511;个人信条: &#x1f335;知行合一 &#x1f…

数据集收集列表(opencv,机器学习,深度学习)持续更新

opencv 车牌识别数据集 opencv 手写数字识别数据集 机器学习 印第安糖尿病 Pima Indians数据集 &#xff0c;下载地址 Boston波士顿房价数据集 &#xff0c;下载

MetInfo5.0文件包含漏洞

MetInfo历史版本与文件 环境在这里下载&#xff0c;使用phpstudy搭建 我们来看到这个index.php&#xff0c;如下图所示&#xff0c;其中定义了fmodule变量与module变量&#xff0c;其中require_once语句表示将某个文件引入当前文件&#xff0c;在这个代码中&#xff0c;通过r…

PostgreSQL问题记录:column “...“ does not exist

在PostgreSQL中&#xff0c;不论是在pgAdmin中&#xff0c;还是在命令行控制台里面&#xff0c;在SQL语句中表示属性值的总会遇到ERROR: column “…” does not exist这样的错误&#xff0c;比如下面的语句&#xff1a; 解决方案&#xff1a;将 “txt2txt” 的双引号改成单引…

配置本地maven

安装maven安装包 修改环境变量 vim ~/.bash_profile export JMETER_HOME/Users/yyyyjinying/apache-jmeter-5.4.1 export GOROOT/usr/local/go export GOPATH/Users/yyyyjinying/demo-file/git/backend/go export GROOVY_HOME/Users/yyyyjinying/sortware/groovy-4.0.14 exp…

虚拟机的安装

需要的工具 ①VMware Workstation 17 提取链接&#xff1a;https://pan.baidu.com/s/1e2p_wlYwdM-JxbXVMb3W0Q?pwd16ed 提取码&#xff1a;16ed ②Redhat镜像 9.1版本提取链接&#xff1a;https://pan.baidu.com/s/1sJC275e2d_9tPDElC83o2g?pwdss9x 提取码&#xff1a;…

Linux系统Ubuntu配置Docker详细流程

本文介绍在Linux操作系统Ubuntu的18.04及以上版本中&#xff0c;配置开源容器化平台和工具集Docker的详细方法&#xff1b;其中&#xff0c;我们以配置Docker平台的核心组件之一——Docker Engine为例来详细介绍。 首先&#xff0c;大家需要明确&#xff0c;我们常说的Docker&a…

pytorch(b站小土堆学习笔记P1-P15)

P3. Python学习中的两大法宝函数&#xff08;当然也可以用在PyTorch&#xff09; import torch#查看pytorch有哪些指令 print(dir(torch)) print(dir(torch.cuda)) #查看每条指令怎么用 help(torch.cuda.is_available) P4. PyCharm及Jupyter使用及对比 P5 dataset和dataloade…

【算法】滑动窗口

滑动窗口应用场景 关键词&#xff1a; 满足xxx条件&#xff08;计算结果&#xff0c;出现次数&#xff0c;同时包含&#xff09; 最长/最短 子串/子数组/子序列 例如&#xff1a;长度最小的子数组 滑动窗使用思路&#xff08;寻找最长&#xff09; 核心&#xff1a;左右双指…

2021年06月 C/C++(六级)真题解析#中国电子学会#全国青少年软件编程等级考试

C/C++编程(1~8级)全部真题・点这里 第1题:逆波兰表达式 逆波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式2 + 3的逆波兰表示法为+ 2 3。逆波兰表达式的优点是运算符之间不必有优先级关系,也不必用括号改变运算次序,例如(2 + 3) * 4的逆波兰表示法为* + 2 3 …

基于MQTT协议的物联网关

随着工业领域的不断发展&#xff0c;数字化转型已经成为企业迈向未来的必由之路。在这个数字化浪潮中&#xff0c;HiWoo Box以其强大的功能和创新的设计&#xff0c;在工业物联网领域被越来越多的人所熟知。特别是其基于MQTT协议的物联网关能力&#xff0c;也为企业实现智能化数…

无门槛访问ChatGPT升级版-数据指北AI

大家好&#xff0c;我是脚丫先生 (o^^o) 给小伙伴们介绍ChatGPT升级版不需要任何门槛&#xff0c;不需要单独搞账号&#xff0c;只要邮箱登录的方式&#xff0c;即可访问平台&#xff0c;以用户体验为首要&#xff0c;让所有人都能无门槛的使用目前市面上最强大的AI智能聊天&a…

ubuntu20.04+ROS noetic在线运行单USB双目ORB_SLAM

双目摄像头主要有以下几种&#xff0c;各有优缺点。 1.单USB插口&#xff0c;左右图像单独输出2.双USB插口&#xff0c;左右图像单独输出&#xff08;可能存在同步性问题&#xff09;3.双USB插口&#xff0c;左右图像合成输出4.单USB插口&#xff0c;左右图像合成输出 官方版…

Java实现获取微信小程序scheme码报错

如标题所见&#xff0c;使用Java获取小程序scheme时除了出现文档中的常见错误&#xff0c;我将我调试的时候遇到的错误和解决方式分享出来方便大家少花一部分时间解决该问题。&#xff08;往下划有结论节省时间&#xff09;。 获取scheme码之前需要先获取access_token&#xff…

使用Postman如何在接口测试前将请求的参数进行自定义处理

1、前言 当我们使用 Postman 进行接口测试时&#xff0c;对于简单的不需要处理的接口&#xff0c;直接请求即可&#xff0c;但是对于需要处理的接口&#xff0c;如需要转码、替换值等&#xff0c;则就麻烦一些&#xff0c;一般我们都是先手动把修改好的值拷贝到请求里再进行请…

Jaeger的经典BUG原创

前端&#xff0c;笔者在使用Jaeger进行Trace监控的时候&#xff0c;当数据量增大到一定数量级时&#xff0c;出现了一次CPU暴增导致节点服务器挂了的经典案例&#xff0c;这里对案例进行一个简单的抽象&#xff0c;供大家参考&#xff1a; 首先通过pprof对耗时的函数进行定位&…