element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Avnet Boards Forums
  • Products
  • Dev Tools
  • Avnet Boards Community
  • Avnet Boards Forums
  • More
  • Cancel
Avnet Boards Forums
ZedBoard Hardware Design Vivado BRAM Instantiation Issues
  • Forum
  • Documents
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Avnet Boards Forums to participate - click to join for free!
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • State Not Answered
  • Replies 0 replies
  • Subscribers 324 subscribers
  • Views 117 views
  • Users 0 members are here
  • zynq 7000
  • vivado
  • bram
Related

Vivado BRAM Instantiation Issues

dniemann17
dniemann17 2 months ago

Hello!

We are currently working on a project which requires us to extend a previously created memory interface on a ZedBoard from being 4k in size to 256k (A 1/4 of a MB). 
We had previously created a file, called pocket_core_top_mem.v which instantiated a 4k long memory (4 xilinx_tdpram_1024x36 modules) that has been working for the longest time. This old interface used only 4 blocks of 140 available Block RAM modules on the zedboard for the project (50 blocks are used elsewhere, leaving 86 remaining).

Fullscreen pocket_core_top_mem.v.txt Download
// Memory I/O for pocket_core_top

module pocket_core_top_mem
  (
  input              clk_bist,          // BIST clock
  input              reset_bist,   	    // Sync active high reset

  input              clk_axi,           // Clock for AXI4 domain
  input              reset_axi,         // Active high sync reset
  input wire         tdp_en_a,          // Enable operations RAM Port A
  input wire         tdp_en_b,          // Enable operations RAM Port B   
  input wire [3:0]   tdp_wren_a,        // Write Enables RAM Port A
  input wire [11:0]  tdp_addr_a,        // Address RAM Port A
  input wire [11:0]  tdp_addr_b,        // Address RAM Port B
  input wire [31:0]  tdp_din_a,         // Write Data RAM Port A
  input wire [31:0]  tdp_din_b,         // Write Data RAM Port B
  output wire [31:0] tdp_dout_a,        // Read Data RAM Port A
  output wire [31:0] tdp_dout_b			// Read Data RAM Port B
  );

// TDP Clk & Rst Port A
wire tdp_clk_a   = clk_axi;
wire tdp_reset_a = reset_axi;


// TDP Clk & Rst Port B
wire tdp_clk_b   = clk_bist;
wire tdp_reset_b = reset_bist;
wire [3:0] tdp_wren_b = {4{tdp_en_b}};

// TDP Byte Enable Port A
wire tdp_en_a_0 = tdp_en_a & ~tdp_addr_a[11] & ~tdp_addr_a[10];
wire tdp_en_a_1 = tdp_en_a & ~tdp_addr_a[11] &  tdp_addr_a[10];
wire tdp_en_a_2 = tdp_en_a &  tdp_addr_a[11] & ~tdp_addr_a[10];
wire tdp_en_a_3 = tdp_en_a &  tdp_addr_a[11] &  tdp_addr_a[10];

// TDP Byte Enable Port B
wire tdp_en_b_0 = tdp_en_b & ~tdp_addr_b[11] & ~tdp_addr_b[10];
wire tdp_en_b_1 = tdp_en_b & ~tdp_addr_b[11] &  tdp_addr_b[10];
wire tdp_en_b_2 = tdp_en_b &  tdp_addr_b[11] & ~tdp_addr_b[10];
wire tdp_en_b_3 = tdp_en_b &  tdp_addr_b[11] &  tdp_addr_b[10];

