You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Vivado Design Suite User Guide: Synthesis (UG901)
-- Byte Write Enable—True Dual Port with Byte-Wide Write Enable (Verilog)
`ifdef BSV_ASSIGNMENT_DELAY
`else
`define BSV_ASSIGNMENT_DELAY
`endif
// Dual-Ported BRAM (WRITE FIRST) with byte enables
module BRAM2BE(CLKA,
ENA,
WEA,
ADDRA,
DIA,
DOA,
CLKB,
ENB,
WEB,
ADDRB,
DIB,
DOB
);
parameter PIPELINED = 0;
parameter ADDR_WIDTH = 1;
parameter DATA_WIDTH = 1;
parameter CHUNKSIZE = 1;
parameter WE_WIDTH = 1;
parameter MEMSIZE = 1;
input CLKA;
input ENA;
input [WE_WIDTH-1:0] WEA;
input [ADDR_WIDTH-1:0] ADDRA;
input [DATA_WIDTH-1:0] DIA;
output [DATA_WIDTH-1:0] DOA;
input CLKB;
input ENB;
input [WE_WIDTH-1:0] WEB;
input [ADDR_WIDTH-1:0] ADDRB;
input [DATA_WIDTH-1:0] DIB;
output [DATA_WIDTH-1:0] DOB;
(* RAM_STYLE = "BLOCK" *)
reg [DATA_WIDTH-1:0] RAM[0:MEMSIZE-1] /* synthesis syn_ramstyle="no_rw_check" */ ;
reg [DATA_WIDTH-1:0] DOA_R;
reg [DATA_WIDTH-1:0] DOA_R2;
reg [DATA_WIDTH-1:0] DOB_R;
reg [DATA_WIDTH-1:0] DOB_R2;
`ifdef BSV_NO_INITIAL_BLOCKS
`else
// synopsys translate_off
integer i;
initial
begin : init_block
for (i = 0; i < MEMSIZE; i = i + 1) begin
RAM[i] = { ((DATA_WIDTH+1)/2) { 2'b10 } };
end
DOA_R = { ((DATA_WIDTH+1)/2) { 2'b10 } };
DOA_R2 = { ((DATA_WIDTH+1)/2) { 2'b10 } };
DOB_R = { ((DATA_WIDTH+1)/2) { 2'b10 } };
DOB_R2 = { ((DATA_WIDTH+1)/2) { 2'b10 } };
end
// synopsys translate_on
`endif // !`ifdef BSV_NO_INITIAL_BLOCKS
// PORT A
integer j;
always @(posedge CLKA) begin
if (ENA) begin
for(j = 0; j < WE_WIDTH; j = j + 1) begin: porta_we
if (WEA[j]) begin
RAM[ADDRA][j*CHUNKSIZE+:CHUNKSIZE] = `BSV_ASSIGNMENT_DELAY DIA[j*CHUNKSIZE+:CHUNKSIZE];
end
end
DOA_R = `BSV_ASSIGNMENT_DELAY RAM[ADDRA];
end
end
// PORT B
integer k;
always @(posedge CLKB) begin
if (ENB) begin
for(k = 0; k < WE_WIDTH; k = k + 1) begin: portb_we
if (WEB[k]) begin
RAM[ADDRB][k*CHUNKSIZE+:CHUNKSIZE] = `BSV_ASSIGNMENT_DELAY DIB[k*CHUNKSIZE+:CHUNKSIZE];
end
end
DOB_R = `BSV_ASSIGNMENT_DELAY RAM[ADDRB];
end
end
// Output drivers
always @(posedge CLKA) begin
DOA_R2 <= `BSV_ASSIGNMENT_DELAY DOA_R;
end
always @(posedge CLKB) begin
DOB_R2 <= `BSV_ASSIGNMENT_DELAY DOB_R;
end
assign DOA = (PIPELINED) ? DOA_R2 : DOA_R;
assign DOB = (PIPELINED) ? DOB_R2 : DOB_R;
endmodule // BRAM2BE
When the DATA_WIDTH is set to 16 and the WE_WIDTH is set to 2, the WE mapping on RAMB18E2 should be 'b11, but the result is only 'b1.
As a consequence, bits[15:8] cannot be written into the memory.
Strangely, when the DATA_WIDTH is set to 24, this problem does not occur.
The text was updated successfully, but these errors were encountered:
ChienTeLi
changed the title
Unexpected BRAM2BE synthesis results in Vivado
Unexpected BRAM2BE synthesis results in Vivado 2022.2
Apr 9, 2025
In the port A/B always blocks, the choice between non-blocking or blocking assignments for RAM and DOA_R/DOB_R signals determines whether the port operates in READ_FIRST mode or WRITE_FIRST mode.
I tried to synthesize a module in Vivado, but I found that the synthesis result of BRAM2BE is not as expected.
As shown in the code, the synthesis results are compared below.
Using original BRAM2BE.v from https://github.com/B-Lang-org/bsc/blob/main/src/Verilog.Vivado/BRAM2BE.v
Using modified BRAM2BE.v which references:
-- Byte Write Enable—True Dual Port with Byte-Wide Write Enable (Verilog)
When the DATA_WIDTH is set to 16 and the WE_WIDTH is set to 2, the WE mapping on RAMB18E2 should be 'b11, but the result is only 'b1.
As a consequence, bits[15:8] cannot be written into the memory.
Strangely, when the DATA_WIDTH is set to 24, this problem does not occur.
The text was updated successfully, but these errors were encountered: