data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v
 line:39: before: "resetb_tb"
1: b'%Warning-STMTDLY: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:21: Unsupported: Ignoring delay on this delayed statement.\n      #5 clk_tb = 1\'b0;\n      ^\n                  ... Use "/* verilator lint_off STMTDLY */" and lint_on around source to disable this message.\n%Warning-STMTDLY: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:22: Unsupported: Ignoring delay on this delayed statement.\n      #5 clk_tb = 1\'b1;\n      ^\n%Error: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:39: syntax error, unexpected \'@\'\n  @(posedge clk_tb)     resetb_tb = 1\'b1;\n  ^\n%Error: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:47: syntax error, unexpected \'@\'\n     @(posedge clk_tb);\n     ^\n%Error: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:50: syntax error, unexpected \'@\'\n     @(posedge clk_tb);\n     ^\n%Error: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:53: syntax error, unexpected \'@\'\n     @(posedge clk_tb);\n     ^\n%Error: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:56: syntax error, unexpected \'@\'\n     @(posedge clk_tb);\n     ^\n%Error: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:63: syntax error, unexpected \'@\'\n     @(posedge clk_tb);\n     ^\n%Warning-STMTDLY: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:66: Unsupported: Ignoring delay on this delayed statement.\n     #0;\n     ^\n%Error: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:68: syntax error, unexpected \'@\'\n     @(posedge clk_tb);\n     ^\n%Warning-STMTDLY: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:71: Unsupported: Ignoring delay on this delayed statement.\n     #0;\n     ^\n%Error: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:73: syntax error, unexpected \'@\'\n     @(posedge clk_tb);\n     ^\n%Warning-STMTDLY: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:76: Unsupported: Ignoring delay on this delayed statement.\n     #0;\n     ^\n%Error: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:78: syntax error, unexpected \'@\'\n     @(posedge clk_tb);\n     ^\n%Warning-STMTDLY: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:81: Unsupported: Ignoring delay on this delayed statement.\n     #0;\n     ^\n%Error: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:100: syntax error, unexpected \'@\'\n  @(posedge clk_tb)     resetb_tb = 1\'b1;\n  ^\n%Error: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:108: syntax error, unexpected \'@\'\n     @(posedge clk_tb);\n     ^\n%Error: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:111: syntax error, unexpected \'@\'\n     @(posedge clk_tb);\n     ^\n%Error: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:118: syntax error, unexpected \'@\'\n     @(posedge clk_tb);\n     ^\n%Warning-STMTDLY: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:121: Unsupported: Ignoring delay on this delayed statement.\n     #0;\n     ^\n%Error: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:123: syntax error, unexpected \'@\'\n     @(posedge clk_tb);\n     ^\n%Warning-STMTDLY: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:126: Unsupported: Ignoring delay on this delayed statement.\n     #0;\n     ^\n%Error: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:144: syntax error, unexpected \'@\'\n  @(posedge clk_tb)     resetb_tb = 1\'b1;\n  ^\n%Error: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:152: syntax error, unexpected \'@\'\n     @(posedge clk_tb);\n     ^\n%Error: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:159: syntax error, unexpected \'@\'\n     @(posedge clk_tb);\n     ^\n%Warning-STMTDLY: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:162: Unsupported: Ignoring delay on this delayed statement.\n     #0;\n     ^\n%Error: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:181: syntax error, unexpected \'@\'\n  @(posedge clk_tb)     resetb_tb = 1\'b1;\n  ^\n%Error: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:186: syntax error, unexpected \'@\'\n     @(posedge clk_tb);\n     ^\n%Warning-STMTDLY: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:189: Unsupported: Ignoring delay on this delayed statement.\n     #0;\n     ^\n%Error: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:210: syntax error, unexpected \'@\'\n  @(posedge clk_tb)     resetb_tb = 1\'b1;\n  ^\n%Error: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:218: syntax error, unexpected \'@\'\n     @(posedge clk_tb);\n     ^\n%Warning-STMTDLY: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:221: Unsupported: Ignoring delay on this delayed statement.\n     #0;\n     ^\n%Error: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:228: syntax error, unexpected \'@\'\n     @(posedge clk_tb);\n     ^\n%Warning-STMTDLY: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:231: Unsupported: Ignoring delay on this delayed statement.\n     #0;\n     ^\n%Error: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:253: Unsupported or unknown PLI call: $dumpfile\n $dumpfile("tb_log/mmu_tb.vcd");\n ^~~~~~~~~\n%Error: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:254: Unsupported or unknown PLI call: $dumpvars\n $dumpvars(0,mmu_tb);\n ^~~~~~~~~\n%Error: data/full_repos/permissive/114498561/01-embedded-softcore-rv32i/mmu_tb.v:263: syntax error, unexpected \'@\'\n @(posedge clk_tb);\n ^\n%Error: Exiting due to 25 error(s), 12 warning(s)\n        ... See the manual and https://verilator.org for more assistance.\n'
module mmu_tb();
   reg clk_tb, resetb_tb, dm_we_tb;
   reg [31:0] im_addr_tb, dm_addr_tb, dm_di_tb;
   wire [31:0] im_do_tb, dm_do_tb;
   reg [3:0]  dm_be_tb;
   reg 	      is_signed_tb;
   wire [11:2] im_addr_out_tb;
   wire [31:0] im_data_tb, io_data_read_tb, io_data_write_tb;
   wire [7:0]  io_addr_tb;
   wire        io_en_tb, io_we_tb;

   reg [31:0]  instruction_memory [0:4095];
   reg [31:0]  io_memory [0:255];

   integer     i;
   
   always begin : CLK_GENERATOR
      #5 clk_tb = 1'b0;
      #5 clk_tb = 1'b1;
   end


   task run_test1;
      integer 	    i;
      begin
	 $display("(TT) --------------------------------------------------");
	 $display("(TT) Test 1: Byte R/W ");
	 $display("(TT) 1. Writes 0, 1, ... to 0x10000000, ... consecutively in unsigned bytes");
	 $display("(TT) 2. Then reads from the same addresses. Values should be same");
	 $display("(TT) 3. The first dm_do(prev) is invalid");
	 $display("(TT) --------------------------------------------------");
	 
	 resetb_tb = 1'b0;
	 dm_we_tb = 1'b0;
	 is_signed_tb = 1'b0;
	 @(posedge clk_tb)	    resetb_tb = 1'b1;
	 dm_we_tb = 1'b1;
	 

	 for (i = 0; i < 8; i = i + 1) begin
	    dm_addr_tb = 32'h10000000 + i*4;
	    dm_di_tb = 4*i + 0;
	    dm_be_tb = 4'b0001;
	    @(posedge clk_tb);
	    dm_be_tb = 4'b0010;
	    dm_di_tb = 4*i + 1;
	    @(posedge clk_tb);
	    dm_be_tb = 4'b0100;
	    dm_di_tb = 4*i + 2;
	    @(posedge clk_tb);
	    dm_be_tb = 4'b1000;
	    dm_di_tb = 4*i + 3;
	    @(posedge clk_tb);
	 end
	 dm_we_tb = 1'b0;

	 for (i = 0; i < 8; i = i + 1) begin
	    dm_addr_tb = 32'h10000000 + i*4;
	    dm_be_tb = 4'b0001;
	    @(posedge clk_tb);
	    $display("(TT) dm_addr = 0x%h, dm_be = %b, dm_do(prev) = %d", 
		     dm_addr_tb, dm_be_tb, dm_do_tb);
	    #0;
	    dm_be_tb = 4'b0010;
	    @(posedge clk_tb);
	    $display("(TT) dm_addr = 0x%h, dm_be = %b, dm_do(prev) = %d", 
		     dm_addr_tb, dm_be_tb, dm_do_tb);
	    #0;
	    dm_be_tb = 4'b0100;
	    @(posedge clk_tb);
	    $display("(TT) dm_addr = 0x%h, dm_be = %b, dm_do(prev) = %d", 
		     dm_addr_tb, dm_be_tb, dm_do_tb);
	    #0;
	    dm_be_tb = 4'b1000;
	    @(posedge clk_tb);
	    $display("(TT) dm_addr = 0x%h, dm_be = %b, dm_do(prev) = %d", 
		     dm_addr_tb, dm_be_tb, dm_do_tb);
	    #0;
	 end
      end
   endtask


   task run_test2;
      integer 	    i;
      begin
	 $display("(TT) --------------------------------------------------");
	 $display("(TT) Test 2: Half Word R/W ");
	 $display("(TT) 1. Writes 0, 1, ... to 0x10000000, ... consecutively in unsigned half words");
	 $display("(TT) 2. Then reads from the same addresses. Values should be same");
	 $display("(TT) 3. The first dm_do(prev) is invalid");
	 $display("(TT) --------------------------------------------------");
	 
	 resetb_tb = 1'b0;
	 dm_we_tb = 1'b0;
	 is_signed_tb = 1'b0;
	 @(posedge clk_tb)	    resetb_tb = 1'b1;
	 dm_we_tb = 1'b1;
	 

	 for (i = 0; i < 8; i = i + 1) begin
	    dm_addr_tb = 32'h10000000 + i*4;
	    dm_di_tb = 2*i + 0;
	    dm_be_tb = 4'b0011;
	    @(posedge clk_tb);
	    dm_be_tb = 4'b1100;
	    dm_di_tb = 2*i + 1;
	    @(posedge clk_tb);
	 end
	 dm_we_tb = 1'b0;

	 for (i = 0; i < 8; i = i + 1) begin
	    dm_addr_tb = 32'h10000000 + i*4;
	    dm_be_tb = 4'b0011;
	    @(posedge clk_tb);
	    $display("(TT) dm_addr = 0x%h, dm_be = %b, dm_do(prev) = %d", 
		     dm_addr_tb, dm_be_tb, dm_do_tb);
	    #0;
	    dm_be_tb = 4'b1100;
	    @(posedge clk_tb);
	    $display("(TT) dm_addr = 0x%h, dm_be = %b, dm_do(prev) = %d", 
		     dm_addr_tb, dm_be_tb, dm_do_tb);
	    #0;
	 end
      end
   endtask

   task run_test3;
      integer 	    i;
      begin
	 $display("(TT) --------------------------------------------------");
	 $display("(TT) Test 3: Word R/W ");
	 $display("(TT) 1. Writes 0, 1, ... to 0x10000000, ... consecutively in unsigned words");
	 $display("(TT) 2. Then reads from the same addresses. Values should be same");
	 $display("(TT) 3. The first dm_do(prev) is invalid");
	 $display("(TT) --------------------------------------------------");
	 
	 resetb_tb = 1'b0;
	 dm_we_tb = 1'b0;
	 is_signed_tb = 1'b0;
	 @(posedge clk_tb)	    resetb_tb = 1'b1;
	 dm_we_tb = 1'b1;
	 

	 for (i = 0; i < 8; i = i + 1) begin
	    dm_addr_tb = 32'h10000000 + i*4;
	    dm_di_tb = i;
	    dm_be_tb = 4'b1111;
	    @(posedge clk_tb);
	 end
	 dm_we_tb = 1'b0;

	 for (i = 0; i < 8; i = i + 1) begin
	    dm_addr_tb = 32'h10000000 + i*4;
	    dm_be_tb = 4'b1111;
	    @(posedge clk_tb);
	    $display("(TT) dm_addr = 0x%h, dm_be = %b, dm_do(prev) = %d", 
		     dm_addr_tb, dm_be_tb, dm_do_tb);
	    #0;
	 end
      end
   endtask


   task run_test4;
      integer 	    i;
      begin
	 $display("(TT) --------------------------------------------------");
	 $display("(TT) Test 4: Read Instruction Memory ");
	 $display("(TT) 1. Reads words from 0x0000000, 0x0000004, ...");
	 $display("(TT) 2. Pipelined. Should read 4095, 4094, ...");
	 $display("(TT) 3. The first read is invalid");
	 $display("(TT) --------------------------------------------------");
	 
	 resetb_tb = 1'b0;
	 dm_we_tb = 1'b0;
	 is_signed_tb = 1'b0;
	 @(posedge clk_tb)	    resetb_tb = 1'b1;
	 

	 for (i = 0; i < 8; i = i + 1) begin
	    im_addr_tb = 32'h0 + i*4;
	    @(posedge clk_tb);
	    $display("(TT) im_addr = 0x%h, im_do(prev) = %d", 
		     im_addr_tb, im_do_tb);
	    #0;
	 end
      end
   endtask


   task run_test5;
      integer 	    i;
      begin
	 $display("(TT) --------------------------------------------------");
	 $display("(TT) Test 5: IO R/W ");
	 $display("(TT) 1. Writes 0, 1, ... to 0x80000000, ... consecutively in unsigned words");
	 $display("(TT) 2. The IO port should pipeline output the written values");
	 $display("(TT) 3. Then IO port is read");
	 $display("(TT) 4. IO port should read 4096, 4097, ...");
	 $display("(TT) 5. The first dm_do(prev) is invalid");
	 $display("(TT) --------------------------------------------------");
	 
	 resetb_tb = 1'b0;
	 dm_we_tb = 1'b0;
	 is_signed_tb = 1'b0;
	 @(posedge clk_tb)	    resetb_tb = 1'b1;
	 dm_we_tb = 1'b1;
	 

	 for (i = 0; i < 8; i = i + 1) begin
	    dm_addr_tb = 32'h80000000 + i*4;
	    dm_di_tb = i;
	    dm_be_tb = 4'b1111;
	    @(posedge clk_tb);
	    $display("(TT) io_we = %b, io_addr = 0x%h, io_data_write = 0x%h",
		     io_we_tb, io_addr_tb, io_data_write_tb);
	    #0;
	 end
	 dm_we_tb = 1'b0;

	 for (i = 0; i < 8; i = i + 1) begin
	    dm_addr_tb = 32'h80000000 + i*4;
	    dm_be_tb = 4'b1111;
	    @(posedge clk_tb);
	    $display("(TT) dm_addr = 0x%h, dm_be = %b, dm_do(prev) = %d", 
		     dm_addr_tb, dm_be_tb, dm_do_tb);
	    #0;
	 end
      end
   endtask

   
   assign im_data_tb = instruction_memory[im_addr_out_tb[11:2]];
   assign io_data_read_tb = io_memory[io_addr_tb[7:2]];
   
   mmu UUT(.clk(clk_tb), .resetb(resetb_tb), .dm_we(dm_we_tb), 
	   .im_addr(im_addr_tb), .im_do(im_do_tb),
	   .dm_addr(dm_addr_tb), .dm_di(dm_di_tb),
	   .dm_do(dm_do_tb), .dm_be(dm_be_tb),
	   .is_signed(is_signed_tb),
	   .im_addr_out(im_addr_out_tb), .im_data(im_data_tb),
	   .io_addr(io_addr_tb), .io_en(io_en_tb), .io_we(io_we_tb),
	   .io_data_read(io_data_read_tb), .io_data_write(io_data_write_tb)
	   );


   initial
     begin : RUN_ALL_TESTS
	$dumpfile("tb_log/mmu_tb.vcd");
	$dumpvars(0,mmu_tb);

	for (i = 0; i < 4096; i = i + 1) begin
	   instruction_memory[i] = 4095 - i;
	end
	for (i = 0; i < 256; i = i + 1) begin
	   io_memory[i] = 4096 + i;
	end

	@(posedge clk_tb);

	run_test1();
	run_test2();
	run_test3();
	run_test4();
	run_test5();

	$finish;
	
     end


