HDL:硬件描述语言,并发,时序========RTL:寄存器传输级语言
Verilog和VHDL的区别:VHDL侧重于系统级描述——系统级设计人员所采用,Verilog侧重于模块行为的抽象描述——电路级设计人员
前端:系统级、算法级(c/matlab)、寄存器变换级(RTL Verilog/SV)
后端:逻辑门级、开关级、物理(版图)级
数字电路设计两个要素:线(wire)和器件(module)
RTL基本单元:寄存器、ALU、MUX等
电路的功能描述:算法状态机图、有限状态机、数据流图、控制流图
除endmodule、begin_end、fork_join外都要加分号
标识符只可以由字母、数字、下划线和$组成,开头必须是字母或下划线,是区分大小写的
数据类型
Verilog HDL19种中4个最基本的数据类型:Integer型(32位有符号整数)、parameter(符号常量)、reg型、wire型
常量
整数型常量:<位宽>'<进制><数字>
<数字>缺省十进制,32位
wire[31:0]a;//长度为32
wire[31] a;//长度为31,不建议
x表示不定值,z表示高阻值
最左边的x或z具有扩展性:8’bx1 =8’bxxxxxxx1
?是z的另一种表示符号,在case语句中使用
负数:在位宽前加一个减号
-8’d5 = 8’b1111_1011//5的补数(反码加1)
parameter常量的声明:module test # (parameter p=4’h1)
localparam和parameter的区别:parameter可做传递参数的接口
常用的三种变量:线网型,寄存器型,数组
线网型nets型:输出始终随输入的变化而变化的变量:wire,不能存值
表示以assign语句赋值的组合逻辑
缺省为wire型,位宽1bit
寄存器型register型:表示过程块(initial always task function)语句内的指定信号过程块中信号必须为reg型
reg生成触发器和组合逻辑,wire只能生成组合逻辑
数组型memory型:reg[n-1]存储器名[m-1;0];//m个位宽为n的存储单元
需指明赋值的存储单元rega[7:0]=0;//不合法 rega[7]=0;//合法
运算符
算术运算符(双目运算符):%取余:两侧均为整型,结果为第一个操作数的符号位;某一个为不定值x,结果为x
关系运算法(双目运算符):结果是逻辑值0、1、x,优先级低于算术运算符
逻辑运算符:&& ! ||,(a=3’bx0x && b=3’bx01) = (x && 1) = x非的优先级最高
位运算符:~按位取反 & | ^ ~/~同或,进行运算时位数少的高位自动补0
缩减运算符(单目运算符):& ~& | ~| ^ ~^,低位与第二位进行运算,直至最高位,结果缩减为1位二进制数 eg.b=|a;
移位运算符:用0补空位,左移扩充位数(乘以2n),右移数据丢失(除以2n)
位拼接符:{1’b0,xx……},{4{w}}={w,w,w,w},拼接时必须指明信号的位数,1默认为32位
等式运算符:(逐位相等结果为1,某些位为x或z结果为x) != =和!(case等式运算符,相应位完全一致结果为)xx;//x x===x;//1
条件运算符(三目运算符):信号=a?表达式1:表达式2;
运算符的优先级
连续赋值语句
assign语句,描述组合逻辑最常用的方法,不可出现在过程块中,并行的与位置顺序无关,与过程语句之间也是并行的
结构语句
不可综合的用在测试语句中
过程语句
always不断重复执行,直到仿真结束,initial只执行一次
always块中被赋值的只能是reg型,不加时序控制会导致仿真死锁(eg.always areg=~areg)
always@(*):电平触发,组合逻辑
如a=0等语句只能写在assign,always,initial赋值语句中,三者并行
块语句
begin_end
顺序执行语句,每条语句的延迟时间是相对于前一条语句的仿真时间而言的
begin:块名
块内声明语句;
语句;
end
存在块内声明语句(参数声明,reg变量声明,integer变量声明,real变量声明语句)时要加上块名
fork_join
并行执行语句,不可综合,用在测试文件中,时间排序在最后的语句执行结束或完成一个disable语句
条件语句
if-else语句
if(a)≠if(a==1)//当a为单比特时成立
case语句
每个值的位宽 必须相等,与控制表达式的位宽相同
在分支表达式中,?表示高阻态
按顺序判断,满足一个条件后执行就跳出case语句,故少用casex
casez,不匹配高阻态z的位
casex,不匹配高阻态z和不定值x的位
组合电路设计中,不加上else、default项,会生成隐含锁存器latch,q保持原值,加上后会生成选择器,故组合逻辑中必须要加上else、default项
循环语句
for语句
for(循环变量赋初值;循环执行条件;循环变量增值)执行语句
repeat语句
repeat(循环次数表达式)语句
while语句
while(循环执行条件表达式)执行语句
执行语句中必须有一条改变循环执行条件表达式的语句
forever语句
无条件连续执行forever后面的语句或语句块
必须要写在initial过程块中,不可综合,用在测试文件中
使用时块要加块名,然后用disable加块名,跳出循环
编译预处理语句
宏定义语句define 标志符(即宏名) 字符串(即宏内容)//没有分号
define IN a+b+c+d
使用方法:`IN
文件包含语句`include “文件名"或"文件绝对路径或相对编译文件的路径”//include后面一定要有空格
时间尺度语句`timescale
系统任务语句
显示和写任务:
$display(“a is %b”,a),二进制显示空位会显示零,十进制会空出位数,(%0b显示实际位数)自动换行
w
r
i
t
e
不会自动换行
write不会自动换行 %c或%C:ASCII字符,%s或%S:字符串,%t或%T:当前时间格式("%t",
write不会自动换行time)
可以直接使用
t
i
m
e
,
time,
time,display($time,“%d”,a);//没有指定时间格式,按十进制显示
\n换行,\t制表符,\字符\
监控任务:
$monitor:连续监控指定的参数,参数发生变化打印
$monitoroff停止 $monitoron启动
文件输出任务:从文本文件中读取数据并将数据加载到存储器中
$readmemb读取二进制格式数
r
e
a
d
m
e
m
h
十六进制格式:
readmemh十六进制 格式:
readmemh十六进制格式:readmemb(“<数据文件名>”,<存储器名>,<起始地址>,<结束地址>);//没有起始和结束地址则存储器从其最低位开始加载数据直到最高位
仿真时间函数
$time
$realtime
不同之处:返回64位整型时间/返回实型时间(带有小数)
随机函数random(伪随机)
rand=KaTeX parse error: Expected '}', got 'EOF' at end of input: …//-59~59 rand={rand}%60//0~59
仿真控制任务
$finish(建议使用) $stop(只是暂停仿真)
阻塞赋值与非阻塞赋值
阻塞赋值立即改变,可综合的阻塞赋值操作不能设定有延迟(即使是零延迟,延迟后才赋值,不可综合)
非阻塞赋值在块语句结束后才赋值,只能对寄存器变量进行赋值,故只能用在initial和always块等过程块中,非阻塞赋值不允许用于连续赋值
always块建立组合逻辑模型时,用阻塞赋值
同一个always块中建立时序和组合逻辑电路时,用非阻塞赋值,不要混用
赋值时不要使用#0延迟
任务和函数语句
task语句
任务定义:task<任务名>;
端口及数据类型声明语句;//不用声明数据类型,sv中默认为logic
其他语句;
endtask
任务调用:<任务名>(端口1,端口2……);//端口一一对应
多输入多输出
可包含定时控制语句 包含定时控制语句的任务是不可综合的(# @ wait)
任务的定义与调用必须在一个module中
可调用函数和任务函数
在任务定义结构内不能出现initial和always过程块
任务调用语句只能出现在过程块内
function语句
函数定义:function<返回值位宽或类型说明>函数名;//缺省返回1位reg型数据
端口声明;//至少一个输入参量,无输出(不可有输出或双向变量)
局部变量定义;
其他语句;//必须有一条赋值语句
endfunction
函数调用:<函数名>(端口)
函数在模块内部定义,通常在本模块中调用,也可以从其他模块调用
不可包含定时控制语句,可综合,每调用一次函数,相当于改变此电路的输入得到相应计算结果
可调用函数语句,不可任务函数
模块的调用
端口可以位置关联或名称关联
仿真:前(RTL)仿真,逻辑网表仿真,门级仿真和布线后仿真
tb文件中端口与输入端口连接为reg型,输出端口连接为wire型
inclule "xxx.v"
timescale 1ns/1ps
可不写,files.f和Makefile文件已完成
时钟激励的产生
reg clk;
initial begin
clk=0;
end
always #10 clk=~clk;
=====================
always begin
#10 clk=0;
#10 clk=1;
end
=====================
initial begin
clk=0;
forever #20 clk=~clk;
end
参数传递
module Decoder(A,F);
parameter W=1;
parameter P=1;
……
调用:Decode #(4,0) u_D2(a,b);//位置关联
Decode #(.W(4),.P(0)) u_D2(a,b);//位置关联
悬空端口
输入管脚悬空为高阻z,输出管脚悬空管脚废弃不用
VCS仿真mux2to1
源文件和tb文件代码,tb文件中输入为wire型,输出为reg型
将源文件、tb文件、Makefile、files.f放入一个mux2to1文件夹,进入文件夹运行make all
跑eda工具,执行命令make all,要和Makefile文件同级
点击向下小箭头显示波形