Verilog Icarus提供未定义的值

Verilog Icarus提供未定义的值,verilog,risc,icarus,Verilog,Risc,Icarus,我正在做一个项目,在这个项目中,我正在用Icarus Verilog 0.9.7设计一个简单的RISC机器 这段代码是模块化的,最后我将把几个组件放在一起,但我在内存控制器上工作时遇到了一个问题。对于我所有的测试值,我得到的是未定义的输出,或者“Z”。我怎样才能解决这个问题?我看不出有任何理由不填充这些值 定义内存控制器应该具有的所有行为超出了这个问题的上下文范围,因此我将尽量简短地介绍Verilog主题 这是我当前的Verilog代码。工作台有两个文件,mem.sv和SrcMemoryCont

我正在做一个项目,在这个项目中,我正在用Icarus Verilog 0.9.7设计一个简单的RISC机器

这段代码是模块化的,最后我将把几个组件放在一起,但我在内存控制器上工作时遇到了一个问题。对于我所有的测试值,我得到的是未定义的输出,或者“Z”。我怎样才能解决这个问题?我看不出有任何理由不填充这些值

定义内存控制器应该具有的所有行为超出了这个问题的上下文范围,因此我将尽量简短地介绍Verilog主题

这是我当前的Verilog代码。工作台有两个文件,mem.sv和SrcMemoryController.sv:

    `default_nettype none

module SrcMemoryController(
    inout [31:0] cpu_bus,
    inout [31:0] mem_bus,
    input ma_in,
    input md_in, 
    input md_out, 
    input read,
    input enable,
    output [15:0] address
);

  reg [31:0] ma = 32'bz;
  reg [31:0] md = 32'bz;
  wire [31:0] cpb = cpu_bus;
  wire [31:0] meb = mem_bus;

  always @(*) begin

    if(ma_in) ma = cpb;

    if(md_in) md = cpb;

    if(read) begin
      if(enable) md = meb;
    end

  end

  assign cpu_bus = (md_out) ? md : 32'bz;
  assign mem_bus = (~read && enable) ? md : 32'bz;
  assign address = ma;

endmodule
mem.sv目前可以工作,不是这个问题的根源。无论如何,我都会把它包括在内,以防有用

`default_nettype none

module Memory (
  inout [31:0] mem_bus,
  input [15:0] address,
  input read, 
  input enable
);

  reg [31:0] storage [65535:0];

  always @(enable) begin
    if(enable) begin
      if(read) begin

      end
      if(!read) begin
        storage[address] = mem_bus;
      end
    end
  end

  assign mem_bus = (read) ? storage[address] : 32'bz;

endmodule
这也是测试台。可能不需要它,但发布它可能会有所帮助

    `default_nettype none
`include "mem.sv"