endmodule
module mmu_tb();

   reg clk_tb, resetb_tb, dm_we_tb;
   reg [31:0] im_addr_tb, dm_addr_tb, dm_di_tb;
   wire [31:0] im_do_tb, dm_do_tb;
   reg [3:0]  dm_be_tb;
   reg 	      is_signed_tb;
   wire [11:2] im_addr_out_tb;
   wire [31:0] im_data_tb, io_data_read_tb, io_data_write_tb;
   wire [7:0]  io_addr_tb;
   wire        io_en_tb, io_we_tb;

   reg [31:0]  instruction_memory [0:4095];
   reg [31:0]  io_memory [0:255];

   integer     i;
   
   always begin : CLK_GENERATOR
      #5 clk_tb = 1'b0;
      #5 clk_tb = 1'b1;
   end


   task run_test1;
      integer 	    i;
      begin
	 $display("(TT) --------------------------------------------------");
	 $display("(TT) Test 1: Byte R/W ");
	 $display("(TT) 1. Writes 0, 1, ... to 0x10000000, ... consecutively in unsigned bytes");
	 $display("(TT) 2. Then reads from the same addresses. Values should be same");
	 $display("(TT) 3. The first dm_do(prev) is invalid");
	 $display("(TT) --------------------------------------------------");
	 
	 resetb_tb = 1'b0;
	 dm_we_tb = 1'b0;
	 is_signed_tb = 1'b0;
	 @(posedge clk_tb)	    resetb_tb = 1'b1;
	 dm_we_tb = 1'b1;
	 

	 for (i = 0; i < 8; i = i + 1) begin
	    dm_addr_tb = 32'h10000000 + i*4;
	    dm_di_tb = 4*i + 0;
	    dm_be_tb = 4'b0001;
	    @(posedge clk_tb);
	    dm_be_tb = 4'b0010;
	    dm_di_tb = 4*i + 1;
	    @(posedge clk_tb);
	    dm_be_tb = 4'b0100;
	    dm_di_tb = 4*i + 2;
	    @(posedge clk_tb);
	    dm_be_tb = 4'b1000;
	    dm_di_tb = 4*i + 3;
	    @(posedge clk_tb);
	 end
	 dm_we_tb = 1'b0;

	 for (i = 0; i < 8; i = i + 1) begin
	    dm_addr_tb = 32'h10000000 + i*4;
	    dm_be_tb = 4'b0001;
	    @(posedge clk_tb);
	    $display("(TT) dm_addr = 0x%h, dm_be = %b, dm_do(prev) = %d", 
		     dm_addr_tb, dm_be_tb, dm_do_tb);
	    #0;
	    dm_be_tb = 4'b0010;
	    @(posedge clk_tb);
	    $display("(TT) dm_addr = 0x%h, dm_be = %b, dm_do(prev) = %d", 
		     dm_addr_tb, dm_be_tb, dm_do_tb);
	    #0;
	    dm_be_tb = 4'b0100;
	    @(posedge clk_tb);
	    $display("(TT) dm_addr = 0x%h, dm_be = %b, dm_do(prev) = %d", 
		     dm_addr_tb, dm_be_tb, dm_do_tb);
	    #0;
	    dm_be_tb = 4'b1000;
	    @(posedge clk_tb);
	    $display("(TT) dm_addr = 0x%h, dm_be = %b, dm_do(prev) = %d", 
		     dm_addr_tb, dm_be_tb, dm_do_tb);
	    #0;
	 end
      end
   endtask


   task run_test2;
      integer 	    i;
      begin
	 $display("(TT) --------------------------------------------------");
	 $display("(TT) Test 2: Half Word R/W ");
	 $display("(TT) 1. Writes 0, 1, ... to 0x10000000, ... consecutively in unsigned half words");
	 $display("(TT) 2. Then reads from the same addresses. Values should be same");
	 $display("(TT) 3. The first dm_do(prev) is invalid");
	 $display("(TT) --------------------------------------------------");
	 
	 resetb_tb = 1'b0;
	 dm_we_tb = 1'b0;
	 is_signed_tb = 1'b0;
	 @(posedge clk_tb)	    resetb_tb = 1'b1;
	 dm_we_tb = 1'b1;
	 

	 for (i = 0; i < 8; i = i + 1) begin
	    dm_addr_tb = 32'h10000000 + i*4;
	    dm_di_tb = 2*i + 0;
	    dm_be_tb = 4'b0011;
	    @(posedge clk_tb);
	    dm_be_tb = 4'b1100;
	    dm_di_tb = 2*i + 1;
	    @(posedge clk_tb);
	 end
	 dm_we_tb = 1'b0;

	 for (i = 0; i < 8; i = i + 1) begin
	    dm_addr_tb = 32'h10000000 + i*4;
	    dm_be_tb = 4'b0011;
	    @(posedge clk_tb);
	    $display("(TT) dm_addr = 0x%h, dm_be = %b, dm_do(prev) = %d", 
		     dm_addr_tb, dm_be_tb, dm_do_tb);
	    #0;
	    dm_be_tb = 4'b1100;
	    @(posedge clk_tb);
	    $display("(TT) dm_addr = 0x%h, dm_be = %b, dm_do(prev) = %d", 
		     dm_addr_tb, dm_be_tb, dm_do_tb);
	    #0;
	 end
      end
   endtask

   task run_test3;
      integer 	    i;
      begin
	 $display("(TT) --------------------------------------------------");
	 $display("(TT) Test 3: Word R/W ");
	 $display("(TT) 1. Writes 0, 1, ... to 0x10000000, ... consecutively in unsigned words");
	 $display("(TT) 2. Then reads from the same addresses. Values should be same");
	 $display("(TT) 3. The first dm_do(prev) is invalid");
	 $display("(TT) --------------------------------------------------");
	 
	 resetb_tb = 1'b0;
	 dm_we_tb = 1'b0;
	 is_signed_tb = 1'b0;
	 @(posedge clk_tb)	    resetb_tb = 1'b1;
	 dm_we_tb = 1'b1;
	 

	 for (i = 0; i < 8; i = i + 1) begin
	    dm_addr_tb = 32'h10000000 + i*4;
	    dm_di_tb = i;
	    dm_be_tb = 4'b1111;
	    @(posedge clk_tb);
	 end
	 dm_we_tb = 1'b0;

	 for (i = 0; i < 8; i = i + 1) begin
	    dm_addr_tb = 32'h10000000 + i*4;
	    dm_be_tb = 4'b1111;
	    @(posedge clk_tb);
	    $display("(TT) dm_addr = 0x%h, dm_be = %b, dm_do(prev) = %d", 
		     dm_addr_tb, dm_be_tb, dm_do_tb);
	    #0;
	 end
      end
   endtask


   task run_test4;
      integer 	    i;
      begin
	 $display("(TT) --------------------------------------------------");
	 $display("(TT) Test 4: Read Instruction Memory ");
	 $display("(TT) 1. Reads words from 0x0000000, 0x0000004, ...");
	 $display("(TT) 2. Pipelined. Should read 4095, 4094, ...");
	 $display("(TT) 3. The first read is invalid");
	 $display("(TT) --------------------------------------------------");
	 
	 resetb_tb = 1'b0;
	 dm_we_tb = 1'b0;
	 is_signed_tb = 1'b0;
	 @(posedge clk_tb)	    resetb_tb = 1'b1;
	 

	 for (i = 0; i < 8; i = i + 1) begin
	    im_addr_tb = 32'h0 + i*4;
	    @(posedge clk_tb);
	    $display("(TT) im_addr = 0x%h, im_do(prev) = %d", 
		     im_addr_tb, im_do_tb);
	    #0;
	 end
      end
   endtask


   task run_test5;
      integer 	    i;
      begin
	 $display("(TT) --------------------------------------------------");
	 $display("(TT) Test 5: IO R/W ");
	 $display("(TT) 1. Writes 0, 1, ... to 0x80000000, ... consecutively in unsigned words");
	 $display("(TT) 2. The IO port should pipeline output the written values");
	 $display("(TT) 3. Then IO port is read");
	 $display("(TT) 4. IO port should read 4096, 4097, ...");
	 $display("(TT) 5. The first dm_do(prev) is invalid");
	 $display("(TT) --------------------------------------------------");
	 
	 resetb_tb = 1'b0;
	 dm_we_tb = 1'b0;
	 is_signed_tb = 1'b0;
	 @(posedge clk_tb)	    resetb_tb = 1'b1;
	 dm_we_tb = 1'b1;
	 

	 for (i = 0; i < 8; i = i + 1) begin
	    dm_addr_tb = 32'h80000000 + i*4;
	    dm_di_tb = i;
	    dm_be_tb = 4'b1111;
	    @(posedge clk_tb);
	    $display("(TT) io_we = %b, io_addr = 0x%h, io_data_write = 0x%h",
		     io_we_tb, io_addr_tb, io_data_write_tb);
	    #0;
	 end
	 dm_we_tb = 1'b0;

	 for (i = 0; i < 8; i = i + 1) begin
	    dm_addr_tb = 32'h80000000 + i*4;
	    dm_be_tb = 4'b1111;
	    @(posedge clk_tb);
	    $display("(TT) dm_addr = 0x%h, dm_be = %b, dm_do(prev) = %d", 
		     dm_addr_tb, dm_be_tb, dm_do_tb);
	    #0;
	 end
      end
   endtask

   
   assign im_data_tb = instruction_memory[im_addr_out_tb[11:2]];
   assign io_data_read_tb = io_memory[io_addr_tb[7:2]];
   
   mmu UUT(.clk(clk_tb), .resetb(resetb_tb), .dm_we(dm_we_tb), 
	   .im_addr(im_addr_tb), .im_do(im_do_tb),
	   .dm_addr(dm_addr_tb), .dm_di(dm_di_tb),
	   .dm_do(dm_do_tb), .dm_be(dm_be_tb),
	   .is_signed(is_signed_tb),
	   .im_addr_out(im_addr_out_tb), .im_data(im_data_tb),
	   .io_addr(io_addr_tb), .io_en(io_en_tb), .io_we(io_we_tb),
	   .io_data_read(io_data_read_tb), .io_data_write(io_data_write_tb)
	   );


   initial
     begin : RUN_ALL_TESTS
	$dumpfile("tb_log/mmu_tb.vcd");
	$dumpvars(0,mmu_tb);

	for (i = 0; i < 4096; i = i + 1) begin
	   instruction_memory[i] = 4095 - i;
	end
	for (i = 0; i < 256; i = i + 1) begin
	   io_memory[i] = 4096 + i;
	end

	@(posedge clk_tb);

	run_test1();
	run_test2();
	run_test3();
	run_test4();
	run_test5();

	$finish;
	
     end


endmodule