Search code examples
vhdlfpgaquartus

10821 HDL error - Porting VHDL code from Xlinx to Altera


I'm trying to synthesize a code in VHDL on Quartus II that describes RAM blocks. But this code was meant to be synthesized for a Xlinx chip.

It's part of a lecture from https://opencores.org/project/cpu_lecture

Here follow the entity header:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity RAMB4_S4_S4 is
generic(INIT_00 : bit_vector := X"00000000000000000000000000000000"
                              &  "00000000000000000000000000000000";
        INIT_01 : bit_vector := X"00000000000000000000000000000000"
                              & X"00000000000000000000000000000000";
        INIT_02 : bit_vector := X"00000000000000000000000000000000"
                              & X"00000000000000000000000000000000";
        INIT_03 : bit_vector := X"00000000000000000000000000000000"
                              & X"00000000000000000000000000000000";
        INIT_04 : bit_vector := X"00000000000000000000000000000000"
                              & X"00000000000000000000000000000000";
        INIT_05 : bit_vector := X"00000000000000000000000000000000"
                              & X"00000000000000000000000000000000";
        INIT_06 : bit_vector := X"00000000000000000000000000000000"
                              & X"00000000000000000000000000000000";
        INIT_07 : bit_vector := X"00000000000000000000000000000000"
                              & X"00000000000000000000000000000000";
        INIT_08 : bit_vector := X"00000000000000000000000000000000"
                              & X"00000000000000000000000000000000";
        INIT_09 : bit_vector := X"00000000000000000000000000000000"
                              & X"00000000000000000000000000000000";
        INIT_0A : bit_vector := X"00000000000000000000000000000000"
                              & X"00000000000000000000000000000000";
        INIT_0B : bit_vector := X"00000000000000000000000000000000"
                              & X"00000000000000000000000000000000";
        INIT_0C : bit_vector := X"00000000000000000000000000000000"
                              & X"00000000000000000000000000000000";
        INIT_0D : bit_vector := X"00000000000000000000000000000000"
                              & X"00000000000000000000000000000000";
        INIT_0E : bit_vector := X"00000000000000000000000000000000"
                              & X"00000000000000000000000000000000";
        INIT_0F : bit_vector := X"00000000000000000000000000000000"
                              & X"00000000000000000000000000000000");

port(   ADDRA   : in  std_logic_vector(9 downto 0);
        ADDRB   : in  std_logic_vector(9 downto 0);
        CLKA    : in  std_ulogic;
        CLKB    : in  std_ulogic;
        DIA     : in  std_logic_vector(3 downto 0);
        DIB     : in  std_logic_vector(3 downto 0);
        ENA     : in  std_ulogic;
        ENB     : in  std_ulogic;
        RSTA    : in  std_ulogic;
        RSTB    : in  std_ulogic;
        WEA     : in  std_ulogic;
        WEB     : in  std_ulogic;

        DOA     : out std_logic_vector(3 downto 0);
        DOB     : out std_logic_vector(3 downto 0));
end RAMB4_S4_S4;

The part of the code that is giving me trouble is:

if (rising_edge(CLKB)) then
        if (ENB = '1') then
            DOB(3) <= cv(DATA(conv_integer(ADDRB & "11")));
            DOB(2) <= cv(DATA(conv_integer(ADDRB & "10")));
            DOB(1) <= cv(DATA(conv_integer(ADDRB & "01")));
            DOB(0) <= cv(DATA(conv_integer(ADDRB & "00")));
            if (WEB = '1') then
                DATA(conv_integer(ADDRB & "11")) <= cv1(DIB(3));
                DATA(conv_integer(ADDRB & "10")) <= cv1(DIB(2));
                DATA(conv_integer(ADDRB & "01")) <= cv1(DIB(1));
                DATA(conv_integer(ADDRB & "00")) <= cv1(DIB(0));
            end if;
        end if;
    end if;

And I'm getting the following error message:

Error (10821): HDL error at RAMB4_S4_S4.vhd(129): can't infer register for "DATA[0]" because its behavior does not match any supported register model

As I said before, I know that this code was meant to be synthesized to a Xlinx chip. What I don't know is witch features in this code are not supported by the Quartus II synthesizer and how to modify it in a proper way to by synthesized.


Solution

  • This sounds to me like (what I've recently learnt is) an XY problem: asking about an attempted solution rather than the actual problem.

    The way to get this code working with Intel (Altera) is to find out what kind of RAM this is and to generate the same RAM using Intel's IP generator and then to connect that up in the same place in the code. You will almost certainly find that the interface to the Intel RAM will not be exactly the same as the Xilinx. A good way to fix this is to write an alternative architecture for the Xilinx RAM and to instantiate the Intel RAM in that architecture, doing the necessary name-changing, sense-changing and anything other hacking required there. Such a dummy layer of hierarchy is call a wrapper.

    It may well be the case that the Xilinx RAM is not synthesisable on Xilinx tools either, but is instead just a simulation model, intended to be used in place of the output of a RAM generated by the Xilinx IP generator.

    The actual reason for your error message is not because some "features in this code are not supported by the Quartus II synthesizer" per se, but because Quartus is not recognising the code as being a RAM and so is trying to synthesise flip-flops. It is then discovering that the code cannot be synthesised using flip-flops (because it is modelling the behaviour of a RAM).