`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
//
// uLab GPMC interface verification test bench
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// (c) 2014 Timothy Pearson
// Raptor Engineering
// http://www.raptorengineeringinc.com
//
//////////////////////////////////////////////////////////////////////////////////

module verification;

	// Inputs
	reg clk;
	reg gpmc_advn;
	reg gpmc_oen;
	reg gpmc_wen;
	reg [15:0] gpmc_address;
	reg usermem_wen;
	reg userproc_done;
	reg userlogic_clock;
	reg userlogic_serial_rxd;
	reg host_serial_rxd;
	reg [3:0] four_bit_leds;
	reg [7:0] eight_bit_leds;
	reg sixteen_bit_io_wen;
	reg [3:0] sseg_mux;
	reg [7:0] sseg_data;

	// Outputs
	wire usermem_wait;
	wire userproc_start;
	wire userlogic_reset;
	wire userlogic_serial_txd;
	wire host_serial_txd;
	wire [3:0] four_bit_switches;
	wire [7:0] eight_bit_switches;
	wire sixteen_bit_io_mode;
	wire userdevice_reset;

	// Bidirs
	wire [7:0] gpmc_data;
	wire [7:0] usermem_data;
	wire [15:0] usermem_address;
	wire [15:0] sixteen_bit_io;

	// Instantiate the Unit Under Test (UUT)
	main uut (
		.clk(clk), 
		.gpmc_advn(gpmc_advn), 
		.gpmc_oen(gpmc_oen), 
		.gpmc_wen(gpmc_wen), 
		.gpmc_data(gpmc_data), 
		.gpmc_address(gpmc_address), 
		.usermem_wen(usermem_wen), 
		.usermem_wait(usermem_wait), 
		.usermem_data(usermem_data), 
		.usermem_address(usermem_address), 
		.userproc_start(userproc_start), 
		.userproc_done(userproc_done), 
		.userlogic_reset(userlogic_reset), 
		.userlogic_clock(userlogic_clock), 
		.userlogic_serial_txd(userlogic_serial_txd), 
		.userlogic_serial_rxd(userlogic_serial_rxd), 
		.host_serial_txd(host_serial_txd), 
		.host_serial_rxd(host_serial_rxd), 
		.four_bit_leds(four_bit_leds), 
		.eight_bit_leds(eight_bit_leds), 
		.four_bit_switches(four_bit_switches), 
		.eight_bit_switches(eight_bit_switches), 
		.sixteen_bit_io(sixteen_bit_io), 
		.sixteen_bit_io_wen(sixteen_bit_io_wen), 
		.sixteen_bit_io_mode(sixteen_bit_io_mode), 
		.sseg_mux(sseg_mux), 
		.sseg_data(sseg_data), 
		.userdevice_reset(userdevice_reset)
	);

	reg gpmc_data_driven = 0;
	reg [7:0] gpmc_data_out;
	assign gpmc_data = (gpmc_data_driven) ? gpmc_data_out : 8'bz;

	// Generate 100MHz clock
	always begin
		#5;
		clk = !clk;
	end

	// Terminate test bench after specified time has elapsed
	initial begin
		#10000;
		$finish;
	end

	// Test logic analyzer triggering and data acquisition
	initial begin
		// Initialize Inputs
		clk = 0;
		gpmc_advn = 0;
		gpmc_oen = 0;
		gpmc_wen = 0;
		gpmc_address = 0;
		usermem_wen = 0;
		userproc_done = 0;
		userlogic_clock = 0;
		userlogic_serial_rxd = 0;
		host_serial_rxd = 0;
		four_bit_leds = 0;
		eight_bit_leds = 0;
		sixteen_bit_io_wen = 0;
		sseg_mux = 0;
		sseg_data = 0;

		// Wait 100 ns for global reset to finish
		#100;

		// Send user logic reset signal to GPMC interface
		gpmc_address = 16'h000c;
		gpmc_data_out = 8'h01;
		gpmc_data_driven = 1'b1;
		gpmc_advn = 1'b0;
		gpmc_wen = 1'b0;
		#1000
		gpmc_address = 16'h000c;
		gpmc_data_out = 8'h00;
		gpmc_data_driven = 1'b1;
		gpmc_advn = 1'b0;
		gpmc_wen = 1'b0;
		#100
		gpmc_data_driven = 1'b0;
		gpmc_advn = 1'b1;
		gpmc_wen = 1'b1;
	end
      
endmodule

