cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
kavinduvsomadas
Contributor
Contributor
466 Views
Registered: ‎08-28-2020

Simple dual port block ram issue

I tried to create a simple dual port ram using instantiation template code given for the block ram generator (v8.4) in Vivado with common clock configuration.
Port A - read first mode, always enabled
Port B - read first mode, ENB activated
 
BRAM configurations are also given below.
 
8 config 1.JPG9 config 2.JPG10 config 3.JPG
When I tried to simulate the BRAM, I observed that wea or wr_en sampled at negative edge and as a result, data value at the immediate positive clock edge will be written to the BRAM.
I found it when I was reading the written data from the BRAM. Please go through following image and I attached a waveform to get an idea about the issue.
 
Simulation waveform file (.wcfg) also added as a zipped-file.
 
7 bram issue.JPG
 
As you can see in the simulation waveform, at 165 ns, wea will be sampled at negative clock edge and as a result data_wr of 63 will be written at addr_wr of 1 in BRAM in the immediate positive clock edge.
Now if you check 240 ns, you can see 63 value has been read from the 1st location of the BRAM. I clearly don't understand this behaviour, since I haven't configured the BRAM to work with clock inversion. Therefore, it should clearly work with positive clock edge. 
 
Can anyone please tell me is it possible to sample write enable of port A at negative edge of the clock ?
I checked it in the pg058 user guide relevant for block ram generator, but didn't find any clue on that. 
 
Testbench code is given as follows for the above simulation graph.
 
module bram_tb();

    reg clk;
    reg [0:0] wr_en;  
    reg [13:0] addr_wr;
    reg [31:0] data_wr;
    
    reg rd_en;
    reg [13 : 0] addr_rd;
    wire [31 : 0] data_rd;

blk_mem_check bram_store_inst (
  .clka(clk),    // input wire clka
  .wea(wr_en),      // input wire [0 : 0] wea
  .addra(addr_wr),  // input wire [13 : 0] addra
  .dina(data_wr),    // input wire [31 : 0] dina
  .clkb(clk),    // input wire clkb
  .enb(rd_en),      // input wire enb
  .addrb(addr_rd),  // input wire [13 : 0] addrb
  .doutb(data_rd)  // output wire [31 : 0] doutb
);

    initial begin
        #10 clk = 1'b0;
        #10 wr_en = 1'b0; addr_wr = 14'd0; data_wr = 32'd0; addr_rd = 14'd0; rd_en = 1'b0;
        #100;
        #44 wr_en = 1'b1;
        #6 wr_en = 1'b1; addr_wr = 14'd1; data_wr = 32'd63; addr_rd = 14'd1; rd_en = 1'b0;
        #4 wr_en = 1'b0; addr_wr = 14'd0; data_wr = 32'd11; addr_rd = 14'd1; rd_en = 1'b0;
        #16 wr_en = 1'b1; addr_wr = 14'd2; data_wr = 32'd56; addr_rd = 14'd1; rd_en = 1'b0;
        #10 wr_en = 1'b0; addr_wr = 14'd3; data_wr = 32'd31; addr_rd = 14'd1; rd_en = 1'b0;
        #10 wr_en = 1'b0; addr_wr = 14'd4; data_wr = 32'd21; addr_rd = 14'd1; rd_en = 1'b1;
        #10 wr_en = 1'b0; addr_wr = 14'd5; data_wr = 32'd67; addr_rd = 14'd0; rd_en = 1'b1;
        #10 addr_rd = 14'd1; rd_en = 1'b1;
        #10 addr_rd = 14'd2; rd_en = 1'b1;
        #10 addr_rd = 14'd3; rd_en = 1'b1;
        #10 addr_rd = 14'd4; rd_en = 1'b1;
        #10 addr_rd = 14'd5; rd_en = 1'b1;
        
        
        #200 $finish;
    end
    
    always #5 clk = ~ clk;
    
    
endmodule
0 Kudos
0 Replies