01-Verilog基础_1

Verilog RTL编程实践

在进行数字IC设计过程中,RTL coding能力是非常重要的。结合逻辑仿真(VCS)和逻辑综合(Design Compiler)工具。看RTL。

1 ASIC Design Flow

  1. IDEA
  2. Design specification
  3. Design entry/Verilog Coding
  4. Simulation/function verification
  5. chip integration/verificattion
  6. Sysnthesis/Pre layout/Timing/formal verification
  7. scan chain insertion/Test;Generation/fault simulation
  8. physical design
  9. To sign off
  10. production ready masks
    数字IC设计流程需要了解,这里简单介绍一下。

ALU描述Spec-->RTL-->进行逻辑仿真-->将RTL转化为Gate Netlist(使用逻辑综合工具)-->layout-->production

2 什么是Verilog?

Verilog VHDL--寄存器级硬件描述语言,基于C语言进行设计的。
2005年,在verilog基础上,出现了system verilog,三大属性Design、Verificaiton、Assertion。

verilog从84年开始出现,到现在已经经过了三四十年的发展,但是仍然适用很多公司的开发。
verilog在芯片设计和芯片验证领域使用非常广泛。

2.1 推荐阅读

  • IEEE1364 standard;SystemVerilog IEEE 1800
  • Digital VLSI design with Verilog

3 verilog语义语法

3.1 verilog缺点

只用于描述数字电路,不用于模拟电路的设计。

3.2 Verilog语言层次

  • Behavioral--行为级,加法,乘法等。
  • RTL--寄存器传输级(Register Transition Level),触发器(DFF),verilog中没有对于DFF进行建模,使用always进行建模。
  • Gate--门级电路,与非门等,Verilog中对于门级电路是有建模的。
  • Layout(VLSI)--画管子,源极、栅极、漏极。

3.2 module

module adder_4_RTL(a,b,c_in,sum,c_out);
  output[3:0] sum;
  output c_out;
  input[3:0] a,b;
  input c_in;

  assign{c_out,sum}=a+b+c_in;  行为级描述,可以进行综合
endmodule

  1. module name(数字、字母、下划线、$)
  2. module module_name(端口名)
  3. input/output[位宽]--[3:0]表示4位的位宽
  4. assign--连续赋值语句,将左侧和右侧进行连接,主要对于组合逻辑电路进行建模
  5. {MSB(最高位),LSB(最低位)}--表示拼接符
  6. endmodule--结束模块

3.3 structure model(门级建模)

使用门级进行描述

module mux(f,a,b,sel);   
  output  f;              输出
  input  a,b,sel;         输入
  
  and #5 g1(f1,a,nsel);   #5表示输入到输出有一个延时,#5表示多少取决于timescale(仿真的精度和单位)
  and #5 g2(f2,b,sel);    
  or     g4(nsel,sel);
endmodule  

/*
  and--表示实例化一个与门
  g1--实例化门的名称
  (f1,a,nsel)--f1表示与门的输出,a表示出入,nsel-表示sel取反;
  nsel--sel取反(经过一个反相器)之后得到nsel
  or--表示或门
  门级模块的建模往往第一个是输出,后面的是输入
*/

3.4 concepts--概念

1 concurrency--并发性

C语言是从上向下执行的,硬件是不同的,同时有很多电路进行工作。

2 structure

verilog有门级建模

3 Procedural Statements

过程化执行,从上到下执行。

4 Time

Verilog中有时序的概念

3.5 identifiers--标识符

  • 标识符以数字、字母、下划线、$组成
  • 不能以数字和$进行开头
  • verilog是大小写敏感的语言
  • 书写变量的时候尽量有意义

3.6 comments--注释

  • //单行注释
  • /xxxxxx/ 多行注释

3.7 Value Set

verilog对于硬件进行建模。

  • 0--低电平或者假
  • 1--高电平或者是真
  • x--未知的逻辑状态,亚稳态就是会产生未知状态
  • z--高阻抗状态,在电路中挂一个高电阻

3.8 number

  <size>'<radix><value>
  • size--位宽,将使用的进制转变为二进制数的位宽
  • radix--进制,b/B表示二进制,o/O表示八进制,d/D表示十进制,h/H表示十六进制
  • value--数值,0-f,x,z
    位宽相当于走线
8'h ax =1010xxxx
12'o 3zx7=011zzzxxx111

注意

  • 十六进制,一位可以使用四位二进制数进行表示
  • 八进制,一位可以使用三位二进制数进行表示
  • 十六进制a--1010
  • 十六进制5--0101
  • 有些电路中可以使用55和aa可以进行简单的验证

数字中可以插入下划线

//数字中插入下划线是用与分割长的数字
12'b 000_111_010_100
12'b 000111010100
12'o 07_24

位扩展

