尝试在 Verilog 中综合 RAM 时 Quartus 崩溃
Quartus crashes when trying to synthesize RAM in Verilog
我正在尝试在 Altera MAX II (EPM240) 上做 VGA RAMDAC。我正在为 RAM 创建 76800 字节的数组。 hvsync_generator 模块生成 VGA 信号。主模块从 RAM 中获取数据并将其传输到 pixels 总线。它运行良好,像素(320 * 240)显示在屏幕上。我想使用不同的微控制器从外部写入 RAM。我是 Verilog 的新手,我不知道如何在 RAM 中正确保存数据。下面是 Quartus 给我的错误。
我的代码:
module ramdac (
input clk, // clock 50 mhz
output reg [7:0] pixels, // digital video bus
output hsync_out, // H SYNC
output vsync_out, // V SYNC
output inDisplayArea, //
input we, // WE RAM
input [7:0] in_data, // input data for ram
input [16:0] in_address // input address for ram
);
reg clk_25;
reg [16:0] displayAddr;
wire [9:0] CounterX;
wire [9:0] CounterY;
reg [7:0] mem [76799:0]; // frame buffer 76800 bytes (320 x 240)
// devide clock
always @(posedge clk)
begin
clk_25 <= ~ clk_25;
end
hvsync_generator hvsync(
.clk(clk_25),
.vga_h_sync(hsync_out),
.vga_v_sync(vsync_out),
.CounterX(CounterX),
.CounterY(CounterY),
.inDisplayArea(inDisplayArea)
);
always @(posedge clk_25)
begin
if (inDisplayArea)
begin
displayAddr <= ((CounterX - 1) >> 1) + ((CounterY >> 1) * 320); // calculate ram index by screen coords
pixels <= mem[displayAddr];
end
else
pixels <= 0;
end
// try to write new ram data
always @(posedge clk)
begin
// if this line is deleted, then there will be NO error
if(we) mem[in_address] <= in_data;
end
endmodule
错误详情:
Problem Details
Error:
Internal Error: Sub-system: OPT, File: /quartus/synth/opt/opt_op_decsel.cpp, Line: 2046
in_width <= 16
Stack Trace:
0x110ee: RTL_OPERATOR::replace_decoder_nlut + 0x10e (SYNTH_OPT)
0x29fca: RTL_OPERATOR::replace_decs_with_gates + 0xfa (SYNTH_OPT)
0x2771e: RTL_OPERATOR::exit_cleaning + 0x82 (SYNTH_OPT)
0x3684b: RTL_SCRIPT::call_common_rtl_fns + 0xa1b (SYNTH_OPT)
0x34942: RTL_SCRIPT::call_named_function + 0x552 (SYNTH_OPT)
0x33a08: RTL_SCRIPT::process_script + 0x52c (SYNTH_OPT)
0x33013: opt_process_netlist_scripted + 0x7df (SYNTH_OPT)
0x3a1fa: RTL_ROOT::process_sgate_netlist + 0x1aa (SYNTH_OPT)
0x15d728: SGN_SYNTHESIS::high_level_synthesis + 0x198 (synth_sgn)
0x15e132: SGN_SYNTHESIS::process_current_stage + 0x222 (synth_sgn)
0xc75d5: SGN_EXTRACTOR::synthesize_partition + 0x195 (synth_sgn)
0xc71bf: SGN_EXTRACTOR::synthesis + 0x20f (synth_sgn)
0xc7334: SGN_EXTRACTOR::synthesis_and_post_processing + 0xc4 (synth_sgn)
0x12b02: sgn_full + 0xd2 (synth_sgn)
0x4458: qsyn_execute_sgn + 0x1e8 (quartus_map)
0x14246: QSYN_FRAMEWORK::execute_core + 0x136 (quartus_map)
0x13d2b: QSYN_FRAMEWORK::execute + 0x49b (quartus_map)
0x1150c: qexe_do_normal + 0x1ec (comp_qexe)
0x16622: qexe_run + 0x432 (comp_qexe)
0x17371: qexe_standard_main + 0xc1 (comp_qexe)
0x1b42b: qsyn_main + 0x53b (quartus_map)
0x13258: msg_main_thread + 0x18 (CCL_MSG)
0x14a5e: msg_thread_wrapper + 0x6e (CCL_MSG)
0x16af0: mem_thread_wrapper + 0x70 (ccl_mem)
0x12af1: msg_exe_main + 0xa1 (CCL_MSG)
0x2a236: __tmainCRTStartup + 0x10e (quartus_map)
0x17033: BaseThreadInitThunk + 0x13 (KERNEL32)
0x4d240: RtlUserThreadStart + 0x20 (ntdll)
End-trace
Executable: quartus_map
Comment:
None
System Information
Platform: windows64
OS name: Windows 10
OS version: 10.0
Quartus Prime Information
Address bits: 64
Version: 20.1.1
Build: 720
Edition: Lite Edition
如何将外部数据正确写入RAM?
UPD:错误出现前几秒,我在日志中收到警告:
Warning (276002): Cannot convert all sets of registers into RAM megafunctions when creating nodes; therefore, the resulting number of registers remaining in design can cause longer compilation time or result in insufficient memory to complete Analysis and Synthesis
问题是此 FPGA 中没有足够的单元来容纳该内存量。如果您只对从内存中读取的内容进行编码,那么合成器将不会创建所需数量的链接,这也不会导致错误。如果您同时对读取和写入进行编码,那么合成器才会创建所有的存储单元。对于现实中的 Altera MAX II,您可以创建大约 16 KB。
我正在尝试在 Altera MAX II (EPM240) 上做 VGA RAMDAC。我正在为 RAM 创建 76800 字节的数组。 hvsync_generator 模块生成 VGA 信号。主模块从 RAM 中获取数据并将其传输到 pixels 总线。它运行良好,像素(320 * 240)显示在屏幕上。我想使用不同的微控制器从外部写入 RAM。我是 Verilog 的新手,我不知道如何在 RAM 中正确保存数据。下面是 Quartus 给我的错误。
我的代码:
module ramdac (
input clk, // clock 50 mhz
output reg [7:0] pixels, // digital video bus
output hsync_out, // H SYNC
output vsync_out, // V SYNC
output inDisplayArea, //
input we, // WE RAM
input [7:0] in_data, // input data for ram
input [16:0] in_address // input address for ram
);
reg clk_25;
reg [16:0] displayAddr;
wire [9:0] CounterX;
wire [9:0] CounterY;
reg [7:0] mem [76799:0]; // frame buffer 76800 bytes (320 x 240)
// devide clock
always @(posedge clk)
begin
clk_25 <= ~ clk_25;
end
hvsync_generator hvsync(
.clk(clk_25),
.vga_h_sync(hsync_out),
.vga_v_sync(vsync_out),
.CounterX(CounterX),
.CounterY(CounterY),
.inDisplayArea(inDisplayArea)
);
always @(posedge clk_25)
begin
if (inDisplayArea)
begin
displayAddr <= ((CounterX - 1) >> 1) + ((CounterY >> 1) * 320); // calculate ram index by screen coords
pixels <= mem[displayAddr];
end
else
pixels <= 0;
end
// try to write new ram data
always @(posedge clk)
begin
// if this line is deleted, then there will be NO error
if(we) mem[in_address] <= in_data;
end
endmodule
错误详情:
Problem Details
Error:
Internal Error: Sub-system: OPT, File: /quartus/synth/opt/opt_op_decsel.cpp, Line: 2046
in_width <= 16
Stack Trace:
0x110ee: RTL_OPERATOR::replace_decoder_nlut + 0x10e (SYNTH_OPT)
0x29fca: RTL_OPERATOR::replace_decs_with_gates + 0xfa (SYNTH_OPT)
0x2771e: RTL_OPERATOR::exit_cleaning + 0x82 (SYNTH_OPT)
0x3684b: RTL_SCRIPT::call_common_rtl_fns + 0xa1b (SYNTH_OPT)
0x34942: RTL_SCRIPT::call_named_function + 0x552 (SYNTH_OPT)
0x33a08: RTL_SCRIPT::process_script + 0x52c (SYNTH_OPT)
0x33013: opt_process_netlist_scripted + 0x7df (SYNTH_OPT)
0x3a1fa: RTL_ROOT::process_sgate_netlist + 0x1aa (SYNTH_OPT)
0x15d728: SGN_SYNTHESIS::high_level_synthesis + 0x198 (synth_sgn)
0x15e132: SGN_SYNTHESIS::process_current_stage + 0x222 (synth_sgn)
0xc75d5: SGN_EXTRACTOR::synthesize_partition + 0x195 (synth_sgn)
0xc71bf: SGN_EXTRACTOR::synthesis + 0x20f (synth_sgn)
0xc7334: SGN_EXTRACTOR::synthesis_and_post_processing + 0xc4 (synth_sgn)
0x12b02: sgn_full + 0xd2 (synth_sgn)
0x4458: qsyn_execute_sgn + 0x1e8 (quartus_map)
0x14246: QSYN_FRAMEWORK::execute_core + 0x136 (quartus_map)
0x13d2b: QSYN_FRAMEWORK::execute + 0x49b (quartus_map)
0x1150c: qexe_do_normal + 0x1ec (comp_qexe)
0x16622: qexe_run + 0x432 (comp_qexe)
0x17371: qexe_standard_main + 0xc1 (comp_qexe)
0x1b42b: qsyn_main + 0x53b (quartus_map)
0x13258: msg_main_thread + 0x18 (CCL_MSG)
0x14a5e: msg_thread_wrapper + 0x6e (CCL_MSG)
0x16af0: mem_thread_wrapper + 0x70 (ccl_mem)
0x12af1: msg_exe_main + 0xa1 (CCL_MSG)
0x2a236: __tmainCRTStartup + 0x10e (quartus_map)
0x17033: BaseThreadInitThunk + 0x13 (KERNEL32)
0x4d240: RtlUserThreadStart + 0x20 (ntdll)
End-trace
Executable: quartus_map
Comment:
None
System Information
Platform: windows64
OS name: Windows 10
OS version: 10.0
Quartus Prime Information
Address bits: 64
Version: 20.1.1
Build: 720
Edition: Lite Edition
如何将外部数据正确写入RAM?
UPD:错误出现前几秒,我在日志中收到警告:
Warning (276002): Cannot convert all sets of registers into RAM megafunctions when creating nodes; therefore, the resulting number of registers remaining in design can cause longer compilation time or result in insufficient memory to complete Analysis and Synthesis
问题是此 FPGA 中没有足够的单元来容纳该内存量。如果您只对从内存中读取的内容进行编码,那么合成器将不会创建所需数量的链接,这也不会导致错误。如果您同时对读取和写入进行编码,那么合成器才会创建所有的存储单元。对于现实中的 Altera MAX II,您可以创建大约 16 KB。