玩命加载中 . . .

force verilog内部信号

force verilog内部信号为某个值,可以这样写:

initial begin  //verilog internal signal access
  force xxx.xxx.xxx = 16'hfffd;
  #500 release xxx.xxx.xxx;
end

force vhdl内部信号

而对于vhdl内部信号,使用force是错误的,vhdl语言不允许这样做。但是EDA工具一般都会提供函数,例如cadence的ncsim,可以使用$nc_forcenc_release访问vhdl内部信号。

initial begin //vhdl internal signal access
  $nc_force("xxx.xxx.xxx", "X'FFFD'");
  #500 $nc_release(xxx.xxx.xxx);
end
  • 类封装了数据和操作这些数据的子程序
  • 类可以定义在program、package、module中,或者在这些块之外的任何地方。类应当在program或者module之外的package中定义,避免与其他块内变量出现冲突。
  • new()创建对象、分配空间并执行构造函数
  • 赋值为null释放对象空间
  • 通过static来声明静态变量,是的该变量被该类的所有实例所共享,但使用范围仅限于该类
  • 通过类名::变量来访问静态变量
  • 静态变量在声明时初始化
  • 静态方法跟静态变量类似,也通过static声明
  • 静态方法不允许读写非静态变量
  • 类中的方法默认是自动存储的
  • 当使用一个变量时,会优先在当前作用域中寻找,接着在上一级作用域寻找,直到找到该变量为止。this可以明确指定当前作用域。
  • 接口信号必须使用非阻塞赋值来驱动
  • modport将信号分组并指定方向
  • clocking时钟块用于控制同步信号的时序

testbench注意事项:

  • $exit用于结束程序块,$finish用于结束仿真
  • 时钟产生不应该放在program程序块中,会引起信号的竞争,而应该放在module中
  • 例化时如果端口名字和数据类型一致,例化时可以用.*(隐式端口连接)

DUT代码

以简单的乘法器为例写testbench

//mul.v
module mul(
  input             clk,
  input             rst_n,
  input             in_vld,
  input      [11:0] mul_ain,
  input      [11:0] mul_bin,
  output reg [22:0] mul_out,
  output reg        out_vld
);

always @(posedge clk)
  if(in_vld)
    mul_out <= $signed(mul_ain) * $signed(mul_bin);

always @(posedge clk,negedge rst_n)
  if(!rst_n)
    out_vld <= 1'b0;
  else
    out_vld <= in_vld;

endmodule
  • 缺省情况下参数的类型是与其前一个参数相同的,而第一个参数的缺省类型是logic单bit输入
  • 参数的传递方式可以使用ref指定为引用,通常用于数组引用;当不希望子程序改变数组值时,可以使用const ref类型
  • ref参数只能被用于带自动存储(automatic)的子程序中,即使用ref参数时子程序必须指明automatic属性
  • 自动存储相对的是静态存储,当多个地方调用静态存储子程序时,不同的线程之间会窜用这些局部变量,而自动存储能够迫使仿真器使用堆栈存储局部变量
  • 函数使用return返回一个值,调用时可以使用void忽略返回值,例如void'($fscanf(file,"%d",i));
module test_func();

int arr[];

//************************************
// operator = "+", return a.sum
// operator = "x", return a.product
//************************************
function automatic int alu(
    const ref int a[],           //数组引用,const不能改变数组
    input string operator = "+"  //指定default值
);

int result;

if(operator=="x") begin
  result = 1;
  for(a[i])
    result *= a[i];
end
else begin
  result = 0;
  for(a[i])
    result += a[i];
end

return result;
endfunction

initial begin
  arr = new[5];
  arr = '{1,2,3,4,5};
  $display(alu(arr));    //15, use default operator
  $display(alu(arr,"x")) //120
end

endmodule

内建数据类型

四状态:reg, wire, logic, integer, time(默认值为X)
双状态:bit, int, byte, shortint, longint, real(默认值为0)
有符号数:int, byte, shortint, longint, integer(可以使用unsigned申明为无符号数)

🔖 $isunknown操作符:
作用:使用$isunknown操作符,可以在表达式的任意位出现X或Z时返回1

//test_isunknown.sv
module test_isunknown();

logic [3:0] din;

initial begin
  din = 4'b1001;  //Unknown not found!
  din = 4'b1x01;  //Unknown is detected!
  din = 4'b1z01;  //Unknown is detected!
  if($isunknown(din))
    $display("Unknown is detected!");
  else
    $display("Unknown not found!");
end

endmodule