回文位验证代码的FPGA/ASIC可综合性分析及实现优化问询
回文验证Verilog代码的可综合性疑问与解答
问题背景
用户提供的回文位验证Verilog代码如下:
module model #(parameter DATA_WIDTH=32 ) ( input [DATA_WIDTH-1:0] din, output logic dout ); logic [$clog2(DATA_WIDTH):0] accum; int i; assign dout = (din[0] ~^ din[DATA_WIDTH-1]); always_comb begin for(i = 1; i < (DATA_WIDTH+1)/2 ; i++) begin assign dout = dout & (din[i] ~^ din[DATA_WIDTH-1-i]); end end endmodule
用户疑惑:这段代码中组合逻辑内的递归式dout赋值看起来不具备可综合性,因此想知道:
- 这段代码能否在FPGA中实现综合?
- 是否也能在ASIC中综合?
- 是否应该采用宏展开的方式编写成如下形式?
宏展开示例代码:
assign dout = (din[0] ~^ din[DATA_WIDTH-1]) & (din[1] ~^ din[DATA_WIDTH-2]) & ... ;
解答
1. FPGA综合可行性
这段代码无法在主流FPGA综合工具中正常综合。核心问题出在always_comb块内的循环赋值:循环里反复执行assign dout = dout & ...,属于对同一个信号设置多个驱动源,同时还存在递归式的信号值引用,形成了组合逻辑循环。主流FPGA综合工具(如Xilinx Vivado、Intel Quartus)会检测到多重驱动或组合环路错误,直接拒绝生成网表。
2. ASIC综合可行性
ASIC综合工具(如Synopsys Design Compiler)同样会拒绝这段代码。ASIC综合对代码规范性要求更严格,这种存在多重驱动、循环依赖的写法完全违反可综合代码的基本规则,工具会抛出明确的错误提示,无法生成有效的门级电路。
3. 推荐的可综合写法
你提到的宏展开思路是正确的,但手动编写长与链效率低且不易维护。更优的方式是使用Verilog的generate块实现参数化的对称位比较,代码既符合可综合规范,又能灵活适配不同的DATA_WIDTH:
module model #(parameter DATA_WIDTH=32 ) ( input [DATA_WIDTH-1:0] din, output logic dout ); logic [(DATA_WIDTH+1)/2 - 1:0] match_bits; generate for (genvar i = 0; i < (DATA_WIDTH+1)/2; i++) begin : match_loop assign match_bits[i] = din[i] ~^ din[DATA_WIDTH-1 - i]; end endgenerate assign dout = &match_bits; endmodule
该写法通过生成块逐个比较每一对对称位,将比较结果存入临时数组,最后对所有结果做与运算得到最终的回文验证信号。这种写法在FPGA和ASIC综合工具中都能正常编译,同时保持了代码的可扩展性。
内容的提问来源于stack exchange,提问作者overcookedlobster
相关产品推荐
相关产品推荐

