//
// Top level module for absolutely trivial bootloader for the FPGA
// for the MAX80 project by Per Mårtensson and H. Peter Anvin.
//
// This bootloader simply gives the ESP32 processor control of the
// connections to the FPGA flash.
//

// Sharing JTAG pins (via JTAGEN)
`undef SHARED_JTAG

module bootldr
  #(parameter logic [6:1] x_mosfet,
    parameter logic [7:0] fpga_ver)
   (
    // Clock oscillator
    input	  master_clk, // 336 MHz from PLL2
    input	  master_pll_locked, // PLL2 is locked, master_clk is good
    output	  reset_plls, // Reset all PLLs including PLL2

    input	  board_id, // This better match the firmware

    // ABC-bus
    inout	  abc_clk, // ABC-bus 3 MHz clock
    inout [15:0]  abc_a, // ABC address bus
    inout [7:0]   abc_d, // ABC data bus
    output	  abc_d_oe, // Data bus output enable
    inout	  abc_rst_n, // ABC bus reset strobe
    inout	  abc_cs_n, // ABC card select strobe
    inout [4:0]   abc_out_n, // OUT, C1-C4 strobe
    inout [1:0]   abc_inp_n, // INP, STATUS strobe
    inout	  abc_xmemfl_n, // Memory read strobe
    inout	  abc_xmemw800_n, // Memory write strobe (ABC800)
    inout	  abc_xmemw80_n, // Memory write strobe (ABC80)
    inout	  abc_xinpstb_n, // I/O read strobe (ABC800)
    inout	  abc_xoutpstb_n, // I/O write strobe (ABC80)
    // The following are inverted versus the bus IF
    // the corresponding MOSFETs are installed
    inout	  abc_rdy_x, // RDY = WAIT#
    inout	  abc_resin_x, // System reset request
    inout	  abc_int80_x, // System INT request (ABC80)
    inout	  abc_int800_x, // System INT request (ABC800)
    inout	  abc_nmi_x, // System NMI request (ABC800)
    inout	  abc_xm_x, // System memory override (ABC800)
    // Host/device control
    output	  abc_host, // 1 = host, 0 = target

    // ABC-bus extension header
    // (Note: cannot use an array here because HC and HH are
    // input only.)
    inout	  exth_ha,
    inout	  exth_hb,
    input	  exth_hc,
    inout	  exth_hd,
    inout	  exth_he,
    inout	  exth_hf,
    inout	  exth_hg,
    input	  exth_hh,

    // SDRAM bus
    output	  sr_clk,
    output [1:0]  sr_ba, // Bank address
    output [12:0] sr_a, // Address within bank
    inout [15:0]  sr_dq, // Also known as D or IO
    output [1:0]  sr_dqm, // DQML and DQMH
    output	  sr_cs_n,
    output	  sr_we_n,
    output	  sr_cas_n,
    output	  sr_ras_n,

    // SD card
    input	  sd_cd_n,
    output	  sd_cs_n,
    output	  sd_clk,
    output	  sd_di,
    input	  sd_do,

    // Serial console (naming is FPGA as DCE)
    input	  tty_txd,
    output	  tty_rxd,
    input	  tty_rts,
    output	  tty_cts,
    input	  tty_dtr,

    // SPI flash memory (also configuration)
    output	  flash_cs_n,
    output	  flash_sck,
    inout [1:0]   flash_io,

    // SPI bus (connected to ESP32 so can be bidirectional)
    inout	  spi_clk,
    inout	  spi_miso,
    inout	  spi_mosi,
    inout	  spi_cs_esp_n, // ESP32 IO10
    inout	  spi_cs_flash_n, // ESP32 IO01

    // Other ESP32 connections
    inout	  esp_io0, // ESP32 IO00
    inout	  esp_int, // ESP32 IO09

    // I2C bus (RTC and external)
    inout	  i2c_scl,
    inout	  i2c_sda,
    input	  rtc_32khz,
    input	  rtc_int_n,

    // LEDs
    output [2:0]  led,

    // USB
    inout	  usb_dp,
    inout	  usb_dn,
    output	  usb_pu,
    input	  usb_rx,
    input	  usb_rx_ok,

    // HDMI
    output [2:0]  hdmi_d,
    output	  hdmi_clk,
    inout	  hdmi_scl,
    inout	  hdmi_sda,
    inout	  hdmi_hpd,

    // Unconnected pins with pullups, used for randomness
    inout [2:0]   rngio,

    // Various clocks available to the top level as well as internally
    output	  sdram_clk,	// 168 MHz SDRAM clock
    output	  sys_clk,	//  84 MHz System clock
    output	  flash_clk,	// 134 MHz Serial flash ROM clock
    output	  usb_clk,	//  48 MHz USB clock
    output	  vid_clk,	//  56 MHz Video pixel clock
    output	  vid_hdmiclk	// 280 MHz HDMI serializer clock = vid_clk x 5
    );

   // -----------------------------------------------------------------------
   //   Unused I/O devices
   // -----------------------------------------------------------------------

   assign reset_plls = 1'b0;

   assign abc_d_oe = 1'b0;
   assign abc_host = 1'b0;

   assign sr_clk      = 1'b0;
   assign sr_ba       = 2'b0;
   assign sr_a        = 'b0;
   assign sr_dq       = 'b0;
   assign sr_dqm      = 2'b11;
   assign sr_cs_n     = 1'b1;
   assign sr_we_n     = 1'b1;
   assign sr_cas_n    = 1'b1;
   assign sr_ras_n    = 1'b1;

   assign sd_cs_n     = 1'b1;
   assign sd_clk      = 1'b1;
   assign sd_di       = 1'b1;

   assign tty_rxd     = 1'b1;
   assign tty_cts     = 1'b1;

   assign i2c_scl     = 1'bz;
   assign i2c_sda     = 1'bz;

   assign hdmi_d      = 3'b000;
   assign hdmi_clk    = 1'b0;

   assign sdram_clk   = 1'b0;
   assign sys_clk     = 1'b0;
   assign flash_clk   = 1'b0;
   assign usb_clk     = 1'b0;
   assign vid_clk     = 1'b0;
   assign vid_hdmiclk = 1'b0;

   // -----------------------------------------------------------------------
   //   PLLs, clocks and reset
   // -----------------------------------------------------------------------

   wire rst_n = ~master_pll_locked;

   // -----------------------------------------------------------------------
   //   Flashing of LEDs
   // -----------------------------------------------------------------------

   reg [13:0]	  led_flash_ctr; // Flash LED @ 2 Hz to show in boot loader

   // The negedge of rtc_32khz is more stable than the posedge
   always @(negedge rtc_32khz)
     led_flash_ctr <= led_flash_ctr + 1'b1;

   assign led[0] = flash_io[1];
   assign led[1] = ~flash_cs_n;
   assign led[2] = led_flash_ctr[13];

   // -----------------------------------------------------------------------
   //   ESP32 <-> flash SPI logic
   // -----------------------------------------------------------------------

   assign flash_cs_n  = spi_cs_flash_n;
   assign flash_sck   = spi_clk;
   assign flash_io[0] = spi_miso;
   assign spi_mosi    = flash_io[1];
   assign spi_int     = 1'b0;	// Let ESP32 know configuration is done

endmodule
