//  Project:           ESY-Praktikum-Testbench
//  File:              random_tl.sv
//  Title:             Random Testbench Toplevel
//  Description:       Creates a Testbench that tests the Toplevel-Design with random based verifikation
//                 
//
// --------------------------------------------------------------------
//
//------------------------------------------------------------
// Notes:
//
//
//------------------------------------------------------------
// Development History:
//
//   __DATE__ _BY_ _REV_ _DESCRIPTION___________________________
//   14/06/22  JU/TL  1.0    Initial testbench design
//
//------------------------------------------------------------
// Dependencies:
//	Toplevel-Design
// 
//
//------------------------------------------------------------



//------------------------------------------------------------
// 
//
//                     Testbench
//
//------------------------------------------------------------

class Taster_rnd;
	rand bit [1:0] data;
	constraint Rst_rnd
	{
	data dist {0:=70,1 :=30};
	}
endclass

class Data_ADC_rnd;
	rand bit [7:0] data;
endclass


`timescale 1ns/1ps
module tb;

// inputs and outputs
reg taster;
reg [7:0]data_ADC;
reg clk12M;
wire RED;
wire GRN;
wire alarm;
wire alarm_r;
wire SI;
wire SO;
wire SCK;
wire nCS;
reg endOfConvRnd;

//random
Taster_rnd taster_rnd = new();
Data_ADC_rnd data_ADC_rnd = new();

// connect module
SPI_FRAM_Module fram_storage(
.SI(SI),
.SO(SO),
.SCK(SCK),
.nCS(nCS),.opcode(),.addr());
Top top(.clk(clk12M),.rst(taster),.endOfConv(endOfConvRnd),.LEDg(GRN),.LEDr(RED),.AlarmAmpel(alarm),.Alarm_R(alarm_r));

initial
begin
    clk12M=1'b0;
end
always 
  #41.666666 clk12M=~clk12M;                             //clock generation
  
//random test
 initial begin
		endOfConvRnd = 1;	 
	repeat (2) begin
		#100000000
		#100000000
		#100000000
		#100000000
		#100000000
		#100000000
		#100000000
		#100000000
		#100000000
		#100000000
		data_ADC_rnd.randomize();
		taster_rnd.randomize();
		
		taster = taster_rnd.data;		
		data_ADC = data_ADC_rnd.data;

		
		// assertions

		// assert color green
		assert property(@(posedge clk12M) disable iff (alarm | alarm_r) ((data_ADC < 100) |=> ##4 (!RED && GRN)));
		
		//assert color yellow
		
		assert property(@(posedge clk12M) disable iff (alarm | alarm_r) (((data_ADC >= 100) && (data_ADC <= 168))|=> ##4 (RED && GRN)));
		
		//assert color red + alarm
		
		assert property(@(posedge clk12M) disable iff (alarm_r) (data_ADC > 168) |=> ##4 (RED && !GRN && alarm));
		
		//assert alarm reset working
		
		assert property(@(posedge clk12M) (alarm_r |=> ##4 (!RED && !GRN && !alarm)));
		
		$monitor("time=%t, data_ADC=%d, RED=%d, GRN=%d, taster=%d",$time,data_ADC, RED, GRN, taster);
	end
	$stop;
end

endmodule

