0
votes

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

2 Answers

1
votes

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
0
votes

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