Verilog自编函数clog2替代SV中的系统函数$clog2

先放函数,已验证和$clog2输出一致,注意需满足输入n ≥ 1

// 返回以2为底的n的对数
function integer clog2 (input integer n); begin
  n = n - 1;
  for (clog2 = 0; n > 0; clog2 = clog2 + 1)
    n = n >> 1;
end
endfunction

另外,经评论区提醒,在Vivado 2017以后的版本中,可以直接使用系统函数$clog2(),不需要去自编函数了。后续又测试了Quartus 18.1 同样支持$clog2(),各位可自行测试使用的工具是否支持$clog2()。

一.为什么需要以2为底n的对数的函数

在Verilog编写代码过程中,经常需要根据一个常量来定义一个变量的位宽,例如,要编写一个计数器,计数最大值为常量N,那么计数变量cnt的位宽应该是多少呢?这个问题在SV可利用系统函数$clog2来解决,如下:

module counter
#(
  parameter CNT_MAX = 1023
)(
  output logic cnt_finish,

  input  logic clk,
  input  logic rstn
);

logic [$clog2(CNT_MAX+1)-1 : 0] cnt;
always_ff @(posedge clk, negedge rstn) begin
  if (~rstn)
    cnt <= '0;
  else if (cnt < CNT_MAX)
    cnt <= cnt + 1'b1;
  else
    cnt <= '0;
end

assign cnt_finish = cnt == CNT_MAX;

endmodule

但是在Verilog中没有这个系统函数,所以需要自行编写

二.Verilog编写求以2为底n的对数的函数

将上面计数器的SV代码改为Verilog,用自编的clog2替代SV的系统函数$clog2

module counter
#(
  parameter CNT_MAX = 1023
)(
  output wire cnt_finish,

  input  wire clk,
  input  wire rstn
);

reg [clog2(CNT_MAX+1)-1 : 0] cnt;
always @(posedge clk, negedge rstn) begin
  if (~rstn)
    cnt <= 'd0;
  else if (cnt < CNT_MAX)
    cnt <= cnt + 1'b1;
  else
    cnt <= 'd0;
end

assign cnt_finish = cnt == CNT_MAX;

// 以2为底的对数函数
function integer clog2 (input integer n); begin
  n = n - 1;
  for (clog2 = 0; n > 0; clog2 = clog2 + 1)
    n = n >> 1;
end
endfunction

endmodule

三.仿真验证

仿真验证自编函数clog2的输出和SV系统函数$clog2的输出是否一致,仿真工具:modelsim SE-64 2020.4,testbench(try_tb.sv)如下:

module try_tb();

timeunit 1ns;
timeprecision 10ps;

initial begin
  for (integer i=1; i<1025; i++) begin
    $display("$clog(%d) = %d,   clog2(%d) = %d", i, $clog2(i), i, clog2(i));
  end
end

// 以2为底的对数函数
function integer clog2 (input integer n); begin
  n = n - 1;
  for (clog2 = 0; n > 0; clog2 = clog2 + 1)
    n = n >> 1;
end
endfunction

endmodule

部分仿真结果:

Verilog自编函数clog2替代SV中的系统函数$clog2-1

Verilog自编函数clog2替代SV中的系统函数$clog2-2

可见,clog2(n) 与 $clog2(n) 输出一致。

  • 3
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值