ASIC-WORLD Verilog(16)综合

news2024/11/25 16:50:14

 写在前面

        在自己准备写一些简单的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 begin
 q <= 0;
end 

always @ (posedge clk)
begin
 q <= 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)
begin
  out = 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
end
  	  	 
endmodule

时序逻辑电路

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

示例:简单的触发器

module flif_flop (clk,reset, q, d);
input clk, reset, d;
output q;
reg q;
  	  	 
always @ (posedge clk )
begin
  if (reset == 1) begin
    q <= 0;
  end else begin
    q <= d;
  end
end
  	  	 
endmodule

Verilog编码风格

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

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTML基础代码

以下是HTML基础代码&#xff1a; <!DOCTYPE html> <html> <head><title>网页标题</title> </head> <body><h1>这是一级标题</h1><p>这是一个段落。</p><img src"图片路径" alt"图片描述…

PNG图片压缩原理

png&#xff1f;&#xff1f;png的图片我们每天都在用&#xff0c;可是png到底是什么&#xff0c;它的压缩原理是什么&#xff1f; 很好&#xff0c;接下来我将会给大家一一阐述。 什么是PNG PNG的全称叫便携式网络图型&#xff08;Portable Network Graphics&#xff09;是…

一文讲清楚redis的线程池jedis

背景 在shigen实习的时候&#xff0c;遇到了日志系统的性能优化问题&#xff0c;当时的优化点就是&#xff1a;使用redis的线程池&#xff0c;实现并发状态下的性能优化。但是找了很多的技术方案&#xff0c;发现redis的线程池配置起来比较麻烦。正巧&#xff0c;这个周末shig…

arthas常用命令,排查cpu和内存场景

常用命令 命令&#xff1a;dashboard 查看jvm总体信息&#xff0c;包括线程&#xff0c;内存和运行环境 命令&#xff1a;monitor monitor -c 5 com.liubike.ta.controller.service.ApiService newString "param[1]2"每5秒统计一次监控方法被调用的次数 命令&…

numpy矩阵求MSE

MSE loss #官方示例 from sklearn.metrics import mean_squared_error y_true [[0.5, 1],[-1, 1],[7, -6]] y_pred [[0, 2],[-1, 2],[8, -5]] mean_squared_error(y_true, y_pred) #0.708验证 import numpy as np A np.array(y_true) B np.array(y_pred)mse (np.square…

【图解RabbitMQ-1】图解消息队列是什么玩意儿?它的应用场景有哪些?

&#x1f9d1;‍&#x1f4bb;作者名称&#xff1a;DaenCode &#x1f3a4;作者简介&#xff1a;CSDN实力新星&#xff0c;后端开发两年经验&#xff0c;曾担任甲方技术代表&#xff0c;业余独自创办智源恩创网络科技工作室。会点点Java相关技术栈、帆软报表、低代码平台快速开…

NeoVim 安装

一、NeoVim 是什么&#xff1f; hyperextensible Vim-based text editor 译&#xff1a;基于超可扩展Vim的文本编辑器 二、如何安装NeoVim 1.brew 安装 注&#xff1a;brew 是 MacOS 上的包管理工具&#xff0c;即该命令一般情况下只适用于 Mac 电脑 brew install neovim如果…

4.Flasgger-接口文档化

