文章目录
- 前言
- Chapter1--设计方法简介
-
- 1.Verilog特点
- 2.HDL设计与验证的流程
- 3.Verilog编程思想
- Chapter2--Verilog语言基础
-
- 1.Top-Down&Bottom-Up
- 2.语法
-
- (1)描述方法
- (2)注释和标识符
- (3)模块和端口
- (4)编译指令和延时指令
- (5)逻辑值和常量
- (6)变量类型
- (7)参数
- (8)并发和顺序
- (9)操作数,操作符,表达式
-
- 1. 操作符(主要记录一些特殊的)
- 2. 操作数
- (10)系统任务和系统函数
- Chapter3--描述方法和设计层次
-
- 1.数据流描述
-
- 1.1连续赋值语句
- 1.2多驱动源线网
-
- 1.2.1 wor,wand
- 1.2.2 tri
- 2.行为描述
-
- 2.1 语句
- 2.2 过程赋值语句
- 2.3 语句组
- 2.4 高级编程语句
-
- 要点1:if-else有优先级
- 要点2:case无优先级
- 要点3:for,while,repeat都是不推荐的写法
- 3.结构化描述
-
- 3.1实例化模块
- 3.2参数化模块
- 一些常用缩写
前言
这里主要是写一些读后的笔记和要点,算是一种巩固吧
Chapter1–设计方法简介
该章节主要是讲了Verilog HDL等的概念和一些基本设计
1.Verilog特点
- 互连
- 并发
- 时间
2.HDL设计与验证的流程
- 系统与功能模块定义 System Level
- 行为级描述测试激励 Behavior Level
- 寄存器传输级 RTL Register Transfer Level
- 对RTL级描述进行仿真功能
- 逻辑综合
- 门级 Gate Level
- 综合后门级仿真
- 布局规划和布局布线
- 布局布线后的时序仿真和验证
3.Verilog编程思想
- 心中要有电路
- 要对时序有清楚了解
- 不追求代码简洁
Chapter2–Verilog语言基础
1.Top-Down&Bottom-Up
其实就是所谓自顶向下和自低向上,当然推荐的是自顶向下来实现
2.语法
(1)描述方法
- 数据流描述:使用assign语句进行连续赋值语句
- 行为描述:使用always/initial来进行过程赋值语句
- 结构化描述:实例化已有的功能模块
(2)注释和标识符
- 注释:
//这里可以插入注释
/*这里可以插入注释*/
- 标识符
可以使用0-9,a-z,A-z,$,_的任意组合
(3)模块和端口
- 模块:module/endmodule
module module_name(port_list);
endmodule
- 端口:input,output
input wire input_name
output reg output_name
(4)编译指令和延时指令
- 预处理指令
//用来设定仿真时间单位和时间精度
`timescale
//用来定义一些宏
`define/`undef
//用来避免重复定义宏
`ifdef/`else/`endif
//用来包含一些头文件
`include
//将其他编译指令重新设置为缺省值
`resetall
- 延时指令
//延时指令一般要结合timescale的设定延时单位和时间精度
#time
(5)逻辑值和常量
-
逻辑值
-1.0:低电平
-2.1:高电平
-3.X:未知状态,用作条件判断时候表示不关心
-4.Z:高阻态,没有任何驱动
-
常量
-1.整数型:
长度'数值符号 数字
-2.实数型:同上,不过最前一位为符号位
-3.字符串型:
-tips可以在数字内插入下划线,起到方便查看的效果reg [1:字长*位数] message
(6)变量类型
- 线网类型:未初始的时候值未 Z
- wire,tri:表示电路里的物理连线,tri多驱动源建模
- wor,trior:线或
- wand,triand:线与
- trireg:总线保持功能
- tri1,tri0:无驱动的时候,连线状态1/0
- supply1,supply0:电源和地
- 寄存器类型
- reg:寄存器类型,可以自定义位数
- integer:整数类型数据,可以存储至少32位的整数
- time:时间类型,可以存储至少64位的时间值
- real,realtime:实数和实数时间的寄存器
- 变量类型的关键–驱动和赋值
- 驱动driving:线网类型是驱动的,值是不会被储存的
- 赋值assigning:寄存器类型是赋值的,值是会被存储的
(7)参数
parameter:其实就是类似一种常数的定义,方便一次修改多个值
(8)并发和顺序
- 并发:
fork...join
- 顺序:
begin...end
(9)操作数,操作符,表达式
1. 操作符(主要记录一些特殊的)
(1). 归约操作符
//将m中所有bits相与,输出位1bit
&m
//与非
~&m
//或
|m
//或非
~|m
//异或
^m
//异或非
~^m
(2). 全等操作符
这里需要比较逻辑1,0,x,z都相等
m===n
m!==n
(3). 复制操作符
{m,n}
{k{m}}
(4). 条件操作符
sel?m:n
2. 操作数
- 常数define,integer
- 参数parameter
- 线网wire
- 寄存器reg
- 位选
- 部分选
- 存储器单元
- 系统函数
- 自定义参数的返回值
(10)系统任务和系统函数
- 系统任务:也即是完成某些特殊功能
- 系统函数:用于实现特殊功能的函数
这里我自己还没有特别使用过所以只记录
$display() //显示任务
$fopen() //文件打开
$fdisplay() //文件显示
$fclose() //文件关闭
$readmemh() //读取文件1
$readmemb() //读取文件2
$finish() //仿真退出
$stop() //仿真挂起
$setup() //检查建立时间
$hold() //检查保持时间
$time() //返回64位模拟时间
Chapter3–描述方法和设计层次
正如chapter2.2.(1)中说的描述方法有三类,我们分别进行详细的了解
1.数据流描述
- 定义:信号从输入流到输出,输入变化输出也会随之改变
- 连续赋值语句
1.1连续赋值语句
特点如下
- 连续驱动
- 只有wire才能在assign内被赋值,或者准确说驱动
- 对于assign进行组合逻辑建模
- 并行,也就是各个进程都是并发的,一同工作
1.2多驱动源线网
1.2.1 wor,wand
其实就是可以使用线或,线与来实现将线网类型进行连接,使得有双态
例子如下
//这样的写法会使得最后output是output|output
wire a,b,c,d
wor output
assign output = a^b;
assign output = c|d;
1.2.2 tri
同时也可以使用tri来实现三态总线相连
input a,b,c,d,en1,en2
output wireTri
tri wireTri
assign wireTri = en1?1'bz:(a^b)
assign wireTri = en2?1'bz:(c&d)
2.行为描述
2.1 语句
- initial:只执行一次
- always:总是运行
- begin…end、fork…join:过程块
- @(条件):事件语句
- #时间:延时语句
- wait(条件):等待语句
2.2 过程赋值语句
- 阻塞赋值:包含两个关键,1.右边表达式计算和对左寄存器赋值的操作必须连续 2.多个阻塞赋值之间必须前一个运行完了后续的才可以运行
- 非阻塞赋值:包含一个关键,右边表达式先计算,最后再一次性给左寄存器进行赋值
- 过程连续赋值
- assign/deassign:在过程语句里,强制对reg进行赋值和释放
- force/release:在过程语句里,强制对reg/wire进行赋值和释放
2.3 语句组
- 顺序语句组:begin…end,里面的语句是顺序执行
- 并行语句组:fork…join,里面的语句是一同执行
2.4 高级编程语句
要首先明白,只能在initial always里面使用这些高级编程语句
- if-else
- case-endcase,casex,casez
- forever,repeat,while,for
这里附带几个要点
要点1:if-else有优先级
要点2:case无优先级
要点3:for,while,repeat都是不推荐的写法
因为综合后会过分使用寄存器资源,造成很大程度上的浪费
3.结构化描述
简单来说就是实例化,主要有三种方法
- 实例化其他模块
- 实例化门
- 实例化UDP
3.1实例化模块
先了解一个模块的端口属性
- input:wire
- output:reg
- inout:tri
那么实例化后可以这样
- input相连:wire/reg
- output相连:wire
- inout相连:输入则wire驱动,输出则输出驱动的wire
3.2参数化模块
- parameter
- defparam
一些常用缩写
- Clock—clk
- Select—sel
- Reset—rst
- System—sys