硬件(如Verilog)中循环区间填充算法的常用实现方法咨询
硬件中循环区间填充算法的Verilog实现
针对你提出的需求——输入两个N位独热码总线,生成2^N位的输出总线,循环填充两个独热码对应位置之间的所有位,硬件中最常用的实现方式分为两种,适配不同场景:
1. 组合逻辑逐位判断(适合N较大的场景)
这种方式通过并行比较每个输出位是否处于循环区间内,资源占用更均匀,不会因N增大导致移位器资源爆炸。
实现步骤:
- 从输入独热码中提取对应的位置索引
k(a的独热位位置)和m(b的独热位位置); - 对输出的每一位
i,判断是否满足循环区间条件:- 若
k <= m:当i在[k, m]范围内时置1; - 若
k > m:当i在[k, 2^N-1]或[0, m]范围内时置1。
- 若
Verilog代码示例
module cyclic_range_fill #( parameter N = 4 // 输入总线宽度,输出宽度为2^N )( input wire [N-1:0] a, // 独热码:标记区间起始位置 input wire [N-1:0] b, // 独热码:标记区间结束位置 output reg [(1<<N)-1:0] result // 2^N位输出,区间内所有位置1 ); // 提取独热码对应的位置索引 reg [N-1:0] k, m; always @* begin k = '0; for (int i = 0; i < N; i++) begin if (a[i]) k = i; // 取独热码中为1的位索引 end m = '0; for (int i = 0; i < N; i++) begin if (b[i]) m = i; end end // 生成循环区间掩码 always @* begin result = '0; for (int i = 0; i < (1<<N); i++) begin result[i] = (k <= m) ? ((i >= k) && (i <= m)) : ((i >= k) || (i <= m)); end end endmodule
2. 移位拼接掩码(适合N较小的场景)
当N较小时(如N≤8),可以通过移位和逻辑或操作直接生成掩码,速度更快,代码更简洁。
实现逻辑:
- 若
k <= m:掩码为((1 << (m - k + 1)) - 1) << k; - 若
k > m:掩码为(((1 << ((1<<N) - k + m + 1)) - 1) << k) | ((1 << (m + 1)) - 1)。
Verilog代码示例
module cyclic_range_fill_shift #( parameter N = 4 )( input wire [N-1:0] a, input wire [N-1:0] b, output reg [(1<<N)-1:0] result ); reg [N-1:0] k, m; always @* begin k = '0; for (int i = 0; i < N; i++) begin if (a[i]) k = i; end m = '0; for (int i = 0; i < N; i++) begin if (b[i]) m = i; end end always @* begin if (k <= m) begin result = ((1 << (m - k + 1)) - 1) << k; end else begin result = (((1 << ((1<<N) - k + m + 1)) - 1) << k) | ((1 << (m + 1)) - 1); end end endmodule
关于示例的说明
你给出的示例中a=0110并非严格独热码(存在两个1),若按独热码规则处理会取最后一个为1的位索引(即k=2),b=0001对应m=0,此时输出会是1111111111111101(bit0和bit2-15置1)。如果示例中的输入是数值而非独热码(a=6、b=1),只需将代码中提取索引的部分改为直接使用输入数值即可。
内容的提问来源于stack exchange,提问作者Ivan Sladkov
相关产品推荐
相关产品推荐

