Verilog位改变位置

时间:2014-06-11 15:01:39

标签: bit-manipulation verilog bit

假设我有一个注册reg [15:0] my_reg,其中包含一个16位签名样本:

如何找到第一位变更所在的位置? 这意味着,如果假设my_reg = 16'b0001011011010111,我怎么知道从01的第一次更改是my_reg [12]?对于以1开头的数字,负数,例如my_reg = 16'b1111011011010111会对第一个出现的0(在这种情况下为11)的位置感兴趣。

最终目标(增加一点上下文)是实现数字FPGA内置自动增益控制(AGC)。

3 个答案:

答案 0 :(得分:4)

与上述相同的技术但是参数化。使用XOR移位一位来确定位改变的位置,然后使用降序优先级编码器输出第一个 换地点。我塞满my_reg[0],所以第一位不会创建增量。

localparam width=16;

reg  [width-1:0] my_reg;
wire [width:0] delta;
reg  [$clog2(width)-1:0] index; // Note: $clog2 was added in IEEE1364-2005
integer i;

assign delta = my_reg ^ { my_reg, my_reg[0] };

always @* begin
  index = 0;
  for (i=0; i<width; i=i+1)
    if (delta[i])
      index = i;
end

EDA游乐场上面的代码(感谢您提出这个问题,BTW) http://www.edaplayground.com/x/3uP

答案 1 :(得分:2)

针对此的双线解决方案如下:

my_reg1_diff = (my_reg1 ^ (my_reg1 << 1))>>1 ;
my_reg1_diff_pos = $floor($ln(my_reg1_diff)/$ln(2));    //log2 of (my_reg1_diff)

请参阅edaplayground.com上的工作示例。

它类似于starbox答案中描述的想法。您可以使用查找表或case语句为可合成的log2函数建模。有关示例,请参阅edaplayground.com

答案 2 :(得分:1)

您需要的是领先的标志探测器。

你可以通过执行16位my_reg变量的XOR,然后是一个计算重复位数的case语句,然后你需要在这个数字上加一个。

例如:

如果我们有一个4位寄存器,我们可以计算前导位的数量。您可以根据您希望处理所有位相同的情况来修改此代码。

wire [3:0] my_reg;
wire [2:0] xor_bits;
reg [2:0] count;

// XOR bits
assign xor_bits = {my_reg[3] ^ my_reg[2], my_reg[2] ^ my_reg[1], my_reg[1] ^ my_reg[0];

always @ (*) begin
case (xor_bits)
000: change_location= 4;
00X: change_location= 3;
0XX: change_location= 2;
default: change_location= 1;
endcase

end