// Write Data RAM Port A
wire [35:0] int_tdp_din_a = {4'd0, tdp_din_a[31:0]};

// Write Data RAM Port B
wire [35:0] int_tdp_din_b = {4'd0, tdp_din_b[31:0]};

// Single Module Read Data RAM Port A
wire [35:0] int_tdp_dout_a_0;
wire [35:0] int_tdp_dout_a_1;
wire [35:0] int_tdp_dout_a_2;
wire [35:0] int_tdp_dout_a_3;

// Single Module Read Data RAM Port B
wire [35:0] int_tdp_dout_b_0;
wire [35:0] int_tdp_dout_b_1;
wire [35:0] int_tdp_dout_b_2;
wire [35:0] int_tdp_dout_b_3;

// Read Data RAM Port A
wire [35:0] int_tdp_dout_a = tdp_addr_a[11] ?
							(tdp_addr_a[10] ? int_tdp_dout_a_3 : int_tdp_dout_a_2 ) :
							(tdp_addr_a[10] ? int_tdp_dout_a_1 : int_tdp_dout_a_0 ) ;
							
// Read Data RAM Port B
wire [35:0] int_tdp_dout_b = tdp_addr_b[11] ?
							(tdp_addr_b[10] ? int_tdp_dout_b_3 : int_tdp_dout_b_2 ) :
							(tdp_addr_b[10] ? int_tdp_dout_b_1 : int_tdp_dout_b_0 ) ;
						 

// Assign Outputs
assign tdp_dout_a[31:0] = int_tdp_dout_a[31:0];
assign tdp_dout_b[31:0] = int_tdp_dout_b[31:0];



xilinx_tdpram_1024x36 RAM_I_0 (
   .clk_a   (tdp_clk_a)        // input         Clock Port A
  ,.reset_a (tdp_reset_a)      // input         Sync active high reset
  ,.en_a    (tdp_en_a_0)       // input         Enable operations Port A
  ,.regce_a (1'b0)             // input         Output Register Clock Enable Port A - Not using OutReg
  ,.wren_a  (tdp_wren_a[3:0])  // input   [3:0] Write Enables Port A
  ,.addr_a  (tdp_addr_a[9:0])  // input   [9:0] Address Port A
  ,.din_a   (int_tdp_din_a[35:0])  // input  [35:0] Data Port A
  ,.dout_a  (int_tdp_dout_a_0[35:0]) // output [35:0] Data Port A

  ,.clk_b   (tdp_clk_b)        // input         Clock Port B
  ,.reset_b (tdp_reset_b)  	   // input         Sync active high reset
  ,.en_b    (tdp_en_b_0)       // input         Enable operations Port B
  ,.regce_b (1'b0)             // input         Output Register Clock Enable Port B
  ,.wren_b  (tdp_wren_b[3:0])  // input   [3:0] Write Enables Port B
  ,.addr_b  (tdp_addr_b[9:0])  // input   [9:0] Address Port B
  ,.din_b   (int_tdp_din_b[35:0])  // input  [35:0] Data Port B
  ,.dout_b  (int_tdp_dout_b_0[35:0]) // output [35:0] Data Port B
);

xilinx_tdpram_1024x36 RAM_I_1 (
   .clk_a   (tdp_clk_a)        // input         Clock Port A
  ,.reset_a (tdp_reset_a)      // input         Sync active high reset
  ,.en_a    (tdp_en_a_1)       // input         Enable operations Port A
  ,.regce_a (1'b0)             // input         Output Register Clock Enable Port A - Not using OutReg
  ,.wren_a  (tdp_wren_a[3:0])  // input   [3:0] Write Enables Port A
  ,.addr_a  (tdp_addr_a[9:0])  // input   [9:0] Address Port A
  ,.din_a   (int_tdp_din_a[35:0])  // input  [35:0] Data Port A
  ,.dout_a  (int_tdp_dout_a_1[35:0]) // output [35:0] Data Port A

  ,.clk_b   (tdp_clk_b)        // input         Clock Port B
  ,.reset_b (tdp_reset_b)  	   // input         Sync active high reset
  ,.en_b    (tdp_en_b_1)       // input         Enable operations Port B
  ,.regce_b (1'b0)             // input         Output Register Clock Enable Port B
  ,.wren_b  (tdp_wren_b[3:0])  // input   [3:0] Write Enables Port B
  ,.addr_b  (tdp_addr_b[9:0])  // input   [9:0] Address Port B
  ,.din_b   (int_tdp_din_b[35:0])  // input  [35:0] Data Port B
  ,.dout_b  (int_tdp_dout_b_1[35:0]) // output [35:0] Data Port B
);

xilinx_tdpram_1024x36 RAM_I_2 (
   .clk_a   (tdp_clk_a)        // input         Clock Port A
  ,.reset_a (tdp_reset_a)      // input         Sync active high reset
  ,.en_a    (tdp_en_a_2)       // input         Enable operations Port A
  ,.regce_a (1'b0)             // input         Output Register Clock Enable Port A - Not using OutReg
  ,.wren_a  (tdp_wren_a[3:0])  // input   [3:0] Write Enables Port A
  ,.addr_a  (tdp_addr_a[9:0])  // input   [9:0] Address Port A
  ,.din_a   (int_tdp_din_a[35:0])  // input  [35:0] Data Port A
  ,.dout_a  (int_tdp_dout_a_2[35:0]) // output [35:0] Data Port A

  ,.clk_b   (tdp_clk_b)        // input         Clock Port B
  ,.reset_b (tdp_reset_b)  	   // input         Sync active high reset
  ,.en_b    (tdp_en_b_2)       // input         Enable operations Port B
  ,.regce_b (1'b0)             // input         Output Register Clock Enable Port B
  ,.wren_b  (tdp_wren_b[3:0])  // input   [3:0] Write Enables Port B
  ,.addr_b  (tdp_addr_b[9:0])  // input   [9:0] Address Port B
  ,.din_b   (int_tdp_din_b[35:0])  // input  [35:0] Data Port B
  ,.dout_b  (int_tdp_dout_b_2[35:0]) // output [35:0] Data Port B
);

xilinx_tdpram_1024x36 RAM_I_3 (
   .clk_a   (tdp_clk_a)        // input         Clock Port A
  ,.reset_a (tdp_reset_a)      // input         Sync active high reset
  ,.en_a    (tdp_en_a_3)       // input         Enable operations Port A
  ,.regce_a (1'b0)             // input         Output Register Clock Enable Port A - Not using OutReg
  ,.wren_a  (tdp_wren_a[3:0])  // input   [3:0] Write Enables Port A
  ,.addr_a  (tdp_addr_a[9:0])  // input   [9:0] Address Port A
  ,.din_a   (int_tdp_din_a[35:0])  // input  [35:0] Data Port A
  ,.dout_a  (int_tdp_dout_a_3[35:0]) // output [35:0] Data Port A

  ,.clk_b   (tdp_clk_b)        // input         Clock Port B
  ,.reset_b (tdp_reset_b)      // input         Sync active high reset
  ,.en_b    (tdp_en_b_3)       // input         Enable operations Port B
  ,.regce_b (1'b0)             // input         Output Register Clock Enable Port B
  ,.wren_b  (tdp_wren_b[3:0])  // input   [3:0] Write Enables Port B
  ,.addr_b  (tdp_addr_b[9:0])  // input   [9:0] Address Port B
  ,.din_b   (int_tdp_din_b[35:0])  // input  [35:0] Data Port B
  ,.dout_b  (int_tdp_dout_b_3[35:0]) // output [35:0] Data Port B
);


endmodule // pocket_core_top_mem

While doing this, we simply started by trying to nest multiple memory files (using xilinx_tdpram_1024x36 modules), where we would have a .v file and module for 16k ram (4 4k modules), a file for 64k ram (4 16k modules), and finally a top file which consisted of 4 64k modules. (called pocket_core_mem_16k.v, pocket_core_mem_64k.v, and pocket_core_top_mem_nested.v here).
Fullscreen pocket_core_mem_16k.v.txt Download
// Memory I/O for pocket_core_mem_16k

module pocket_core_mem_16k
  (
  input              rx_clk,          // BIST clock
  input              reset_bist,   	    // Sync active high reset

  input              clk_axi,           // Clock for AXI4 domain
  input              reset_axi,         // Active high sync reset
  input wire         tdp_en_a,          // Enable operations RAM Port A
  input wire         tdp_en_b,          // Enable operations RAM Port B   
  input wire [3:0]   tdp_wren_a,        // Write Enables RAM Port A
  input wire [11:0]  tdp_addr_a,        // Address RAM Port A
  input wire [11:0]  tdp_addr_b,        // Address RAM Port B
  input wire [31:0]  tdp_din_a,         // Write Data RAM Port A
  input wire [31:0]  tdp_din_b,         // Write Data RAM Port B
  output wire [31:0] tdp_dout_a,        // Read Data RAM Port A
  output wire [31:0] tdp_dout_b			// Read Data RAM Port B
  );

// TDP Clk & Rst Port A
wire tdp_clk_a   = clk_axi;
wire tdp_reset_a = reset_axi;


// TDP Clk & Rst Port B
wire tdp_clk_b   = rx_clk;
wire tdp_reset_b = reset_bist;
wire [3:0] tdp_wren_b = {4{tdp_en_b}};

// RAM Select MUX Signal
reg [1:0] ram_sel_a = 2'b00;
reg [1:0] ram_sel_b = 2'b00;

// TDP Byte Enable Port A
wire tdp_en_a_0 = tdp_en_a & ~tdp_addr_a[11] & ~tdp_addr_a[10];
wire tdp_en_a_1 = tdp_en_a & ~tdp_addr_a[11] &  tdp_addr_a[10];
wire tdp_en_a_2 = tdp_en_a &  tdp_addr_a[11] & ~tdp_addr_a[10];
wire tdp_en_a_3 = tdp_en_a &  tdp_addr_a[11] &  tdp_addr_a[10];

// TDP Byte Enable Port B
wire tdp_en_b_0 = tdp_en_b & ~tdp_addr_b[11] & ~tdp_addr_b[10];
wire tdp_en_b_1 = tdp_en_b & ~tdp_addr_b[11] &  tdp_addr_b[10];
wire tdp_en_b_2 = tdp_en_b &  tdp_addr_b[11] & ~tdp_addr_b[10];
wire tdp_en_b_3 = tdp_en_b &  tdp_addr_b[11] &  tdp_addr_b[10];

// Write Data RAM Port A
wire [35:0] int_tdp_din_a = {4'd0, tdp_din_a[31:0]};

// Write Data RAM Port B
wire [35:0] int_tdp_din_b = {4'd0, tdp_din_b[31:0]};

// Single Module Read Data RAM Port A
wire [35:0] int_tdp_dout_a_0;
wire [35:0] int_tdp_dout_a_1;
wire [35:0] int_tdp_dout_a_2;
wire [35:0] int_tdp_dout_a_3;

// Single Module Read Data RAM Port B
wire [35:0] int_tdp_dout_b_0;
wire [35:0] int_tdp_dout_b_1;
wire [35:0] int_tdp_dout_b_2;
wire [35:0] int_tdp_dout_b_3;

// Read Data RAM Port A
wire [35:0] int_tdp_dout_a = ram_sel_a[1] ?
							(ram_sel_a[0] ? int_tdp_dout_a_3 : int_tdp_dout_a_2 ) :
							(ram_sel_a[0] ? int_tdp_dout_a_1 : int_tdp_dout_a_0 ) ;
							
// Read Data RAM Port B
wire [35:0] int_tdp_dout_b = ram_sel_b[1] ?
							(ram_sel_b[0] ? int_tdp_dout_b_3 : int_tdp_dout_b_2 ) :
							(ram_sel_b[0] ? int_tdp_dout_b_1 : int_tdp_dout_b_0 ) ;
						 

// Assign Outputs
assign tdp_dout_a[31:0] = int_tdp_dout_a[31:0];
assign tdp_dout_b[31:0] = int_tdp_dout_b[31:0];



xilinx_tdpram_1024x36 RAM_I_0 (
   .clk_a   (tdp_clk_a)        // input         Clock Port A
  ,.reset_a (tdp_reset_a)      // input         Sync active high reset
  ,.en_a    (tdp_en_a_0)       // input         Enable operations Port A
  ,.regce_a (1'b0)             // input         Output Register Clock Enable Port A - Not using OutReg
  ,.wren_a  (tdp_wren_a[3:0])  // input   [3:0] Write Enables Port A
  ,.addr_a  (tdp_addr_a[9:0])  // input   [9:0] Address Port A
  ,.din_a   (int_tdp_din_a[35:0])  // input  [35:0] Data Port A
  ,.dout_a  (int_tdp_dout_a_0[35:0]) // output [35:0] Data Port A

  ,.clk_b   (tdp_clk_b)        // input         Clock Port B
  ,.reset_b (tdp_reset_b)  	   // input         Sync active high reset
  ,.en_b    (tdp_en_b_0)       // input         Enable operations Port B
  ,.regce_b (1'b0)             // input         Output Register Clock Enable Port B
  ,.wren_b  (tdp_wren_b[3:0])  // input   [3:0] Write Enables Port B
  ,.addr_b  (tdp_addr_b[9:0])  // input   [9:0] Address Port B
  ,.din_b   (int_tdp_din_b[35:0])  // input  [35:0] Data Port B
  ,.dout_b  (int_tdp_dout_b_0[35:0]) // output [35:0] Data Port B
);

xilinx_tdpram_1024x36 RAM_I_1 (
   .clk_a   (tdp_clk_a)        // input         Clock Port A
  ,.reset_a (tdp_reset_a)      // input         Sync active high reset
  ,.en_a    (tdp_en_a_1)       // input         Enable operations Port A
  ,.regce_a (1'b0)             // input         Output Register Clock Enable Port A - Not using OutReg
  ,.wren_a  (tdp_wren_a[3:0])  // input   [3:0] Write Enables Port A
  ,.addr_a  (tdp_addr_a[9:0])  // input   [9:0] Address Port A
  ,.din_a   (int_tdp_din_a[35:0])  // input  [35:0] Data Port A
  ,.dout_a  (int_tdp_dout_a_1[35:0]) // output [35:0] Data Port A

  ,.clk_b   (tdp_clk_b)        // input         Clock Port B
  ,.reset_b (tdp_reset_b)  	   // input         Sync active high reset
  ,.en_b    (tdp_en_b_1)       // input         Enable operations Port B
  ,.regce_b (1'b0)             // input         Output Register Clock Enable Port B
  ,.wren_b  (tdp_wren_b[3:0])  // input   [3:0] Write Enables Port B
  ,.addr_b  (tdp_addr_b[9:0])  // input   [9:0] Address Port B
  ,.din_b   (int_tdp_din_b[35:0])  // input  [35:0] Data Port B
  ,.dout_b  (int_tdp_dout_b_1[35:0]) // output [35:0] Data Port B
);

xilinx_tdpram_1024x36 RAM_I_2 (
   .clk_a   (tdp_clk_a)        // input         Clock Port A
  ,.reset_a (tdp_reset_a)      // input         Sync active high reset
  ,.en_a    (tdp_en_a_2)       // input         Enable operations Port A
  ,.regce_a (1'b0)             // input         Output Register Clock Enable Port A - Not using OutReg
  ,.wren_a  (tdp_wren_a[3:0])  // input   [3:0] Write Enables Port A
  ,.addr_a  (tdp_addr_a[9:0])  // input   [9:0] Address Port A
  ,.din_a   (int_tdp_din_a[35:0])  // input  [35:0] Data Port A
  ,.dout_a  (int_tdp_dout_a_2[35:0]) // output [35:0] Data Port A

  ,.clk_b   (tdp_clk_b)        // input         Clock Port B
  ,.reset_b (tdp_reset_b)  	   // input         Sync active high reset
  ,.en_b    (tdp_en_b_2)       // input         Enable operations Port B
  ,.regce_b (1'b0)             // input         Output Register Clock Enable Port B
  ,.wren_b  (tdp_wren_b[3:0])  // input   [3:0] Write Enables Port B
  ,.addr_b  (tdp_addr_b[9:0])  // input   [9:0] Address Port B
  ,.din_b   (int_tdp_din_b[35:0])  // input  [35:0] Data Port B
  ,.dout_b  (int_tdp_dout_b_2[35:0]) // output [35:0] Data Port B
);

xilinx_tdpram_1024x36 RAM_I_3 (
   .clk_a   (tdp_clk_a)        // input         Clock Port A
  ,.reset_a (tdp_reset_a)      // input         Sync active high reset
  ,.en_a    (tdp_en_a_3)       // input         Enable operations Port A
  ,.regce_a (1'b0)             // input         Output Register Clock Enable Port A - Not using OutReg
  ,.wren_a  (tdp_wren_a[3:0])  // input   [3:0] Write Enables Port A
  ,.addr_a  (tdp_addr_a[9:0])  // input   [9:0] Address Port A
  ,.din_a   (int_tdp_din_a[35:0])  // input  [35:0] Data Port A
  ,.dout_a  (int_tdp_dout_a_3[35:0]) // output [35:0] Data Port A

  ,.clk_b   (tdp_clk_b)        // input         Clock Port B
  ,.reset_b (tdp_reset_b)      // input         Sync active high reset
  ,.en_b    (tdp_en_b_3)       // input         Enable operations Port B
  ,.regce_b (1'b0)             // input         Output Register Clock Enable Port B
  ,.wren_b  (tdp_wren_b[3:0])  // input   [3:0] Write Enables Port B
  ,.addr_b  (tdp_addr_b[9:0])  // input   [9:0] Address Port B
  ,.din_b   (int_tdp_din_b[35:0])  // input  [35:0] Data Port B
  ,.dout_b  (int_tdp_dout_b_3[35:0]) // output [35:0] Data Port B
);


always @(posedge tdp_clk_a)
  begin
    if(tdp_reset_a)
      begin
        ram_sel_a[1:0] <= 2'b00;
      end
    else if(tdp_en_a)
      begin
        ram_sel_a[1:0] <= tdp_addr_a[11:10];
      end
  end

always @(posedge tdp_clk_b)
  begin
    if(tdp_reset_b)
      begin
        ram_sel_b[1:0] <= 2'b00;
      end
    else if(tdp_en_b)
      begin
        ram_sel_b[1:0] <= tdp_addr_b[11:10];
      end
  end


endmodule // pocket_core_mem_16k
Fullscreen pocket_core_mem_64k.v.txt Download
// Memory I/O for pocket_core_mem_64k

module pocket_core_mem_64k
  (
  input              rx_clk,            // BIST clock
  input              reset_bist,   	    // Sync active high reset

  input              clk_axi,           // Clock for AXI4 domain
  input              reset_axi,         // Active high sync reset
  input wire         tdp_en_a,          // Enable operations RAM Port A
  input wire         tdp_en_b,          // Enable operations RAM Port B   
  input wire [3:0]   tdp_wren_a,        // Write Enables RAM Port A
  input wire [13:0]  tdp_addr_a,        // Address RAM Port A
  input wire [13:0]  tdp_addr_b,        // Address RAM Port B
  input wire [31:0]  tdp_din_a,         // Write Data RAM Port A
  input wire [31:0]  tdp_din_b,         // Write Data RAM Port B
  output wire [31:0] tdp_dout_a,        // Read Data RAM Port A
  output wire [31:0] tdp_dout_b			// Read Data RAM Port B
  );

// TDP Clk & Rst Port A
wire tdp_clk_a   = clk_axi;
wire tdp_reset_a = reset_axi;

// TDP Clk & Rst Port B
wire tdp_clk_b   = rx_clk;
wire tdp_reset_b = reset_bist;

// RAM Select MUX Signal
reg [1:0] ram_sel_a = 2'b00;
reg [1:0] ram_sel_b = 2'b00;

// TDP Byte Enable Port A
wire tdp_en_a_0 = tdp_en_a & ~tdp_addr_a[13] & ~tdp_addr_a[12];
wire tdp_en_a_1 = tdp_en_a & ~tdp_addr_a[13] &  tdp_addr_a[12];
wire tdp_en_a_2 = tdp_en_a &  tdp_addr_a[13] & ~tdp_addr_a[12];
wire tdp_en_a_3 = tdp_en_a &  tdp_addr_a[13] &  tdp_addr_a[12];

// TDP Byte Enable Port B
wire tdp_en_b_0 = tdp_en_b & ~tdp_addr_b[13] & ~tdp_addr_b[12];
wire tdp_en_b_1 = tdp_en_b & ~tdp_addr_b[13] &  tdp_addr_b[12];
wire tdp_en_b_2 = tdp_en_b &  tdp_addr_b[13] & ~tdp_addr_b[12];
wire tdp_en_b_3 = tdp_en_b &  tdp_addr_b[13] &  tdp_addr_b[12];

// Write Data RAM Port A
//wire [35:0] int_tdp_din_a = {4'd0, tdp_din_a[31:0]};

// Write Data RAM Port B
//wire [35:0] int_tdp_din_b = {4'd0, tdp_din_b[31:0]};

// Single Module Read Data RAM Port A
wire [31:0] int_tdp_dout_a_0;
wire [31:0] int_tdp_dout_a_1;
wire [31:0] int_tdp_dout_a_2;
wire [31:0] int_tdp_dout_a_3;

// Single Module Read Data RAM Port B
wire [31:0] int_tdp_dout_b_0;
wire [31:0] int_tdp_dout_b_1;
wire [31:0] int_tdp_dout_b_2;
wire [31:0] int_tdp_dout_b_3;

// Read Data RAM Port A
wire [31:0] int_tdp_dout_a = ram_sel_a[1] ?
							(ram_sel_a[0] ? int_tdp_dout_a_3 : int_tdp_dout_a_2 ) :
							(ram_sel_a[0] ? int_tdp_dout_a_1 : int_tdp_dout_a_0 ) ;
							
// Read Data RAM Port B
wire [31:0] int_tdp_dout_b = ram_sel_b[1] ?
							(ram_sel_b[0] ? int_tdp_dout_b_3 : int_tdp_dout_b_2 ) :
							(ram_sel_b[0] ? int_tdp_dout_b_1 : int_tdp_dout_b_0 ) ;
						 

// Assign Outputs
assign tdp_dout_a[31:0] = int_tdp_dout_a[31:0];
assign tdp_dout_b[31:0] = int_tdp_dout_b[31:0];



pocket_core_mem_16k RAM_16K_0 (
   .rx_clk      (tdp_clk_b)               // input         Clock Port B
  ,.reset_bist  (tdp_reset_b)             // input         Sync active high reset
  ,.clk_axi     (tdp_clk_a)               // input         Clock Port A
  ,.reset_axi   (tdp_reset_a)             // input         Sync active high reset

  ,.tdp_en_a    (tdp_en_a_0)              // input         Enable operations Port A
  ,.tdp_en_b    (tdp_en_b_0)              // input         Enable operations Port B
  ,.tdp_wren_a  (tdp_wren_a[3:0])         // input   [3:0] Write Enables Port A
  ,.tdp_addr_a  (tdp_addr_a[11:0])        // input  [11:0] Address Port A
  ,.tdp_addr_b  (tdp_addr_b[11:0])        // input  [11:0] Address Port B
  ,.tdp_din_a   (tdp_din_a[31:0])         // input  [31:0] Data Port A
  ,.tdp_din_b   (tdp_din_b[31:0])         // input  [31:0] Data Port B
  ,.tdp_dout_a  (int_tdp_dout_a_0[31:0])  // output [35:0] Data Port A
  ,.tdp_dout_b  (int_tdp_dout_b_0[31:0])  // output [35:0] Data Port B
);

pocket_core_mem_16k RAM_16K_1 (
   .rx_clk      (tdp_clk_b)               // input         Clock Port B
  ,.reset_bist  (tdp_reset_b)             // input         Sync active high reset
  ,.clk_axi     (tdp_clk_a)               // input         Clock Port A
  ,.reset_axi   (tdp_reset_a)             // input         Sync active high reset

  ,.tdp_en_a    (tdp_en_a_1)              // input         Enable operations Port A
  ,.tdp_en_b    (tdp_en_b_1)              // input         Enable operations Port B
  ,.tdp_wren_a  (tdp_wren_a[3:0])         // input   [3:0] Write Enables Port A
  ,.tdp_addr_a  (tdp_addr_a[11:0])        // input  [11:0] Address Port A
  ,.tdp_addr_b  (tdp_addr_b[11:0])        // input  [11:0] Address Port B
  ,.tdp_din_a   (tdp_din_a[31:0])         // input  [31:0] Data Port A
  ,.tdp_din_b   (tdp_din_b[31:0])         // input  [31:0] Data Port B
  ,.tdp_dout_a  (int_tdp_dout_a_1[31:0])  // output [31:0] Data Port A
  ,.tdp_dout_b  (int_tdp_dout_b_1[31:0])  // output [31:0] Data Port B
);

pocket_core_mem_16k RAM_16K_2 (
   .rx_clk      (tdp_clk_b)               // input         Clock Port B
  ,.reset_bist  (tdp_reset_b)             // input         Sync active high reset
  ,.clk_axi     (tdp_clk_a)               // input         Clock Port A
  ,.reset_axi   (tdp_reset_a)             // input         Sync active high reset

  ,.tdp_en_a    (tdp_en_a_2)              // input         Enable operations Port A
  ,.tdp_en_b    (tdp_en_b_2)              // input         Enable operations Port B
  ,.tdp_wren_a  (tdp_wren_a[3:0])         // input   [3:0] Write Enables Port A
  ,.tdp_addr_a  (tdp_addr_a[11:0])        // input  [11:0] Address Port A
  ,.tdp_addr_b  (tdp_addr_b[11:0])        // input  [11:0] Address Port B
  ,.tdp_din_a   (tdp_din_a[31:0])         // input  [31:0] Data Port A
  ,.tdp_din_b   (tdp_din_b[31:0])         // input  [31:0] Data Port B
  ,.tdp_dout_a  (int_tdp_dout_a_2[31:0])  // output [31:0] Data Port A
  ,.tdp_dout_b  (int_tdp_dout_b_2[31:0])  // output [31:0] Data Port B
);

pocket_core_mem_16k RAM_16K_3 (
   .rx_clk      (tdp_clk_b)               // input         Clock Port B
  ,.reset_bist  (tdp_reset_b)             // input         Sync active high reset
  ,.clk_axi     (tdp_clk_a)               // input         Clock Port A
  ,.reset_axi   (tdp_reset_a)             // input         Sync active high reset

  ,.tdp_en_a    (tdp_en_a_3)              // input         Enable operations Port A
  ,.tdp_en_b    (tdp_en_b_3)              // input         Enable operations Port B
  ,.tdp_wren_a  (tdp_wren_a[3:0])         // input   [3:0] Write Enables Port A
  ,.tdp_addr_a  (tdp_addr_a[11:0])        // input  [11:0] Address Port A
  ,.tdp_addr_b  (tdp_addr_b[11:0])        // input  [11:0] Address Port B
  ,.tdp_din_a   (tdp_din_a[31:0])         // input  [31:0] Data Port A
  ,.tdp_din_b   (tdp_din_b[31:0])         // input  [31:0] Data Port B
  ,.tdp_dout_a  (int_tdp_dout_a_3[31:0])  // output [31:0] Data Port A
  ,.tdp_dout_b  (int_tdp_dout_b_3[31:0])  // output [31:0] Data Port B
);

always @(posedge tdp_clk_a)
  begin
    if(tdp_reset_a)
      begin
        ram_sel_a[1:0] <= 2'b00;
      end
    else if(tdp_en_a)
      begin
        ram_sel_a[1:0] <= tdp_addr_a[13:12];
      end
  end

always @(posedge tdp_clk_b)
  begin
    if(tdp_reset_b)
      begin
        ram_sel_b[1:0] <= 2'b00;
      end
    else if(tdp_en_b)
      begin
        ram_sel_b[1:0] <= tdp_addr_b[13:12];
      end
  end

endmodule // pocket_core_mem_64k
Fullscreen pocket_core_top_mem_nested.v.txt Download
// Memory I/O for pocket_core_top

module pocket_core_top_mem
  (
  input              rx_clk,          // BIST clock
  input              reset_bist,   	    // Sync active high reset

  input              clk_axi,           // Clock for AXI4 domain
  input              reset_axi,         // Active high sync reset
  input wire         tdp_en_a,          // Enable operations RAM Port A
  input wire         tdp_en_b,          // Enable operations RAM Port B   
  input wire [3:0]   tdp_wren_a,        // Write Enables RAM Port A
  input wire [15:0]  tdp_addr_a,        // Address RAM Port A
  input wire [15:0]  tdp_addr_b,        // Address RAM Port B
  input wire [31:0]  tdp_din_a,         // Write Data RAM Port A
  input wire [31:0]  tdp_din_b,         // Write Data RAM Port B
  output wire [31:0] tdp_dout_a,        // Read Data RAM Port A
  output wire [31:0] tdp_dout_b			    // Read Data RAM Port B
  );

// TDP Clk & Rst Port A
wire tdp_clk_a   = clk_axi;
wire tdp_reset_a = reset_axi;

// RAM Select MUX Signal
reg [1:0] ram_sel_a = 2'b00;
reg [1:0] ram_sel_b = 2'b00;

// TDP Clk & Rst Port B
wire tdp_clk_b   = rx_clk;
wire tdp_reset_b = reset_bist;
//wire [3:0] tdp_wren_b = {4{tdp_en_b}};

// TDP Byte Enable Port A
wire tdp_en_a_0 = tdp_en_a & ~tdp_addr_a[15] & ~tdp_addr_a[14];
wire tdp_en_a_1 = tdp_en_a & ~tdp_addr_a[15] &  tdp_addr_a[14];
wire tdp_en_a_2 = tdp_en_a &  tdp_addr_a[15] & ~tdp_addr_a[14];
wire tdp_en_a_3 = tdp_en_a &  tdp_addr_a[15] &  tdp_addr_a[14];

// TDP Byte Enable Port B
wire tdp_en_b_0 = tdp_en_b & ~tdp_addr_b[15] & ~tdp_addr_b[14];
wire tdp_en_b_1 = tdp_en_b & ~tdp_addr_b[15] &  tdp_addr_b[14];
wire tdp_en_b_2 = tdp_en_b &  tdp_addr_b[15] & ~tdp_addr_b[14];
wire tdp_en_b_3 = tdp_en_b &  tdp_addr_b[15] &  tdp_addr_b[14];

// Write Data RAM Port A
//wire [35:0] int_tdp_din_a = {4'd0, tdp_din_a[31:0]};

// Write Data RAM Port B
//wire [35:0] int_tdp_din_b = {4'd0, tdp_din_b[31:0]};

// Single Module Read Data RAM Port A
wire [31:0] int_tdp_dout_a_0;
wire [31:0] int_tdp_dout_a_1;
wire [31:0] int_tdp_dout_a_2;
wire [31:0] int_tdp_dout_a_3;

// Single Module Read Data RAM Port B
wire [31:0] int_tdp_dout_b_0;
wire [31:0] int_tdp_dout_b_1;
wire [31:0] int_tdp_dout_b_2;
wire [31:0] int_tdp_dout_b_3;

// Read Data RAM Port A
wire [31:0] int_tdp_dout_a = ram_sel_a[1] ?
							(ram_sel_a[0] ? int_tdp_dout_a_3 : int_tdp_dout_a_2 ) :
							(ram_sel_a[0] ? int_tdp_dout_a_1 : int_tdp_dout_a_0 ) ;
							
// Read Data RAM Port B
wire [31:0] int_tdp_dout_b = ram_sel_b[1] ?
							(ram_sel_b[0] ? int_tdp_dout_b_3 : int_tdp_dout_b_2 ) :
							(ram_sel_b[0] ? int_tdp_dout_b_1 : int_tdp_dout_b_0 ) ;
						 

// Assign Outputs
assign tdp_dout_a[31:0] = int_tdp_dout_a[31:0];
assign tdp_dout_b[31:0] = int_tdp_dout_b[31:0];


pocket_core_mem_64k RAM_64K_0 (
   .rx_clk      (tdp_clk_b)               // input         Clock Port B
  ,.reset_bist  (tdp_reset_b)             // input         Sync active high reset
  ,.clk_axi     (tdp_clk_a)               // input         Clock Port A
  ,.reset_axi   (tdp_reset_a)             // input         Sync active high reset

  ,.tdp_en_a    (tdp_en_a_0)              // input         Enable operations Port A
  ,.tdp_en_b    (tdp_en_b_0)              // input         Enable operations Port B
  ,.tdp_wren_a  (tdp_wren_a[3:0])         // input   [3:0] Write Enables Port A
  ,.tdp_addr_a  (tdp_addr_a[13:0])        // input  [13:0] Address Port A
  ,.tdp_addr_b  (tdp_addr_b[13:0])        // input  [13:0] Address Port B
  ,.tdp_din_a   (tdp_din_a[31:0])         // input  [31:0] Data Port A
  ,.tdp_din_b   (tdp_din_b[31:0])         // input  [31:0] Data Port B
  ,.tdp_dout_a  (int_tdp_dout_a_0[31:0])  // output [31:0] Data Port A
  ,.tdp_dout_b  (int_tdp_dout_b_0[31:0])  // output [31:0] Data Port B
);

pocket_core_mem_64k RAM_64K_1 (
   .rx_clk      (tdp_clk_b)               // input         Clock Port B
  ,.reset_bist  (tdp_reset_b)             // input         Sync active high reset
  ,.clk_axi     (tdp_clk_a)               // input         Clock Port A
  ,.reset_axi   (tdp_reset_a)             // input         Sync active high reset

  ,.tdp_en_a    (tdp_en_a_1)              // input         Enable operations Port A
  ,.tdp_en_b    (tdp_en_b_1)              // input         Enable operations Port B
  ,.tdp_wren_a  (tdp_wren_a[3:0])         // input   [3:0] Write Enables Port A
  ,.tdp_addr_a  (tdp_addr_a[13:0])        // input  [13:0] Address Port A
  ,.tdp_addr_b  (tdp_addr_b[13:0])        // input  [13:0] Address Port B
  ,.tdp_din_a   (tdp_din_a[31:0])         // input  [31:0] Data Port A
  ,.tdp_din_b   (tdp_din_b[31:0])         // input  [31:0] Data Port B
  ,.tdp_dout_a  (int_tdp_dout_a_1[31:0])  // output [31:0] Data Port A
  ,.tdp_dout_b  (int_tdp_dout_b_1[31:0])  // output [31:0] Data Port B
);

pocket_core_mem_64k RAM_64K_2 (
   .rx_clk      (tdp_clk_b)               // input         Clock Port B
  ,.reset_bist  (tdp_reset_b)             // input         Sync active high reset
  ,.clk_axi     (tdp_clk_a)               // input         Clock Port A
  ,.reset_axi   (tdp_reset_a)             // input         Sync active high reset

  ,.tdp_en_a    (tdp_en_a_2)              // input         Enable operations Port A
  ,.tdp_en_b    (tdp_en_b_2)              // input         Enable operations Port B
  ,.tdp_wren_a  (tdp_wren_a[3:0])         // input   [3:0] Write Enables Port A
  ,.tdp_addr_a  (tdp_addr_a[13:0])        // input  [13:0] Address Port A
  ,.tdp_addr_b  (tdp_addr_b[13:0])        // input  [13:0] Address Port B
  ,.tdp_din_a   (tdp_din_a[31:0])         // input  [31:0] Data Port A
  ,.tdp_din_b   (tdp_din_b[31:0])         // input  [31:0] Data Port B
  ,.tdp_dout_a  (int_tdp_dout_a_2[31:0])  // output [31:0] Data Port A
  ,.tdp_dout_b  (int_tdp_dout_b_2[31:0])  // output [31:0] Data Port B
);

pocket_core_mem_64k RAM_64K_3 (
   .rx_clk      (tdp_clk_b)               // input         Clock Port B
  ,.reset_bist  (tdp_reset_b)             // input         Sync active high reset
  ,.clk_axi     (tdp_clk_a)               // input         Clock Port A
  ,.reset_axi   (tdp_reset_a)             // input         Sync active high reset

  ,.tdp_en_a    (tdp_en_a_3)              // input         Enable operations Port A
  ,.tdp_en_b    (tdp_en_b_3)              // input         Enable operations Port B
  ,.tdp_wren_a  (tdp_wren_a[3:0])         // input   [3:0] Write Enables Port A
  ,.tdp_addr_a  (tdp_addr_a[13:0])        // input  [13:0] Address Port A
  ,.tdp_addr_b  (tdp_addr_b[13:0])        // input  [13:0] Address Port B
  ,.tdp_din_a   (tdp_din_a[31:0])         // input  [31:0] Data Port A
  ,.tdp_din_b   (tdp_din_b[31:0])         // input  [31:0] Data Port B
  ,.tdp_dout_a  (int_tdp_dout_a_3[31:0])  // output [31:0] Data Port A
  ,.tdp_dout_b  (int_tdp_dout_b_3[31:0])  // output [31:0] Data Port B
);

always @(posedge tdp_clk_a)
  begin
    if(tdp_reset_a)
      begin
        ram_sel_a[1:0] <= 2'b00;
      end
    else if(tdp_en_a)
      begin
        ram_sel_a[1:0] <= tdp_addr_a[15:14];
      end
  end

always @(posedge tdp_clk_b)
  begin
    if(tdp_reset_b)
      begin
        ram_sel_b[1:0] <= 2'b00;
      end
    else if(tdp_en_b)
      begin
        ram_sel_b[1:0] <= tdp_addr_b[15:14];
      end
  end

endmodule // pocket_core_top_mem

Unfortunately, when we went to build the project, it ran through with no errors and wrote the bitstream but unfortunately only 2 RAM blocks were instantiated in the implemented design and I was only able to read and write to 0x100 of the memory space I programmed in. In Vivado, it was only reporting that 51 of the 140 RAM blocks were instantiated.
So, I then created and ran a simulation in Icarus Verilog on my files to see if I could indeed read and write to the higher address blocks. This simulation worked and proved my files didn't have a design error.

I was dumbstruck and thought it was how Vivado interpreted my file methodology that was making the error occur. So, I then simply made a single file (named pocket_core_top_mem_single.v here) with 64 xilinx_tdpram_1024x36 modules in it. 
This STILL only had 2 RAM blocks instantiated when Vivado finished building and writing the bitstream:
image
I also ran simulations to confirm if this file worked or not, and they confirmed the file worked.
pocket_core_top_mem_single.v.txt

Would there be anything that could be preventing Vivado from instantiating these 64 BRAM blocks that I may have missed?

Regards,
Daniel

  • Sign in to reply
  • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube