/// LSU EE 3755 -- Spring 2002 -- Computer Organization // /// Testbench for MIPS Functional Simulator // // Does not actually test, just runs it. // // Time-stamp: <24 April 2002, 12:03:47 CDT, koppel@sol> // exemplar translate_off `ifdef MEMBASE `else `define MEMBASE 'h400000 `define DATABASE 'h10010000 `define TEXTSIZE 'h100 `define MEMSIZE 'h200 `define MEMRANGE `MEMBASE:`MEMBASE+`MEMSIZE-1 `define A(addr) ((addr)-`DATABASE+`MEMBASE+`TEXTSIZE) `define MEM(addr) mem[((addr)-`DATABASE+`MEMBASE+`TEXTSIZE)] `endif module test_proc(); wire exception; reg clk; integer cycle_count; parameter cycle_limit = 20; proc dut(exception,clk); reg [31:0] gpr_shadow [0:31]; reg [319:0] isource[`MEMBASE>>2:((`MEMBASE+`MEMSIZE)>>2)-1]; reg [31:0] regname [0:31]; integer i, reg_old, reg_new; always begin clk = 0; #10; clk = 1; #10; end task initmem; input [31:0] addr; input [31:0] text; input [319:0] source; begin if( addr & 3 ) begin $display("Unaligned instruction address, 0x%h",addr); $stop; end if( addr < `MEMBASE || addr >= `MEMBASE + `TEXTSIZE ) begin $display("Address 0x%h out of range.",addr); $stop; end {dut.mem[addr],dut.mem[addr+1],dut.mem[addr+2],dut.mem[addr+3]} = text; while( source[319:312] === 8'b0 ) source = {source[311:0]," "}; isource[addr>>2] = source; end endtask task initdmem; input [31:0] addr; input [31:0] word; reg [31:0] daddr; begin if( addr & 3 ) begin $display("Unaligned data address, 0x%h",addr); $stop; end if( addr < `DATABASE || `A(addr) >= `MEMBASE + `MEMSIZE ) begin $display("Data address 0x%h out of range.",addr); $stop; end daddr = `A(addr); {dut.mem[daddr],dut.mem[daddr+1], dut.mem[daddr+2],dut.mem[daddr+3]} = word; end endtask function [4:0] ito5; input i; integer i; ito5 = i; endfunction integer rno; task initregs; input [31:0] name; input [3:0] cnt; integer i; for(i=0; i<cnt; i=i+1) begin regname[rno] = name + i; rno = rno + 1; end endtask initial begin cycle_count = 0; begin regname[0] = "zero"; regname[1] = "at"; rno = 2; initregs("v0",2); initregs("a0",4); initregs("t0",8); initregs("s0",8); initregs("t8",2); initregs("k0",2); regname[28] = "gp"; regname[29] = "sp"; regname[30] = "fp"; regname[31] = "ra"; end `include `MIPS_PROG for(i=0; i<32; i=i+1) dut.gpr[i] = i*10; for(i=0; i<32; i=i+1) gpr_shadow[i] = dut.gpr[i]; dut.pc = 'h400000; dut.npc = dut.pc + 4; wait( clk == 0 ); forever begin $display("PC 0x%h: %-s",dut.pc,isource[dut.pc>>2]); @( negedge clk ); for(i=0; i<32; i=i+1) if( gpr_shadow[i] !== dut.gpr[i] ) begin reg_old = gpr_shadow[i]; reg_new = dut.gpr[i]; $display(" Register $%d (%s): 0x%h (%d) -> 0x%h (%d)", ito5(i), regname[i], gpr_shadow[i], reg_old, dut.gpr[i], reg_new); gpr_shadow[i] = dut.gpr[i]; end if( exception ) begin $display("Exception, stopping simulation."); $stop; end cycle_count = cycle_count + 1; if( cycle_count >= cycle_limit ) begin $display("Cycle count limit reached, stopping."); $stop; end end end endmodule