// SPDX-FileCopyrightText: 2020 Efabless Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// SPDX-License-Identifier: Apache-2.0

`default_nettype none

`timescale 1 ns / 1 ps

`define FULL_CHIP_SIM

`include "uprj_netlists.v"
`include "caravel_netlists.v"
`include "spiflash.v"
`include "uart_agent.v"

module uart_master_tb;
	reg clock;
	reg RSTB;
	reg CSB;
	reg power1, power2;
	reg power3, power4;

	wire gpio;
	wire [37:0] mprj_io;
	wire [7:0] mprj_io_0;
	wire [15:0] checkbits;

//----------------------------------
// Uart Configuration
// ---------------------------------
reg [1:0]      uart_data_bit        ;
reg	       uart_stop_bits       ; // 0: 1 stop bit; 1: 2 stop bit;
reg	       uart_stick_parity    ; // 1: force even parity
reg	       uart_parity_en       ; // parity enable
reg	       uart_even_odd_parity ; // 0: odd parity; 1: even parity

reg [7:0]      uart_data            ;
reg [15:0]     uart_divisor         ;	// divided by n * 16
reg [15:0]     uart_timeout         ;// wait time limit

reg [15:0]     uart_rx_nu           ;
reg [15:0]     uart_tx_nu           ;
reg [7:0]      uart_write_data [0:39];
reg 	       uart_fifo_enable     ;	// fifo mode disable

reg [31:0]     read_data     ;
reg            flag;
reg            test_fail     ;


	assign checkbits = mprj_io[31:16];

	assign mprj_io[3] = (CSB == 1'b1) ? 1'b1 : 1'bz;

	// External clock is used by default.  Make this artificially fast for the
	// simulation.  Normally this would be a slow clock and the digital PLL
	// would be the fast clock.

	always #12.5 clock <= (clock === 1'b0);

	initial begin
		clock = 0;
	end

	`ifdef WFDUMP
	initial begin
		$dumpfile("simx.vcd");
		$dumpvars(1, uart_master_tb);
		$dumpvars(1, uart_master_tb.uut);
		$dumpvars(1, uart_master_tb.uut.mprj);
		$dumpvars(1, uart_master_tb.uut.mprj.u_wb_host);
		$dumpvars(1, uart_master_tb.uut.mprj.u_wb_host.u_uart2wb);
		$dumpvars(1, uart_master_tb.tb_master_uart);
		//$dumpvars(2, uart_master_tb.uut.mprj.u_pinmux);
	end
       `endif

	initial begin

		// Repeat cycles of 1000 clock edges as needed to complete testbench
		repeat (400) begin
			repeat (1000) @(posedge clock);
			// $display("+1000 cycles");
		end
		$display("%c[1;31m",27);
		$display ("##########################################################");
		`ifdef GL
		   $display ("Monitor: Timeout, Test UART Master (GL) Failed");
		`else
		   $display ("Monitor: Timeout, Test UART Master (RTL) Failed");
		`endif
		$display ("##########################################################");
		$display("%c[0m",27);
		$finish;
	end

	initial begin
            uart_data_bit           = 2'b11;
            uart_stop_bits          = 1; // 0: 1 stop bit; 1: 2 stop bit;
            uart_stick_parity       = 0; // 1: force even parity
            uart_parity_en          = 0; // parity enable
            uart_even_odd_parity    = 1; // 0: odd parity; 1: even parity
            uart_divisor            = 15;// divided by n * 16
            uart_timeout            = 600;// wait time limit
            uart_fifo_enable        = 0;	// fifo mode disable
            tb_master_uart.debug_mode = 0; // disable debug display
            tb_master_uart.uart_init;
            tb_master_uart.control_setup (uart_data_bit, uart_stop_bits, uart_parity_en, uart_even_odd_parity, 
        	                          uart_stick_parity, uart_timeout, uart_divisor);
	   wait(checkbits == 16'h AB60);
		$display("Monitor: UART Master Test Started");

           repeat (4000) @(posedge clock);
           //$write ("\n(%t)Response:\n",$time);
           flag = 0;
           while(flag == 0)
           begin
                tb_master_uart.read_char(read_data,flag);
                $write ("%c",read_data);
           end



           // Remove Wb Reset
           uartm_reg_write('h3080_0000,'h1);

           repeat (2) @(posedge clock);
           #1;

           $display("Monitor: Writing  expected value");
           
           test_fail = 0;
           uartm_reg_write(32'h30020058,32'h11223344);
           uartm_reg_write(32'h3002005C,32'h22334455);
           uartm_reg_write(32'h30020060,32'h33445566);
           uartm_reg_write(32'h30020064,32'h44556677);
           uartm_reg_write(32'h30020068,32'h55667788);
           uartm_reg_write(32'h3002006C,32'h66778899);

           uartm_reg_read_check(32'h30020058,32'h11223344);
           uartm_reg_read_check(32'h3002005C,32'h22334455);
           uartm_reg_read_check(32'h30020060,32'h33445566);
           uartm_reg_read_check(32'h30020064,32'h44556677);
           uartm_reg_read_check(32'h30020068,32'h55667788);
           uartm_reg_read_check(32'h3002006C,32'h66778899);

           $display("###################################################");
           if(test_fail == 0) begin
              `ifdef GL
                  $display("Monitor: Standalone User UART Master (GL) Passed");
              `else
                  $display("Monitor: Standalone User Uart Master (RTL) Passed");
              `endif
           end else begin
               `ifdef GL
                   $display("Monitor: Standalone User Uart Master (GL) Failed");
               `else
                   $display("Monitor: Standalone User Uart Master (RTL) Failed");
               `endif
            end
           $display("###################################################");
           #100

	    $finish;
	end

	initial begin
		RSTB <= 1'b0;
		CSB  <= 1'b1;		// Force CSB high
		#2000;
		RSTB <= 1'b1;	    	// Release reset
		#170000;
		CSB = 1'b0;		// CSB can be released
	end

	initial begin		// Power-up sequence
		power1 <= 1'b0;
		power2 <= 1'b0;
		power3 <= 1'b0;
		power4 <= 1'b0;
		#100;
		power1 <= 1'b1;
		#100;
		power2 <= 1'b1;
		#100;
		power3 <= 1'b1;
		#100;
		power4 <= 1'b1;
	end

	//always @(mprj_io) begin
	//	#1 $display("MPRJ-IO state = %b ", mprj_io[7:0]);
	//end

	wire flash_csb;
	wire flash_clk;
	wire flash_io0;
	wire flash_io1;

	wire VDD3V3 = power1;
	wire VDD1V8 = power2;
	wire USER_VDD3V3 = power3;
	wire USER_VDD1V8 = power4;
	wire VSS = 1'b0;

	caravel uut (
		.vddio	  (VDD3V3),
		.vssio	  (VSS),
		.vdda	  (VDD3V3),
		.vssa	  (VSS),
		.vccd	  (VDD1V8),
		.vssd	  (VSS),
		.vdda1    (USER_VDD3V3),
		.vdda2    (USER_VDD3V3),
		.vssa1	  (VSS),
		.vssa2	  (VSS),
		.vccd1	  (USER_VDD1V8),
		.vccd2	  (USER_VDD1V8),
		.vssd1	  (VSS),
		.vssd2	  (VSS),
		.clock	  (clock),
		.gpio     (gpio),
        .mprj_io  (mprj_io),
		.flash_csb(flash_csb),
		.flash_clk(flash_clk),
		.flash_io0(flash_io0),
		.flash_io1(flash_io1),
		.resetb	  (RSTB)
	);

	spiflash #(
		.FILENAME("uart_master.hex")
	) spiflash (
		.csb(flash_csb),
		.clk(flash_clk),
		.io0(flash_io0),
		.io1(flash_io1),
		.io2(),			// not used
		.io3()			// not used
	);




`ifndef GL // Drive Power for Hold Fix Buf
    // All standard cell need power hook-up for functionality work
    initial begin
    end
`endif    


//---------------------------
//  UART Agent integration
// --------------------------
wire uart_txd,uart_rxd;

assign uart_txd   = mprj_io[35];
assign mprj_io[34]  = uart_rxd ;
 
uart_agent tb_master_uart(
	.mclk                (clock              ),
	.txd                 (uart_rxd           ),
	.rxd                 (uart_txd           )
	);


`include "uart_master_tasks.sv"

endmodule
`default_nettype wire
