Memory verilog中具有数据输入和数据输出的可重新配置内存实例作为参数传递

Memory verilog中具有数据输入和数据输出的可重新配置内存实例作为参数传递,memory,verilog,fifo,hdl,vlsi,Memory,Verilog,Fifo,Hdl,Vlsi,如何制作一个内存模块,其中数据总线宽度作为参数传递给每个实例,并且我的设计根据参数重新配置自身?例如,假设我有字节可寻址内存,DATA-IN总线宽度为32位(每个周期写入4个字节),而DATA-OUT为16位(每个周期读取2个字节)。例如,DATA-IN为64位,DATA-OUT为16位。对于所有这些情况,我的设计应该是可行的 我尝试的是根据设计参数生成写入指针值,例如,DATA-IN32位,写入指针在写入时每个周期递增4。对于64位,增量为8,依此类推 问题是:如何根据传递给实例的参数在一个周

如何制作一个内存模块,其中
数据
总线宽度作为参数传递给每个实例,并且我的设计根据参数重新配置自身?例如,假设我有字节可寻址内存,
DATA-IN
总线宽度为32位(每个周期写入4个字节),而
DATA-OUT
为16位(每个周期读取2个字节)。例如,
DATA-IN
为64位,
DATA-OUT
为16位。对于所有这些情况,我的设计应该是可行的

我尝试的是根据设计参数生成写入指针值,例如,
DATA-IN
32位,写入指针在写入时每个周期递增4。对于64位,增量为8,依此类推

问题是:如何根据传递给实例的参数在一个周期内写入4、8或16个字节

//Something as following I want to implement. This memory instance can be considered as internal memory of FIFO having different datawidth for reading and writing in case you think of an application of such memory

module mem#(parameter DIN=16, parameter DOUT=8, parameter ADDR=4,parameter BYTE=8)
(
  input  [DIN-1:0]  din,
  output [DOUT-1:0] dout,
  input             wen,ren,clk
);

localparam DEPTH = (1<<ADDR);
reg [BYTE-1:0] mem [0:DEPTH-1];
reg wpointer=5'b00000;
reg rpointer=5'b00000;
reg [BYTE-1:0] tmp [0:DIN/BYTE-1];

function [ADDR:0] ptr;
input [4:0] index;
integer i;
  begin
    for(i=0;i<DIN/BYTE;i=i+1)  begin 
      mem[index] = din[(BYTE*(i+1)-1):BYTE*(i)]; // something like this I want to implement, I know this line is not allowed in verilog, but is there any alternative to this?
      index=index+1;
    end
    ptr=index;
  end
endfunction

always @(posedge clk) begin 
  if(wen==1)
    wpointer <= wptr(wpointer);
end

always @(posedge clk) begin
  if(ren==1)
    rpointer <= ptr(rpointer);
end

endmodule
//我想实现以下内容。该内存实例可以被视为FIFO的内部内存,具有不同的读写数据宽度,以防您想到这种内存的应用
模块mem#(参数DIN=16,参数DOUT=8,参数ADDR=4,参数BYTE=8)
(
输入[DIN-1:0]DIN,
输出[DOUT-1:0]DOUT,
输入文、任、钟
);
localparam DEPTH=(1
din[(字节*(i+1)-1):字节*(i)]
将不会在Verilog中编译,因为MSB和LSB select位都是变量。Verilog需要一个已知的范围。
+:
用于部分选择(也称为切片)允许变量选择索引和恒定范围值。IEEE Std 1364-2001§4.2.1中介绍了该索引。您也可以在§11.5.1中阅读更多有关该索引的信息,或参考之前提出的问题:和

din[BYTE*i+:BYTE]
应该适合您,或者您可以使用
din[BYTE*(i+1)-1-:BYTE]


此外,您应该使用非阻塞分配(
请通过更新的post@Morgan
mem[index]=din[(BYTE*(i+1)-1)∶8];
这会有什么区别?您能解释一下吗?@Qiu
...
localparam DEPTH = (1<<ADDR);
reg [BYTE-1:0] mem [0:DEPTH-1];
reg [ADDR-1:0] wpointer, rpointer;
integer i;
initial begin // init values for pointers (FPGA, not ASIC)
  wpointer = {ADDR{1'b0}};
  rpointer = {ADDR{1'b0}};
end
always @(posedge clk) begin
  if (ren==1) begin
    for(i=0; i < DOUT/BYTE; i=i+1) begin
        dout[BYTE*i +: BYTE] <= mem[rpointer+i];
    end
    rpointer <= rpointer + (DOUT/BYTE);
  end
  if (wen==1) begin
    for(i=0; i < DIN/BYTE; i=i+1) begin
        mem[wpointer+i] <= din[BYTE*i +: BYTE];
    end
    wpointer <= wpointer + (DIN/BYTE);
  end
end