题解 | #RAM的简单实现#
RAM的简单实现
https://www.nowcoder.com/practice/2c17c36120d0425289cfac0855c28796
参考题解区答案:
通过解法1:我感觉ram初始化不是很对,但是通过了
疑问1:只对ram的地址0进行清零。ram1[0] = 4'b0,也通过?
疑问2:为什么genvar 模块初始化报错?always块中不能使用genvar。可以使用for循环,是可以赋值同样的电路
疑问3:注意这里深度为8,应该是使用[7:0],而不是[2:0]?周周解答:Verilog的语法规定,如reg [2:0]a[7:0]的声明,对于a的访问访问只能是:a[0]-a[7],不存在a[8]或以上。
注意1:读写操作可以同时进行,当同一个时刻且读写地址相同时,读数据就会是写操作之前的数值,之后该地址的数值才改变为写数据。
解法2:使用for循环初始化
注意点1:使用for循环,always块开始需要加上名字,begin:ram8,如果使用reg而不是integer也可以不加。
注意点2:readdata加上复位值。
注意点3:integer不可综合,使用reg替代即可。
注意点4:reg [3:0] i;//位宽不能是3,要是4,否则会因为溢出而无限循环。
`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] ram1 [7:0]; reg [3:0] i;//位宽不能是3,要是4,否则会因为溢出而无限循环。 always @ (posedge clk, negedge rst_n) begin // integer i;//不可综合 if (!rst_n) begin for(i=0;i<8;i=i+1) ram1[i] <= 4'b0; end else begin ram1[write_addr] <= write_en ? write_data : 4'b0; end end always @ (posedge clk, negedge rst_n) begin if(!rst_n) read_data <= 4'b0; else read_data <= read_en ? ram1[read_addr] : 4'b0; end endmodule
// genvar i; // generate // for(i=0;i<8;i = i+1):ram_reset // ram1[i] = 4'b0; // endgenerate
`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] ram1 [7:0]; always @ (posedge clk, negedge rst_n) begin if (!rst_n) begin ram1[0] = 4'b0; // genvar i; // generate // for(i=0;i<8;i = i+1):ram_reset // ram1[i] = 4'b0; // endgenerate end else begin ram1[write_addr] <= write_en ? write_data : 4'b0; end end always @ (posedge clk) begin read_data <= read_en ? ram1[read_addr] : 4'b0; end endmodule