//------------------------------------------------------------------------------
// CERN BE-CO-HT
// White Rabbit Trigger Distribution (WRTD)
// https://ohwr.org/projects/wrtd
//------------------------------------------------------------------------------
//
// unit name:   main
//
// description: Testbench for the SVEC-based FMC TDC+FD WRTD reference design.
//
//------------------------------------------------------------------------------
// Copyright CERN 2018-2019
//------------------------------------------------------------------------------
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 2.0 (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-2.0.
// Unless required by applicable law or agreed to in writing, software,
// hardware and materials distributed under this License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions
// and limitations under the License.
//------------------------------------------------------------------------------

`timescale 1ns/1ps

`include "wrtd_driver.svh"
`include "vhd_wishbone_master.svh"

`define TDC_DIRECT_BASE 'h18000

module main;

   wire clk_sys, rst_sys_n;

   wire sfp_txp, sfp_txn, sfp_rxp, sfp_rxn;

   IVHDWishboneMaster host (clk_sys, rst_sys_n);

   dut_env DUT (host, clk_sys, rst_sys_n, sfp_txp, sfp_txn, sfp_rxp, sfp_rxn);

   IMockTurtleIRQ MtIrqMonitor (`MT_ATTACH_IRQ(DUT.DUT.cmp_mock_turtle));

   assign sfp_rxp = sfp_txp;
   assign sfp_rxn = sfp_txn;

   WrtdDrv dev;

   const uint64_t MT_BASE = 'h0002_0000;

   CBusAccessor acc;

   initial begin

      $timeformat (-6, 3, "us", 10);

      #10us;
      acc = host.get_accessor();
      acc.set_default_xfer_size(4);
      dev = new (acc, MT_BASE, MtIrqMonitor, "DUT");
      dev.init();

      dev.add_rule ( "rule0" );
      dev.set_rule ( "rule0", "NET0", "LC-O1", 200000 );
      dev.enable_rule ( "rule0" );

      dev.add_rule ( "rule1" );
      dev.set_rule ( "rule1", "NET1", "LC-O2", 200000 );
      dev.enable_rule ( "rule1" );

      dev.add_rule ( "rule2" );
      dev.set_rule ( "rule2", "NET2", "LC-O3", 200000 );
      dev.enable_rule ( "rule2" );

      dev.add_rule ( "rule3" );
      dev.set_rule ( "rule3", "LC-I1", "NET0", 0 );
      dev.enable_rule ( "rule3" );

      dev.add_rule ( "rule4" );
      dev.set_rule ( "rule4", "LC-I2", "NET1", 0 );
      dev.enable_rule ( "rule4" );

      dev.add_rule ( "rule5" );
      dev.set_rule ( "rule5", "LC-I3", "NET2", 0 );
      dev.enable_rule ( "rule5" );

      // Set dead-time
      acc.write(`TDC_DIRECT_BASE + 'h4, 'h40);
      // Enable channels
      acc.write(`TDC_DIRECT_BASE + 'h0, 'h1f);
   end

   initial begin
      forever begin
         if ( ( dev != null ) && ( dev.ready ) )
         dev.update ();
         #1us;
      end
   end

endmodule // main
