verilog 笔记

每日一言

A scar indicates that something is missing. You lost something important, and there’s a hole in your heart. Having that empty hole can lead to anger, hate, despair, or… it can make you reach for the sky. – Fuuko Kurasaki
fromAccel World

verilog语言程序的基本结构

verilog 标识符

verlog的标识符有以下三点要求:

  • 第一个字符不能是数字
  • 区分大小写,不能与Verilog的保留字相同
  • 关键字必须小写

这里不是重点,简单了解即可,我们看点示例:

1732356334264

同时在创建verilog项目时,项目名,verilog文件名,和设计模块的名字,必须要相同,否则可能会因名字未定义而编译失败。

verilog 的注释语法与c语言的语法一样,同时每个语句的后面也要以”;” 结尾。

逻辑值

verilog是四值逻辑语言。有四种基本的逻辑值:

含义
0 逻辑0、逻辑非、低电平
1 逻辑1、逻辑真、高电平
x/X 不确定的逻辑状态
z/Z 高阻态

接口描述

verilog 的每个模块都由两部分组成:

  1. 接口描述
  2. 功能描述

我们首先来学习如何描述一个模块的接口:

声明一个模块

声明一个模块的格式如下:

1
2
3
4
5
6
7
8
9
10
11
module <module_name>(prot list);

input ;
output ;// I/O端口描述

wire ;
reg ;// 信号类型说明

/* function */

endmodule

对于一个端口,首先我们需要描述这个端口是输入端(input)还是输出端(output),然后我们需要描述这个端口是寄存器类型还是线网类型。

I/O声明对于每个端口来说是必须的,但是第二种类型说明在端口为线网类型时可以省略。即不特殊声明的端口默认为线网类型。

示例如下:(一位全加器)

1
2
3
4
5
6
7
moduleadder ( a, b, cin ,sum, co) ;

input a , b , cin ;
output sum , co ;

assign{co,sum} = a+b+cin;
endmodule

如果输入/输出有多个位,例如四位的全加器,输入a,b 各有四个位,可以如下声明:

1
input [3:0]a,b;

但是加入一个芯片,有四组输入,每组输入为3位,可以如下声明:

1
input [2:0]a[0:3]

I/O 端口定义:

1732362363033

数据类型定义

1732362404447

注意:输入和双向端口不能声明为reg型。

parameter 类型说明

parameter 定义的符号常量只能在定义模块内使用。定义之后,就可以将该数字以定义的变量表示。

示例:

1
2
3
4
5
6
7
module mux (  i1, i2, sel , out ) ;
parameter width=4 ;
input sel ;
input [width-1:0] i1,i2; //用参数来说明wire 的位宽
output[width-1:0] out ;
assign out = sel ? i1 : i2 ;
endmodul

数的表示

verilog 中表示一个数的方法是:<二进制位宽>' <进制><数字>;

进制常用的表示方法有:

  • b (2进制)(z,x 等状态也当作一个二进制位)
  • d (10进制)
  • h (16进制)
  • 如果直接输一个数字,默认会当作32位10进制数

示例如下:

1732363258312

运算符

1732363583758

区分逻辑操作、位操作与归约操作

逻辑操作

逻辑操作有两个操作数,只不过返回的结果只有1位,1’b1或1’b0 。只能用于进行逻辑判断。用法与c语言相同

位操作

位操作也有两个操作数,其结果是两个操作数进行按位运算,位数小的数高位补0。总体用法也与c类似。

归约运算

归约运算只有一个操作数,结果只有一位,是对操作数的每一位逐位进行运算,取最后的一次运算的结果为整个运算的结果。

例如 a = 4'b1011

1
&a = 1'b0

过程为:

  1. 1 & 1 = 0 缩减为100
  2. 0 & 0 = 0 缩减为1 0
  3. 1 & 0 = 0 结果为0

位拼接运算

{ } ,将两个或多个信号的某些位拼接起来。但是不允许连接非定长常数

例子:

1
2
output reg f1,f2,f3;
assign {f1,f2,f3} = 3'b100;

用{ }连接时的线我们可以当作一个拥有多位宽的类型。将其中的线视为一个整体。

