// 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

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

/*
 * This testbench expands upon test2 by doing a complete load of data
 * to all cells in the array, and then testing that the cells are
 * generating the correct function by applying input via the logic
 * analyzer, and reading output from the GPIO (the C program reads
 * output from the logic analyzer and copies it to the GPIO).
 */

module chaos_test3_tb;
	reg clock;
	reg RSTB;
	reg CSB;

	reg power1, power2;

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

	assign checkbits  = mprj_io[31:16];
	assign uart_tx = mprj_io[6];
	assign checklut  = mprj_io[15:8];

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

	initial begin
		clock = 0;
	end

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

	initial begin
		$dumpfile("chaos_test3.vcd");
		// $dumpvars(0, chaos_test3_tb);
		// Check the overall signals in the chaos automaton without
		// saving tons of data from the 400 individual cells.
		$dumpvars(1, chaos_test3_tb);
		$dumpvars(1, chaos_test3_tb.uut.mprj.chaos);
		$dumpvars(1, chaos_test3_tb.uut.mprj.chaos.chaos_array_inst);

		// Test break-out cell (see note in chaos_automaton.v)
		// $dumpvars(1, chaos_test3_tb.uut.mprj.chaos.chaos_array_inst.chaos_cell_inst_0_0);
		// And look at the LUT values in above cells.
		// $dumpvars(0, chaos_test3_tb.uut.mprj.chaos.chaos_array_inst.chaos_cell_inst_0_0.lutdata[3]);

		// Check where in the program the CPU is operating
		$dumpvars(1, chaos_test3_tb.uut.soc.soc.cpu.picorv32_core.dbg_insn_addr);
		$dumpvars(1, chaos_test3_tb.uut.soc.soc.cpu.picorv32_core.dbg_insn_opcode);
		$dumpvars(1, chaos_test3_tb.uut.soc.soc.cpu.picorv32_core.dbg_ascii_instr);
		// Check GPIO serial load, which gates the 1st part of the simulation
		$dumpvars(1, chaos_test3_tb.uut.mprj_io_loader_clock);
		$dumpvars(1, chaos_test3_tb.uut.mprj_io_loader_resetn);

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

	initial begin
		wait(checkbits == 16'hAB40);
		$display("Chaos Test 3 started");
		wait(checkbits == 16'hAB41);
		$display("Chaos Test 3 midpoint");
		wait(checkbits == 16'h0000);
		$display("Chaos Test 3 saw LUT data = 0000");
		wait(checkbits == 16'hffff);
		$display("Chaos Test 3 saw LUT data = FFFF");
		wait(checkbits == 16'hAB51);
		#10000;
		$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;
		#200;
		power1 <= 1'b1;
		#200;
		power2 <= 1'b1;
	end

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

	wire VDD1V8;
    	wire VDD3V3;
	wire VSS;
    
	assign VDD3V3 = power1;
	assign VDD1V8 = power2;
	assign VSS = 1'b0;

	caravel uut (
		.vddio	  (VDD3V3),
		.vssio	  (VSS),
		.vdda	  (VDD3V3),
		.vssa	  (VSS),
		.vccd	  (VDD1V8),
		.vssd	  (VSS),
		.vdda1    (VDD3V3),
		.vdda2    (VDD3V3),
		.vssa1	  (VSS),
		.vssa2	  (VSS),
		.vccd1	  (VDD1V8),
		.vccd2	  (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("chaos_test3.hex")
	) spiflash (
		.csb(flash_csb),
		.clk(flash_clk),
		.io0(flash_io0),
		.io1(flash_io1),
		.io2(),			// not used
		.io3()			// not used
	);

	// Testbench UART
	tbuart tbuart (
		.ser_rx(uart_tx)
	);

endmodule
`default_nettype wire
