题解主体
要实现RAM,首先要声明数据的存储空间,例如:[3:0] rom [7:0];变量名称ram之前的[3:0]表示每个数据具有多少位,指位宽;变量名称ram之后的[7:0]表示需要多少个数据,指深度,注意这里深度为8,应该是使用[7:0],而不是[2:0];
声明存储变量之后,需要对ram进行初始化,写入数据,当write_en有效,向write_addr写入write_data,当read_en有效,根据输入的read_addr输出read_data。需要注意的是,题目要求实现真双端口RAM,即可以同时写入和读出,所以需要使用两个always语句块实现写入和读出逻辑,不可以在同一个always块中使用if-else if-else if结果。以下为错误代码。
reg [3:0] ram_data [7:0];
always @(posedge clk or negedge rst_n)
if (!rst_n) //对RAM中的数据进行初始化
begin
ram_data[0] <= 4'd0;
ram_data[1] <= 4'd0;
ram_data[2] <= 4'd0;
ram_data[3] <= 4'd0;
ram_data[4] <= 4'd0;
ram_data[5] <= 4'd0;
ram_data[6] <= 4'd0;
ram_data[7] <= 4'd0;
end
else if(write_en) //当write_en有效,向write_addr写入write_data
begin
ram_data[write_addr] <= write_data;
end
else if(read_en) //当read_en有效,根据输入的read_addr输出read_data
begin
read_data <= ram_data[read_addr];
end
按照以上代码,如果write_en和read_en同时有效,只有写操作会执行,而读操作被屏蔽。最好将读写其中一个分离到单独的always语句块。
always @(posedge clk or negedge rst_n)
if (!rst_n)
read_data <= 4’d0;
else if (read_en)
begin
read_data <= ram_data[read_addr];
end
else
begin
read_data <= 4’d0;
end
参考答案
`timescale 1ns/1ns module ram_mod( input clk, input rst_n, input write_en, input [7:0]write_addr, input [3:0]write_data, input read_en, input [7:0]read_addr, output reg [3:0]read_data ); reg [3:0] ram_data [7:0]; always @(posedge clk or negedge rst_n) if (!rst_n) //对RAM中的数据进行初始化 begin ram_data[0] <= 4'd0; ram_data[1] <= 4'd0; ram_data[2] <= 4'd0; ram_data[3] <= 4'd0; ram_data[4] <= 4'd0; ram_data[5] <= 4'd0; ram_data[6] <= 4'd0; ram_data[7] <= 4'd0; end else if(write_en) //当write_en有效,向write_addr写入write_data begin ram_data[write_addr] <= write_data; end else begin ram_data[0] <= ram_data[0]; ram_data[1] <= ram_data[1]; ram_data[2] <= ram_data[2]; ram_data[3] <= ram_data[3]; ram_data[4] <= ram_data[4]; ram_data[5] <= ram_data[5]; ram_data[6] <= ram_data[6]; ram_data[7] <= ram_data[7]; end always @(posedge clk or negedge rst_n) if (!rst_n) read_data <= 4'd0; else if (read_en) read_data <= ram_data[read_addr]; else read_data <= 4'd0; endmodule