0

I am writing a memory system for a basic 16-bit educational CPU and am running into issues with Quartus Synthesis of my module. Specifically, I have broken down the address space into a few different parts and one of them (which is a ROM) is not synthesizing properly. (NOTE: I am synthesizing for a DE2-115 Altera board, QuartusII 12.1, SystermVerilog code)

So, in order to make the memory-mapped VRAM (a memory module that is dual-ported to allow VGA output while the CPU writes colors) more usable, I included a small ROM in the address space that includes code (assembled functions) that allow you to write characters into memory, ie a print_char function. This ROM is located in memory at a specific address, so in order to simplify the SV, I implemented the ROM (and all the memory modules) like so:

module printROM
  (input  rd_cond_code_t      re_L,
   input  wr_cond_code_t      we_L,
   input  logic [15:0]        memAddr,
   input  logic               clock,
   input  logic               reset_L,
   inout  wire [15:0]         memBus,
   output mem_status_t        memStatus);

   reg [15:0]                 rom[`VROM_ADDR_LO:`VROM_ADDR_HI];
   reg [15:0]                 dataOut;

   /* The ROM */
   always @(posedge clock) begin
      if (re_L == MEM_RD) begin
         dataOut <= rom[memAddr];
      end
   end

   /* Load the rom data */
   initial $readmemh("printROM.hex", rom);

   /* Drive the line */
   tridrive #(.WIDTH(16)) romOut(.data(dataOut),
                                 .bus(memBus),
                                 .en_L(re_L));
/* Manage asserting completion of a read or a write */
   always_ff @(posedge clock, negedge reset_L) begin
      if (~reset_L) begin
         memStatus <= MEM_NOT_DONE;
      end
      else begin
         if ((we_L == MEM_WR) | (re_L == MEM_RD)) begin
            memStatus <= MEM_DONE;
         end
         else begin
            memStatus <= MEM_NOT_DONE;
         end
      end
   end

endmodule // printROM

Where VROM_ADDR_LO and VROM_ADDR_HI are two macros defining the addresses of this ROM, namely 'hEB00 and 'hEFFF. Thus, when an address in that range is read/written to by the CPU, this module is able to properly index into the rom memory. This technique works fine in VCS simulation.

However, when I go to synthesize this module, Quartus correctly implies a ROM but has issues initializing it. I get this error:

Error (113012): Address at line 11 exceeds the specified depth (1280) in the Memory Initialization File "psx18240.ram0_printROM_38938673.hdl.mif"

It looks like Quartus is converting the .hex file I give as the ROM code (ie printROM.hex) and using the CPU visible addresses (ie starting at 'hEB00) for the generated .mif file even though the size of rom is obviously too small. Does Quartus not support this syntax or am I doing something wrong?

2 Answers 2

1

It would appear that Quartus does not like what you're doing. Probably better would be if you only want a rom with 1280 entries, then you should just create one from 0:1279, and address it using that range (this is what your logic would have to synthesize into anyway).

   reg [15:0]           rom[0:`VROM_ADDR_HI-`VROM_ADDR_LO];

   assign romAddr = (memAddr - `VROM_ADDR_LO);
   always @(posedge clock) begin
      if (re_L == MEM_RD) begin
         dataOut <= rom[romAddr];
      end
   end
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks; this was my solution too. I was just wondering if there was something I wasn't considering because I like the style I wrote it in. Just another little piece of SystemVerilog Quartus hasnt quite implemented I guess.....
0

Go for ROM Megafunctions in mega wizard plugin manager in quartus. Its is a GUI based ipcore generater. There you can paramterize all the options even including the hex file. But you have to follow Intel hex file format. This also available in file->new.

For hdl based instantiation http://quartushelp.altera.com/12.1/mergedProjects/hdl/mega/mega_file_lpm_rom.htm

User guide. https://www.google.co.in/url?sa=t&source=web&rct=j&ei=nVAGVKvSDcu9ugTMooCQDQ&url=http://www.altera.com/literature/ug/ug_ram_rom.pdf&cd=1&ved=0CBsQFjAA&usg=AFQjCNE2ZXM1gIsMZ5BvkKTHanX1E7vamg

1 Comment

Unfortunately, the Megablocks do not allow you to specify and address range like I am asking for (ie, I want 'hEB00 to map to the 0th element of the memory, 'hEB01 to the 1st, etc). Also, for my purposes, they are typically more confusing and harder to simulate than the Verilog I have above, which synthesizes to use the same resources (Inferring ROMs: altera.com/literature/hb/qts/qts_qii51007.pdf).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.