module tb_MemoryController;

  wire [31:0] mem_bus;
  wire [31:0] cpu_bus;
  reg [31:0] bus_sim;
  reg bus_sim_out = 0;

  // Tri-state buffer
  assign cpu_bus = bus_sim_out ? bus_sim : 32'bz; 

  reg ma_in, md_in, md_out;
  reg read, enable;
  wire [15:0] address;

  Memory vmem( mem_bus, address, read, enable );
  SrcMemoryController dut( cpu_bus, mem_bus, ma_in, md_in, md_out,
                       read, enable, address );

  initial begin
    $dumpfile("mem_file.vcd");
    $dumpvars(0, dut);
    $dumpvars(0, vmem);

    test_memory(0, 0);
    test_memory(10, 0);
    #1 assert_empty(mem_bus);
    #1 assert_empty(cpu_bus);
    test_memory(65535, 65535);
    test_memory(1231, 123);
    test_memory(1231231, 65535);
    test_memory(0, 65535);
    test_memory(100, 100);
    test_memory(515, 515);
    #1 assert_empty(mem_bus);
    #1 assert_empty(cpu_bus);
    $finish();
  end

  task test_memory;
    input [31:0] data;
    input [15:0] addr;
    begin
      #1
      zero_inputs();
      #1
      write_value(data, addr);
      #1
      load_spoof(); 
      #1
      read_value(addr);
      #1
      assertEquals(cpu_bus, data);
      zero_inputs();
    end
  endtask

  task write_value;
    input [31:0] data;
    input [15:0] addr;
    begin
      #1
      enable <= 0;
      bus_sim <= addr;
      bus_sim_out <= 1;
      ma_in <= 1;
      #1
      bus_sim <= data;
      bus_sim_out <= 1;
      ma_in <= 0;
      md_in <= 1;
      read <= 0;
      enable <= 1; 
    end
  endtask

  task read_value;
    input [15:0] addr;
    begin
      #1 
      enable <= 0;
      bus_sim <= addr;
      bus_sim_out <= 1;
      ma_in <= 1;
      #1
      ma_in <= 0;
      read <= 1;
      enable <= 1;
      bus_sim_out <= 0;
      md_out <= 1;
    end
  endtask

  task load_spoof;
    begin
      #1
      bus_sim <= 32'hABCDABCD;
      bus_sim_out <= 1;
      ma_in <= 1;
      md_in <= 1;
      read <= 0;
      enable <= 0; 
      #1
      zero_inputs();
    end
  endtask

  task zero_inputs;
    begin
      ma_in <= 0;
      md_in <= 0;
      md_out <= 0;
      read <= 0;
      enable <= 0;
      bus_sim_out <= 0;
    end
  endtask

  task pulseClock;
    begin
    end
  endtask

  task assertEquals;
    input [31:0] val;
    input [31:0] exp;
    begin
      if (val == exp) $display("[TEST][PASSED] %d", val);
      else $display("[TEST][FAILED] Got %d, expected %d", val, exp);
    end
  endtask


  task assert_empty;
    input [31:0] a;
    begin
      if (a === 32'bz) $display("[TEST][PASSED] (Bus empty)", a);
      else $display("[TEST][FAILED] (Value on bus)", a, 32'bz);
    end
  endtask

endmodule
`default\u nettype none
`包括“mem.sv”
模块tb_存储器控制器;
导线[31:0]内存总线;
线[31:0]cpu_总线;
注册[31:0]总线sim卡;
reg bus_sim_out=0;
//三态缓冲器
分配cpu\u总线=总线\u sim\u输出?总线sim:32'bz;
注册硕士学位,硕士学位,硕士学位;
reg read,启用;
电报[15:0]地址;
内存vmem(内存总线、地址、读取、启用);
SRCMORYCONTROLLER dut(cpu_总线、内存总线、内存输入、内存输入、内存输出、,
读取、启用、地址);
初始开始
$dumpfile(“mem_file.vcd”);
$dumpvars(0,dut);
$dumpvars(0,vmem);
测试存储器(0,0);
测试存储器(10,0);
#1断言为空(内存总线);
#1断言_为空(cpu_总线);
测试存储器(65535,65535);
测试存储器(1231123);
测试存储器(123165535);
测试存储器(065535);
测试存储器(100100);
测试存储器(51515);
#1断言为空(内存总线);
#1断言_为空(cpu_总线);
$finish();
结束
任务测试记忆;
输入[31:0]数据;
输入[15:0]地址;
开始
#1
零输入();
#1
写入_值(数据、地址);
#1
加载欺骗();
#1
读取值(addr);
#1
资产质量(cpu_总线、数据);
零输入();
结束
结束任务
任务写入值;
输入[31:0]数据;
输入[15:0]地址;
开始
#1

启用凯文评论中给出的答案,我将详细说明它是如何修复的


我将mem.sv中的always@(enable)更改为always@(*),更改后,其余代码立即开始工作,并具有完整的功能。非常感谢Kevin1494

谢谢!然而,这并没有解决问题。我将检查所有操作数以确保它们正确。现在完成,更新两个文件。好的。这应该已经解决了,复制它时一定出错了。感谢您的帮助我没有编写测试台,我对Verilog还很陌生,也没有学到多少东西。我分析了EPWave并看到了同样的情况,但测试台是由我的助教编写的,我知道它是有效的。请尝试使用
always@(*)
而不是
always@(enable)
来创建
内存逻辑块。此外,无需创建额外的导线
cpb
meb
您可以直接使用
inout
端口