RedSpirit
RedSpirit

Reputation: 21

Quartus crashes when trying to synthesize RAM in Verilog

I am trying to do VGA RAMDAC at Altera MAX II (EPM240). I am create 76800 bytes array for RAM. The hvsync_generator module generates a VGA signal. The main module takes data from RAM and transfers it to the pixels bus. It works well, pixels (320 * 240) are displayed on the screen. I want to write to RAM externally using a different microcontroller. I am new to Verilog and I don’t know how to properly save data in RAM. Below is the error that Quartus gives me.

My code:

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

Error details:

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

How do I write external data to RAM correctly?

UPD: A few seconds before the error appears I get a warning in log:

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

Upvotes: 1

Views: 983

Answers (1)

RedSpirit
RedSpirit

Reputation: 21

The problem is that there are not enough cells in this FPGA for that amount of memory. If you encode only reading from memory, then the synthesizer will not create the required number of links and this will not cause an error. If you encode both reading and writing, then only then the synthesizer will create all the memory cells. For Altera MAX II in reality, you can create about 16 kilobytes.

Upvotes: 1

Related Questions