////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 1995-2003 Xilinx, Inc.
// All Right Reserved.
////////////////////////////////////////////////////////////////////////////////
//   ____  ____ 
//  /   /\/   / 
// /___/  \  /    Vendor: Xilinx 
// \   \   \/     Version : 8.1.03i
//  \   \         Application : ISE
//  /   /         Filename : cpu_tb.tfw
// /___/   /\     Timestamp : Mon Nov 12 01:08:47 2007
// \   \  /  \ 
//  \___\/\___\ 
//
//Command: 
//Design Name: cpu_tb
//Device: Xilinx
//
`timescale 1ns/1ps

module cpu_tb;
    wire [31:0] addr;
    reg [31:0] data$inout$reg = 32'b00000000000000000000000000000000;
    // wire [31:0] data = data$inout$reg;
		wire [31:0] data;
    wire readmem;
    wire writemem;
    reg intrq = 1'b0;
    wire [1:0] type;
    reg rst = 1'b1;
    reg clk = 1'b0;

    parameter PERIOD = 20;
    // parameter real DUTY_CYCLE = 0.5;
    parameter OFFSET = 0;

    initial    // Clock process for clk
    begin
        #OFFSET;
        forever
        begin
            clk = 1'b0;
//            #(PERIOD-(PERIOD*DUTY_CYCLE)) clk = 1'b1;
//            #(PERIOD*DUTY_CYCLE);
              #20 clk = 1'b1;
              #20;
       end
    end
		
	
	wire[7:0] sevseg;
	wire[3:0] anod;
	wire r, g, b;
	wire hs, vs;
	wire[7:0] sw = 8'b00001110;
	wire[2:0] btn = 3'b000;
	wire[7:0] ld;
	
	
	main UUT (.clk(clk), .sevseg(sevseg), .anod(anod), 
		.ps2d(1'b0), .ps2c(1'b0), 
		.r(r), .g(g), .b(b), .hs(hs), .vs(vs), .sw(sw), 
		.btn(btn), .ld(ld), .rst(rst), .clk_aux(clk));


    integer TX_FILE = 0;
    integer TX_ERROR = 0;

		initial
		begin


			$monitor ( "rst = %h sel_A_reg = %h addr = %h datain = %h readmem = %h writemem = %h datain = %h regA = %h regC = %h rdack_A = %h tos = %h csp = %h micr_pc = %h pc = %h ir = %h clk_cpu= %h",
								rst, UUT.sel_A_reg, UUT.addr, UUT.datain, UUT.readmem, UUT.writemem, UUT.cpu0.datain,
								UUT.cpu0.regA, UUT.cpu0.regC, UUT.rdack_A, UUT.cpu0.tos, UUT.cpu0.csp, 
								UUT.cpu0.micr_pc, UUT.cpu0.pc, UUT.cpu0.ir, UUT.clk_cpu ); 

/*
			$monitor ( "addr_bus = %h data = %h data_b_r = %h readmem = %h writemem = %h enmem_bus = %h enmem_A = %h wmem_A = %h datamem_A = %h wmem_bus = %h rdack_A = %h rd_last_A = %h sel_A = %h sel_B = %h csp = %h micr_pc = %h pc = %h ir = %h clk_cpu= %h",
								UUT.addr_bus, UUT.data, UUT.data_b_r, UUT.readmem, UUT.writemem, 
								UUT.enmem_bus, UUT.enmem_A, UUT.wmem_A, UUT.datamem_A, UUT.wmem_bus, UUT.rdack_A, UUT.rd_last_A, UUT.sel_A, UUT.sel_B, UUT.cpu0.csp, 
								UUT.cpu0.micr_pc, UUT.cpu0.pc, UUT.cpu0.ir, UUT.clk_cpu ); 

*/
/*

			$monitor ( "micr_pc = %h data = %h template = %h clk = %h ", 
							UUT.cpu0.micr_pc, UUT.data_cpu,  UUT.cpu0.template, clk);

*/
/*

	 		$monitor ("addr = %h writemem = %h ir = %h pc = %h to_page_zero = %h pcb_source = %h template = %h regA = %h regB = %h dsp = %h tos = %h", 
					addr, writemem, UUT.ir, UUT.pc, UUT.to_page_zero, UUT.pcb_source, UUT.template, UUT.regA, UUT.regB, 
					UUT.dsp, UUT.tos );




			$monitor ("ir = %h", 
				UUT.cpu0.ir);



			$monitor ("ir = %h data = %h enbus = %h enbus_1 = %h rack = %h readmem = %h writemem = %h waitcpu_w = %h micr_pc = %h clk = %h", 
				UUT.ir, data, mar0.enbus, mar0.enbus_1, rdack, readmem, writemem, waitcpu_w, UUT.micr_pc, clk);
*/

		end


    
    initial begin  // Open the results file...
        TX_FILE = $fopen("results.txt");
        #50000 // old pFinal time:  1020 ns
				$displayh ( UUT.cpu0.ir );
        if (TX_ERROR == 0) begin
            $display("No errors or warnings.");
            $fdisplay(TX_FILE, "No errors or warnings.");
        end else begin
            $display("%d errors found in simulation.", TX_ERROR);
            $fdisplay(TX_FILE, "%d errors found in simulation.", TX_ERROR);
        end
        $fclose(TX_FILE);
        $stop;
    end

    initial begin
        // -------------  Current Time:  29ns
        //#25;
		  #843
        rst = 1'b0;
        data$inout$reg = 32'bZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ;
        // -------------------------------------
    end


		initial begin		
				#0;
				forever
					begin
					@(posedge clk);
					if (UUT.cpu0.ir[23:16] == 8'h3c)
						begin
							$display ("**** print %h ", UUT.cpu0.tos );
						end
					end
		end


    task CHECK_addr;
        input [31:0] NEXT_addr;

        #0 begin
            if (NEXT_addr !== addr) begin
                $display("Error at time=%dns addr=%b, expected=%b", $time, addr, NEXT_addr);
                $fdisplay(TX_FILE, "Error at time=%dns addr=%b, expected=%b", $time, addr, NEXT_addr);
                $fflush(TX_FILE);
                TX_ERROR = TX_ERROR + 1;
            end
        end
    endtask
    task CHECK_readmem;
        input NEXT_readmem;

        #0 begin
            if (NEXT_readmem !== readmem) begin
                $display("Error at time=%dns readmem=%b, expected=%b", $time, readmem, NEXT_readmem);
                $fdisplay(TX_FILE, "Error at time=%dns readmem=%b, expected=%b", $time, readmem, NEXT_readmem);
                $fflush(TX_FILE);
                TX_ERROR = TX_ERROR + 1;
            end
        end
    endtask
    task CHECK_writemem;
        input NEXT_writemem;

        #0 begin
            if (NEXT_writemem !== writemem) begin
                $display("Error at time=%dns writemem=%b, expected=%b", $time, writemem, NEXT_writemem);
                $fdisplay(TX_FILE, "Error at time=%dns writemem=%b, expected=%b", $time, writemem, NEXT_writemem);
                $fflush(TX_FILE);
                TX_ERROR = TX_ERROR + 1;
            end
        end
    endtask
    task CHECK_type;
        input [1:0] NEXT_type;

        #0 begin
            if (NEXT_type !== type) begin
                $display("Error at time=%dns type=%b, expected=%b", $time, type, NEXT_type);
                $fdisplay(TX_FILE, "Error at time=%dns type=%b, expected=%b", $time, type, NEXT_type);
                $fflush(TX_FILE);
                TX_ERROR = TX_ERROR + 1;
            end
        end
    endtask

endmodule

