如何在verilog中为16个端口映射内存
how to map memory for 16 ports in verilog
module testing123(Clk, Rst_n);
. . .
wire [7:0] port1_data;
wire [7:0] port2_data;
wire [7:0] port3_data;
wire [7:0] port4_data;
wire [7:0] port5_data;
wire [7:0] port6_data;
wire [7:0] port7_data;
wire [7:0] port8_data;
wire [7:0] port9_data;
wire [7:0] port10_data;
wire [7:0] port11_data;
wire [7:0] port12_data;
wire [7:0] port13_data;
wire [7:0] port14_data;
wire [7:0] port15_data;
reg [flit_port_width-1:0] flit_out1;
reg [flit_port_width-1:0] flit_out2;
reg [flit_port_width-1:0] flit_out3;
reg [flit_port_width-1:0] flit_out4;
reg [flit_port_width-1:0] flit_out5;
reg [flit_port_width-1:0] flit_out6;
reg [flit_port_width-1:0] flit_out7;
reg [flit_port_width-1:0] flit_out8;
reg [flit_port_width-1:0] flit_out9;
reg [flit_port_width-1:0] flit_out10;
reg [flit_port_width-1:0] flit_out11;
reg [flit_port_width-1:0] flit_out12;
reg [flit_port_width-1:0] flit_out13;
reg [flit_port_width-1:0] flit_out14;
reg [flit_port_width-1:0] flit_out15;
. . .
RAM_Memory #(/*addr_width*/ 32'd16,
/*data_width*/ 32'd8,
/*lo*/ 32'd0,
/*hi*/ 32'd63) Memory1(.clk(Clk)
,.rst(Rst_n)
,.flit_out(flit_out1)
,.dataout(port1_data)
);
RAM_Memory #(/*addr_width*/ 32'd16,
/*data_width*/ 32'd8,
/*lo*/ 32'd0,
/*hi*/ 32'd63) Memory2(.clk(Clk)
,.rst(Rst_n)
,.flit_out(flit_out2)
,.dataout(port2_data)
);
RAM_Memory #(/*addr_width*/ 32'd16,
/*data_width*/ 32'd8,
/*lo*/ 32'd0,
/*hi*/ 32'd63) Memory3(.clk(Clk) ...
);
. . .
endmodule
module RAM_Memory(
flit_out,
rst,
clk,
dataout
);
parameter addr_width = 1;
parameter data_width = 1;
parameter lo = 0;
parameter hi = 1;
integer count, i;
input [34:0] flit_out;
input rst,clk;
output [data_width - 1 : 0] dataout;
reg we;
reg [data_width - 1 : 0] dataout;
reg [addr_width - 1 : 0] addr;
reg [data_width - 1 : 0] data_in;
reg [data_width - 1 : 0] mem [lo:hi];
initial begin
count =0; i=0;
end
always @(posedge clk)begin
count<=count+1;
we<=0;
if(count>=1) begin
we<=1;
end
end
always @(we)begin
assign data_in = flit_out[7:0];
assign addr = flit_out[23:8];
mem[addr]<= data_in;
assign dataout = mem[addr];
end
always @(count)begin
if(count>=68)begin
count<=0;
end
end
endmodule
这里给出一个RAM_Memory模块,通过端口映射到其他模块testing123,用于将数据从15个端口存储到64宽内存。但是只有一个端口内存模块存储64个数据,"mem"寄存器不会为其他映射模块刷新。数据会丢失。如何刷新"mem"寄存器或所有映射端口从0值开始?
我没有完全理解这个问题,但发现了一些错误。您的代码包含:
always @(we)begin
assign data_in = flit_out[7:0];
assign addr = flit_out[23:8];
mem[addr]<= data_in;
assign dataout = mem[addr];
end
其中包含一些问题。
- 您触发了始终开启的
we
但未在块内使用 we
。这并不代表硬件中的任何内容。您更有可能希望触发器在使能为高时更新。
代码示例
always @(posedge clk) begin
if (en) begin
//..
end
end
- 在内部使用 assign 可能总是无法达到您的预期。
您很可能只想:
always @* begin
data_in = filt_out[7:0]
addr = flit_out[23:8];
dataout = mem[addr];
- 最好不要混合使用非阻塞 (
<=
) 和阻塞 (=
) 分配。如果它们都是触发器 (@(posedge clk)
) 则使用非阻塞 (<=
) 如果它是组合 (always @*
) 则使用阻塞 (=
).
有问题的代码块将变为
always @(posedge clk)begin
if (we) begin
data_in <= flit_out[7:0];
addr <= flit_out[23:8];
mem[addr] <= data_in;
dataout <= mem[addr];
end
end
查看代码,我认为这不是您想要的 data_in 并且 addr 解码应该在该块之外完成。
//Semantically split the bus
assign data_in = flit_out[7:0];
assign addr = flit_out[23:8];
always @(posedge clk)begin
if (we) begin
mem[addr] <= data_in;
dataout <= mem[addr];
end
end
一些使您更容易阅读代码的建议。
使用现代端口声明对可读性有很大影响。
module RAM_Memory(
flit_out,
rst,
clk,
dataout
);
parameter addr_width = 1;
parameter data_width = 1;
parameter lo = 0;
parameter hi = 1;
input [34:0] flit_out;
input rst,clk;
output [data_width - 1 : 0] dataout;
reg [data_width - 1 : 0] dataout;
变成
module RAM_Memory#(
parameter ADDR_WIDTH = 1, //They don not have to be upper case
parameter DATA_WIDTH= 1, // But most languages semantically define upper case as constants
parameter LO = 0;
parameter HI = 1;
)(
input [34:0] flit_out,
input rst,
input clk,
output [DATA_WIDTH-1:0] dataout
);
您的实例可以从 :
RAM_Memory #(/*addr_width*/ 32'd16,
/*data_width*/ 32'd8,
/*lo*/ 32'd0,
/*hi*/ 32'd63) Memory2(.clk(Clk)
,.rst(Rst_n)
,.flit_out(flit_out2)
,.dataout(port2_data)
);
到
RAM_Memory #(
.ADDR_WIDTH( 6 ), //No need to specify the width of parameter
.DATA_WIDTH( 8 ),
.LO ( 0 ),
.HI ( 63 )
) Memory2 (
.clk ( Clk )
,.rst ( Rst_n )
,.flit_out ( flit_out2 )
,.dataout ( port2_data)
);
Accessing instance of one module from inside of several other modules? (verilog)
module testing123(Clk, Rst_n);
. . .
wire [7:0] port1_data;
wire [7:0] port2_data;
wire [7:0] port3_data;
wire [7:0] port4_data;
wire [7:0] port5_data;
wire [7:0] port6_data;
wire [7:0] port7_data;
wire [7:0] port8_data;
wire [7:0] port9_data;
wire [7:0] port10_data;
wire [7:0] port11_data;
wire [7:0] port12_data;
wire [7:0] port13_data;
wire [7:0] port14_data;
wire [7:0] port15_data;
reg [flit_port_width-1:0] flit_out1;
reg [flit_port_width-1:0] flit_out2;
reg [flit_port_width-1:0] flit_out3;
reg [flit_port_width-1:0] flit_out4;
reg [flit_port_width-1:0] flit_out5;
reg [flit_port_width-1:0] flit_out6;
reg [flit_port_width-1:0] flit_out7;
reg [flit_port_width-1:0] flit_out8;
reg [flit_port_width-1:0] flit_out9;
reg [flit_port_width-1:0] flit_out10;
reg [flit_port_width-1:0] flit_out11;
reg [flit_port_width-1:0] flit_out12;
reg [flit_port_width-1:0] flit_out13;
reg [flit_port_width-1:0] flit_out14;
reg [flit_port_width-1:0] flit_out15;
. . .
RAM_Memory #(/*addr_width*/ 32'd16,
/*data_width*/ 32'd8,
/*lo*/ 32'd0,
/*hi*/ 32'd63) Memory1(.clk(Clk)
,.rst(Rst_n)
,.flit_out(flit_out1)
,.dataout(port1_data)
);
RAM_Memory #(/*addr_width*/ 32'd16,
/*data_width*/ 32'd8,
/*lo*/ 32'd0,
/*hi*/ 32'd63) Memory2(.clk(Clk)
,.rst(Rst_n)
,.flit_out(flit_out2)
,.dataout(port2_data)
);
RAM_Memory #(/*addr_width*/ 32'd16,
/*data_width*/ 32'd8,
/*lo*/ 32'd0,
/*hi*/ 32'd63) Memory3(.clk(Clk) ...
);
. . .
endmodule
module RAM_Memory(
flit_out,
rst,
clk,
dataout
);
parameter addr_width = 1;
parameter data_width = 1;
parameter lo = 0;
parameter hi = 1;
integer count, i;
input [34:0] flit_out;
input rst,clk;
output [data_width - 1 : 0] dataout;
reg we;
reg [data_width - 1 : 0] dataout;
reg [addr_width - 1 : 0] addr;
reg [data_width - 1 : 0] data_in;
reg [data_width - 1 : 0] mem [lo:hi];
initial begin
count =0; i=0;
end
always @(posedge clk)begin
count<=count+1;
we<=0;
if(count>=1) begin
we<=1;
end
end
always @(we)begin
assign data_in = flit_out[7:0];
assign addr = flit_out[23:8];
mem[addr]<= data_in;
assign dataout = mem[addr];
end
always @(count)begin
if(count>=68)begin
count<=0;
end
end
endmodule
这里给出一个RAM_Memory模块,通过端口映射到其他模块testing123,用于将数据从15个端口存储到64宽内存。但是只有一个端口内存模块存储64个数据,"mem"寄存器不会为其他映射模块刷新。数据会丢失。如何刷新"mem"寄存器或所有映射端口从0值开始?
我没有完全理解这个问题,但发现了一些错误。您的代码包含:
always @(we)begin
assign data_in = flit_out[7:0];
assign addr = flit_out[23:8];
mem[addr]<= data_in;
assign dataout = mem[addr];
end
其中包含一些问题。
- 您触发了始终开启的
we
但未在块内使用we
。这并不代表硬件中的任何内容。您更有可能希望触发器在使能为高时更新。
代码示例
always @(posedge clk) begin
if (en) begin
//..
end
end
- 在内部使用 assign 可能总是无法达到您的预期。
您很可能只想:
always @* begin
data_in = filt_out[7:0]
addr = flit_out[23:8];
dataout = mem[addr];
- 最好不要混合使用非阻塞 (
<=
) 和阻塞 (=
) 分配。如果它们都是触发器 (@(posedge clk)
) 则使用非阻塞 (<=
) 如果它是组合 (always @*
) 则使用阻塞 (=
).
有问题的代码块将变为
always @(posedge clk)begin
if (we) begin
data_in <= flit_out[7:0];
addr <= flit_out[23:8];
mem[addr] <= data_in;
dataout <= mem[addr];
end
end
查看代码,我认为这不是您想要的 data_in 并且 addr 解码应该在该块之外完成。
//Semantically split the bus
assign data_in = flit_out[7:0];
assign addr = flit_out[23:8];
always @(posedge clk)begin
if (we) begin
mem[addr] <= data_in;
dataout <= mem[addr];
end
end
一些使您更容易阅读代码的建议。
使用现代端口声明对可读性有很大影响。
module RAM_Memory(
flit_out,
rst,
clk,
dataout
);
parameter addr_width = 1;
parameter data_width = 1;
parameter lo = 0;
parameter hi = 1;
input [34:0] flit_out;
input rst,clk;
output [data_width - 1 : 0] dataout;
reg [data_width - 1 : 0] dataout;
变成
module RAM_Memory#(
parameter ADDR_WIDTH = 1, //They don not have to be upper case
parameter DATA_WIDTH= 1, // But most languages semantically define upper case as constants
parameter LO = 0;
parameter HI = 1;
)(
input [34:0] flit_out,
input rst,
input clk,
output [DATA_WIDTH-1:0] dataout
);
您的实例可以从 :
RAM_Memory #(/*addr_width*/ 32'd16,
/*data_width*/ 32'd8,
/*lo*/ 32'd0,
/*hi*/ 32'd63) Memory2(.clk(Clk)
,.rst(Rst_n)
,.flit_out(flit_out2)
,.dataout(port2_data)
);
到
RAM_Memory #(
.ADDR_WIDTH( 6 ), //No need to specify the width of parameter
.DATA_WIDTH( 8 ),
.LO ( 0 ),
.HI ( 63 )
) Memory2 (
.clk ( Clk )
,.rst ( Rst_n )
,.flit_out ( flit_out2 )
,.dataout ( port2_data)
);
Accessing instance of one module from inside of several other modules? (verilog)