True Dual Port Asymmetric RAM Read First (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_tdp_read_first.v

 

// Asymetric RAM - TDP  

// READ_FIRST MODE.

// asym_ram_tdp_read_first.v

 

 

module asym_ram_tdp_read_first (clkA, clkB, enaA, weA, enaB, weB, addrA, addrB, diA, doA, diB, 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, weB;

input enaA, enaB;

 

input [ADDRWIDTHA-1:0] addrA;

input [ADDRWIDTHB-1:0] addrB;

input [WIDTHA-1:0] diA;

input [WIDTHB-1:0] diB;

 

output [WIDTHA-1:0] doA;

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 [WIDTHA-1:0] readA;

reg [WIDTHB-1:0] readB;

 

always @(posedge clkB)

begin

if (enaB) begin

 readB <= RAM[addrB] ;

 if (weB)

  RAM[addrB] <= diB;

 end  

end

 

 

always @(posedge clkA)

begin : portA

integer i;

reg [log2RATIO-1:0] lsbaddr ;

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

  lsbaddr = i;

 if (enaA) begin

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

 

  if (weA)

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

 end

end

end

 

assign doA = readA;

assign doB = readB;

 

endmodule