我得到的输出是错误的

问题描述 投票:0回答:1

当我尝试显示 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 等等。

verilog system-verilog iverilog
1个回答
0
投票

我认为问题出在重置上。

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,以便正确重置设计。应该可以。

对于所有对这个问题投反对票的人,请不要阻止那些试图学习新东西的人。如果这个问题不值得您花时间,请继续!

© www.soinside.com 2019 - 2024. All rights reserved.