Simple Dual-Port Asymmetric RAM When Write is Wider than Read (Verilog) - 2022.1 English

Vivado Design Suite User Guide: Synthesis (UG901)

Document ID
UG901
Release Date
2022-06-06
Version
2022.1 English

Filename: asym_ram_sdp_write_wider.v

 

 

// Asymmetric port RAM

// Write wider than Read. Write Statement in a loop.

// asym_ram_sdp_write_wider.v

 

module asym_ram_sdp_write_wider (clkA, clkB, weA, enaA, enaB, addrA, addrB, diA, doB);

parameter WIDTHB = 4;

parameter SIZEB = 1024;

parameter ADDRWIDTHB = 10;

 

parameter WIDTHA = 16;

parameter SIZEA = 256;

parameter ADDRWIDTHA = 8;

input clkA;

input clkB;

input weA;

input enaA, enaB;

input [ADDRWIDTHA-1:0] addrA;

input [ADDRWIDTHB-1:0] addrB;

input [WIDTHA-1:0] diA;

output [WIDTHB-1:0] doB;

`define max(a,b) {(a) > (b) ? (a) : (b)}

`define min(a,b) {(a) < (b) ? (a) : (b)}

 

function integer log2;

input integer value;

reg [31:0] shifted;

integer res;

begin

if (value < 2)

 log2 = value;

else

begin

 shifted = value-1;

 for (res=0; shifted>0; res=res+1)

  shifted = shifted>>1;

 log2 = res;

end

end

endfunction

 

localparam maxSIZE = `max(SIZEA, SIZEB);

localparam maxWIDTH = `max(WIDTHA, WIDTHB);

localparam minWIDTH = `min(WIDTHA, WIDTHB);

 

localparam RATIO = maxWIDTH / minWIDTH;

localparam log2RATIO = log2(RATIO);

 

reg [minWIDTH-1:0] RAM [0:maxSIZE-1];

reg [WIDTHB-1:0] readB;

 

always @(posedge clkB) begin

if (enaB) begin

 readB <= RAM[addrB];

 end

end

assign doB = readB;

 

always @(posedge clkA)

begin : ramwrite

integer i;

reg [log2RATIO-1:0] lsbaddr;

for (i=0; i< RATIO; i= i+ 1) begin : write1

 lsbaddr = i;

  if (enaA) begin

  if (weA)

   RAM[{addrA, lsbaddr}] <= diA[(i+1)*minWIDTH-1 -: minWIDTH];

  end

end

end

 

endmodule