Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
11 years ago

Problems synthesizeing infered true dual ported RAM

Hello Everybody,

I'm pretty new to the Altera World and just hit some problems while trying to synthesize an infering true dual ported RAM. I already found some code snips but I didn't find the 100% match for my case. So now I try to combine these code snips to meet my requirements.

This is the code which is able to be synthesized:


  port_a : PROCESS (clk_a)
  BEGIN
    IF (clk_a'EVENT AND clk_a = '1') THEN
      IF (enable_a = '1') THEN
          v_memory(conv_integer(address_a(c_mem_addr_bits+1 DOWNTO 2)))
             := to_bitvector(data_write_a);
          data_read_a <=
            to_stdlogicvector(v_memory(conv_integer(
              address_a(c_mem_addr_bits+1 DOWNTO 2))));
      END IF;
    END IF;
  END PROCESS port_a;
  port_b : PROCESS (clk_a)
  BEGIN
    IF (clk_a'EVENT AND clk_a = '1') THEN
      IF (enable_b = '1') THEN
          v_memory(conv_integer(address_b(c_mem_addr_bits+1 DOWNTO 2)))
             := to_bitvector(data_write_b);
          data_read_b <=
            to_stdlogicvector(v_memory(conv_integer(
              address_b(c_mem_addr_bits+1 DOWNTO 2))));
      END IF;
    END IF;
  END PROCESS port_b;

But if I try to insert a byte enable signal, it doesn't synthesize anymore. The code is as following (added code is marked blue):


  port_a : PROCESS (clk_a)
  BEGIN
    IF (clk_a'EVENT AND clk_a = '1') THEN                   -- This is Line 157
      IF (enable_a = '1') THEN
        IF (write_byte_enable_a(3) = '1') THEN
          -- 31 DOWNTO 24
          v_memory(conv_integer(address_a(c_mem_addr_bits+1 DOWNTO 2)))
            (31 DOWNTO 24) := to_bitvector(data_write_a(31 DOWNTO 24));
          data_read_a(31 DOWNTO 24) <=
            to_stdlogicvector(v_memory(conv_integer(
              address_a(c_mem_addr_bits+1 DOWNTO 2)))(31 DOWNTO 24));
        END IF;
      END IF;
    END IF;
  END PROCESS port_a;
  port_b : PROCESS (clk_a)
  BEGIN
    IF (clk_a'EVENT AND clk_a = '1') THEN                   -- This is Line 202
      IF (enable_b = '1') THEN
        IF (write_byte_enable_b(3) = '1') THEN
          -- 31 DOWNTO 24
          v_memory(conv_integer(address_b(c_mem_addr_bits+1 DOWNTO 2)))
            (31 DOWNTO 24) := to_bitvector(data_write_b(31 DOWNTO 24));
          data_read_b(31 DOWNTO 24) <=
            to_stdlogicvector(v_memory(conv_integer(
              address_b(c_mem_addr_bits+1 DOWNTO 2)))(31 DOWNTO 24));
        END IF;
      END IF;
    END IF;
  END PROCESS port_b;

As you can see, I just use the highest byte on that 31 bit vector to minimize the possibility of "false code". When I try to synthesize this code, I get the following error messeges:

Error (10028): Can't resolve multiple constant drivers for net "v_memory[0][31]" at dp_ram.vhd(202)

Error (10029): Constant driver at dp_ram.vhd(157)

Error (10028): Can't resolve multiple constant drivers for net "v_memory[0][30]" at dp_ram.vhd(202)

Error (10028): Can't resolve multiple constant drivers for net "v_memory[0][29]" at dp_ram.vhd(202)

Error (10028): Can't resolve multiple constant drivers for net "v_memory[0][28]" at dp_ram.vhd(202)

Error (10028): Can't resolve multiple constant drivers for net "v_memory[0][27]" at dp_ram.vhd(202)

Error (10028): Can't resolve multiple constant drivers for net "v_memory[0][26]" at dp_ram.vhd(202)

Error (10028): Can't resolve multiple constant drivers for net "v_memory[0][25]" at dp_ram.vhd(202)

Error (10028): Can't resolve multiple constant drivers for net "v_memory[0][24]" at dp_ram.vhd(202)

Error (10028): Can't resolve multiple constant drivers for net "v_memory[1][31]" at dp_ram.vhd(202)

Error (10028): Can't resolve multiple constant drivers for net "v_memory[1][30]" at dp_ram.vhd(202)

Error (10028): Can't resolve multiple constant drivers for net "v_memory[1][29]" at dp_ram.vhd(202)

Error (10028): Can't resolve multiple constant drivers for net "v_memory[1][28]" at dp_ram.vhd(202)

Error (10028): Can't resolve multiple constant drivers for net "v_memory[1][27]" at dp_ram.vhd(202)

Error (10028): Can't resolve multiple constant drivers for net "v_memory[1][26]" at dp_ram.vhd(202)

Error (10028): Can't resolve multiple constant drivers for net "v_memory[1][25]" at dp_ram.vhd(202)

Error (10028): Can't resolve multiple constant drivers for net "v_memory[1][24]" at dp_ram.vhd(202)

Error (10028): Can't resolve multiple constant drivers for net "v_memory[2][31]" at dp_ram.vhd(202)

Error (10028): Can't resolve multiple constant drivers for net "v_memory[2][30]" at dp_ram.vhd(202)

Error (12153): Can't elaborate top-level user hierarchy

Error: Quartus II 32-bit Analysis & Synthesis was unsuccessful. 20 errors, 3 warnings

Error: Peak virtual memory: 532 megabytes

Error: Processing ended: Thu Apr 24 10:27:45 2014

Error: Elapsed time: 00:00:05

Error: Total CPU time (on all processors): 00:00:05

To locate the refered lines (157 and 202), I commented them in the posted code snips.

I don't know why the synthesis tool can't handle the byte enable. Can anyone help me to find a workaround?

My second problem hit me when I tried to use two different clock domains to use port_a and port_b independently. Is it due to the internal structure not possible to use a second clock domain on the same RAM? Does there exist a workaround too?

I'm using Quartus II 32-bit Version 13.0.1 Build 232 06/12/2013 SJ Web Edition.

Thanks in advance!

Best Regards,

solectrix03

14 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    THe loop problem is because it does not follow the template. If you raise a support request with altera they may try and support it in future, but their answer now will be "it doesnt follow the template, therefore we dont support it". I have had this before with memories inside generate loops that did not use a write-enable, and were generated using FFs. The response was "It does not have a write enable, if you add one then it will be infered" ---etc etc.

    As for the memory init - Quartus does not support textio for initialising rams. The annoying thing is that it is supported in Verilog, and Xilinx support it for VHDL. I raised this a few years ago, and to my knowledge it is still not supported. You could re-raise the support request, but unless you threaten to take your massive custom to xilinx, they probably wont do anything about it.

    Edit: I didnt fully read your post before I pressed send (friday lunchtime pub visit etc etc). I guess they started to support textio for init, but I guess its not complete (as usual - just like their poor attempt at 2008 support).
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thanks alot Tricky! Your reply answered alot of questions...

    I think I need to think over something new for the initialization.

    From my side it looks like my problem is solved. Thanks to everyone for your help!
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    It looks like Quartus is not only ignoring std.textio library functions (as known before), but also the initilization function for the shared variable.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I found that the initialization function is correctly evaluated, but because the result of endfile(ini_file) is apparently undefined, both alternatives of the IF statement are skipped. An assignment before the IF statement will be however copied to the function result.

    So the simple point is that TEXTIO functions are still unsupported in recent Quartus versions.