一.下载安装 pip install flasgger0.9.7.1二.基本使用 from flask import Flask, jsonify from flasgger import Swaggerapp Flask(__name__) swagger Swagger(app)app.route(/colors/<palette>/) def colors(palette):"""Example endpoint returnin…

git co 命令是什么意思,用法是怎么样的

偶然看到同事使用 git co feat/xxx 来操作 git&#xff0c;以为 co 是什么 git 新命令&#xff0c;看起来很牛逼&#xff0c;所以问了下 chatgpt&#xff0c;chatgpt 的回答如下&#xff1a; git co 是 git checkout 的缩写形式&#xff0c;需要在Git的全局配置或别名配置中启用…

基于 Zookeeper 实现服务注册和服务发现

文章目录 前言声明前置知识服务注册和发现Zookeeper 工作原理实现过程注册中心服务注册服务发现 总结 前言 无论是采用SOA还是微服务架构&#xff0c;都需要使用服务注册和服务发现组件。我刚开始接触 Dubbo 时一直对服务注册/发现以及 Zookeeper 的作用感到困惑&#xff0c;现…

100天精通Python(可视化篇)——第99天:Pyecharts绘制多种炫酷K线图参数说明+代码实战

文章目录 专栏导读一、K线图介绍1. 说明2. 应用场景 二、配置说明三、K线图实战1. 普通k线图2. 添加辅助线3. k线图鼠标缩放4. 添加数据缩放滑块5. K线周期图表 书籍推荐 专栏导读 &#x1f525;&#x1f525;本文已收录于《100天精通Python从入门到就业》&#xff1a;本专栏专…

UI自动化之混合框架

什么是混合框架&#xff0c;混合框架就是将数据驱动与关键字驱动结合在一起&#xff0c;主要用来回归业务主流程&#xff0c;将核心流程串联起来。 上一篇我们写到了关键字驱动框架&#xff0c;关键字驱动框架是针对一个业务场景的单条测试用例的。 我们以163邮箱的登录到创建…

官方发布:Mac 版 Visual Studio IDE将于明年 8 月 31 日停止支持

近日&#xff0c;微软官方宣布&#xff1a;适用于 Mac 平台的 Visual Studio 集成开发环境&#xff08;IDE&#xff09;已经启动 "退休" 进程。Visual Studio for Mac 17.6 将继续支持 12 个月&#xff0c;持续到 2024 年 8 月 31 日。 微软表示在未来的 1 年内将重…

Matlab图像处理-中值滤波

中值滤波 中值滤波也是基于空间域&#xff08;邻域&#xff09;操作的&#xff0c;中值滤波是将像素邻域内灰度的中值来代替中心像素的值&#xff0c;把不同灰度的像素点看起来更接近于邻域内的像素点。 优点是可以很好的过滤掉椒盐噪声。中值滤波是非线性的图像处理方法&…

Matlab图像处理-均值滤波

均值滤波 均值滤波所使用的运算是卷积。均值滤波用邻域内像素的平均值来代替中心像素的值&#xff0c;相当于低通滤波&#xff0c;有将图像模糊化的趋势&#xff0c;对椒盐噪声基本无能为力。 在MATLAB中&#xff0c;可使用imfilter函数来实现线性空间滤波&#xff0c;该函数的…

被动操作系统指纹识别的强大功能可实现准确的物联网设备识别

到 2030 年&#xff0c;企业网络和互联网上的物联网设备数量预计将达到290 亿。这种指数级增长无意中增加了攻击面。 每个互连设备都可能为网络攻击和安全漏洞创造新的途径。Mirai 僵尸网络通过使用数千个易受攻击的 IoT 设备对关键互联网基础设施和热门网站发起大规模 DDoS 攻…

查看占用GPU资源的 进程所属docker容器,并杀死 docker 中的僵尸进程!

查看占用GPU资源的所属docker 进程&#xff0c;并杀死 docker 中的僵尸进程&#xff01; 问题描述&#xff1a;查看当前占用GPU资源的进程属于哪个Docker容器杀死 docker 中的僵尸进程 问题描述&#xff1a; 问题1&#xff1a;一台服务器&#xff0c;每个人在上面 run 一个容器…

企业主流全链路监控系统 - OpenTelemetry(二)

OpenTelemetry 二 4. 部署&#xff08;python&#xff09;准备工作&#xff08;1/5&#xff09;创建 HTTP Server&#xff08;2/5&#xff09;Automatic instrumentation&#xff08;3/5&#xff09;增加观测项&#xff08;Manual&#xff09;&#xff08;4/5&#xff09;向 Co…

win11右键菜单栏改回win10

1.右键 WIN 图标&#xff0c;点击 " 终端(管理员) ” 2.执行以下命令 reg add "HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32" /f /ve3.重启电脑

【c++随笔03】构造函数、析构函数、拷贝构造函数、移动构造函数

【c随笔03】构造函数、析构函数、拷贝构造函数、移动构造函数 一、构造函数1、为何要有构造函数&#xff1f;2、构造函数定义3、无参构造、带参构造4、构造函数注意事项4.1 构造函数是特殊的&#xff0c;不是常规的成员函数&#xff0c;不能直接调d1.Date() 。4.2 如果通过无参…