///////////////////////////////////////////////////
//                                               //
//   init_feb_power_tester.v                     //
//   v1.0 for Cyclone Fpga       jb/2023.        //
//                                               //
///////////////////////////////////////////////////



`timescale 1ns/1ps 
module init_feb_power_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;




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"


coluta_slow_control csc0
    (
    // 3 clock copies for tripple redundant design    
     .clk1   (clk_40M),
     .clk2   (clk_40M),
     .clk3   (clk_40M),

    //ADC slow control interface signals
     .reset  (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; 
init_pwr_up_fpga F1
     (  
      .FPGA_CLK      (clk_40M_fpga),  //fpga clock, 40MHz system clock copy (LVPECL signaling)

      //I2C interface (1.2V) to COLUTA chip

      .LPGBT12_M2SCL     (SCL), 
      .LPGBT12_M2SDA     (SDA),   
      .LPGBT12_RSTN      (RSTB),  


//      .DA             (DA[15:0]),
//      .DB             (DB[15:0]),


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

 

//*************************Histogram package control register is now use for Init_FEB_power hardware*********************************
// 5 LSB bits are used only 
//
// Here is the definition of them:
// 
// DA[0] 0  LpGBT12 i2c selected
// DA[0] 1  LPGBT13 i2c selected
//
//resets
//	LPGBT12_RSTN  = !(DA[1]);
//	LPGBT13_RSTN  = !(DA[2]);
//
//2.5V enable signal 
//  DA[3]; //1 lpgbt12 2.5V is enabled (pulled up) 
//  DA[4]; //1 lpgbt13 2.5V is enabled (pulled up)
//



//to generate I2C siganls for lpgbt12 and pull-up 2.5V for LPGBT12
//set    DA[0] = 1'b0
//       DA[2:1] = 2'b01
//       DA[4:3] = 2'b01
//

//   lpgbt12 2.5v pulled up, lpgbt12_rstn generated  lpgbt12 i2c selected
//            01                     01                      0
//             5'b01010
//             5'h0a
                                                         

                //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)
                write_FIFO_A(8'h04, {{64{1'b0}}, 64'h00000000_01_00ff0a});
                write_status({8'hff, 8'h01, 8'h00, 8'h00, 8'h11,  8'hfe});
                #150000;

//   lpgbt13 2.5v pulled up, lpgbt13_rstn generated  lpgbt13 i2c selected
//            10                     10                      1
//             5'b10101
//             5'h15
               write_status({8'hff, 8'h40, 8'h00, 8'h05, 8'h11,  8'hfe});
               write_FIFO_A(8'h04, {{64{1'b0}}, 64'h00000000_01_00ff0a}); //was ff15
               write_status({8'hff, 8'h04, 8'h00, 8'h00, 8'h11,  8'hfe});
               #3000;





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


