当我尝试显示 RAM 的输出时,它没有按顺序读取 data_in 输入。 RAM 输出从 B 开始,如 000 地址,但我尝试在 000 地址上写入 A,依此类推 这是设计块代码
module task (
input [2:0] address_ram,
input [7:0] data_in,
output [(DATA_WIDTH-1):0] q_ram,
input clk,
input rst,
input we
);
parameter DATA_WIDTH = 8;
parameter ADDR_WIDTH = 8;
// RAM content
reg [DATA_WIDTH-1:0] ram [2**ADDR_WIDTH-1:0];
reg [ADDR_WIDTH-1:0] addr_r;
always @(posedge clk or negedge rst) begin
if (rst) begin
// Reset condition
addr_r <= 8'b0;
end else begin
// WRITE to RAM
if (we) begin
ram[addr_r] <= data_in;
end
// READ from RAM
addr_r <= address_ram;
end
end
assign q_ram = ram[address_ram];
endmodule
这是测试平台
// Code your testbench here
// or browse Examples
module task_tb;
// Parameters
parameter DATA_WIDTH = 8;
parameter ADDR_WIDTH = 8;
// Inputs and Outputs
reg clk, rst, we;
reg [DATA_WIDTH-1:0] data_in;
reg [2:0] address_ram;
wire [(DATA_WIDTH-1):0] q_ram_out;
// Instantiate the home_task module
home_task uut (
.clk(clk),
.rst(rst),
.we(we),
.address_ram(address_ram),
.data_in(data_in),
.q_ram(q_ram_out)
);
// Clock Generation
always begin
#5 clk = ~clk; // Toggle the clock every 5 time units
end
// Initial Block
initial begin
clk = 0;
rst = 0; // Assert reset initially
we = 0;
data_in = 8'b01000001;
address_ram = 3'b000;
result = 1;
// Apply reset for some time
#10 rst = 0;
#10;
// Write data to RAM
we = 1;
address_ram = 3'b000;
data_in = 8'b01000001; // 'A'
#10;
we = 1;
address_ram = 3'b001;
data_in = 8'b01000010; // 'B'
#10;
we = 1;
address_ram = 3'b010;
data_in = 8'b01000011; // 'C'
#10;
we = 1;
address_ram = 3'b011;
data_in = 8'b01000100; // 'D'
#10;
we = 1;
address_ram = 3'b100;
data_in = 8'b01000101; // 'E'
#10;
we = 1;
address_ram = 3'b101;
data_in = 8'b01000110; // 'F'
#10;
we = 1;
address_ram = 3'b110;
data_in = 8'b01000111; // 'G'
#10;
we = 1;
address_ram = 3'b111;
data_in = 8'b01001000; // 'H'
#10;
address_ram = 3'b000;
repeat (2**3) begin
$display("Read Data from RAM at address %b: %c", address_ram, q_ram_out);
#10;
address_ram = address_ram + 1;
end
// Add more stimulus as needed
#100 $finish;
end
endmodule
我正在写入 RAM ABCDEFGH 但输出显示它以 000 作为 B、001 作为 C 等开始...但我希望结果是 A 作为 000 B 作为 001 等等。
我认为问题出在重置上。
always
语句查找 negedge rst
,但 if (rst)
检查 rst=1'b1
以重置设计。
另外,需要指出的一点是,您正在使用
ram_address
的注册版本,即 addr_r
写入 RAM。因此,测试平台中的第一个 wren
将使用 addr_r
的重置值进行写入。但你的设计的重置条件是错误的。
首先,对您的测试平台进行重置,我注意到
rst
保持 0
。而且,如果您使用注册的 ram_address
进行写入,您还应该在代码中注册 we
和 data_in
,以便所有信号正确对齐。
我将重写代码如下:
module task (
input [2:0] address_ram,
input [7:0] data_in,
output [(DATA_WIDTH-1):0] q_ram,
input clk,
input rst,
input we
);
parameter DATA_WIDTH = 8;
parameter ADDR_WIDTH = 8;
// RAM content
reg [DATA_WIDTH-1:0] ram [2**ADDR_WIDTH-1:0];
reg [ADDR_WIDTH-1:0] addr_r;
reg [DATA_WIDTH-1:0] data_in_r;
reg we_r;
always @(posedge clk or negedge rst) begin
if (rst == 1'b0) begin
addr_r <= {ADDR_WIDTH{1'b0}};
data_in_r <= {DATA_WIDTH{1'b0}};
we_r <= 1'b0;
end else begin
addr_r <= address_ram;
data_in_r <= data_in;
we_r <= we;
end
end
always @(posedge clk) begin
if (we_r) begin
ram[addr_r] <= data_in_r;
end
end
assign q_ram = ram[addr_r];
endmodule
通过分离always块,代码更加清晰。现在,
addr_r
、data_in
和we
都注册了一个时钟周期。而且你的读取条件也是使用注册版的ram_address
在您的测试平台中,
rst
应从 0 变为 1,以便正确重置设计。应该可以。
对于所有对这个问题投反对票的人,请不要阻止那些试图学习新东西的人。如果这个问题不值得您花时间,请继续!