inferring rams/roms still can be a tricky subject. you should read the synthesis coding guide and also look at the logs and implementation results. seemingly minor details can cause the tools to do unexpected things.
It's tricky. best to read the docs for whatever synthesis tool you're using. More reliable than people guessing. You may also be expecting too much, sadly.So, RAM being internal to the FPGA, I don't think I'm expecting too much to have a piece of verilog or VHDL that would make a simple demonstration of what it works.
So, RAM being internal to the FPGA, I don't think I'm expecting too much to have a piece of
verilog or VHDL that would make a simple demonstration of what it works. So to rephrase
my question: can anybody point me to a short piece of verilog that explains how to use
MAX10's internal RAM?
Code Verilog - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 module test190803(DA, DB, max_clk, clk); output reg[15:0] DA, DB; // Data of the DAC output reg max_clk; // Clock of the DAC input clk; // FPGA 100 MHz input clock // Some variables reg[15:0] sine[0:1023]; reg[9:0] sinindex; reg[9:0] cosindex; initial begin sinindex = 0; cosindex = 256; $readmemh("sinetable.txt", sine); end always@(posedge clk) begin if(max_clk == 0) begin max_clk <= 1; sinindex <= sinindex+1; cosindex <= cosindex+1; end else begin max_clk <= 0; end // ROM must be read unconditionally to infer dual port ROM DA <= sine[sinindex]; DB <= sine[cosindex]; end endmodule
Info (276014): Found 1 instances of uninferred RAM logic
Info (276013): RAM logic "dual_port_rom:SineRom|rom" is uninferred because MIF is not supported for the selected family
Error (276003): Cannot convert all sets of registers into RAM megafunctions when creating nodes. The resulting number of registers remaining in design exceeds the number of registers in the device or the number specified by the assignment max_number_of_registers_from_uninferred_rams. This can cause longer compilation time or result in insufficient memory to complete Analysis and Synthesis
Error: Quartus Prime Analysis & Synthesis was unsuccessful. 1 error, 6 warnings
Error: Peak virtual memory: 652 megabytes
Error: Processing ended: Fri Aug 09 16:52:29 2019
Error: Elapsed time: 00:00:09
Error: Total CPU time (on all processors): 00:00:18
Error (293001): Quartus Prime Full Compilation was unsuccessful. 3 errors, 6 warnings
There's a little trick with MAX10. You need to select a configuration scheme with memory initialization to allow ROM inference
Code Verilog - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 // Quartus Prime Verilog Template // Dual Port ROM module dual_port_rom #(parameter DATA_WIDTH=16, parameter ADDR_WIDTH=13) ( input [(ADDR_WIDTH-1):0] addr_a, addr_b, input clk, output reg [(DATA_WIDTH-1):0] q_a, q_b); // Declare the ROM variable reg [DATA_WIDTH-1:0] rom[2**ADDR_WIDTH-1:0]; // Initialize the ROM with $readmemh instead of readmemb. initial begin $readmemh("sine8192.hex", rom); end always @ (posedge clk) begin q_a <= rom[addr_a]; q_b <= rom[addr_b]; end endmodule module Test190801(DA, DB, max_clk, clk); output reg[15:0] DA, DB; // Data of the DAC output reg max_clk; // Clock of the DAC input clk; // FPGA 100 MHz input clock // Some variables reg[12:0] sinindex; reg[12:0] cosindex; // Instanciation of dual port ROM dual_port_rom SineRom( .addr_a(sinindex), .addr_b(sinindex), .clk(clk), q_a(DA), q_b(DB) ); // Index calculation always@(posedge clk) begin if(max_clk == 0) begin max_clk <= 1; sinindex <= sinindex+1; cosindex <= cosindex+1; end else begin max_clk <= 0; end end endmodule
Code Verilog - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 // Quartus Prime Verilog Template // Dual Port ROM module dual_port_rom #(parameter DATA_WIDTH=16, parameter ADDR_WIDTH=13) ( input [(ADDR_WIDTH-1):0] addr_a, addr_b, input clk, output reg [(DATA_WIDTH-1):0] q_a, q_b); // Declare the ROM variable reg [DATA_WIDTH-1:0] rom[2**ADDR_WIDTH-1:0]; // Initialize the ROM with $readmemh instead of readmemb. initial begin $readmemh("sine8192.hex", rom); end always @ (posedge clk) begin q_a <= rom[addr_a]; q_b <= rom[addr_b]; end endmodule module Test190801(DA, DB, max_clk, clk); output wire[15:0] DA, DB; // Data of the DAC output reg max_clk; // Clock of the DAC input clk; // FPGA 100 MHz input clock // Some variables reg[12:0] sinindex; reg[12:0] cosindex; // Instanciation of dual port ROM dual_port_rom SineRom( .addr_a(sinindex), .addr_b(sinindex), .clk(clk), .q_a(DA), .q_b(DB) ); // Index calculation always@(posedge clk) begin if(max_clk == 0) begin max_clk <= 1; sinindex <= sinindex+1; cosindex <= cosindex+1; end else begin max_clk <= 0; end end endmodule
Another question: this is a dual port ROM, which is fine for the current design,
but is it possible to make a 8-port ROM? For example by adding addr_a to addr_h,
q_a to q_h?
Simulation wise Modelsim handles a file with hex data with $readmemh just fine. I checked that the data was read in using the 1024 size file that was posted earlier in the thread. If Quartus doesn't initialize a ROM properly with the $readmemh system task then that is a Quartus tool problem (Xilinx/Microsemi has no problem doing this).is "sine8192.hex" something that works in simulation? I suspect readmemh failure is just a warning or silent failure.
Info (19000): Inferred 1 megafunctions from design logic
Info (276029): Inferred altsyncram megafunction from the following design logic: "dual_port_rom:SineRom|rom_rtl_0"
Info (286033): Parameter INIT_FILE set to db/test.ram0_dual_port_rom_e5e0e3d2.hdl.mif
Info (12133): Instantiated megafunction "dual_port_rom:SineRom|altsyncram:rom_rtl_0" with the following parameter:
Info (12134): Parameter "INIT_FILE" = "db/test.ram0_dual_port_rom_e5e0e3d2.hdl.mif"
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?