+ Post New Thread
Results 1 to 15 of 15
  1. #1
    Member level 2
    Points: 387, Level: 4

    Join Date
    Feb 2019
    Posts
    46
    Helped
    0 / 0
    Points
    387
    Level
    4

    What is the vhdl equivalent of "initial begin" to initialize a ROM.

    Greetings ... tell you that a couple of days ago I am trying to translate a verilog file to vhdl and I found the next block that initializes a ROM.

    Code:
    // Make sure the memory is implemented as distributed
       (* rom_style = "distributed" *)
       reg [38:0]  rom [63:0];  // 39 bit word 64 words deep
    
       initial begin
          // rom entries contain (in order) the address, a bitmask, and a bitset
          //***********************************************************************
          // State 1 Initialization
          //***********************************************************************
    
          // Store the power bits
          rom[0] = {7'h28, 16'h0000, 16'hFFFF};
    
          // Store CLKOUT0 divide and phase
          rom[1]  = (S1_CLKOUT0_FRAC_EN == 0) ?
    						{7'h09, 16'h8000, S1_CLKOUT0[31:16]}:
    						{7'h09, 16'h8000, S1_CLKOUT0_FRAC_CALC[31:16]};
          rom[2]  = (S1_CLKOUT0_FRAC_EN == 0) ?
    						{7'h08, 16'h1000, S1_CLKOUT0[15:0]}:
    						{7'h08, 16'h1000, S1_CLKOUT0_FRAC_CALC[15:0]};
    
          // Store CLKOUT1 divide and phase
          rom[3]  = {7'h0A, 16'h1000, S1_CLKOUT1[15:0]};
          rom[4]  = {7'h0B, 16'hFC00, S1_CLKOUT1[31:16]};
    
          // Store CLKOUT2 divide and phase
          rom[5]  = {7'h0C, 16'h1000, S1_CLKOUT2[15:0]};
          rom[6]  = {7'h0D, 16'hFC00, S1_CLKOUT2[31:16]};
    
          // Store CLKOUT3 divide and phase
          rom[7]  = {7'h0E, 16'h1000, S1_CLKOUT3[15:0]};
          rom[8]  = {7'h0F, 16'hFC00, S1_CLKOUT3[31:16]};
    
          // Store CLKOUT4 divide and phase
          rom[9]  = {7'h10, 16'h1000, S1_CLKOUT4[15:0]};
          rom[10]  = {7'h11, 16'hFC00, S1_CLKOUT4[31:16]};
    
          // Store CLKOUT5 divide and phase
          rom[11] = {7'h06, 16'h1000, S1_CLKOUT5[15:0]};
          rom[12] = (S1_CLKOUT0_FRAC_EN == 0) ?
                    {7'h07, 16'hC000, S1_CLKOUT5[31:16]}:
                    {7'h07, 16'hC000, S1_CLKOUT5[31:30], S1_CLKOUT0_FRAC_CALC[35:32],S1_CLKOUT5[25:16]};
    
          // Store CLKOUT6 divide and phase
          rom[13] = {7'h12, 16'h1000, S1_CLKOUT6[15:0]};
          rom[14] = (S1_CLKFBOUT_FRAC_EN == 0) ?
                    {7'h13, 16'hC000, S1_CLKOUT6[31:16]}:
                    {7'h13, 16'hC000, S1_CLKOUT6[31:30], S1_CLKFBOUT_FRAC_CALC[35:32],S1_CLKOUT6[25:16]};
    
          // Store the input divider
          rom[15] = {7'h16, 16'hC000, {2'h0, S1_DIVCLK[23:22], S1_DIVCLK[11:0]} };
    
          // Store the feedback divide and phase
          rom[16] = (S1_CLKFBOUT_FRAC_EN == 0) ?
                    {7'h14, 16'h1000, S1_CLKFBOUT[15:0]}:
                    {7'h14, 16'h1000, S1_CLKFBOUT_FRAC_CALC[15:0]};
          rom[17] = (S1_CLKFBOUT_FRAC_EN == 0) ?
                    {7'h15, 16'h8000, S1_CLKFBOUT[31:16]}:
                    {7'h15, 16'h8000, S1_CLKFBOUT_FRAC_CALC[31:16]};
    
          // Store the lock settings
          rom[18] = {7'h18, 16'hFC00, {6'h00, S1_LOCK[29:20]} };
          rom[19] = {7'h19, 16'h8000, {1'b0 , S1_LOCK[34:30], S1_LOCK[9:0]} };
          rom[20] = {7'h1A, 16'h8000, {1'b0 , S1_LOCK[39:35], S1_LOCK[19:10]} };
    
          // Store the filter settings
          rom[21] = {7'h4E, 16'h66FF,
                    S1_DIGITAL_FILT[9], 2'h0, S1_DIGITAL_FILT[8:7], 2'h0,
                    S1_DIGITAL_FILT[6], 8'h00 };
          rom[22] = {7'h4F, 16'h666F,
                    S1_DIGITAL_FILT[5], 2'h0, S1_DIGITAL_FILT[4:3], 2'h0,
                    S1_DIGITAL_FILT[2:1], 2'h0, S1_DIGITAL_FILT[0], 4'h0 };
    
          //***********************************************************************
          // State 2 Initialization
          //***********************************************************************
    
          // Store the power bits
          rom[23] = {7'h28, 16'h0000, 16'hFFFF};
    
          // Store CLKOUT0 divide and phase
          rom[24] = (S2_CLKOUT0_FRAC_EN == 0) ?
                    {7'h09, 16'h8000, S2_CLKOUT0[31:16]}:
                    {7'h09, 16'h8000, S2_CLKOUT0_FRAC_CALC[31:16]};
          rom[25] = (S2_CLKOUT0_FRAC_EN == 0) ?
                    {7'h08, 16'h1000, S2_CLKOUT0[15:0]}:
                    {7'h08, 16'h1000, S2_CLKOUT0_FRAC_CALC[15:0]};
    
          // Store CLKOUT1 divide and phase
          rom[26] = {7'h0A, 16'h1000, S2_CLKOUT1[15:0]};
          rom[27] = {7'h0B, 16'hFC00, S2_CLKOUT1[31:16]};
    
          // Store CLKOUT2 divide and phase
          rom[28] = {7'h0C, 16'h1000, S2_CLKOUT2[15:0]};
          rom[29] = {7'h0D, 16'hFC00, S2_CLKOUT2[31:16]};
    
          // Store CLKOUT3 divide and phase
          rom[30] = {7'h0E, 16'h1000, S2_CLKOUT3[15:0]};
          rom[31] = {7'h0F, 16'hFC00, S2_CLKOUT3[31:16]};
    
          // Store CLKOUT4 divide and phase
          rom[32] = {7'h10, 16'h1000, S2_CLKOUT4[15:0]};
          rom[33] = {7'h11, 16'hFC00, S2_CLKOUT4[31:16]};
    
          // Store CLKOUT5 divide and phase
          rom[34] = {7'h06, 16'h1000, S2_CLKOUT5[15:0]};
          rom[35] = (S2_CLKOUT0_FRAC_EN == 0) ?
                    {7'h07, 16'hC000, S2_CLKOUT5[31:16]}:
                    {7'h07, 16'hC000, S2_CLKOUT5[31:30], S2_CLKOUT0_FRAC_CALC[35:32],S2_CLKOUT5[25:16]};
    
          // Store CLKOUT6 divide and phase
          rom[36] = {7'h12, 16'h1000, S2_CLKOUT6[15:0]};
          rom[37] = (S2_CLKFBOUT_FRAC_EN == 0) ?
                    {7'h13, 16'hC000, S2_CLKOUT6[31:16]}:
                    {7'h13, 16'hC000, S2_CLKOUT6[31:30], S2_CLKFBOUT_FRAC_CALC[35:32],S2_CLKOUT6[25:16]};
    
          // Store the input divider
          rom[38] = {7'h16, 16'hC000, {2'h0, S2_DIVCLK[23:22], S2_DIVCLK[11:0]} };
    
          // Store the feedback divide and phase
          rom[39] = (S2_CLKFBOUT_FRAC_EN == 0) ?
                    {7'h14, 16'h1000, S2_CLKFBOUT[15:0]}:
                    {7'h14, 16'h1000, S2_CLKFBOUT_FRAC_CALC[15:0]};
          rom[40] = (S2_CLKFBOUT_FRAC_EN == 0) ?
                    {7'h15, 16'h8000, S2_CLKFBOUT[31:16]}:
                    {7'h15, 16'h8000, S2_CLKFBOUT_FRAC_CALC[31:16]};
    
          // Store the lock settings
          rom[41] = {7'h18, 16'hFC00, {6'h00, S2_LOCK[29:20]} };
          rom[42] = {7'h19, 16'h8000, {1'b0 , S2_LOCK[34:30], S2_LOCK[9:0]} };
          rom[43] = {7'h1A, 16'h8000, {1'b0 , S2_LOCK[39:35], S2_LOCK[19:10]} };
    
          // Store the filter settings
          rom[44] = {7'h4E, 16'h66FF,
                    S2_DIGITAL_FILT[9], 2'h0, S2_DIGITAL_FILT[8:7], 2'h0,
                    S2_DIGITAL_FILT[6], 8'h00 };
          rom[45] = {7'h4F, 16'h666F,
                    S2_DIGITAL_FILT[5], 2'h0, S2_DIGITAL_FILT[4:3], 2'h0,
                    S2_DIGITAL_FILT[2:1], 2'h0, S2_DIGITAL_FILT[0], 4'h0 };
    
          // Initialize the rest of the ROM
          rom[46] = {7'h28,32'h0000_0000};
          for(ii = 47; ii < 64; ii = ii +1) begin
             rom[ii] = 0;
          end
       end
    I have been suggested to use a process as shown below, but this is not working for me.

    Code:
    type array_64x39 is array (63 downto 0) of std_logic_vector(38 DOWNTO 0);
    attribute rom_style : string;
    SIGNAL rom          : array_64x39 register;  
    attribute rom_style of rom : signal is "distributed";
    
    process
    begin
        -- Store the power bits
      rom(0)            <= "0101000" & x"0000" & x"FFFF";
      
      -- Store CLKOUT0 divide and phase
      S1_CLKOUT0_FRAC_A <= ("0001001" & x"8000" & S1_CLKOUT0(31 downto 16)) when S1_CLKOUT0_FRAC_EN = 0 else ("0001001" & x"8000" & S1_CLKOUT0_FRAC_CALC(31 downto 16));
      rom(1)            <= S1_CLKOUT0_FRAC_A;
      
      S1_CLKOUT0_FRAC_B <= ("0001000" & x"1000" & S1_CLKOUT0(15 downto 0)) when(S1_CLKOUT0_FRAC_EN = 0) else ("0001000" & x"1000" & S1_CLKOUT0_FRAC_CALC(15 downto 0));
      rom(2)            <= S1_CLKOUT0_FRAC_B;
      
      -- Store CLKOUT1 divide and phase
      rom(3)            <= "0001010" & x"1000" & S1_CLKOUT1(15 downto 0);
      rom(4)            <= "0001011" & x"FC00" & S1_CLKOUT1(31 downto 16);
      
      -- Store CLKOUT2 divide and phase
      rom(5)            <= "0001100" & x"1000" & S1_CLKOUT2(15 downto 0);
      rom(6)            <= "0001101" & x"FC00" & S1_CLKOUT2(31 downto 16);
      
      -- Store CLKOUT3 divide and phase
      rom(7)            <= "0001110" & x"1000" & S1_CLKOUT3(15 downto 0);
      rom(8)            <= "0001111" & x"FC00" & S1_CLKOUT3(31 downto 16);
      
      -- Store CLKOUT4 divide and phase
      rom(9)            <= "0010000" & x"1000" & S1_CLKOUT4(15 downto 0);
      rom(10)           <= "0010001" & x"FC00" & S1_CLKOUT4(31 downto 16);
      
      -- Store CLKOUT5 divide and phase
      rom(11)           <= "0000110" & x"1000" & S1_CLKOUT5(15 downto 0);
      S1_CLKOUT0_FRAC_C <= ("0000111" & x"C000" & S1_CLKOUT5(31 downto 16)) when (S1_CLKOUT0_FRAC_EN = 0) else ("0000111" & x"C000" & S1_CLKOUT5(31 downto 30) & S1_CLKOUT0_FRAC_CALC(35 downto 32) & S1_CLKOUT5(25 downto 16));
      rom(12)           <= S1_CLKOUT0_FRAC_C;
      
      -- Store CLKOUT6 divide and phase
      rom(13)           <= "0010010" & x"1000" & S1_CLKOUT6(15 downto 0);
      S1_CLKOUT0_FRAC_D <= ("0010011" & x"C000" & S1_CLKOUT6(31 downto 16)) when (S1_CLKFBOUT_FRAC_EN = 0) else ("0010011" & x"C000" & S1_CLKOUT6(31 downto 30) & S1_CLKFBOUT_FRAC_CALC(35 downto 32) & S1_CLKOUT6(25 downto 16));
      rom(14)           <=  S1_CLKOUT0_FRAC_D;
      
      -- Store the input divider
      rom(15)           <= "0010110" & x"C000" & ("00" & S1_DIVCLK(23 downto 22) & S1_DIVCLK(11 downto 0));
      
      -- Store the feedback divide and phase
      S1_CLKOUT0_FRAC_E <= ("0010100" & x"1000" & S1_CLKFBOUT(15 downto 0)) when (S1_CLKFBOUT_FRAC_EN = 0) else ("0010100" & x"1000" & S1_CLKFBOUT_FRAC_CALC(15 downto 0));
      rom(16)           <= S1_CLKOUT0_FRAC_E ;
      
      S1_CLKOUT0_FRAC_F <= ("0010011" & x"8000" & S1_CLKFBOUT(31 downto 16)) when (S1_CLKFBOUT_FRAC_EN = 0) else ("0010011" & x"8000" & S1_CLKFBOUT_FRAC_CALC(31 downto 16));  
      rom(17)           <=  S1_CLKOUT0_FRAC_F;
      
      -- Store the lock settings
      rom(18)           <= "0011000" & x"FC00" & ("000000" & S1_LOCK(29 downto 20));
      rom(19)           <= "0011001" & x"8000" & ('0'  & S1_LOCK(34 downto 30) & S1_LOCK(9 downto 0));
      rom(20)           <= "0011010" & x"8000" & ('0'  & S1_LOCK(39 downto 35) & S1_LOCK(19 downto 10));
      
      -- Store the filter settings
      rom(21)           <= "1001110" & x"66FF" & S1_DIGITAL_FILT(9) & "00" & S1_DIGITAL_FILT(8 downto 7) & "00" & S1_DIGITAL_FILT(6) & x"00";
      rom(22)           <= "1001111" & x"666F" & S1_DIGITAL_FILT(5) & "00" & S1_DIGITAL_FILT(4 downto 3) & "00" & S1_DIGITAL_FILT(2 downto 1) & "00" & S1_DIGITAL_FILT(0) & x"0" ;
      
      --***********************************************************************
      --State 2 Initialization
             --***********************************************************************
      -- Store the power bits
      rom(23)           <= "0101000" & x"0000" & x"FFFF";
      
      -- Store CLKOUT0 divide and phase
      S1_CLKOUT0_FRAC_G <=  ("0001001" & x"8000" & S2_CLKOUT0(31 downto 16))+8
       when (S2_CLKOUT0_FRAC_EN = 0) else ("0001001" & x"8000" & S2_CLKOUT0_FRAC_CALC(31 downto 16));
      rom(24)           <= S1_CLKOUT0_FRAC_G;
      
      S1_CLKOUT0_FRAC_H <= ("0001000" & x"1000" & S2_CLKOUT0(15 downto 0)) when (S2_CLKOUT0_FRAC_EN = 0) else ("0001000" & x"1000" & S2_CLKOUT0_FRAC_CALC(15 downto 0));
      rom(25)           <= S1_CLKOUT0_FRAC_H;
      
      -- Store CLKOUT1 divide and phase
      rom(26)           <= "0001010" & x"1000" & S2_CLKOUT1(15 downto 0);
      rom(27)           <= "0001011" & x"FC00" & S2_CLKOUT1(31 downto 16);
      
      -- Store CLKOUT2 divide and phase
      rom(28)           <= "0001100" & x"1000" & S2_CLKOUT2(15 downto 0);
      rom(29)           <= "0001101" & x"FC00" & S2_CLKOUT2(31 downto 16);
      
      -- Store CLKOUT3 divide and phase
      rom(30)           <= "0001110" & x"1000" & S2_CLKOUT3(15 downto 0);
      rom(31)           <= "0001111" & x"FC00" & S2_CLKOUT3(31 downto 16);
      
      -- Store CLKOUT4 divide and phase
      rom(32)           <= "0010000" & x"1000" & S2_CLKOUT4(15 downto 0);
      rom(33)           <= "0010001" & x"FC00" & S2_CLKOUT4(31 downto 16);
      
      -- Store CLKOUT5 divide and phase
      rom(34)           <= "0000110" & x"1000" & S2_CLKOUT5(15 downto 0);
      
      S1_CLKOUT0_FRAC_I <= ("0000111" & x"C000" & S2_CLKOUT5(31 downto 16)) when (S2_CLKOUT0_FRAC_EN = 0) else (x"0007" & x"C000" & S2_CLKOUT5(31 downto 30) & S2_CLKOUT0_FRAC_CALC(35 downto 32) & S2_CLKOUT5(25 downto 16));
      rom(35)           <= S1_CLKOUT0_FRAC_I;
      
      -- Store CLKOUT6 divide and phase
      rom(36)           <= "0010010" & x"1000" & S2_CLKOUT6(15 downto 0);
      
      S1_CLKOUT0_FRAC_J <= "0010011" & x"C000" & S2_CLKOUT6(31 downto 16) when (S2_CLKFBOUT_FRAC_EN = 0) else "0010011" & x"C000" & S2_CLKOUT6(31 downto 30) & S2_CLKFBOUT_FRAC_CALC(35 downto 32) & S2_CLKOUT6(25 downto 16);
      rom(37)           <= S1_CLKOUT0_FRAC_J;
      
      -- Store the input divider
      rom(38)           <= "0010110" & x"C000" & ("00" & S2_DIVCLK(23 downto 22) & S2_DIVCLK(11 downto 0));
      
      -- Store the feedback divide and phase
      S1_CLKOUT0_FRAC_K <= "0010100" & x"1000" & S2_CLKFBOUT(15 downto 0) when (S2_CLKFBOUT_FRAC_EN = 0) else "0010100" & x"1000" & S2_CLKFBOUT_FRAC_CALC(15 downto 0);
      rom(39)           <= S1_CLKOUT0_FRAC_K;
      
      S1_CLKOUT0_FRAC_L <= "0010101" & x"8000" & S2_CLKFBOUT(31 downto 16) when (S2_CLKFBOUT_FRAC_EN = 0) else "0010101" & x"8000" & S2_CLKFBOUT_FRAC_CALC(31 downto 16);                
      rom(40)           <= S1_CLKOUT0_FRAC_L;
      
      -- Store the lock settings
      rom(41)           <= "0011000" & x"FC00" & ("000000" & S2_LOCK(29 downto 20));
      rom(42)           <= "0011001" & x"8000" & ('0' & S2_LOCK(34 downto 30) & S2_LOCK(9 downto 0));
      rom(43)           <= "0011010" & x"8000" & ('0' & S2_LOCK(39 downto 35) & S2_LOCK(19 downto 10));
      
      -- Store the filter settings
      rom(44)           <= "1001110" & x"66FF" & S2_DIGITAL_FILT(9) & "00"  & S2_DIGITAL_FILT(8 downto 7)  & "00"  & S2_DIGITAL_FILT(6)  & x"00" ;
      rom(45)           <= "1001111" & x"666F"  & S2_DIGITAL_FILT(5)  & "00"  & S2_DIGITAL_FILT(4 downto 3)  & "00"  & S2_DIGITAL_FILT(2 downto 1)  & "00"  & S2_DIGITAL_FILT(0) & x"0";
      
      -- Initialize the rest of the ROM
      rom(46)           <= "0101000" & x"00000000";
      
        fill : for ii in 47 to 63 loop
          rom(ii) <= "000000000000000000000000000000000000000";
        end  loop fill;
    end process;
    Can someone help me with this problem please.

  2. #2
    Super Moderator
    Points: 261,421, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    45,677
    Helped
    13885 / 13885
    Points
    261,421
    Level
    100

    Re: What is the vhdl equivalent of "initial begin" to initialize a ROM.

    A process isn't the equivalent of an initial block, you should have an initializer for the signal array representing the rom. It may use a function generating the data.

    I'm not sure about the variable elements in your initial block. Are they parameters?



    •   AltAdvertisement

        
       

  3. #3
    Member level 2
    Points: 387, Level: 4

    Join Date
    Feb 2019
    Posts
    46
    Helped
    0 / 0
    Points
    387
    Level
    4

    Re: What is the vhdl equivalent of "initial begin" to initialize a ROM.

    Thanks for answering FvM, tell you that S1_CLKOUT0_FRAC_EN or S1_CLKOUT0 if they are parameters and S1_CLKOUT0_FRAC_A and others are signals that I had to create since I could not make a direct assignment to the rom.
    A question to your suggestion, how can I call this function to initialize the rom.



  4. #4
    Advanced Member level 5
    Points: 38,017, Level: 47
    Achievements:
    7 years registered

    Join Date
    Jun 2010
    Posts
    6,888
    Helped
    2025 / 2025
    Points
    38,017
    Level
    47

    Re: What is the vhdl equivalent of "initial begin" to initialize a ROM.

    you can call a function during initiialisation:

    Code VHDL - [expand]
    1
    2
    3
    4
    5
    6
    7
    
    function some_init_func return integer is
    begin
      return 10;
    end function;
     
    constant SOME_CONSTANT : integer := some_init_func;
    signal int_sig : integer := some_init_func;



  5. #5
    Super Moderator
    Points: 261,421, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    45,677
    Helped
    13885 / 13885
    Points
    261,421
    Level
    100

    Re: What is the vhdl equivalent of "initial begin" to initialize a ROM.

    you can call a function during initiialisation
    Typically, the initialisation function has an array result and sets the whole ROM at once. Inside the function, a for loop or case construct delivers the individual constant values.

    Alternatively, a ROM can be initialized in a generate loop, like below

    Code VHDL - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    -- uses parameters OLEN, ILEN, RLEN
    CONSTANT ROMSIZE : INTEGER  := 2**RLEN;
    CONSTANT ROMMAX : INTEGER  := 2**OLEN;
    CONSTANT ROMMAX : INTEGER  := 2**OLEN-ILEN;
    TYPE ATANTAB IS ARRAY(0 TO ROMSIZE-1) OF UNSIGNED (OLEN-1 DOWNTO 0);
    TYPE ATANTAB2 IS ARRAY(0 TO ROMSIZE-1) OF UNSIGNED (OLEN-RLEN DOWNTO 0);
    SIGNAL ATANROM : ATANTAB;
    SIGNAL ATANROM2 : ATANTAB2;
     
    BEGIN
    GENROM:
    FOR idx in 0 TO ROMSIZE-1 GENERATE
      CONSTANT x: REAL := ARCTAN(real(idx)/real(ROMSIZE))/MATH_PI_OVER_4;
      CONSTANT xn: UNSIGNED (OLEN-1 DOWNTO 0) := CONV_UNSIGNED(INTEGER(x*real(ROMMAX)),OLEN);
      CONSTANT x2: REAL := ARCTAN(real(idx+1)/real(ROMSIZE))/MATH_PI_OVER_4 - x;
      CONSTANT xn2: UNSIGNED (OLEN-RLEN DOWNTO 0) := CONV_UNSIGNED(INTEGER(x2*real(ROMMAX2)),OLEN-RLEN+1);
    BEGIN
      ATANROM(idx) <= UNSIGNED(xn); 
      ATANROM2(idx) <= UNSIGNED(xn2);   
    END GENERATE;

    S1_CLKOUT0_FRAC_A and others are signals that I had to create since I could not make a direct assignment to the rom.
    All ROM values must be known at compile time. They can depend on calculated constants, but not signals.



  6. #6
    Advanced Member level 5
    Points: 24,433, Level: 38
    barry's Avatar
    Join Date
    Mar 2005
    Location
    California, USA
    Posts
    4,690
    Helped
    1036 / 1036
    Points
    24,433
    Level
    38

    Re: What is the vhdl equivalent of "initial begin" to initialize a ROM.

    If it's a ROM, can't you just define it as an IP block that gets loaded during configuration? For example, with the Xilinx tools you would have a memory defined that uses a .coe file that contains the ROM values that gets read during compilation; there's no need to "initialize" the ROM in your code. That looks to me like writing to a RAM.



    •   AltAdvertisement

        
       

  7. #7
    Super Moderator
    Points: 261,421, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    45,677
    Helped
    13885 / 13885
    Points
    261,421
    Level
    100

    Re: What is the vhdl equivalent of "initial begin" to initialize a ROM.

    There are many possible reasons why you may want to describe the ROM content in HDL, e.g. use the language features to calculate a lookup table as in my previous snippet. Or using module parameters to modify the content, as Cesar0182 apparently wants. But also many possible reasons to generate the table with other tools and import it to the project. It really depends on the application.



    •   AltAdvertisement

        
       

  8. #8
    Advanced Member level 5
    Points: 24,433, Level: 38
    barry's Avatar
    Join Date
    Mar 2005
    Location
    California, USA
    Posts
    4,690
    Helped
    1036 / 1036
    Points
    24,433
    Level
    38

    Re: What is the vhdl equivalent of "initial begin" to initialize a ROM.

    Maybe just a minor point (depending on speed and utilization), but when it's implemented in the code, you now have to generate all the associated routing to handle writing. A ROM, by definition, does not have a write port, but what you've REALLY got is a RAM that's only written once, but it's still a RAM and it's going to require all the necessary overhead.



  9. #9
    Advanced Member level 5
    Points: 38,017, Level: 47
    Achievements:
    7 years registered

    Join Date
    Jun 2010
    Posts
    6,888
    Helped
    2025 / 2025
    Points
    38,017
    Level
    47

    Re: What is the vhdl equivalent of "initial begin" to initialize a ROM.

    Quote Originally Posted by barry View Post
    Maybe just a minor point (depending on speed and utilization), but when it's implemented in the code, you now have to generate all the associated routing to handle writing. A ROM, by definition, does not have a write port, but what you've REALLY got is a RAM that's only written once, but it's still a RAM and it's going to require all the necessary overhead.
    I dont quite know what you mean? A ROM in an FPGA is just a BRAM/M9k whatever thats pre-loaded with data with the write-port not connected. This can be infered from HDL as a constant with synchronous access:

    Code VHDL - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    constant SOME_ROM : slv_array_t := init_rom;
     
    ....
     
    process(clk)
    begin
      if rising_edge(clk)
        rom_op <= SOME_ROM(addr);
        -- no write logic in sight
      end if;
    end process;



  10. #10
    Advanced Member level 5
    Points: 24,433, Level: 38
    barry's Avatar
    Join Date
    Mar 2005
    Location
    California, USA
    Posts
    4,690
    Helped
    1036 / 1036
    Points
    24,433
    Level
    38

    Re: What is the vhdl equivalent of "initial begin" to initialize a ROM.

    Quote Originally Posted by TrickyDicky View Post
    I dont quite know what you mean? A ROM in an FPGA is just a BRAM/M9k whatever thats pre-loaded with data with the write-port not connected. This can be infered from HDL as a constant with synchronous access:

    Code VHDL - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    constant SOME_ROM : slv_array_t := init_rom;
     
    ....
     
    process(clk)
    begin
      if rising_edge(clk)
        rom_op <= SOME_ROM(addr);
        -- no write logic in sight
      end if;
    end process;
    I don't understand what you've got there. What is "rom_op" ? What is addr? Isn't that logic? How do you get data into a RAM without writing it? (To be honest, I don't actually know the mechanism of how "ROM" gets loaded from a bitfile.)

    If you have to write to that BRAM, you're going to need some logic, and you're going to need some routing connected to your logic. And it's going to have to meet timing.



  11. #11
    Super Moderator
    Points: 261,421, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    45,677
    Helped
    13885 / 13885
    Points
    261,421
    Level
    100

    Re: What is the vhdl equivalent of "initial begin" to initialize a ROM.

    It's surely possible to design a RAM that is loaded by the FPGA fabric at run time. However the ROM initialisation examples discussed in this thread don't involve write logic. Instead they infer a RAM preloaded from the configuration bitstream.



  12. #12
    Super Moderator
    Points: 31,842, Level: 43
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    7,369
    Helped
    1728 / 1728
    Points
    31,842
    Level
    43

    Re: What is the vhdl equivalent of "initial begin" to initialize a ROM.

    Quote Originally Posted by barry View Post
    (To be honest, I don't actually know the mechanism of how "ROM" gets loaded from a bitfile.)
    For both Xilinx and Altera the bitstreams include all the bit locations of the block RAMs in the devices. Specifically that is how Xilinx updates a bitfile with the software program for an embedded Microblaze design.



  13. #13
    Advanced Member level 5
    Points: 24,433, Level: 38
    barry's Avatar
    Join Date
    Mar 2005
    Location
    California, USA
    Posts
    4,690
    Helped
    1036 / 1036
    Points
    24,433
    Level
    38

    Re: What is the vhdl equivalent of "initial begin" to initialize a ROM.

    Quote Originally Posted by FvM View Post
    It's surely possible to design a RAM that is loaded by the FPGA fabric at run time. However the ROM initialisation examples discussed in this thread don't involve write logic. Instead they infer a RAM preloaded from the configuration bitstream.
    I don’t see how the example in #9 can load the ROM from the bit file; it uses a clock.



  14. #14
    Super Moderator
    Points: 31,842, Level: 43
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    7,369
    Helped
    1728 / 1728
    Points
    31,842
    Level
    43

    Re: What is the vhdl equivalent of "initial begin" to initialize a ROM.

    Quote Originally Posted by barry View Post
    I donít see how the example in #9 can load the ROM from the bit file; it uses a clock.
    That is how you would use access the ROM, as both Xilinx and Altera have to have a clock to their block RAMs. That code lacks any code for an init_rom function to initialize the ROM, which is in the example provided by FvM in #5 (though not implemented as a function).



    •   AltAdvertisement

        
       

  15. #15
    Super Moderator
    Points: 261,421, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    45,677
    Helped
    13885 / 13885
    Points
    261,421
    Level
    100

    Re: What is the vhdl equivalent of "initial begin" to initialize a ROM.

    I donít see how the example in #9 can load the ROM from the bit file; it uses a clock.
    The code only defines the ROM content. It's translated to a *.hex file by the FPGA synthesis tool and linked to the bit file. Hardware to load the bitfile into the RAM is already present in the FPGA, read the hardware manuals.



--[[ ]]--