diff --git a/library/common/ad_mem_asym.v b/library/common/ad_mem_asym.v index 3b5639948..b43196902 100644 --- a/library/common/ad_mem_asym.v +++ b/library/common/ad_mem_asym.v @@ -45,29 +45,51 @@ module ad_mem_asym #( parameter B_ADDRESS_WIDTH = 10, parameter B_DATA_WIDTH = 64) ( - input clka, - input wea, - input [A_ADDRESS_WIDTH-1:0] addra, - input [A_DATA_WIDTH-1:0] dina, + input clka, + input wea, + input [A_ADDRESS_WIDTH-1:0] addra, + input [A_DATA_WIDTH-1:0] dina, - input clkb, - input [B_ADDRESS_WIDTH-1:0] addrb, - output reg [B_DATA_WIDTH-1:0] doutb); + input clkb, + input reb, + input [B_ADDRESS_WIDTH-1:0] addrb, + output reg [B_DATA_WIDTH-1:0] doutb); - localparam MEM_ADDRESS_WIDTH = (A_ADDRESS_WIDTH > B_ADDRESS_WIDTH) ? A_ADDRESS_WIDTH : B_ADDRESS_WIDTH; - localparam MEM_DATA_WIDTH = (A_DATA_WIDTH > B_DATA_WIDTH) ? B_DATA_WIDTH : A_DATA_WIDTH; + `define max(a,b) {(a) > (b) ? (a) : (b)} + `define min(a,b) {(a) < (b) ? (a) : (b)} + + function integer clog2; + input integer value; + begin + if (value < 2) + clog2 = value; + else begin + value = value - 1; + for (clog2 = 0; value > 0; clog2 = clog2 + 1) + value = value >> 1; + end + end + endfunction + + localparam MEM_ADDRESS_WIDTH = `max(A_ADDRESS_WIDTH, B_ADDRESS_WIDTH); + localparam MIN_WIDTH = `min(A_DATA_WIDTH, B_DATA_WIDTH); + localparam MAX_WIDTH = `max(A_DATA_WIDTH, B_DATA_WIDTH); + localparam MEM_DATA_WIDTH = MIN_WIDTH; localparam MEM_SIZE = 2 ** MEM_ADDRESS_WIDTH; - localparam MEM_RATIO = (A_DATA_WIDTH > B_DATA_WIDTH) ? A_DATA_WIDTH/B_DATA_WIDTH : B_DATA_WIDTH/A_DATA_WIDTH; - localparam MEM_IO_COMP = (A_DATA_WIDTH > B_DATA_WIDTH) ? 1'b1 : 1'b0; + localparam MEM_RATIO = MAX_WIDTH / MIN_WIDTH; + localparam MEM_RATIO_LOG2 = clog2(MEM_RATIO); // internal registers - reg [MEM_DATA_WIDTH-1:0] m_ram[0:MEM_SIZE-1]; + reg [MEM_DATA_WIDTH-1:0] m_ram[0:MEM_SIZE-1]; - // write interface options + //--------------------------------------------------------------------------- + // write interface + //--------------------------------------------------------------------------- - generate if (MEM_IO_COMP == 0) begin + // write data width is narrower than read data width + generate if (A_DATA_WIDTH <= B_DATA_WIDTH) begin always @(posedge clka) begin if (wea == 1'b1) begin m_ram[addra] <= dina; @@ -76,85 +98,50 @@ module ad_mem_asym #( end endgenerate - generate if ((MEM_IO_COMP == 1) && (MEM_RATIO == 2)) begin - always @(posedge clka) begin - if (wea == 1'b1) begin - m_ram[{addra, 1'd0}] <= dina[((1*B_DATA_WIDTH)-1):(B_DATA_WIDTH*0)]; - m_ram[{addra, 1'd1}] <= dina[((2*B_DATA_WIDTH)-1):(B_DATA_WIDTH*1)]; + // write data width is wider than read data width + generate if (A_DATA_WIDTH > B_DATA_WIDTH) begin + always @(posedge clka) begin : memwrite + integer i; + reg [MEM_RATIO_LOG2-1:0] lsb; + for (i = 0; i < MEM_RATIO; i = i + 1) begin : awrite + lsb = i; + if (wea) begin + m_ram[{addra, lsb}] <= dina[i * MIN_WIDTH +: MIN_WIDTH]; + end end end end endgenerate - generate if ((MEM_IO_COMP == 1) && (MEM_RATIO == 4)) begin - always @(posedge clka) begin - if (wea == 1'b1) begin - m_ram[{addra, 2'd0}] <= dina[((1*B_DATA_WIDTH)-1):(B_DATA_WIDTH*0)]; - m_ram[{addra, 2'd1}] <= dina[((2*B_DATA_WIDTH)-1):(B_DATA_WIDTH*1)]; - m_ram[{addra, 2'd2}] <= dina[((3*B_DATA_WIDTH)-1):(B_DATA_WIDTH*2)]; - m_ram[{addra, 2'd3}] <= dina[((4*B_DATA_WIDTH)-1):(B_DATA_WIDTH*3)]; + //--------------------------------------------------------------------------- + // read interface + //--------------------------------------------------------------------------- + + // read data width is narrower than write data width + generate if (A_DATA_WIDTH >= B_DATA_WIDTH) begin + always @(posedge clkb) begin + if (reb == 1'b1) begin + doutb <= m_ram[addrb]; end end end endgenerate - generate if ((MEM_IO_COMP == 1) && (MEM_RATIO == 8)) begin - always @(posedge clka) begin - if (wea == 1'b1) begin - m_ram[{addra, 3'd0}] <= dina[((1*B_DATA_WIDTH)-1):(B_DATA_WIDTH*0)]; - m_ram[{addra, 3'd1}] <= dina[((2*B_DATA_WIDTH)-1):(B_DATA_WIDTH*1)]; - m_ram[{addra, 3'd2}] <= dina[((3*B_DATA_WIDTH)-1):(B_DATA_WIDTH*2)]; - m_ram[{addra, 3'd3}] <= dina[((4*B_DATA_WIDTH)-1):(B_DATA_WIDTH*3)]; - m_ram[{addra, 3'd4}] <= dina[((5*B_DATA_WIDTH)-1):(B_DATA_WIDTH*4)]; - m_ram[{addra, 3'd5}] <= dina[((6*B_DATA_WIDTH)-1):(B_DATA_WIDTH*5)]; - m_ram[{addra, 3'd6}] <= dina[((7*B_DATA_WIDTH)-1):(B_DATA_WIDTH*6)]; - m_ram[{addra, 3'd7}] <= dina[((8*B_DATA_WIDTH)-1):(B_DATA_WIDTH*7)]; + // read data width is wider than write data width + generate if (A_DATA_WIDTH < B_DATA_WIDTH) begin + always @(posedge clkb) begin : memread + integer i; + reg [MEM_RATIO_LOG2-1:0] lsb; + for (i = 0; i < MEM_RATIO; i = i + 1) begin : aread + lsb = i; + if (reb == 1'b1) begin + doutb[i*MIN_WIDTH +: MIN_WIDTH] <= m_ram[{addrb, lsb}]; + end end end end endgenerate - // read interface options - - generate if ((MEM_IO_COMP == 1) || (MEM_RATIO == 1)) begin - always @(posedge clkb) begin - doutb <= m_ram[addrb]; - end - end - endgenerate - - generate if ((MEM_IO_COMP == 0) && (MEM_RATIO == 2)) begin - always @(posedge clkb) begin - doutb <= {m_ram[{addrb, 1'd1}], - m_ram[{addrb, 1'd0}]}; - end - end - endgenerate - - generate if ((MEM_IO_COMP == 0) && (MEM_RATIO == 4)) begin - always @(posedge clkb) begin - doutb <= {m_ram[{addrb, 2'd3}], - m_ram[{addrb, 2'd2}], - m_ram[{addrb, 2'd1}], - m_ram[{addrb, 2'd0}]}; - end - end - endgenerate - - generate if ((MEM_IO_COMP == 0) && (MEM_RATIO == 8)) begin - always @(posedge clkb) begin - doutb <= {m_ram[{addrb, 3'd7}], - m_ram[{addrb, 3'd6}], - m_ram[{addrb, 3'd5}], - m_ram[{addrb, 3'd4}], - m_ram[{addrb, 3'd3}], - m_ram[{addrb, 3'd2}], - m_ram[{addrb, 3'd1}], - m_ram[{addrb, 3'd0}]}; - end - end - endgenerate - endmodule // *************************************************************************** diff --git a/library/util_adcfifo/util_adcfifo.v b/library/util_adcfifo/util_adcfifo.v index a048d9524..94d266edc 100644 --- a/library/util_adcfifo/util_adcfifo.v +++ b/library/util_adcfifo/util_adcfifo.v @@ -213,6 +213,7 @@ module util_adcfifo #( .addra (adc_waddr_int), .dina (adc_wdata_int), .clkb (dma_clk), + .reb (1'b1), .addrb (dma_raddr), .doutb (dma_rdata_s)); end diff --git a/library/xilinx/axi_adcfifo/axi_adcfifo_dma.v b/library/xilinx/axi_adcfifo/axi_adcfifo_dma.v index 40a074bc6..998722a1a 100644 --- a/library/xilinx/axi_adcfifo/axi_adcfifo_dma.v +++ b/library/xilinx/axi_adcfifo/axi_adcfifo_dma.v @@ -60,7 +60,7 @@ module axi_adcfifo_dma #( localparam DMA_ADDRESS_WIDTH = 8; localparam AXI_ADDRESS_WIDTH = (DMA_MEM_RATIO == 2) ? (DMA_ADDRESS_WIDTH - 1) : ((DMA_MEM_RATIO == 4) ? (DMA_ADDRESS_WIDTH - 2) : (DMA_ADDRESS_WIDTH - 3)); - + // internal registers @@ -157,7 +157,7 @@ module axi_adcfifo_dma #( end end end - + assign dma_wready_s = (DMA_READY_ENABLE == 0) ? 1'b1 : dma_wready; assign dma_rd_s = (dma_raddr == dma_waddr_rel_s) ? 1'b0 : dma_wready_s; @@ -198,6 +198,7 @@ module axi_adcfifo_dma #( .addra (axi_waddr), .dina (axi_ddata), .clkb (dma_clk), + .reb (1'b1), .addrb (dma_raddr), .doutb (dma_rdata_s)); diff --git a/library/xilinx/axi_dacfifo/axi_dacfifo_rd.v b/library/xilinx/axi_dacfifo/axi_dacfifo_rd.v index 1a3bbbd31..b50ae0673 100644 --- a/library/xilinx/axi_dacfifo/axi_dacfifo_rd.v +++ b/library/xilinx/axi_dacfifo/axi_dacfifo_rd.v @@ -162,6 +162,7 @@ module axi_dacfifo_rd #( .addra (axi_mem_waddr), .dina (axi_rdata), .clkb (dac_clk), + .reb (1'b1), .addrb (dac_mem_raddr), .doutb (dac_data)); diff --git a/library/xilinx/axi_dacfifo/axi_dacfifo_wr.v b/library/xilinx/axi_dacfifo/axi_dacfifo_wr.v index 4a18391f4..04e2b1108 100644 --- a/library/xilinx/axi_dacfifo/axi_dacfifo_wr.v +++ b/library/xilinx/axi_dacfifo/axi_dacfifo_wr.v @@ -188,6 +188,7 @@ module axi_dacfifo_wr #( .addra (dma_mem_waddr), .dina (dma_data), .clkb (axi_clk), + .reb (1'b1), .addrb (axi_mem_raddr), .doutb (axi_mem_rdata_s)); diff --git a/library/xilinx/axi_dacfifo/util_dacfifo_bypass.v b/library/xilinx/axi_dacfifo/util_dacfifo_bypass.v index 3cc883439..9a008ca64 100644 --- a/library/xilinx/axi_dacfifo/util_dacfifo_bypass.v +++ b/library/xilinx/axi_dacfifo/util_dacfifo_bypass.v @@ -118,6 +118,7 @@ module util_dacfifo_bypass #( .addra (dma_mem_waddr), .dina (dma_data), .clkb (dac_clk), + .reb (1'b1), .addrb (dac_mem_raddr), .doutb (dac_mem_rdata_s));