Verilog最小位宽度

Verilog最小位宽度,verilog,system-verilog,Verilog,System Verilog,我正在寻找一种干净的方法来声明具有参数化位宽度的Verilog/SystemVerilog类型。这就是我到目前为止所得到的,我想知道是否有更好的方法。我已经浏览了LRM 1800-2009和-2017中的系统功能。我能找到的最接近的是$bits,但我想要$minbits之类的东西。我忽略了什么吗 在VHDL中,只需指定范围即可: 信号计数器:从0到最大计数的整数范围; …编译器将计算保持该范围的最小位宽度 对于20 ns和125 ms的参数值,计数器应为23位,最大计数为6250000 模块去

我正在寻找一种干净的方法来声明具有参数化位宽度的Verilog/SystemVerilog类型。这就是我到目前为止所得到的,我想知道是否有更好的方法。我已经浏览了LRM 1800-2009和-2017中的系统功能。我能找到的最接近的是
$bits
,但我想要
$minbits
之类的东西。我忽略了什么吗

在VHDL中,只需指定
范围即可:

信号计数器:从0到最大计数的整数范围;
…编译器将计算保持该
范围的最小位宽度

对于20 ns和125 ms的参数值,计数器应为23位,最大计数为6250000

模块去盎司
#(
参数CLOCK\u PERIOD\u ns=20,//纳秒。
参数DEBOUNCE_PERIOD_ms=125//毫秒。
)
. . .
函数int MinBitWidth([1023:0]值);
开始
对于(MinBitWidth=0;值>0;MinBitWidth=MinBitWidth+1)
开始
值=值>>1;
结束
结束
端功能
localparam MAX_COUNT_32位=去抖动周期_ms*1_000 _000/时钟周期_ns;//默认类型为32位。
localparam计数器\u位=最小比特宽度(最大\u计数\u 32位);//计算所需的实际位宽度。
typedef逻辑[计数器\u位-1:0]t计数器;
localparam TCounter MAX_COUNT=MAX_COUNT_32位;//指定一种实际位宽度(来自Quartus的截断警告)。
localparam TCounter ONE=1;
计数器;
. . .
始终@(posedge时钟)
开始
. . .
if(counter==MAX\u COUNT\u 32BITS-1)//合成一个32位比较器,无论需要多少位,未使用的位连接到地。
. . .
if(counter==MAX\u COUNT-ONE)//按预期合成23位比较器。
. . .
计数器>1;
结束
结束
端功能
正确算法 正确的算法是计算原始值的最小比特宽度,该算法由给出

以下是作为函数的正确算法:

函数整数最小比特宽度;
输入[1023:0]值;
开始
对于(MinBitWidth=0;值>0;MinBitWidth=MinBitWidth+1)
开始
值=值>>1;
结束
结束
端功能

$clog2
来自IEEE标准1800-2017第20.8.1节整数数学函数:

系统功能
$clog2
应返回原木基座2的上限 参数(日志向上舍入为整数值)

产出:

MAX_COUNT_32BITS = 6250000, COUNTER_BITS = 23

只要做+1就可以得到2的幂的正确值


$clog2(最大计数32位+1)

在阅读了您关于地址总线WITDH()的回答后,我考虑到了这一点,但其中有一个非常微妙(甚至是狡猾的)它不起作用的原因。我将更新我的帖子,解释最小位宽度和地址总线宽度之间的差异。我现在更新了它,以说明
$clog2
如何无法计算2次幂的最小位宽度。是的,但这是一种笨拙的编码。我想知道Verilog/SystemVerilog是否在某个地方内置了此算法,以便我可以使用更简单的代码,如VHDL。@tim因为您知道$clog2减去一,并且您不想这样做,所以您不使用$clog2(值+1)是有原因的吗?这是一个很好的建议,可以在函数
MinBitWidth
中修复算法,但我也在寻找一种方法来消除其他笨拙的编码。这是一个很好的建议,可以修复算法,但从语义角度看,它有点混淆了它的含义。我可以替换
MinBitWidth 使用
$clog2(value+1);
函数来保持语义含义,但我也在寻找一种方法来消除其他笨拙的编码。
MAX_COUNT_32BITS = 6250000, COUNTER_BITS = 23