SystemVerilog BRAM映射失败求助:写入计数器值无法综合
Yosys综合Tang Nano 4K RAM时写入计数器值失败的问题
在使用Yosys为Tang Nano 4K综合SystemVerilog存储器时,遇到如下问题:仅当向RAM写入固定值时可正常完成综合,若写入计数器值则综合失败。
可正常工作的代码
module top ( input logic clk_i, output logic data_o ); reg [31:0] counter = '0; (* ram_style="block" *) reg [31:0] video_ram_array [0:(2**15)-1]; always_ff @(posedge clk_i) begin counter <= counter + 1; // video_ram_array[counter] <= counter; video_ram_array[counter] <= 32'h1234; end always_comb begin data_o = video_ram_array[counter][0]; end endmodule
无法工作的代码
module top ( input logic clk_i, output logic data_o ); reg [31:0] counter = '0; (* ram_style="block" *) reg [31:0] video_ram_array [0:(2**15)-1]; always_ff @(posedge clk_i) begin counter <= counter + 1; video_ram_array[counter] <= counter; // video_ram_array[counter] <= 32'h1234; end always_comb begin data_o = video_ram_array[counter][0]; end endmodule
综合错误信息
2.8. Executing MEMORY_LIBMAP pass (mapping memories to cells). <suppressed ~2 debug messages> ERROR: no valid mapping found for memory top.video_ram_array make: *** [run] Error 1
补充信息
即使将RAM规模缩小至[0:2],问题仍存在。怀疑首次成功是因为综合器优化了BRAM,但netlistsvg显示结构符合预期,不确定是否实际有效。
问题原因与解决方法
原因分析
核心问题在于:
- 时序与端口约束不匹配:Tang Nano 4K搭载的Gowin BRAM原语对同步读写的时序、端口信号复用有严格要求。你的代码中,
counter同时作为写地址、写数据和读地址,且读写地址在同一时钟沿使用同一信号值,这种组合无法匹配BRAM原语的端口逻辑,导致Yosys的MEMORY_LIBMAP pass找不到有效映射。 - 固定值写入的特殊优化:写入固定值时,Yosys会自动将RAM优化为只读存储器(ROM),绕过了BRAM的写端口约束,因此能正常综合,但这并非实际的可写BRAM实现。
解决步骤
拆分读写地址,消除时序冲突
将读地址延迟一个时钟周期,避免读写操作在同一周期复用同一地址信号,匹配BRAM的同步端口时序要求:module top ( input logic clk_i, output logic data_o ); reg [31:0] counter = '0; reg [31:0] read_addr = '0; (* ram_style="block" *) reg [31:0] video_ram_array [0:(2**15)-1]; always_ff @(posedge clk_i) begin counter <= counter + 1; read_addr <= counter; // 读地址延迟一个周期,规避读写时序冲突 video_ram_array[counter] <= counter; end always_comb begin data_o = video_ram_array[read_addr][0]; end endmodule调整综合约束或直接例化BRAM原语
- 若拆分地址后仍有问题,可先移除
(* ram_style="block" *)约束,让Yosys自动选择存储器类型(分布式RAM可绕过部分BRAM端口限制,但若需BRAM则不推荐)。 - 直接例化Gowin官方提供的BRAM原语,完全控制端口连接,确保符合器件的物理特性。
- 若拆分地址后仍有问题,可先移除
检查综合脚本的库配置
确保Yosys综合脚本正确加载了Gowin的器件库,示例脚本片段:read_verilog top.sv synth_gowin -family GW1NR -device GW1NR-LV9QN88PC6/I5 write_verilog -attr2comment top_synth.v
验证说明
首次写固定值时的“成功”是Yosys将RAM优化为ROM的结果,并非实际的可写BRAM。可通过查看综合后的网表文件(top_synth.v)确认是否真的映射到了BRAM原语。
内容的提问来源于stack exchange,提问作者Filip
相关产品推荐
相关产品推荐

