假设我有一个注册reg [15:0] my_reg
,其中包含一个16位签名样本:
如何找到第一位变更所在的位置?
这意味着,如果假设my_reg = 16'b0001011011010111
,我怎么知道从0
到1
的第一次更改是my_reg [12]
?对于以1
开头的数字,负数,例如my_reg = 16'b1111011011010111
会对第一个出现的0
(在这种情况下为11
)的位置感兴趣。
最终目标(增加一点上下文)是实现数字FPGA内置自动增益控制(AGC)。
答案 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