最高位是0,x,z是可以进行扩展的,最高位位1的时候是不能进行扩展的

4'b x1=4'b xx_x1
//最高位是x,所以进行了扩展

4'b 1x=4'b 00_1x  
//1是不能向高位进行扩展的,如果能扩展结果变为
// 4'b 111x 结果错误
// SV中进行了语法的改进

默认

  • size--不写,根据值进行推断
  • radix--不写,默认是十进制

3.9 nets-线网

可以认为是被逻辑驱动的硬件连线

  • z--表示不连接,没有连线的状态
  • wire--线
  • wand--线与
  • wor--线或
  • tri--三态

nets建模

对于上述的图片解释:

  1. 使用wire 变量 声明一根线Y a,b改变 y就发生变化
  2. assign--将左右进行连接
  3. &--按位与

4.二值逻辑和四值逻辑

4.1 二值逻辑

二值逻辑:0,1

// bit为关键字
bit [MSB:LSB] variable_name = value;
bit [7:0] a = 8'b1;
  • bit类型默认为无符号数
  • bit经常使用在验证环境中
module test_tb();

bit [3:0] a;

initial begin
  a = 4'b0;
  $display("a = %b",a);
endmodule
  • initial 语句是不可综合的
  • initial 语句之间是并行的,initial中间的语句是串行的
Makefile 中的技巧
FLIST := ../tb/tb_top.v
  • filelist定义路径
  • gf进入定义的filelist
  • bf退出定义的filelist
// 默认bit为无符号数,有符号数加signed
bit [31:0] signed data = -155;
a = -10;

原码:1 1010
反码:1 0101
补码:1 0110

// 负数打印的是补码 1 0110
  • byte/shortint/int/longint都是有符号数

  • real 类似于c语言中的double

  • shortreal 类似于c语言中的float

4.2 四值逻辑

二值逻辑不能描述电路所有的状态,所以要使用四值逻辑0,1,x,z

  • verilog:使用reg类型
  • system verilog:使用logic类型
reg [MSB:LSB] variable_name = value;
logic [MSB:LSB] variable_name = value;
  • reg类型默认为无符号数unsigned

  • reg类型不能用于连续复制语句,logic语句可以用于连续赋值语句assign

  • logic = reg + wire

  • 连续赋值语句使用wire或者logic类型的变量

  • logic只能有一个驱动,三态门不能使用logic

  • integer 32bit signed

  • time 64bit unsigned

integer var_name = value;
time var_name = value;

4.3 单驱动和双驱动

assign b = din_c;
assign b = din_d;
  • 上述情况就是多驱动
  • din_c驱动b的时候,din_d处于z态
  • din_d驱动b的时候,din_c处于z态
  • 大多数情况下变量处于单驱动状态

5.枚举数据类型

  • 状态机中使用较多,FSM
enum bit[2:0] {s0 = 3'b001,s1 = 3'b010,s2 = 3'b100} st;
  • enum - 定义枚举关键字
  • bit [2:0] - 枚举的每个状态的类型和位宽
  • {s0,s1,s2} - 描述每个状态及编码
  • st - 枚举类型的名称
enum bit[2:0] {IDLE = 3'b001,TEST = 3'b010,START = 3'b100} st;

initial begin
  st = START;
  $display("st = %b,name = %s",st,st.name);
end
  • st = 100
  • st.name = START

typedef

typedef enum  bit[2:0] {xxx} state;
state st; // 定义枚举变量
st = START;
  • 写状态机的时候也可以不使用枚举类型,直接定义状态参数
parameter IDLE = 4'b0001,
          TEST = 4'b0010;

6.数组

6.1 固定数组

logic/reg/bit/integer.. name [size];
  • 越界写操作会被忽略
  • 越界读操作:二值逻辑返回0,四值逻辑返回x
  • 支持多维数组
  • 数组元素的index从0开始
integer numbers [5];
int b[2] = `{3,7};
int c[2][3] = `{{3,4,5},{4,5,7}};
int d[7][2] = `{default:-1}; // 所有元素初始设置为-1

通过赋值的方式可以实现数组的拷贝

int c [2][3];
int a [2][3] = c;
for(int i = 0;i<$dimension(a);i++)
  $display($size(a,i+1));
  • $dimension(数组名) - 返回数组维数
  • $size(数组名,维度) - 返回数组对应维度的长度
logic test [7:0][3:0]
// [7:0] 第一维度
// [3:0] 第二维度

$size(test,1) // 8
$size(test,2) // 4
logic [3:0] arr[3]; // 一维数组
logic [3:0] arr[3][3]; // 二维数组
logic [3:0] arr[2:0][3]; // 二维数组
posted @ 2023-01-09 22:20  Icer_Newer  阅读(122)  评论(0编辑  收藏  举报