~ruther/verilog-riscv-semestral-project

32388b786d96e16d5264fe541d217ba5ca6b7084 — Rutherther 1 year, 5 months ago ee0204c
feat: add support for loading and saving ram from disk
2 files changed, 43 insertions(+), 7 deletions(-)

M src/ram.sv
M testbench/tb_cpu_program.sv
M src/ram.sv => src/ram.sv +23 -3
@@ 7,9 7,14 @@ module ram (
  output [31:0] rd);

  reg [31:0]      mask;
  reg [31:0]      memory[128];
  reg [31:0]      memory[1023];

  assign rd = memory[a[8:2]]; // word aligned
  assign rd = memory[a[11:2]]; // word aligned

  parameter        LOAD_FILE = 0;
  parameter string LOAD_FILE_PATH = "";
  parameter        WRITE_FILE = 0;
  parameter string WRITE_FILE_PATH = "";

  always_comb begin
    mask = {


@@ 20,8 25,23 @@ module ram (
            };
  end

  initial
    if (LOAD_FILE == 1) begin
      $display("Loading file %s into memory.", LOAD_FILE_PATH);
      $readmemh(LOAD_FILE_PATH, memory);
    end

  initial begin
    if (WRITE_FILE == 1) begin
      wait (a == {32{1'b1}});
      #5
      $display("Writing memory to file %s.", WRITE_FILE_PATH);
      $writememh(WRITE_FILE_PATH, memory);
    end
  end

  always_ff @ (posedge clk)
    if(we)
      memory[a[8:2]] = (rd & ~mask) | (wd & mask);
      memory[a[11:2]] = (rd & ~mask) | (wd & mask);

endmodule

M testbench/tb_cpu_program.sv => testbench/tb_cpu_program.sv +20 -4
@@ 3,7 3,7 @@ import cpu_types::*;
module tb_cpu_program();
  reg clk, rst_n;

  wire [31:0] memory_address, memory_write, memory_out;
  wire [31:0] memory_address, cpu_memory_address, memory_write, memory_out;
  wire [3:0]  memory_write_byte_enable;
  wire        memory_we;



@@ 15,6 15,14 @@ module tb_cpu_program();
  parameter string  CPU_PROGRAM_PATH;
  parameter string  CPU_PROGRAM_NAME;

  parameter         MEMORY_LOAD_FILE = 0;
  parameter string  MEMORY_LOAD_FILE_PATH = "";
  parameter         MEMORY_WRITE_FILE = 0;
  parameter string  MEMORY_WRITE_FILE_PATH = "";

  // assign 0xFF... when ebreak. To save the memory to a file.
  assign memory_address = ebreak == 1'b1 ? {32{1'b1}} : cpu_memory_address;

  cpu uut(
    .clk(clk),
    .rst_n(rst_n),


@@ 22,7 30,7 @@ module tb_cpu_program();
    .instruction(instruction),
    .pc(pc),

    .memory_address(memory_address),
    .memory_address(cpu_memory_address),
    .memory_out(memory_out),
    .memory_write(memory_write),
    .memory_byte_enable(memory_write_byte_enable),


@@ 31,7 39,12 @@ module tb_cpu_program();
    .ebreak(ebreak)
  );

  ram memory_inst(
  ram #(
    .LOAD_FILE(MEMORY_LOAD_FILE),
    .LOAD_FILE_PATH(MEMORY_LOAD_FILE_PATH),
    .WRITE_FILE(MEMORY_WRITE_FILE),
    .WRITE_FILE_PATH(MEMORY_WRITE_FILE_PATH)
  ) memory_inst(
    .clk(clk),
    .a(memory_address),
    .write_byte_enable(memory_write_byte_enable),


@@ 40,12 53,15 @@ module tb_cpu_program();
    .rd(memory_out)
  );

  file_program_memory #(.FILE_NAME(CPU_PROGRAM_PATH)) prog_mem_inst(
  file_program_memory #(
    .FILE_NAME(CPU_PROGRAM_PATH)
  ) prog_mem_inst(
    .addr(pc[11:0]),
    .instruction(instruction)
  );

  always_ff @ (posedge ebreak) begin
    $display("ebreak!");
    #15 $finish;
  end


Do not follow this link