System verilog learning

准备全面拥抱SV语言,System verilog增加了些结构体、接口等有用的东西,为了更懒的写代码,学学先~。
参考文档
SystemVerilog IEEE 1800-2017.pdf
SystemVerilog硬件设计及建模
Question
  • SV与Verilog的异同?
SV是verilog的升级版,verilog是SV的子集,verilog不再更新。
版本1800-20121800-2017


学习内容
  • 什么是包,包是怎么定义的,有什么作用?
在多个模块中使用用户定义类型,避免重复定义。
可定义的类型包括:parameter/localparam/const/typedef/task/function/import/操作符重载(?define吗)
使用package // endpackage 进行包定义。使用import进行包的导入模块操作,星号表示导入包内所有元素。 ::表示作用域解析操作符。
在模块头部导入包,即可在接口定义段使用包内容。
注意:包中parameter/localparameter都是相同的,无法被重定义。
  • $unit是什么?
也是个命名空间,在模块之外的就算。咩啥卵用,不管。
注意:所有定义放在package中,避免混乱。
  • 常量定义有哪几种?及应用场景?
引入简单赋值全1全0的方法:通过硬撇号加数字的方式。ex: data='0,data='1,data='x,data='z
`define:宏定义
localparam:模块内的常量定义,无法传参到上层模块。
parameter:常量定义,可由上层进行参数传递。
上层定义方法:根据需要定义参数进行逐层传递
子层例化引用,使用类端口连接方式传参。
const:跟parameter不同的是,其可以在仿真过程中被设置,而非解析阶段。行为像变量,但不能被写入。
存点确定数据有用,ex不可改写的数组,类似C语言。
const logic [7:0] cl_data = 8'd7;
注意:无需传参到上层的定义均使用localparam。
  • 变量定义有哪几种,及应用场景?
四态类型:更适合RTL建模,用Z和X检查未连接及设计错误。两态类型无法检测此类错误。
logic:0,1,x,z。替代reg。
建模wire和reg都使用logic(隐式推断),inout类型才使用wire。
两态类型:更适用于系统级和交易级建模,无法赋初始值(综合中不使用)。
bit:0,1
byte:8bit
shortint:16bit
int:32bit
longint:64bit
其他抽象类型:shortreal eal(双精度)
注意:所有的两态数据类型从逻辑0开始仿真。
SV放宽了变量的使用规则。简化了数据类型的使用。任何数据类型的变量都可通过下述方式赋值:
(1)在任意的initial/always 块中。
(2)通过单个持续赋值语句赋值assign。
(3)通过模块的output/inout驱动赋值。
不要多重驱动。
  • 用户定义类型及枚举定义及场景?
typedef:用户自定义类型,用于对冗长定义的文本替换,懒鬼使用。
enum:枚举类型,标签值的集合。状态机建模会用到。
匿名枚举:
枚举类型重定义:自定义枚举
枚举类型存在一些方法(函数),仿真用到再说。
注意:如果使用包内定义,为了使得枚举标签可见,使用通配符方式导入整个包。
  • 数组有哪几种类型?应用场景是否可综合?
非压缩数组:非压缩数组的向量范围在信号名称后面。
logic [31:0] data [1024];
压缩数组:压缩数组的向量范围在信号名称前面。
logic [3:0][7:0] data;
数组咋初始化?
压缩:
非压缩:
注意数组可使用typedef自定义。
数组可通过模块端口传递。SV允许任何类型及维数的数组接口传递。数组及数组赋值都是可综合的。
非压和压缩之间不可直接赋值。
  • 结构体的定义及应用场景?
struct:类似C语言,变量或者常量的集合,可用于对信号分组,封装成总线等。
没有typedef的为匿名结构体,否则为自定义结构体。
q:结构体如果在综合中怎么初始化?
(1)直接在声明的时候类似logic进行初始化。
(2)复位方式分别初始化成员变量。
(3)复位方式直接整体初始化。
全部默认值为0的时候指定:IW = '{default:0};
压缩结构体和非压缩结构体的区别?
使用packed声明压缩结构体。压缩结构体存储为一个向量,向量运算规则适用压缩结构体,是连续存储的,可通过bit位进行引用。
压缩结构体必须包含压缩变量,无法包含real、非压缩的东西。
注意:非压缩和压缩结构体都是可综合的。可通过模块和端口进行结构体的传递。
  • 联合体是啥?
union:可表示多种数据类型的一个元素,同一时刻只会使用一种数据类型。
也分为自定义联合体、匿名联合体;非压缩联合体,压缩联合体。
注意:只有压缩联合体是可综合的。
  • 过程块类型及应用场景?
好处是无需综合器推断是否为时序还是组合逻辑电路。
always_ff:时序建模语句。
always_ff @(posedge i_clk)
begin
    if (xx)
        q <= d;    
end 
always_comb:组合逻辑建模语句。无需使用@(*)
always_comb
begin
    if (xx)
        q = a;
    else
        q = b;
end
awlays_latch:锁存器建模语句。
always_latch
begin
    if (xx)
        q = a;
end
注意:三者都是可综合的。
  • 任务和函数?哪样的任务和函数是可综合的?
task
function
  • 层次化设计中网表实例简化?
SV提供的简化网表的三种方法:.name(dot name)、.*(dot star)、interface。
模块原型:方便在例化的文件内查看模块的端口定义。
如果模块有这个声明,则在模块的定义时无需再重复定义端口声明,使用.*替代即可。
extern:
extern module demo_sv (
    input     i_clk       ,
    input     i_rst_n     ,
    input     i_a          ,
    output    o_b                    
);

module demo_sv (.*);
logic [7:0] l_cnt = '0;
always_ff @(posedge i_clk)
begin
    if (i_a)
        l_cnt <= l_cnt + 1'b1;
end
assign o_b = l_cnt[7];

endmodule // end the demo_sv model
简化的模块实例网表:降低语法结构的冗长,增强可维护性。
.name方法:通过简化.data(data)为.data,编译器会自动连接同名信号。
.*方法:自动连接同名信号。无法推断的连接需用verilog的方式进行显示声明连接。
注意.*后边无逗号。
线网别名化:不同的名称表示同一线网。
alias:可和.*一起使用,推断效果更佳
  • 什么是接口?怎么定义及怎样使用?输入输出方向不一致的接口怎么指定?
interface:接口是一种抽象的端口类型。允许许多信号合成一组由一个端口表示。
外部信号可放在interface中定义,然后通过接口连接到多个模块。
显式命名的接口端口和通用接口端口:
显式:
通用:
对于接口的方向不同可由modport指定:描述了接口表示的端口的接入方式。
不同模块可能使用的信号是不同的,modport中不使用的信号可不包括。
modport使用方法:
可重构接口:接口中可使用参数重定义和generate语句。

  • 行为级及交易级建模?

以上。



















原文地址:https://www.cnblogs.com/kingstacker/p/13468309.html