///////////////////////////////////////////////////
//                                               //
// COLUTAV4_FPGA_tester.v                        //
//   v1.1 for Cyclone Fpga       jb/2021.        //
//                                               //
///////////////////////////////////////////////////
`timescale 1ns/1ps 
module COLUTA_FPGA_tester;

//parameters

parameter clk9600_hp = 0.052; //half period of 9.6GHz clock (52.083333ps), units are ns

parameter FTDI_to_FPGA = 1'b0;
parameter FPGA_to_FTDI = 1'b1; 

parameter  I2C_NOP    = 3'b000; //Wishbone commands
parameter  I2C_W_INIT = 3'b001; //I2C Wishbone registers init
parameter  I2C_WR     = 3'b010;
parameter  I2C_RD     = 3'b100;  
parameter  I2C_ERR    = 3'b011;    
parameter  I2C_DELAY  = 3'b111;
parameter  STP        = 1'b1;   //stop bit generated
parameter  NSTP       = 1'b0;   //no stop bit required

parameter  sim_type = 0; //0- functional simulation 1-pnr simulation

//variables
wire        BC_RST;
reg         reset;
reg         FTDI_A_op=1'b0, FTDI_B_op=1'b0;
reg         start_FTDI_A_op=1'b0, start_FTDI_B_op=1'b0;
wire  [7:0] DATA_A, DATA_B;
reg [319:0] DATA_to_FTDI_A={320{1'b0}}, DATA_to_FTDI_B={320{1'b0}}, 
            status_read_back_data, FIFO_A_read_back_data,
            USB_I2C_cmd;
reg  [23:0] read_only_bits=24'h8acda1;
wire[319:0] DATA_from_FTDI_A, DATA_from_FTDI_B;
reg         clk_40M=1'b0;
reg         clk_9600M=1'b0, clk_4800M=1'b0, clk_640M=1'b0, clk_320M=1'b0, clk_160M=1'b0, clk_80M=1'b0; 
reg         clk_20M=1'b0, clk_10M=1'b0, clk_5M=1'b0;

reg         WR_bit=1'b0, RD_bit=1'b1;
reg         Stop_condition_detected, Start_condition_detected;
reg   [7:0] NUM_WORDS_A, NUM_WORDS_B;
wire[127:0] global_cntrl_bits;
reg   [3:0] chip_id=4'b0001;
wire  [7:0] frm, dat;
integer     i;


//test bench SCL, SDA            
wire        SCL;
wire        SDA;
pullup (weak1)(SDA);

supply0	    gnd;
//the model of nmos inside COLUTA chip
wire         SDAen, SDAo, SDA_OC;
assign SDA = SDAen ? SDAo : 1'bz;
pullup (weak1)(SDA);
//nmos	(SDA, gnd, SDA_OC);   



//tranif0

always begin
@(posedge SDA) Stop_condition_detected <= SCL;
end
always begin
@(negedge SDA) Start_condition_detected <= SCL;
end



reg   [7:0] cntrl_byte8  = 8'b00000000,
            cntrl_byte9  = 8'b00000001,
            cntrl_byte10 = 8'b00000010,
            cntrl_byte11 = 8'b00000011,
            cntrl_byte12 = 8'b00000100,
            cntrl_byte13 = 8'b00000101,
            cntrl_byte14 = 8'b00000110,
            cntrl_byte15 = 8'b00000111;

reg [127:0] dr, dw, dw1, dw2 ;
reg   [5:0] addr;
reg         i2c_data_ok=0;
reg  [15:0] aw1, aw2, aw3, aw4;


//9.6GHz clock generator
always 
 begin
  clk_9600M=0;
  #clk9600_hp;
  clk_9600M=1;
  #clk9600_hp;
 end

//4.8GHz generator
always @ (posedge clk_9600M)
clk_4800M <= !clk_4800M;	 

//640MHz clock generator
reg [3:0] cnt9600=4'b0000;
always @ (posedge clk_9600M)
  begin
    if (cnt9600==14) cnt9600 <= 4'b0000;
	else         cnt9600 <= cnt9600 + 4'b0001;
	
    if (cnt9600<=7)  clk_640M  <= 1;
    else             clk_640M  <= 0;	 
  end 

//320MHz clock
always @ (posedge clk_640M)
clk_320M <= !clk_320M;	 

//160MHz clock
always @ (posedge clk_320M)
clk_160M <= !clk_160M;	 

//80MHz clock
always @ (posedge clk_160M)
clk_80M <= !clk_80M;	 

//40MHz clock
always @ (posedge clk_80M)
clk_40M <= !clk_40M;	

//20MHz clock
always @ (posedge clk_40M)
clk_20M <= !clk_20M;		 

//10MHz clock
always @ (posedge clk_20M)
clk_10M <= !clk_10M;

//5MHz clock
always @ (posedge clk_10M)
clk_5M <= !clk_5M;



//***************************************************************************************     
//********************************* DUT ************************************************* 
//***************************************************************************************     
assign BC_RST = ~reset;

//load DAC_SDO signal for DAC unit
reg  DAC_SDO;
wire DAC_SDIN, DAC_SCLK;
always @(posedge DAC_SCLK)
begin
 DAC_SDO <= DAC_SDIN;
end

//data for AD9650
wire       CLK_9650, adc16a_clk, adc16b_clk;
reg [15:0] DA=16'h0001, DB=16'h0002;

assign  #9 adc16a_clk   = CLK_9650;
assign  #9 adc16b_clk   = CLK_9650;

always @(posedge CLK_9650)
begin
 DA <= DA + 16'h0002;  //even numbers
 DB <= DB + 16'h0002;  //odd  numbers
end

//simplistic model for ADC121 
wire      ADC121_CS, ADC121_SCLK;
wire      ADC121_DATA1, ADC121_DATA2, ADC121_DATA3, ADC121_DATA4;
reg [15:0]AD_DATA1_i=16'h0001,AD_DATA2_i=16'h0002,AD_DATA3_i=16'h0003,AD_DATA4_i=16'h0004; 
reg [15:0]AD_DATA1, AD_DATA2, AD_DATA3, AD_DATA4; 
always@(posedge ADC121_SCLK)
 begin
  if (~ADC121_CS)
   begin
    AD_DATA1 <= {AD_DATA1[14:0], 1'b0};
    AD_DATA2 <= {AD_DATA2[14:0], 1'b0};
    AD_DATA3 <= {AD_DATA3[14:0], 1'b0};
    AD_DATA4 <= {AD_DATA4[14:0], 1'b0};
   end
  else
   begin
    AD_DATA1 <= AD_DATA1_i;
    AD_DATA2 <= AD_DATA2_i;
    AD_DATA3 <= AD_DATA3_i;
    AD_DATA4 <= AD_DATA4_i;
   end
 end

assign ADC121_DATA1 = AD_DATA1[15];
assign ADC121_DATA2 = AD_DATA2[15];
assign ADC121_DATA3 = AD_DATA3[15];
assign ADC121_DATA4 = AD_DATA4[15];


//COLUTA ddpu


reg [15:0] ser_data_in, 
           ser_data_in1=16'h1000, //distribution #1
           ser_data_in2=16'h1001,
           ser_data_in3=16'h1001,
           ser_data_in4=16'h1001,
           ser_data_in5=16'h1001,
		   
           ser_data_in6=16'h1001, //distribution #2
           ser_data_in7=16'h1002,
           ser_data_in8=16'h1001;			   
		   
reg  [2:0] ser_data_sw=3'b000;
always @(posedge clk_40M)
begin
 ser_data_sw  <= ser_data_sw + 3'b001;

 if      (ser_data_sw==3'b000) ser_data_in  <= ser_data_in1;
 else if (ser_data_sw==3'b001) ser_data_in  <= ser_data_in2;
 else if (ser_data_sw==3'b010) ser_data_in  <= ser_data_in3;
 else if (ser_data_sw==3'b011) ser_data_in  <= ser_data_in4;
 else if (ser_data_sw==3'b100) ser_data_in  <= ser_data_in5;
 else if (ser_data_sw==3'b101) ser_data_in  <= ser_data_in6;
 else if (ser_data_sw==3'b110) ser_data_in  <= ser_data_in7;
 else                          ser_data_in  <= ser_data_in8;

end


wire [543:0] m0_cntrl;
wire   [3:0] c_frame_del;
wire ser_clk;
wire FRAME, DATA1;
assign  #0.5 ser_clk = clk_640M;  
 
generate
    if (sim_type==0)assign c_frame_del = 4'b0110; //find a right value for each technology corner !!!
    else            assign c_frame_del = 4'b0000;
endgenerate

reg invert_mdac0=1;


ddpuTMR d1
 (
//CP640/CP40 relation bits
 .be_tst(1'b1),
 .ae_tst(1'b1),
	
//test inputs
 .test_inputs (16'h4321),
	
//bunch crossing reset signal
 .bc_reset(1'b1),  
	
//clocks
 .clk40(clk_40M),      // 40MHz clock
 .clk80A(clk_80M),     // 80MHz clock
 .clk80B(clk_80M),     // 80MHz clock
 .clk80C(clk_80M),     // 80MHz clock
 .clk640(ser_clk),     //640MHz clock	
	
//
 .flag(1'b0),          
 .valid(1'b0),        

//MDAC outputs
 .mdac_b(4'b0000),     //MDAC bits 
 .mdac_c(8'b00000000), //MDAC comparators

//SAR outputs
 .sar({4'b0000, ser_data_in[15:0]}),        //SAR outputs
	
//control bits	
    .cntrl_bits({m0_cntrl[290:8], 4'b0100, {c_frame_del}}),   //control bits, manualy set here 
    //.cntrl_bits({m0_cntrl[302:0]}), 

 .I2C_ID (chip_id[3:0]),         //chip I2C address
 .CH_N (3'b001),                 //ADC channel number		
 .invert_mdac0(invert_mdac0),
	
//serial output data
 .BCID_out(FRAME),        //BCID/frame serial output
 .DATA_out_a(DATA1a),     //data serial output, normal mode
 .DATA_out_b(DATA1b)      //data serial output, 32 bit mode
	                      //this output is for simulation only!!!
 );


wire   [7:0] dataout, msel;
wire         m_reset;
wire         seu_err;
wire         clk5;
reg          mclk_del;
reg  [543:0] csc_control_bits, csc_rb;
reg   [47:0] csc_bits;
reg    [5:0] sub_addr = 6'b000000;       //ADC subaddress
reg    [7:0] ADC_sel;
reg          wr_flag, rd_back_mux;
reg   [47:0] csc_bits0, csc_bits1, csc_bits2, csc_bits3, csc_bits4;




// SEU event generator
// We consider an event with the width ~50ns
// and one with the width of 450ns
// Events are generated periodicaly and counted by
// SEU counters
reg seu_event_40M;
reg seu_event_5M;
always begin
    seu_event_40M=0;
    seu_event_5M =0;
    #180000;               //distance between SEU events
    repeat (1) @(posedge clk_40M);
    seu_event_40M=1;
    seu_event_5M =1;
    repeat (1) @(posedge clk_40M);
    seu_event_40M=0;
    repeat (7)@(posedge clk_40M);
    seu_event_5M =1;
end




wire i2c_cp40;
assign #0.5 i2c_cp40 = clk_40M;


//coluta i2c slave module
coluta_i2c i2c 
(
//i2c signals
    .SDAi(SDA),
    .SDAo(SDAo),
    .SDAen(SDAen),
    .SCL(SCL),
    .SDA_OC(SDA_OC),
    .resetB(~reset),  
    .clk1(i2c_cp40),
    .clk2(i2c_cp40),
    .clk3(i2c_cp40),

    .chip_id(chip_id[3:0]),

// interface signals to coluta slow control modules
    .frm        (frm[7:0]),
    .dat        (dat[7:0]),
    .m_reset    (m_reset),
    .msel       (msel[7:0]),
    .dataout    ({7'b0000000, dataout[0]}), 

//global control bits
    .cntrl_bits (global_cntrl_bits), 

//seu test signal
//    .seu_event(1'b0),
//  .seu_err(seu_err)

    .read_only_bits(read_only_bits)
);


// interface module to the coluta slow control
// 8 such a modules can be connected to the "coluta_i2c" module
// module "0"


slow_controlTMR csc0
    (
    // 3 clock copies for tripple redundant design    
     .clkA   (clk_40M),
     .clkB   (clk_40M),
     .clkC   (clk_40M),

    //ADC slow control interface signals
     .resetA  (m_reset),
     .resetB  (m_reset),
	 .resetC  (m_reset),
     .msel   (msel[0]),
     .datin  (dat[0]),
     .frmin  (frm[0]),
     .datout (dataout[0]),

//32 io lines for i2c readout
//   .io_lines(io_lines_data),


	
    //ADC module control bits and 
     .m_cntrl(m0_cntrl[543:0]) 

    //simulated SEU event
     //.sim_seu_event(1'b0)
     );




//FT2232 FIFO A emulator
FT2232 A
      (      
       .rst_in         (reset),
       .clk            (clk_40M),
       .NUM_WORDS      (NUM_WORDS_A),
		
       //host(USB) side of the interface
       //always 8 bytes are transfered
       .data_to_FPGA   (DATA_to_FTDI_A),
       .data_from_FPGA (DATA_from_FTDI_A),
       .fifo_op_type   (FTDI_A_op),       //0-data from host to FPGA, 1-data from FPGA to host
       .start_fifo_op  (start_FTDI_A_op),
       .op_done        (FTDI_A_done),
 

       //245 fifo signals
       .DATA           (DATA_A[7:0]),  //fifo A DATA
       .RXF            (RXF_A),  //low active: data available in FIFO
       .TXE            (TXE_A),  //low active: data can be written into FIFO
       .RD             (RD_A),   //ReaD enable,  low to high transition
       .WR             (WR_A)    //WRite enable, high to low transition
       );

//FT2232 FIFO B emulator
FT2232 B     
      (      
       .rst_in         (reset),
       .clk            (clk_40M),
       .NUM_WORDS      (NUM_WORDS_B),
		
       //host(USB) side of the interface
       //always 8 bytes are transfered
       .data_to_FPGA   (DATA_to_FTDI_B),
       .data_from_FPGA (DATA_from_FTDI_B),
       .fifo_op_type   (FTDI_B_op),       //0-data from host to FPGA, 1-data from FPGA to host
       .start_fifo_op  (start_FTDI_B_op),
       .op_done        (FTDI_B_done),
 
       //245 fifo signals
       .DATA           (DATA_B[7:0]),  //fifo A DATA
       .RXF            (RXF_B),  //low active: data available in FIFO
       .TXE            (TXE_B),  //low active: data can be written into FIFO
       .RD             (RD_B),   //ReaD enable,  low to high transition
       .WR             (WR_B)    //WRite enable, high to low transition
       );
	

//set delay  to 0 for functional simulation
//adjust that delay for pnr simulation
wire clk_40M_fpga;
assign  #0 clk_40M_fpga = clk_40M; 
COLUTAV4_fpga F1
     (  
      .FPGA_CLK      (clk_40M_fpga),  //fpga clock, 40MHz system clock copy (LVPECL signaling)

      //I2C interface (1.2V) to COLUTA chip
      .SCL           (SCL),  //10 MHz I2C clock  ...no pullup resistor on this line
      .SDA           (SDA),   
      .RSTB          (RSTB),   


      //COLUTA serializer data (LVDS signalig)
      //COLUTA output inverted due to inversion inside the SLVS driver
      .FRAME1        (FRAME),     //serial data synchronized with 640MHz clock
      .DATA1         (DATA1b),    //serial data synchronized with 640MHz clock change to DATA1a if serializer test involved!!!
      .DATA2         (DATA1b),    //serial data synchronized with 640MHz clock		  
      .DATA3         (DATA1a),    //serial data synchronized with 640MHz clock
      .DATA4         (DATA1b),    //serial data synchronized with 640MHz clock
      .DATA5         (DATA1a),    //serial data synchronized with 640MHz clock
      .DATA6         (DATA1b),    //serial data synchronized with 640MHz clock		  
      .DATA7         (DATA1a),    //serial data synchronized with 640MHz clock
      .DATA8         (DATA1b),    //serial data synchronized with 640MHz clock
      .FRAME8        (FRAME),    //serial data synchronized with 640MHz clock

/*
      .\FRAME1(n)    (~FRAME),   //serial data synchronized with 640MHz clock
      .\DATA1(n)     (~DATA1a),   //serial data synchronized with 640MHz clock
      .\DATA2(n)     (~DATA1b),   //serial data synchronized with 640MHz clock		  
      .\DATA3(n)     (~DATA1a),   //serial data synchronized with 640MHz clock
      .\DATA4(n)     (~DATA1b),   //serial data synchronized with 640MHz clock
      .\DATA5(n)     (~DATA1a),   //serial data synchronized with 640MHz clock
      .\DATA6(n)     (~DATA1b),   //serial data synchronized with 640MHz clock		  
      .\DATA7(n)     (~DATA1a),   //serial data synchronized with 640MHz clock
      .\DATA8(n)     (~DATA1b),   //serial data synchronized with 640MHz clock
      .\FRAME8(n)    (~FRAME),   //serial data synchronized with 640MHz clock

      .\FPGA_CLK(n)  (~clk_40M_fpga),  //fpga clock, 40MHz system clock copy (LVPECL signaling)

*/
      //DRE ADC interface (1.8V signalig)
      .CLK_9650       (CLK_9650),   //main ADC clock, LVDS signaling
      .SYNC           (SYNC),
      .CSB            (CSB),
      .SCLK           (SCLK),
      .SDIO           (SDIO),
      .ORA            (ORA),
      .ORB            (ORB),
      .DCOA           (adc16a_clk),
      .DCOB           (adc16b_clk),
      .DA             (DA[15:0]),
      .DB             (DB[15:0]),
  
      //DAC control signals (3.3V signaling)
      .DAC_RSTSEL     (DAC_RSTSEL),
      .DAC_RESET_b    (DAC_RESET_b),
      .DAC_SCLK       (DAC_SCLK),
      .DAC_SYNC_b     (DAC_SYNC_b),
      .DAC_SDIN       (DAC_SDIN),
      .DAC_SDO        (DAC_SDO),
      .DAC_LDAC_b     (DAC_LDAC_b),

      //dosimeter controls (1.2V signaling)
      .FPGA_IO1       (FPGA_IO1),
      .FPGA_IO2       (FPGA_IO2),
 
      //dosimeter ADC121 controls (3.3V signaling) 
      .ADC121_CS      (ADC121_CS),    //chip select signal
      .ADC121_SCLK    (ADC121_SCLK),  //SCLK signal
      .ADC121_DATA1   (ADC121_DATA1), //data from ADC#1
      .ADC121_DATA2   (ADC121_DATA2), //data from ADC#2
      .ADC121_DATA3   (ADC121_DATA3), //data from ADC#3
      .ADC121_DATA4   (ADC121_DATA4), //data from ADC#4
 		  
      //AD9508 reset and sync signals
      .FPGA_9508_RSTB (FPGA_9508_RSTB),
      .FPGA_9508_SYNCB(FPGA_9508_SYNCB),
  	
      //Bunch crossing reset signal
      .BC_RST          (BC_RST),	 
      .BCR_AUX        (BCR_AUX),
            

      //ALFE signals
      .ALFE_RSTB(ALFE_RSTB), 
      .ALFE_CP40(ALFE_CP40),


      // USB interface signals  (3.3V signaling)
      .RST_N          (~reset),  //RSTOUT# from FT2232
      //fifo A
      .DATA_A         (DATA_A[7:0]),  //fifo A DATA
      .RXF_A          (RXF_A),  //low active: data available in FIFO
      .TXE_A          (TXE_A),  //low active: data can be written into FIFO
      .RD_A           (RD_A),  //ReaD enable,  low to high transition
      .WR_A           (WR_A),  //WRite enable, high to low transition
      .SI_WU_A        (SI_WU_A),  //SendImmediate/WakeUp

      //fifo B
      .DATA_B         (DATA_B[7:0]),  //fifo B DATA
      .RXF_B          (RXF_B),
      .TXE_B          (TXE_B),
      .RD_B           (RD_B),
      .WR_B           (WR_B),
      .SI_WU_B        (SI_WU_B),

      //programmable delay trigger    
      .trigger        (),  //interface to external pulser   (3.3V signaling)
	  		  
      // test points
      .TP1            (),
      .TP2            (),
      .TP_dummy       ()    //just to remove warnings about signals which do not drive logic
      );

//***************************************************************************************     
//********************************* DUT END********************************************** 
//***************************************************************************************     

reg  [15:0] dat_w1       = 16'b0000_0000_0000_0001;// data word 1
reg  [15:0] dat_w2       = 16'b0000_0000_0000_0010;// data word 2
reg  [15:0] dat_w3       = 16'b0000_0000_0000_0011;// data word 3

 
//***************************************************************************************  
//The main test sequence			
    initial begin
//    $sdf_annotate("COLUTAV3_fpga_v.sdo", COLUTA_FPGA_tester.F1, , ,"typical"); //minimum, typical, maximum
//    $sdf_annotate("C:/Users/Jaro/Documents/My Electronics projects/NEVIS_65n_ADC/COLUTA_V4/digital/coluta_i2c/Source_files/pnr/coluta_i2c.sdf", COLUTA_FPGA_tester.i2c , , ,"maximum");
//    $sdf_annotate("C:/Users/Jaro/Documents/My Electronics projects/NEVIS_65n_ADC/COLUTA_V4/digital/coluta_slow_control/Source_files/pnr/slow_controlTMR.sdf", COLUTA_FPGA_tester.csc0, , ,"maximum");
    $sdf_done();

                $display("\n\nSimulation starts");   
                reset = 1; 
                DATA_to_FTDI_B = {{64{1'b0}}, 16'h0000, 8'hff, 8'h05, 8'h04, 8'h03, 8'h02,  8'hfe};
                FTDI_B_op=FTDI_to_FPGA;

                repeat(10) @(negedge clk_5M);
                reset_signal;
                repeat(7) @(negedge clk_5M);

                $display("\n         ");
                //this is an initial command 
                //and is needed to initialize the FPGA status register after reset
                //
                //status word mapping:    st6    st5     st4     st3     st2     st1
                write_status({          8'hff,  8'h20,  8'h00, 8'h00, 8'h00,  8'hfe});
                #100;

                //send command to read the status
                write_status({8'hff, 8'h80, 8'h00, 8'h00, 8'h00,  8'hfe});
                #100;

                //read status register into "status_read_back_data"
                read_status(status_read_back_data); 


                $display("\nStatus read: %h", status_read_back_data[63:0]);
                dr = {8'hff, 8'h80, 8'h00, 8'h00, 8'h00,  8'hfe};
                if (dr[63:0]!==status_read_back_data[47:0])$display("Status read error !!!!");
                else                                       $display("Operation succesfull");
 
               //Software reset
                write_status({8'hff, 8'h20, 8'h00, 8'h00, 8'h00,  8'hfe});
				$display("Software reset issed");
                #200;


//initialize Wishbone registers and define the I2C communication speed
                i2c_init;


//***************AD9508 control
                //initialize writing into AD9508 control register
                write_status({8'hff, 8'h40, 8'h00, 8'h03, 8'h15,  8'hfe});
                #100;                
                //send 3 bytes to FIFO A (to be sent to AD9508 control register)
                write_FIFO_A(8'h03, {{64{1'b0}}, 64'h0000000000_08011d});  //was 08011d;
                //execute AD9508 control register intruction
                write_status({8'hff, 8'h01, 8'h00, 8'h03, 8'h15,  8'hfe});
                #10000;
//                if (F1.AD9508_reg==24'h08011d)$display("AD9508 reg operation succesfull10");
//                else                          $display("AD9508 reg operation error!!!");
//



//***************COLUTA & AD9650 measurements
                //start COLUTA & ADC9650 analog measurement
                write_status({8'hff, 8'h04, 8'h00, 8'h00, 8'h00,  8'hfe});
                //one may want to wait enough time for data 
                //to fill complete dual port memories (PC undisturbed data taking)
                //waiting can be avoided, though
                $display("Filling DP memory with data, may take some time ");
                repeat (8200)@(posedge clk_40M);  
//                @(posedge F1.eof_ADC_write);				
                $display("Dual port memory filled with data now");
				
                //initialize the read-back data from COLUTA dual port memory
                write_status({8'hff, 8'h40, 8'h00, 8'h01, 8'h1b,  8'hfe});
                #100;
                $display("\nWarning: Coluta test data are not checked at this moment as the ddpu mode is set to a normal mode for histograming test!!!!!!!");              
                $display("\nTo check Coluta test data change manualy the ddpu control mode to serializer test mode");    
/*            
                //ddpu serializer test mode data checks
                //read data from FIFO A 
                read_FIFO_A(8'h08,FIFO_A_read_back_data);
                $display("\nColuta data: %h", FIFO_A_read_back_data[63:0]);
//frame
                if (FIFO_A_read_back_data[15]!=1'b1)            $display("Coluta frame error !!!");
                else if(FIFO_A_read_back_data[7:0]!=8'b00000000)$display("Coluta frame error !!!!");
//channel a	in test mode			
                else if(FIFO_A_read_back_data[20:16]!=5'b01001) $display("Coluta data ch_a error !!!");
                else if(FIFO_A_read_back_data[31:28]!=4'b1010)  $display("Coluta data ch_a error !!!!");
//channel b in test mode				
                else if(FIFO_A_read_back_data[36:32]!=5'b01010) $display("Coluta data ch_b error !!!");
                else if(FIFO_A_read_back_data[47:44]!=4'b1010)  $display("Coluta data ch_b error !!!!");
				
                else                                            $display("Operation succesfull3");
*/
 
                //prepare status register for leading edge of AD9650 init signal
                write_status({8'hff, 8'h00, 8'h00, 8'h00, 8'h00,  8'hfe});


                //initialize the read-back data from AD9650 dual port memory
                write_status({8'hff, 8'h40, 8'h00, 8'h01, 8'h07,  8'hfe});

                //read data from FIFO A
                read_FIFO_A(8'h08,FIFO_A_read_back_data);
                $display("\nAD9650 data: %h", FIFO_A_read_back_data[63:0]);
                aw1=FIFO_A_read_back_data[15: 0];
                aw2=FIFO_A_read_back_data[31:16] - 16'h0001;
                aw3=FIFO_A_read_back_data[47:32] - 16'h0002;
                aw4=FIFO_A_read_back_data[63:48] - 16'h0003;                
                if     (aw1!=aw2) $display("AD9650 byte1_2 error !!!!");
                else if(aw2!=aw3) $display("AD9650 byte2_3 error !!!!");
                else if(aw3!=aw4) $display("AD9650 byte3_4 error !!!!");
                else              $display("Operation succesfull");
                
                $display("AD9650 data wa1: %h", aw1);
                $display("AD9650 data wa2: %h", aw2);
                $display("AD9650 data wa3: %h", aw3);
                $display("AD9650 data wa4: %h", aw4);		
                #500;
//****************



                //prepare status register for leading edge of DAC init signal
                write_status({8'hff, 8'h00, 8'h00, 8'h00, 8'h00,  8'hfe});
 
/*
//***************False condition control
                //initialize writing into DAC control register
                write_status({8'hff, 8'h40, 8'h00, 8'h07, 8'h09,  8'hfe});
                #100;                
                //send 7 bytes to FIFO A (to be sent to DAC control register)
                write_FIFO_A(8'h07, {{64{1'b0}},64'b00000000_000_011100000000000000001111_11001_100000000000000000000011});
                //execute DAC control register intruction
                write_status({8'hff, 8'h01, 8'h00, 8'h00, 8'h09,  8'hfe});
                #100; //is also fine
*/
//              false_start_generator;
//  			#10000;
//              false_start_generator;
//****************


//***************AD121 control
                //initialize writing into AD121 control register
                write_status({8'hff, 8'h40, 8'h00, 8'h01, 8'h0d,  8'hfe});
                #100;                
                //send 1 byte to FIFO A (to be sent to AD121 control register)
                write_FIFO_A(8'h01, {{64{1'b0}}, 64'h00000000000000_61});
                //execute AD121 control register intruction
                write_status({8'hff, 8'h01, 8'h00, 8'h00, 8'h0d,  8'hfe});
                #3000; //previous command will be executed in paralel to the next one
                //start analog measurement
                write_status({8'hff, 8'h04, 8'h00, 8'h00, 8'h00,  8'hfe});
                //wait untill ADC121 dual port memory has the data
                //this process is very slow!!!
                $display("Filling DP memory with data, may take some time ");
                repeat (8200)@(posedge clk_40M); 
                $display("Dual port memory filled with data now"); 

                //initialize the read-back data from ADC121 dual port memory
                write_status({8'hff, 8'h40, 8'h00, 8'h08, 8'h0f,  8'hfe});
                #100;
                //read data from FIFO A
                read_FIFO_A(8'h08,FIFO_A_read_back_data);
                #100
                $display("\nAD121 data:  %h", FIFO_A_read_back_data[63:0]);
                aw1=FIFO_A_read_back_data[11: 0];
                aw2=FIFO_A_read_back_data[23:12] - 16'h0001;
                aw3=FIFO_A_read_back_data[35:24] - 16'h0002;
                aw4=FIFO_A_read_back_data[47:36] - 16'h0003;                
                if     (aw1!=aw2) $display("Coluta data error !!!!");
                else if(aw2!=aw3) $display("Coluta data error !!!!");
                else if(aw3!=aw4) $display("Coluta data error !!!!");
                else              $display("Operation succesfull");
//****************




//*************************Histogram package control******************************************************************
                //this simulation expects that data from Coluta channel 1  is within "fff" range
                //

                //Clear histogram bins

                //initialize writing into histogram control register
                write_status({8'hff, 8'h00, 8'h00, 8'h00, 8'h00,  8'hfe});
                write_status({8'hff, 8'h40, 8'h00, 8'h05, 8'h11,  8'hfe});
                #100;                
                //send 4 bytes to FIFO A (to be sent into histogram control register)
                //init "fff" histogram bins with zero
                write_FIFO_A(8'h04, {{64{1'b0}}, 64'h00000000_01_00ffff});
//              write_FIFO_A(8'h05, {{64{1'b0}}, 64'h00000000_40000fff});
                //execute histogram control register intruction
                write_status({8'hff, 8'h01, 8'h00, 8'h00, 8'h11,  8'hfe});

                @(negedge F1.h1.op_in_progress )
                #3000;
                

                //Perform histogramming

                //initialize writing into histogram control register
//                write_status({8'hff, 8'h40, 8'h00, 8'h04, 8'h11,  8'hfe});
                write_status({8'hff, 8'h40, 8'h00, 8'h05, 8'h11,  8'hfe});
                #100;                
                //send 4 bytes to FIFO A (to be sent into histogram control register)
                //perform histogramming with "fff" maximum number of hits in histogram
                write_FIFO_A(8'h04, {{64{1'b0}}, 64'h00000000_03_00ffff});
//              write_FIFO_A(8'h05, {{64{1'b0}}, 64'h00000000_c0000fff});
                //execute histogram control register intruction
                //with start analog measurement signal
                write_status({8'hff, 8'h04, 8'h00, 8'h00, 8'h11,  8'hfe});
//
                @(negedge F1.h1.op_in_progress )
                #3000;


                //Read the histogramming data
 
                //first move data to histogramm dual port memory
                //initialize writing into histogram control register
//                write_status({8'hff, 8'h40, 8'h00, 8'h04, 8'h11,  8'hfe});
                write_status({8'hff, 8'h40, 8'h00, 8'h05, 8'h11,  8'hfe});
                #100;                
                //send 4 bytes to FIFO A (to be sent into histogram control register)
                //to read histogramming data
                write_FIFO_A(8'h04, {{64{1'b0}}, 64'h00000000_02_00ffff});
//              write_FIFO_A(8'h05, {{64{1'b0}}, 64'h00000000_80000fff});
                //execute histogram control register intruction
                write_status({8'hff, 8'h04, 8'h00, 8'h00, 8'h11,  8'hfe});

                //@(negedge F1.\h1|op_in_progress~q )
                //@(negedge F1.h1.op_in_progress )
                repeat (4100) @(posedge clk_40M);

                //then read histogram dual port memory to PC
                //initialize the read-back data from histogram  dual port memory
//                write_status({8'hff, 8'h40, 8'h00, 8'h20, 8'h13,  8'hfe});
                write_status({8'hff, 8'h40, 8'h00, 8'h20, 8'h43,  8'hfe});
                #100;
                //read data from FIFO A
                read_FIFO_A(8'h10,FIFO_A_read_back_data);
                #10000;
                $display("\nHistogram data: %h", FIFO_A_read_back_data[127:0]);
				$display("\nHistogram data:");
                $display("Histogram data bin#: %h, bin count: %h", 
                           FIFO_A_read_back_data[36:22], FIFO_A_read_back_data[21: 0]);
                $display("Histogram data bin#: %h, bin count: %h", 
                           FIFO_A_read_back_data[100:86], FIFO_A_read_back_data[85:64]);

                //read data from FIFO A
                read_FIFO_A(8'h10,FIFO_A_read_back_data);
                #10000;
                $display("\nHistogram data: %h", FIFO_A_read_back_data[127:0]);
                $display("Histogram data bin#: %h, bin count: %h", 
                          FIFO_A_read_back_data[36:22], FIFO_A_read_back_data[21: 0]);
                $display("Histogram data bin#: %h, bin count: %h", 
                          FIFO_A_read_back_data[100:86], FIFO_A_read_back_data[85:64]);

                //read data from FIFO A
                read_FIFO_A(8'h10,FIFO_A_read_back_data);
                #10000;
                $display("\nHistogram data: %h", FIFO_A_read_back_data[127:0]);
                $display("Histogram data bin#: %h, bin count: %h", 
                          FIFO_A_read_back_data[36:22], FIFO_A_read_back_data[21: 0]);
                $display("Histogram data bin#: %h, bin count: %h", 
                          FIFO_A_read_back_data[100:86], FIFO_A_read_back_data[85:64]);
						  
                //read data from FIFO A
                read_FIFO_A(8'h10,FIFO_A_read_back_data);
                #10000;
                $display("\nHistogram data: %h", FIFO_A_read_back_data[127:0]);
                $display("Histogram data bin#: %h, bin count: %h", 
                          FIFO_A_read_back_data[36:22], FIFO_A_read_back_data[21: 0]);
                $display("Histogram data bin#: %h, bin count: %h", 
                          FIFO_A_read_back_data[100:86], FIFO_A_read_back_data[85:64]);




                //Perform histogramming again (no bin clearing) 

                //initialize writing into histogram control register
                write_status({8'hff, 8'h40, 8'h00, 8'h04, 8'h11,  8'hfe});
                #100;                
                //send 4 bytes to FIFO A (to be sent into histogram control register)
                //perform histogramming with "h2000" maximum number of hits in histogram
                write_FIFO_A(8'h04, {{64{1'b0}}, 64'h00000000_03_000fff});
                //execute histogram control register intruction
                //with start analog measurement signal
                write_status({8'hff, 8'h04, 8'h00, 8'h00, 8'h11,  8'hfe});

                @(negedge F1.h1.op_in_progress )
                #3000;

                //Read the histogramming data
 
                //first move data to histogramm dual port memory
                //initialize writing into histogram control register
                write_status({8'hff, 8'h40, 8'h00, 8'h04, 8'h11,  8'hfe});
                #100;                
                //send 4 bytes to FIFO A (to be sent into histogram control register)
                //to read histogramming data
                write_FIFO_A(8'h04, {{64{1'b0}}, 64'h00000000_02_00ffff});
                //execute histogram control register intruction
                write_status({8'hff, 8'h04, 8'h00, 8'h00, 8'h11,  8'hfe});

                @(negedge F1.h1.op_in_progress )
                #3000;

                //then read histogram dual port memory into PC
                //initialize the read-back data from histogram  dual port memory
                write_status({8'hff, 8'h40, 8'h00, 8'h20, 8'h13,  8'hfe});
                #100;
                //read data from FIFO A
                read_FIFO_A(8'h10,FIFO_A_read_back_data);
                #10000;
                //$display("\nHistogram data: %h", FIFO_A_read_back_data[127:0]);
                $display("\nHistogram data:");
		        $display("Histogram data bin#: %h, bin count: %h", 
                          FIFO_A_read_back_data[36:22], FIFO_A_read_back_data[21: 0]);
                $display("Histogram data bin#: %h, bin count: %h", 
                          FIFO_A_read_back_data[100:86], FIFO_A_read_back_data[85:64]);

                //read data from FIFO A
                read_FIFO_A(8'h10,FIFO_A_read_back_data);
                #10000;
                //$display("\nHistogram data: %h", FIFO_A_read_back_data[127:0]);
                $display("Histogram data bin#: %h, bin count: %h", 
                          FIFO_A_read_back_data[36:22], FIFO_A_read_back_data[21: 0]);
                $display("Histogram data bin#: %h, bin count: %h", 
                          FIFO_A_read_back_data[100:86], FIFO_A_read_back_data[85:64]);
                //read data from FIFO A
                read_FIFO_A(8'h10,FIFO_A_read_back_data);
                #10000;
                //$display("\nHistogram data: %h", FIFO_A_read_back_data[127:0]);
                $display("Histogram data bin#: %h, bin count: %h", 
                          FIFO_A_read_back_data[36:22], FIFO_A_read_back_data[21: 0]);
                $display("Histogram data bin#: %h, bin count: %h", 
                          FIFO_A_read_back_data[100:86], FIFO_A_read_back_data[85:64]);

                //read data from FIFO A
                read_FIFO_A(8'h10,FIFO_A_read_back_data);
                #10000;
                //$display("\nHistogram data: %h", FIFO_A_read_back_data[127:0]);
                $display("Histogram data bin#: %h, bin count: %h", 
                          FIFO_A_read_back_data[36:22], FIFO_A_read_back_data[21: 0]);
                $display("Histogram data bin#: %h, bin count: %h", 
                          FIFO_A_read_back_data[100:86], FIFO_A_read_back_data[85:64]);



//****************




//********************************************************************************
//***********************************I2C TEST*************************************
//********************************************************************************

//
// I2C control word format
//
// {cw1}, {cw2}, ... {8{1'b0}}
// control word cw: {op_code_byte, 
//                   I2C_address_byte, 
//                   data_byte_1, 
//                   data_byte_2,
//                   ? 
//                   data_byte_n}
//
// operation code byte
//   bits[7:5]   
//           000    nop
//           001    I2C_W_INIT    //I2C Wishbone registers init 
//           010    I2C_WR
//           100    I2C_RD
//           011    I2C_ERR
//           111    I2C_DELAY
//
//    bit  [4]    stop condition (0 no stop, 1 stop bit is on)
//    bits[3:0]   number of data bytes to be transferred 
// 



// Coluta chip control signals for common purposes.
// 128 bits available;
// Send the control data into the register file common for whole coluta chip
// these are CSR bits [191:64] or bytes 9 through 24
//


    cntrl_byte8  = 8'b10000001;    cntrl_byte9  = 8'b10000010;
    cntrl_byte10 = 8'b10000011;    cntrl_byte11 = 8'b10000100;
    cntrl_byte12 = 8'b10000101;    cntrl_byte13 = 8'b10000110;
    cntrl_byte14 = 8'b10000111;    cntrl_byte15 = 8'b10001000;

    dw = {{64{1'b0}}, cntrl_byte8,  cntrl_byte9,  cntrl_byte10, cntrl_byte11, 
                      cntrl_byte12, cntrl_byte13, cntrl_byte14, cntrl_byte15};

    addr = 6'b001000; 
    $display("         ");
    $display("Write CSR bits [127:64]");

//write data into CSR register
    i2c_CSR_write;
    $display("Write operation done");

    repeat(500)@(posedge clk_40M);
//read-back data from CSR register
    $display("Read CSR bits [127:64] back");
    i2c_CSR_read;
//display results
    $display("Data read-back,  Exp: %h", dw[63:0]);
    $display("                 Got: %h", FIFO_A_read_back_data[63:0]);
    if (dw[63:0]!==FIFO_A_read_back_data[63:0])$display("I2C Error !!!!");
    else                                       $display("Operation succesfull");



    cntrl_byte8  = 8'b10010001;    cntrl_byte9  = 8'b10010010;
    cntrl_byte10 = 8'b10010011;    cntrl_byte11 = 8'b10010100;
    cntrl_byte12 = 8'b10010101;    cntrl_byte13 = 8'b10010110;
    cntrl_byte14 = 8'b10010111;    cntrl_byte15 = 8'b10011000;

    dw = {{64{1'b0}}, cntrl_byte8,  cntrl_byte9,  cntrl_byte10, cntrl_byte11, 
                      cntrl_byte12, cntrl_byte13, cntrl_byte14, cntrl_byte15};

    addr = 6'b010000; 
    $display("         ");
 
    $display("Write CSR bits [191:128]");
	#10000;
	false_start_generator;
	#10000;

//write data into CSR register
    i2c_CSR_write;
    $display("Write operation done");
    repeat(500)@(posedge clk_40M);
//read-back data from CSR register
    $display("Read CSR bits [191:128] back");
    i2c_CSR_read;
//display results
    $display("Data read-back,  Exp: %h", dw[63:0]);
    $display("                 Got: %h", FIFO_A_read_back_data[63:0]);
    if (dw[63:0]!==FIFO_A_read_back_data[63:0])$display("I2C Error !!!!");
    else                                       $display("Operation succesfull");


//read back bits from outside of the I2C unit (read only)
    repeat(500)@(posedge clk_40M);
    $display("Read 24 read-only bits");
    addr = 6'b011000;   
    i2c_CSR_read;
//display results
    $display("Data read-back,  Exp: %h", read_only_bits);
    $display("                 Got: %h", FIFO_A_read_back_data[63:40]);
    if (FIFO_A_read_back_data[63:40]!=={read_only_bits  [7:0], 
                                        read_only_bits [15:8],
                                        read_only_bits[23:16]}) $display("I2C Error !!!!");
    else                                                        $display("Operation succesfull");  



//
// Output control data to be sent to Coluta ADC
// 
// Output data format
// dw mapping
// dw [7: 0]  ADC_sel                              internal byte address 0; i2c byte sent first; 
// dw[15: 8] {wr_flag, rd_back_mux, sub_addr[5:0]} internal byte address 1;                               
// dw[31:16] data word 1                           internal byte address 3,2;
// dw[47:32] data word 2                           internal byte address 5,4;
// dw[63:48] data word 3                           internal byte address 7,6;
//
// so 5 I2c transfers needed !!!!
//

//send slow control bits to Coluta ADC 

                //prepare status register for leading edge of DAC init signal
                write_status({8'hff, 8'h00, 8'h00, 8'h00, 8'h00,  8'hfe});

	csc_control_bits[543:0] = {32'hccc3ccc2,  //32             <- important config data [543:512]
                                   
                               32'hccc1bbbb,                 //<- important config data [511:496]
                               32'haaaaaaaa,  //28

                               32'haaaa9999,
                               32'h99999999,  //24

                               32'h88888888,
                               32'h88887777,  //20

                               32'h77777777,
                               32'h66666666,  //16

                               32'h66665555,
                               32'h55555555,  //12

                               32'h44444444,
                               32'h44443333,  //8

                               32'h33323331,
                               32'h22222222,  //4

                               32'h22221111,  
                               32'h11111111}; //0

    for (i = 11; i <= 1; i=i+1) begin                      // <- i=11 leading to sub_addr = 6'd31;
        
        if     (i== 0)csc_bits = csc_control_bits[ 47:  0];
        else if(i== 1)csc_bits = csc_control_bits[ 95: 48];
        else if(i== 2)csc_bits = csc_control_bits[143: 96];
        else if(i== 3)csc_bits = csc_control_bits[191:144];
        else if(i== 4)csc_bits = csc_control_bits[239:192];
        else if(i== 5)csc_bits = csc_control_bits[287:240];
        else if(i== 6)csc_bits = csc_control_bits[335:288];
        else if(i== 7)csc_bits = csc_control_bits[383:336];
        else if(i== 8)csc_bits = csc_control_bits[431:384];
        else if(i== 9)csc_bits = csc_control_bits[479:432];
        else if(i==10)csc_bits = csc_control_bits[527:480];
        else if(i==11)csc_bits = csc_control_bits[543:496];
//
//        repeat (1) @(posedge clk);
        ADC_sel      = 8'b11111111;            // All adc channles are selected <- important
        wr_flag      = 1;                      // write operation        
        rd_back_mux  = 0;                      // readback mux(0- from CSR   1-from coluta memory module)
        addr = 0;                              // i2c address of CSR
//                    
        if     (i== 0)sub_addr = 6'd0;  // ADC subaddress 0,3,6,9,12,15,18,21,24, 27 is selected
        else if(i== 1)sub_addr = 6'd3;
        else if(i== 2)sub_addr = 6'd6;
        else if(i== 3)sub_addr = 6'd9;
        else if(i== 4)sub_addr = 6'd12;
        else if(i== 5)sub_addr = 6'd15;
        else if(i== 6)sub_addr = 6'd18;
        else if(i== 7)sub_addr = 6'd21;
        else if(i== 8)sub_addr = 6'd24;
        else if(i== 9)sub_addr = 6'd27;
        else if(i==10)sub_addr = 6'd30;  
        else if(i==11)sub_addr = 6'd31;  
        $display("i %h, bits %h, subaddress", i, csc_bits, sub_addr);

        dat_w1       = {csc_bits[7:0],   csc_bits[15:8]};  // data word 1
        dat_w2       = {csc_bits[23:16], csc_bits[31:24]}; // data word 2
        dat_w3       = {csc_bits[39:32], csc_bits[47:40]}; // data word 3
	

    	dw = {{64{1'b0}}, ADC_sel, {wr_flag, rd_back_mux, sub_addr}, dat_w1, dat_w2, dat_w3};
        dw1=dw;
    	$display("Write 6 bytes and read back the command itself");
    	i2c_CSR_write;
		
//wait until the last data are moved from "coluta_i2c" to "coluta_slow_control"
   #10000; 

//read them back
    wr_flag      = 0;                       // read operation        
    rd_back_mux  = 1;                       // readback mux(0- from CSR   1-from coluta memory module)
    dw = {{64{1'b0}}, ADC_sel, {wr_flag, rd_back_mux, sub_addr}, {16'h0000}, {16'h0000}, {16'h0000}};
    i2c_CSR_write;
    i2c_CSR_read;
//wait untill the last data are moved from "coluta_slow_control" to "coluta_i2c" 
   #10000;
   dr[47:0] = FIFO_A_read_back_data[47:0];
   // $display("Wrote areg: %h, Read: %h",dw,dr);
        if (dw1[47:0] !== dr[47:0]) begin
            $display("Data read-back error, CSR addr %0b, Exp: %h, Got: %h", addr, dw1[47:0], dr[47:0]);
            i2c_data_ok=0; 
            end
        else begin $display("Data read-back operation %h successful", i, "\n");
             i2c_data_ok=1; 
             end                           

end



//Global test
/*
        if (csc0.mem_voted!==csc_control_bits) begin
            $display("Slow control error :  Exp: %h, \n,       Got: %h", csc_control_bits, csc0.mem_voted);
            i2c_data_ok=0; 
            end
        else begin $display("All slow control data ok!!!", "\n");
             i2c_data_ok=1; 
             end    
*/




for (i = 0; i <= 11; i=i+1) begin
         //radiation write bit flip
	 #1000;
         set_force_wr_net;
//         set_force_mem;
//         set_force_SEU_cnt;
end



/*

//
//read SEU counter
//
for (i = 0; i <= 50; i=i+1) begin

         set_force_wr_net;
         set_force_mem;
         set_force_SEU_cnt;

    addr         = 0;                       // i2c address of CSR
    ADC_sel      = 8'b11111111;             // all ADc channel selected
    sub_addr     = 6'd36;                   // ADC subaddress 36 is selected
    wr_flag      = 0;                       // read operation        
    rd_back_mux  = 1;                       // readback mux(0- from CSR   1-from coluta memory module)
    dw = {{64{1'b0}}, ADC_sel, {wr_flag, rd_back_mux, sub_addr}, 
                               {16'h0000}, {16'h0000}, {16'h0000}};
    i2c_CSR_write;
    i2c_CSR_read;
    $display("Read back SEU counter for   ADC %0b,   : %h", addr,  FIFO_A_read_back_data[15:0]);
    $display("Expected  SEU counter for   ADC %0b,   : %h", addr,  csc0.SEU_cnt);
end

*/

//********************************************************************************
//*********************************I2C TEST END***********************************
//********************************************************************************
//end of simulation ********************
        repeat(100) @(posedge clk_5M);
        $write("Time: %d ", $time);
        $display("Simulation finished");
        $stop;
end



 
 
 
task false_start_generator;
begin
//***************false condition operation control
//any user sequence programmable by these 3 control fields (see false_conditions.v file ) 
//***************************************************************************
//***************************************************************************
//
//  FC control register definition:
//
//  FC_cntrl   [0] RSTB  signal enable
//  FC_cntrl   [1] I2C_mux control (if 1'1b1 also FC function enable)
//
//  FC_cntrl[111:8] SCL_bit wave     104 bit long sequence
//  FC_cntrl[205:112] SDA_outp_en
//  FC_cntrl[319:216] SDA_bit wave
//

//***************************************************************************
//initialize writing into FC control register
                $display("false start generated");
                write_status({8'hff, 8'h00, 8'h00, 8'h00, 8'h00,  8'hfe});
                #1000;                
                write_status({8'hff, 8'h40, 8'h00, 8'h28, 8'h1d,  8'hfe});
                #1000;                
//                                                                                                        
                write_FIFO_A(8'd40, {{104'hFFFFFF_0000000000_000FFFFFFF}, //SDA_bit wave
				                     {104'h000000_0000000000_0000000000}, //SDA_outp_en
				                     {104'hFFFFFF_FFFFFFFF00_0000000000}, //SCL_bit wave
							            8'h02});  //xxxxxx i2c_mux reset
				
                //initialize writing into FC control register
                write_status({8'hff, 8'h01, 8'h00, 8'h28, 8'h1d,  8'hfe});
                #100;   
                write_status({8'hff, 8'h00, 8'h00, 8'h00, 8'h00,  8'hfe});
                #10000;
end
endtask

task false_stop_generator;
begin
//***************false condition operation control
//any user sequence programmable by these 3 control fields (see false_conditions.v file ) 
//***************************************************************************
//***************************************************************************
//
//  FC control register definition:
//
//  FC_cntrl   [0] RSTB  signal enable
//  FC_cntrl   [1] I2C_mux control (if 1'1b1 also FC function enable)
//
//  FC_cntrl[111:8] SCL_bit wave     104 bit long sequence
//  FC_cntrl[205:112] SDA_outp_en
//  FC_cntrl[319:216] SDA_bit wave
//

//***************************************************************************
//initialize writing into FC control register
                $display("false start generated");
                write_status({8'hff, 8'h00, 8'h00, 8'h00, 8'h00,  8'hfe});
                #1000;                
                write_status({8'hff, 8'h40, 8'h00, 8'h28, 8'h1d,  8'hfe});
                #1000;                
//                                                                                                      
                write_FIFO_A(8'd40, {{104'hFFFFFF_F000000000_00000000FF}, //SDA_bit wave
				                     {104'h000000_0000000000_0000000000}, //SDA_outp_en 
				                     {104'h000000_00000FFFFF_FFFFFFFFFF}, //SCL_bit wave 
				                     8'h02});                             //xxxxxx i2c_mux reset
				
                //initialize writing into FC control register
                write_status({8'hff, 8'h01, 8'h00, 8'h28, 8'h1d,  8'hfe});
                #100;   
                write_status({8'hff, 8'h00, 8'h00, 8'h00, 8'h00,  8'hfe});
                #10000;
end
endtask

//************************************************************************************* 
//************************************************************************************* 
//************************************************************************************* 
//************************************************************************************* 
// - Single Event Transient - - - - - - - - - - - - - - - - - - - - - - - - - -
task set_force_wr_net; 
  begin
//   force csc0.m_wr_del2=1'b1;
   #35;
//   force csc0.m_wr_del2=1'b0;
   #15;
  end
endtask


task set_force_mem; 
  begin
//   force csc0.mem1[543]=1'b1;
   #35;
//   force csc0.mem1[543]=1'b0;
   #15;
  end
endtask

task set_force_SEU_cnt; 
  begin
//   force csc0.SEU_cnt1[15]=1'b1;
   #35;
//   force csc0.SEU_cnt1[15]=1'b0;
   #15;
  end
endtask


task swb;
 input [47:0] inba;
 output[47:0] outba;
  begin
   outba = {inba  [7:0], inba[15: 8],
            inba[23:16], inba[31:24],
            inba[39:32], inba[47:40] };
  end
endtask


task i2c_CSR_read;
 begin
   //initialize writing into I2C control register
   write_status({8'hff, 8'h40, 8'h00, 8'd14, 8'h01,  8'hfe});
   #100;                
   //send 11 i2c command bytes to FIFO A (to be sent to I2C control register)
//mode 10 bit address mode
//first  i2c address f0
//second i2c address 88 
//restart sequence (nonstop)
//i2c address        f1
//8bytes of data
   USB_I2C_cmd = {{16{1'b0}},
                  {I2C_WR, NSTP, 4'd2}, {5'b11110,chip_id[3:2],WR_bit}, {chip_id[1:0],addr},
                  {I2C_RD,  STP, 4'd9}, {5'b11110,chip_id[3:2],RD_bit}, {64{1'b0}}, 
                  {8'h00}
                 };
   write_FIFO_A(8'd14, USB_I2C_cmd);
 
  //execute I2C control register intruction
   write_status({8'hff, 8'h01, 8'h00, 8'h00, 8'h01,  8'hfe});
   //wait until tranfer done
   repeat (100)@(posedge SCL);
   #3000; 

   //now read I2C data to PC, data are in I2C_shift_back register   
   //initialize the read-back data from I2C_shift_back register
   write_status({8'hff, 8'h40, 8'h00, 8'd8, 8'h02,  8'hfe});
   #100;
   //read data from FIFO A
   FIFO_A_read_back_data = {128{1'b0}};
   read_FIFO_A(8'd8,FIFO_A_read_back_data);
   #1000;       
 end
endtask


task i2c_CSR_write;
 begin
   //initialize writing into I2C control register
   write_status({8'hff, 8'h40, 8'h00, 8'd12, 8'h01,  8'hfe});
   #100;                
   //send 11 i2c command bytes to FIFO A (to be sent to I2C control register)
//mode 10 bit address mode
//first  i2c address f0
//second i2c address 88 
//8bytes of data
   USB_I2C_cmd = {{32{1'b0}},{I2C_WR,  STP, 4'd10}, {5'b11110,chip_id[3:2],WR_bit}, {chip_id[1:0],addr}, dw[63:0],{8'h00}};
   write_FIFO_A(8'd12, USB_I2C_cmd);
   //execute I2C control register intruction
   write_status({8'hff, 8'h01, 8'h00, 8'h00, 8'h01,  8'hfe});
   //wait until tranfer done
   @(posedge Stop_condition_detected);
   #3000;        
 end
endtask


task i2c_init;
 begin
   //initialize writing into I2C control register
   write_status({8'hff, 8'h40, 8'h00, 8'h05, 8'h01,  8'hfe});
   #100;                
   //send 5 bytes to FIFO A (to be sent to I2C control register)
   //set: prescalers for 40MHz clock and 0.5MHz I2C speed 
   //     CTR register EN bit 
//                                                                         100kHz 1f    4f  does not work
//                                                                         400kHz 13
//                                                                         500kHz 0f
//                                                                         1MHz   07
// 
   write_FIFO_A(8'h05, {{64{1'b0}}, {23'h000000}, {I2C_W_INIT, NSTP, 4'b0011},{8'h1f},{8'h00}, {8'h80}, {8'h00}});
   //execute I2C control register intruction
   write_status({8'hff, 8'h01, 8'h00, 8'h00, 8'h01,  8'hfe});
   #1000;
 end
endtask



//task to read data from FIFO A
task read_FIFO_A;
    input    [7:0] NW;
    output [127:0] FIFO_A_data_out;
    begin
                FTDI_A_op=FPGA_to_FTDI;
                FIFO_A_data_out = {128{1'b0}};
                NUM_WORDS_A = NW;
                start_FTDI_A;
		@(posedge FTDI_A_done);
                FIFO_A_data_out = DATA_from_FTDI_A;
	end
endtask

//task to write data into FIFO A
task write_FIFO_A;
    input   [7:0] NW;
    input [319:0] FIFO_A_DATA;
    begin
                FTDI_A_op=FTDI_to_FPGA;
                DATA_to_FTDI_A = FIFO_A_DATA;
                NUM_WORDS_A = NW;
                start_FTDI_A;
		@(posedge FTDI_A_done);
	end
endtask


//task to write data into status register
task write_status;
    input [47:0] status_data;
    begin
                FTDI_B_op=FTDI_to_FPGA;
                DATA_to_FTDI_B = {{64{1'b0}}, 16'h0000, status_data};
                NUM_WORDS_B = 8'h06;
                start_FTDI_B;
		repeat (1) @(posedge FTDI_B_done);
	end
endtask

//task to read status register
task read_status;
    output [63:0] status_data_out;
    begin
                FTDI_B_op=FPGA_to_FTDI;
                status_data_out = {128{1'b0}};
                NUM_WORDS_B = 8'h06;
                start_FTDI_B;
		repeat (1) @(posedge FTDI_B_done);
                status_data_out = DATA_from_FTDI_B;
	end
endtask

//task to generate reset
task reset_signal;
    begin
                repeat(1) @(negedge clk_5M);
                reset = 1;
                repeat(10) @(negedge clk_5M);
                reset = 0;
	end
endtask

task start_FTDI_B;
    begin
                repeat(1) @(posedge clk_40M); 
                start_FTDI_B_op=1'b1;
                repeat(1) @(posedge clk_40M);
                start_FTDI_B_op=1'b0;
	end
endtask

task start_FTDI_A;
    begin
                repeat(1) @(posedge clk_40M); 
                start_FTDI_A_op=1'b1;
                repeat(1) @(posedge clk_40M);
                start_FTDI_A_op=1'b0;
	end
endtask

endmodule


