+ Post New Thread
Results 1 to 11 of 11
  1. #1
    Newbie level 6
    Points: 135, Level: 1

    Join Date
    Apr 2018
    Posts
    13
    Helped
    0 / 0
    Points
    135
    Level
    1

    Writing a ROM in verilog

    Hello All!
    I am trying to write a 2D ROM in verilog
    it is 16 * 16 and each element has 1 byte
    I have felt a little bit dizzy about all websites I saw
    Here is the code
    Thanks for your help!
    Code:
    module Sub_byte(input wire [31:0] W,output reg [31:0] Wi);
    
    reg [7:0] s_box [15:0][15:0];
    
    
    initial
    begin
     	// first row 
    	s_box[0][0] = 8'h63;
    	s_box[0][1] = 8'h7C;
    	s_box[0][2] = 8'h77;
    	s_box[0][3] = 8'h7B;
    	s_box[0][4] = 8'hF2;
    	s_box[0][5] = 8'h6B;
    	s_box[0][6] = 8'h6F;
    	s_box[0][7] = 8'hC5;
    	s_box[0][8] = 8'h30;
    	s_box[0][9] = 8'h01;
    	s_box[0][10] = 8'h67;
    	s_box[0][11] = 8'h2B;
    	s_box[0][12] = 8'hFE;
    	s_box[0][13] = 8'hD7;
    	s_box[0][14] = 8'hAB;
    	s_box[0][15] = 8'h76;
    
    
     	// second row 
    	s_box[1][0] = 8'hCA;
    	s_box[1][1] = 8'h82;
    	s_box[1][2] = 8'hC9;
    	s_box[1][3] = 8'h7D;
    	s_box[1][4] = 8'hFA;
    	s_box[1][5] = 8'h59;
    	s_box[1][6] = 8'h47;
    	s_box[1][7] = 8'hF0;
    	s_box[1][8] = 8'hAD;
    	s_box[1][9] = 8'hD4;
    	s_box[1][10] = 8'hA2;
    	s_box[1][11] = 8'hAF;
    	s_box[1][12] = 8'h9C;
    	s_box[1][13] = 8'hA4;
    	s_box[1][14] = 8'h72;
    	s_box[1][15] = 8'hC0;
    
     	// third row 
    	s_box[2][0] = 8'hB7;
    	s_box[2][1] = 8'hFD;
    	s_box[2][2] = 8'h93;
    	s_box[2][3] = 8'h26;
    	s_box[2][4] = 8'h36;
    	s_box[2][5] = 8'h3F;
    	s_box[2][6] = 8'hF7;
    	s_box[2][7] = 8'hCC;
    	s_box[2][8] = 8'h34;
    	s_box[2][9] = 8'hA5;
    	s_box[2][10] = 8'hE5;
    	s_box[2][11] = 8'hF1;
    	s_box[2][12] = 8'h71;
    	s_box[2][13] = 8'hD8;
    	s_box[2][14] = 8'h31;
    	s_box[2][15] = 8'h15;
    
    
     	// fourth row 
    	s_box[3][0] = 8'h04;
    	s_box[3][1] = 8'hC7;
    	s_box[3][2] = 8'h23;
    	s_box[3][3] = 8'hC3;
    	s_box[3][4] = 8'h18;
    	s_box[3][5] = 8'h96;
    	s_box[3][6] = 8'h05;
    	s_box[3][7] = 8'h9A;
    	s_box[3][8] = 8'h07;
    	s_box[3][9] = 8'h12;
    	s_box[3][10] = 8'h80;
    	s_box[3][11] = 8'hE2;
    	s_box[3][12] = 8'hEB;
    	s_box[3][13] = 8'h27;
    	s_box[3][14] = 8'hB2;
    	s_box[3][15] = 8'h75;
    
    
    
     	// fifth row 
    	s_box[4][0] = 8'h09;
    	s_box[4][1] = 8'h83;
    	s_box[4][2] = 8'h2C;
    	s_box[4][3] = 8'h1A;
    	s_box[4][4] = 8'h1B;
    	s_box[4][5] = 8'h6E;
    	s_box[4][6] = 8'h5A;
    	s_box[4][7] = 8'hA0;
    	s_box[4][8] = 8'h52;
    	s_box[4][9] = 8'h3B;
    	s_box[4][10] = 8'hD6;
    	s_box[4][11] = 8'hB3;
    	s_box[4][12] = 8'h29;
    	s_box[4][13] = 8'h3E;
    	s_box[4][14] = 8'h2F;
    	s_box[4][15] = 8'h84;
    
    
    
     	// sixth row 
    	s_box[5][0]  = 8'h53;
    	s_box[5][1]  = 8'hD1;
    	s_box[5][2]  = 8'h00;
    	s_box[5][3]  = 8'hED;
    	s_box[5][4]  = 8'h20;
    	s_box[5][5]  = 8'hFC;
    	s_box[5][6]  = 8'hB1;
    	s_box[5][7]  = 8'h5B;
    	s_box[5][8]  = 8'h6A;
    	s_box[5][9]  = 8'hCB;
    	s_box[5][10] = 8'hBE;
    	s_box[5][11] = 8'h39;
    	s_box[5][12] = 8'h4A;
    	s_box[5][13] = 8'h4C;
    	s_box[5][14] = 8'h58;
    	s_box[5][15] = 8'hCF;
    
    
     	// seventh row 
    	s_box[6][0] = 8'hD0;
    	s_box[6][1] = 8'hEF;
    	s_box[6][2] = 8'hAA;
    	s_box[6][3] = 8'hFB;
    	s_box[6][4] = 8'h43;
    	s_box[6][5] = 8'h4D;
    	s_box[6][6] = 8'h33;
    	s_box[6][7] = 8'h85;
    	s_box[6][8] = 8'h45;
    	s_box[6][9] = 8'hF9;
    	s_box[6][10] = 8'h02;
    	s_box[6][11] = 8'h7F;
    	s_box[6][12] = 8'h50;
    	s_box[6][13] = 8'h3C;
    	s_box[6][14] = 8'h9F;
    	s_box[6][15] = 8'hA8;
    
     	// eighth row 
    	s_box[7][0] = 8'h51;
    	s_box[7][1] = 8'hA3;
    	s_box[7][2] = 8'h40;
    	s_box[7][3] = 8'h8F;
    	s_box[7][4] = 8'h92;
    	s_box[7][5] = 8'h9D;
    	s_box[7][6] = 8'h38;
    	s_box[7][7] = 8'hF5;
    	s_box[7][8] = 8'hBC;
    	s_box[7][9] = 8'hB6;
    	s_box[7][10] = 8'hDA;
    	s_box[7][11] = 8'h21;
    	s_box[7][12] = 8'h10;
    	s_box[7][13] = 8'hFF;
    	s_box[7][14] = 8'hF3;
    	s_box[7][15] = 8'hD2;
    
     	// ninth row 
    	s_box[8][0] = 8'hCD;
    	s_box[8][1] = 8'h0C;
    	s_box[8][2] = 8'h13;
    	s_box[8][3] = 8'hEC;
    	s_box[8][4] = 8'h5F;
    	s_box[8][5] = 8'h97;
    	s_box[8][6] = 8'h44;
    	s_box[8][7] = 8'h17;
    	s_box[8][8] = 8'hC4;
    	s_box[8][9] = 8'hA7;
    	s_box[8][10] = 8'h7E;
    	s_box[8][11] = 8'h3D;
    	s_box[8][12] = 8'h64;
    	s_box[8][13] = 8'h5D;
    	s_box[8][14] = 8'h19;
    	s_box[8][15] = 8'h73;
    
    
     	// tenth row 
    	s_box[9][0] = 8'h60;
    	s_box[9][1] = 8'h81;
    	s_box[9][2] = 8'h4F;
    	s_box[9][3] = 8'hDC;
    	s_box[9][4] = 8'h22;
    	s_box[9][5] = 8'h2A;
    	s_box[9][6] = 8'h90;
    	s_box[9][7] = 8'h88;
    	s_box[9][8] = 8'h46;
    	s_box[9][9] = 8'hEE;
    	s_box[9][10] = 8'hB8;
    	s_box[9][11] = 8'h14;
    	s_box[9][12] = 8'hDE;
    	s_box[9][13] = 8'h5E;
    	s_box[9][14] = 8'h0B;
    	s_box[9][15] = 8'hDB;
    
    
    
    	// eleventh row 
    	s_box[10][0] = 8'hE0;
    	s_box[10][1] = 8'h32;
    	s_box[10][2] = 8'h3A;
    	s_box[10][3] = 8'h0A;
    	s_box[10][4] = 8'h49;
    	s_box[10][5] = 8'h06;
    	s_box[10][6] = 8'h24;
    	s_box[10][7] = 8'h5C;
    	s_box[10][8] = 8'hC2;
    	s_box[10][9] = 8'hD3;
    	s_box[10][10] = 8'hAC;
    	s_box[10][11] = 8'h62;
    	s_box[10][12] = 8'h91;
    	s_box[10][13] = 8'h95;
    	s_box[10][14] = 8'hE4;
    	s_box[10][15] = 8'h79;
    
    	// twelveth row 
    	s_box[11][0] = 8'hE7;
    	s_box[11][1] = 8'hC8;
    	s_box[11][2] = 8'h37;
    	s_box[11][3] = 8'h6D;
    	s_box[11][4] = 8'h8D;
    	s_box[11][5] = 8'hD5;
    	s_box[11][6] = 8'h4E;
    	s_box[11][7] = 8'hA9;
    	s_box[11][8] = 8'h6C;
    	s_box[11][9] = 8'h56;
    	s_box[11][10] = 8'hF4;
    	s_box[11][11] = 8'hEA;
    	s_box[11][12] = 8'h65;
    	s_box[11][13] = 8'h7A;
    	s_box[11][14] = 8'hAE;
    	s_box[11][15] = 8'h08;
    
    
    	// thirteenth row 
    	s_box[12][0] = 8'hBA;
    	s_box[12][1] = 8'h78;
    	s_box[12][2] = 8'h25;
    	s_box[12][3] = 8'h2E;
    	s_box[12][4] = 8'h1C;
    	s_box[12][5] = 8'hA6;
    	s_box[12][6] = 8'hB4;
    	s_box[12][7] = 8'hC6;
    	s_box[12][8] = 8'hE8;
    	s_box[12][9] = 8'hDD;
    	s_box[12][10] = 8'h74;
    	s_box[12][11] = 8'h1F;
    	s_box[12][12] = 8'h4D;
    	s_box[12][13] = 8'hBD;
    	s_box[12][14] = 8'h8B;
    	s_box[12][15] = 8'h8A;
    
    	// fourteenth row 
    	s_box[13][0] = 8'h70;
    	s_box[13][1] = 8'h3E;
    	s_box[13][2] = 8'hB5;
    	s_box[13][3] = 8'h66;
    	s_box[13][4] = 8'h48;
    	s_box[13][5] = 8'h03;
    	s_box[13][6] = 8'hF6;
    	s_box[13][7] = 8'h0E;
    	s_box[13][8] = 8'h61;
    	s_box[13][9] = 8'h35;
    	s_box[13][10] = 8'h57;
    	s_box[13][11] = 8'hB9;
    	s_box[13][12] = 8'h86;
    	s_box[13][13] = 8'hC1;
    	s_box[13][14] = 8'h1D;
    	s_box[13][15] = 8'h9E;
    
    
    	//fifteenth row 
    	s_box[14][0] = 8'hE1;
    	s_box[14][1] = 8'hF8;
    	s_box[14][2] = 8'h98;
    	s_box[14][3] = 8'h11;
    	s_box[14][4] = 8'h69;
    	s_box[14][5] = 8'hD9;
    	s_box[14][6] = 8'h8E;
    	s_box[14][7] = 8'h94;
    	s_box[14][8] = 8'h9B;
    	s_box[14][9] = 8'h1E;
    	s_box[14][10] = 8'h87;
    	s_box[14][11] = 8'hE9;
    	s_box[14][12] = 8'hCE;
    	s_box[14][13] = 8'h55;
    	s_box[14][14] = 8'h28;
    	s_box[14][15] = 8'hDF;
    
    
    	// fifteenth row 
    	s_box[15][0] = 8'h8C;
    	s_box[15][1] = 8'hA1;
    	s_box[15][2] = 8'h89;
    	s_box[15][3] = 8'h8D;
    	s_box[15][4] = 8'hBF;
    	s_box[15][5] = 8'hE6;
    	s_box[15][6] = 8'h42;
    	s_box[15][7] = 8'h68;
    	s_box[15][8] = 8'h41;
    	s_box[15][9] = 8'h99;
    	s_box[15][10] = 8'h2D;
    	s_box[15][11] = 8'h0F;
    	s_box[15][12] = 8'hB0;
    	s_box[15][13] = 8'h54;
    	s_box[15][14] = 8'hBB;
    	s_box[15][15] = 8'h16;
    end
    
    
    // Loop 
    integer i ;
    
    always@(*) begin
    
    		Wi[7 :0 ] <= s_box [ W[7 :4] ][ W[ 3:0 ] ] ;
    		Wi[15:8 ] <= s_box [ W[15:12]][ W[11:8 ] ] ;
    		Wi[23:16] <= s_box [ W[23:20]][ W[19:16] ] ;
        Wi[31:24] <= s_box [ W[31:28]][ W[27:24] ] ;
     
      end
    endmodule

    •   AltAdvertisment

        
       

  2. #2
    Advanced Member level 5
    Points: 36,630, Level: 46
    Achievements:
    7 years registered

    Join Date
    Jun 2010
    Posts
    6,692
    Helped
    1950 / 1950
    Points
    36,630
    Level
    46

    Re: Writing a ROM in verilog

    And what is the problem?



  3. #3
    Newbie level 6
    Points: 135, Level: 1

    Join Date
    Apr 2018
    Posts
    13
    Helped
    0 / 0
    Points
    135
    Level
    1

    Re: Writing a ROM in verilog

    I think it is a 3D array and also I read in tutorials on verilog that initial block does not use in verilog



  4. #4
    Advanced Member level 3
    Points: 5,524, Level: 17

    Join Date
    Feb 2015
    Posts
    915
    Helped
    263 / 263
    Points
    5,524
    Level
    17

    Re: Writing a ROM in verilog

    Initial statements are sometimes supported for things like ROMs. For FPGA's, initial's are mostly supported for everything. However there are some specific cases that can cause simulation mismatch. In terms of rom implementations, you should double check if this will infer a ROM implemented in a good way. I could easily see some tools not liking 2-d arrays for ROMs and choosing to implement the ROM in a less efficient manner. But maybe your tools will work.

    s_box is a 2d array of 8 bit vectors.


    1 members found this post helpful.

  5. #5
    Newbie level 6
    Points: 135, Level: 1

    Join Date
    Apr 2018
    Posts
    13
    Helped
    0 / 0
    Points
    135
    Level
    1

    Re: Writing a ROM in verilog

    Thanks vGoodtimes for your comment but I have another question.
    How to know that my tool will implement my rom as a rom?
    I am using vivado 5.1



    •   AltAdvertisment

        
       

  6. #6
    Advanced Member level 5
    Points: 36,630, Level: 46
    Achievements:
    7 years registered

    Join Date
    Jun 2010
    Posts
    6,692
    Helped
    1950 / 1950
    Points
    36,630
    Level
    46

    Re: Writing a ROM in verilog

    Do you mean 2015.1? It's an old version, why not newest 18.2?

    Either way, why not just compile it and see if it works? Check the elaborated and synthesised netlists


    1 members found this post helpful.

  7. #7
    Super Moderator
    Points: 247,283, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    42,993
    Helped
    13084 / 13084
    Points
    247,283
    Level
    100

    Re: Writing a ROM in verilog

    The main problem is not in describing the ROM content but if the actual ROM usage is compatible with block RAM hardware properties. The block RAM of most FPGA families is synchronous and provides maximal two simultaneous useable ports.

    To allow ROM inference for the below code, it must be changed to a clocked always block and use at least two s_box instances in dual mode configuration.
    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    
    always@(*) begin
      Wi[7 :0 ] <= s_box [ W[7 :4] ][ W[ 3:0 ] ] ;
      Wi[15:8 ] <= s_box [ W[15:12]][ W[11:8 ] ] ;
      Wi[23:16] <= s_box [ W[23:20]][ W[19:16] ] ;
      Wi[31:24] <= s_box [ W[31:28]][ W[27:24] ] ;
    end



  8. #8
    Newbie level 6
    Points: 135, Level: 1

    Join Date
    Apr 2018
    Posts
    13
    Helped
    0 / 0
    Points
    135
    Level
    1

    Re: Writing a ROM in verilog

    Do you mean that I should put clock and reset?



  9. #9
    Super Moderator
    Points: 247,283, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    42,993
    Helped
    13084 / 13084
    Points
    247,283
    Level
    100

    Re: Writing a ROM in verilog

    You need at least one clocked register level between address input and output to allow ROM inference. The register is modelling the RAM address register which usually doesn't have a reset other than POR. Manufacturer tools may have specific syntax requirements for successful ROM inference, you better follow their design templates strictly.


    1 members found this post helpful.

  10. #10
    Super Moderator
    Points: 247,283, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    42,993
    Helped
    13084 / 13084
    Points
    247,283
    Level
    100

    Re: Writing a ROM in verilog

    The below code compiles fine with Quartus
    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    module Sub_byte(input clk, input wire [31:0] W,output reg [31:0] Wi);
      reg [7:0] s_box [15:0][15:0];
      reg [7:0] s_box2 [15:0][15:0];
     
      //...
      s_box[15][15] = 8'h16;
      s_box2 = s_box;
    end
     
    always@(posedge clk) begin
        Wi[7 :0 ] <= s_box [ W[7 :4] ][ W[ 3:0 ] ] ;
        Wi[15:8 ] <= s_box [ W[15:12]][ W[11:8 ] ] ;
        Wi[23:16] <= s_box2 [ W[23:20]][ W[19:16] ] ;
        Wi[31:24] <= s_box2 [ W[31:28]][ W[27:24] ] ;
      end
    endmodule



    •   AltAdvertisment

        
       

  11. #11
    Member level 4
    Points: 493, Level: 4
    Achievements:
    Created Blog entry

    Join Date
    Apr 2018
    Location
    Gdańsk, Poland
    Posts
    77
    Helped
    13 / 13
    Points
    493
    Level
    4
    Blog Entries
    3

    Re: Writing a ROM in verilog

    For instantiating ROMs you can check what templates already exist in the Xilinx Vivado IDE.
    In menu Edit->Language Templates.
    There are different templates in VHDL and Verilog.
    To encourage me to help more, click on "Helpful Post" if you feel that I've helped you.



--[[ ]]--