运算长度

  • 自动调整位宽:运算表达式结果的长度由最长的操作数决定。
  • 赋值结果的长度: 由赋值左端目标长度决定。

功能描述语句

连续赋值assign语句

句式:

1
assign 赋值目标 = 表达式

使用assign赋值有以下要求:

  • 赋值运算符只能使用’=’
  • assign 后面只能跟一个表达式
  • 避免出现反馈如 : a = a+b
  • inout型引脚只能用在assign中
  • 赋值目标只能是wire型
  • 多个assing 之间是并行关系
  • assign只能逐句使用,只能完成简单的组合逻辑
  • 不能对同一个信号进行多次assign赋值

过程赋值always语句块

always 后面是语句块,并且在always中的赋值语句必须是reg型。

在always 中的所有代码是顺序执行的。

句式:

1
2
3
4
5
6
7
8
always @(敏感信号) 
begin
= ;
<= ;
if 语句;
case 语句;
end

敏感信号

always语句只在敏感信号变化的时候才会启动进程。

  • 上升沿触发:always @(posedge 信号名)
  • 下降沿触发:always @(negedge 信号名)
  • 电平触发:always @(信号名)
    多个电平信号:always @(a or b or c) 或者 always @(a,b,c)
  • 所有信号均触发:always @(*),组合逻辑。

特别注意: 敏感信号 always @(posedge LE or negedge LE) 这种写法是错误的,Verilog 并不支持直接同时检测 posedgenegedge,只能选择其中一个。或者使用LE的电平信号来作为敏感信号。

aways中的两种赋值语句

  1. ‘=’ 赋值,阻塞赋值。会立即更新数值。用于组合逻辑。
  2. ‘<=’ 赋值,非阻塞赋值,延迟更新数,所有的赋值语句同时完成更新。用于时序逻辑。

注意:

  • 不能在组合逻辑中使用 <= 赋值,<= 用于实现时序逻辑
  • 在一个always中不要混用两种赋值语句
简单区分”=” 和 “<=”
1
2
3
4
5
6
7
always@ (* )
begin
d = a;
x = c & d ;
d = b;
y = c & d ;
end

= ,阻塞赋值,会立即覆盖原来的值,所以

  • x = c&a
  • y = c&d
1
2
3
4
5
6
7
always@ (* )
begin
d <= a;
x <= c & d ;
d <= b;
y <= c & d ;
end

<=,非阻塞赋值,会等执行到end语句后再统一赋值,d的最后一个值为 b,所以

  • x = c&b
  • y = c&b

注意:不能在多个always和assign中对同一个信号多次赋值。

转向控制语句

转向控制语句有 for,case,if 语句。 这三种语句都只能在always中使用。

if语句

句式:

1
2
3
4
5
6
7
if(条件1)

else if(条件2)

……

else
  • if 语句中最先出现的条件优先级最高,自上而下优先。
  • 可以有零到多个else if,但是必须有一个else,以保持良好的编码风格。
  • 如果在某个分支中对于某个变量赋值,那么在其他分支中,也需要对于该变量赋值。

case语句

根据某个表达式的值来选择执行体。无优先级。

句式:

1
2
3
4
5
6
7
8
9
10
case(选择表达式)
值1:

值2:

…………

default:

endcase
  • 分支条件必须在表达式范围内,且不能重合
  • 执行时必须选中且只能选中一个分支
  • 如果在某个分支中对于某个变量赋值,那么在其他分支中,也需要对于该变量赋值。

备注:

在 if 或 case 中,如果一个分支内有多条语句,那么需要将其中的语句封装在一个语句块中,即用 begin 表示语句块开始,用 end 表示语句块结束。

for语句

句式:

1
2
3
4
for(表达式1,表达式2,表达式3)
begin

end
  • 表达式1:设置循环变量初值,必须定义一个i 循环变量
  • 表达式2:循环执行判断条件
  • 表达式3:更新循环变量,只能用类似i = i +1 或 i= i - 1;
  • 注意:初值,步长,循环条件中不能有变量

verilog 笔记
http://blog.ulna520.com/2024/11/23/verlog 笔记_20241123_180134/
Veröffentlicht am
November 23, 2024
Urheberrechtshinweis