Quartus вылетает при попытке синтезировать оперативную память в Verilog

Пытаюсь сделать VGA RAMDAC на Altera MAX II (EPM240). Я создаю массив 76800 байт для оперативной памяти. Модуль hvsync_generator генерирует сигнал VGA. Основной модуль берет данные из оперативной памяти и передает их на шину пикселей. Работает хорошо, на экране отображаются пиксели (320*240). Я хочу писать в ОЗУ извне, используя другой микроконтроллер. Я новичок в Verilog и не знаю, как правильно сохранять данные в оперативной памяти. Ниже приведена ошибка, которую выдает мне 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

Как правильно записать внешние данные в оперативную память?

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

person RedSpirit    schedule 12.03.2021    source источник


Ответы (1)


Проблема в том, что в этой ПЛИС не хватает ячеек для такого объема памяти. Если закодировать только чтение из памяти, то синтезатор не создаст нужное количество ссылок и это не вызовет ошибки. Если кодировать и чтение и запись, то только тогда синтезатор создаст все ячейки памяти. Для Altera MAX II реально можно создать около 16 килобайт.

person RedSpirit    schedule 15.03.2021