// Copyright 2023 Google LLC
// Copyright lowRISC contributors
//
// Licensed under the Apache 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://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the 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.

module clkgen_xilultrascaleplus
    #(parameter int ClockFrequencyMhz = 80,
      // Add BUFG if not done by downstream logic
      parameter bit AddClkBuf = 1)
    (input clk_i,
     input clk_n_i,
     input rst_ni,
     input srst_ni,
     output clk_main_o,
     output clk_48MHz_o,
     output clk_aon_o,
     output clk_ibex_o,
     output rst_no);
  logic locked_pll;
  logic io_clk_buf;
  logic io_rst_buf_n;
  logic clk_10_buf;
  logic clk_10_unbuf;
  logic clk_fb_buf;
  logic clk_fb_unbuf;
  logic clk_48_buf;
  logic clk_48_unbuf;
  logic clk_aon_buf;
  logic clk_aon_unbuf;
  logic clk_ibex_buf;
  logic clk_ibex_unbuf;
  logic clk_ibufds_o;

  // Input IBUFDS conver diff-pair to single-end
  IBUFDS clk_ibufds(.I(clk_i),
                    .IB(clk_n_i),
                    .O(clk_ibufds_o));

  localparam real CLKOUT0_DIVIDE_F_CALC = 1200.0 / ClockFrequencyMhz;
  localparam int CLKOUT2_DIVIDE_CALC = CLKOUT0_DIVIDE_F_CALC * 4;

  MMCME2_ADV #(
          .BANDWIDTH("OPTIMIZED"),
          .COMPENSATION("ZHOLD"),
          .STARTUP_WAIT("FALSE"),
          .DIVCLK_DIVIDE(1),
          .CLKFBOUT_MULT_F(12.000),
          .CLKFBOUT_PHASE(0.000),
          .CLKOUT0_DIVIDE_F(CLKOUT0_DIVIDE_F_CALC),
          .CLKOUT0_PHASE(0.000),
          .CLKOUT0_DUTY_CYCLE(0.500),
          .CLKOUT1_DIVIDE(25),
          .CLKOUT1_PHASE(0.000),
          .CLKOUT1_DUTY_CYCLE(0.500),
          .CLKOUT2_DIVIDE(CLKOUT2_DIVIDE_CALC),
          .CLKOUT2_PHASE(0.000),
          .CLKOUT2_DUTY_CYCLE(0.500),
          // With CLKOUT4_CASCADE, CLKOUT6's divider is an input to CLKOUT4's
          // divider. The effective ratio is a multiplication of the two.
          .CLKOUT4_DIVIDE(40),
          .CLKOUT4_PHASE(0.000),
          .CLKOUT4_DUTY_CYCLE(0.500),
          .CLKOUT4_CASCADE("TRUE"),
          .CLKOUT6_DIVIDE(120),
          .CLKIN1_PERIOD(10.000))
      pll(.CLKFBOUT(clk_fb_unbuf),
          .CLKFBOUTB(),
          .CLKOUT0(clk_10_unbuf),
          .CLKOUT0B(),
          .CLKOUT1(clk_48_unbuf),
          .CLKOUT1B(),
          .CLKOUT2(clk_ibex_unbuf),
          .CLKOUT2B(),
          .CLKOUT3(),
          .CLKOUT3B(),
          .CLKOUT4(clk_aon_unbuf),
          .CLKOUT5(),
          .CLKOUT6(),
          // Input clock control
          .CLKFBIN(clk_fb_buf),
          .CLKIN1(clk_ibufds_o),
          .CLKIN2(1'b0),
          // Tied to always select the primary input clock
          .CLKINSEL(1'b1),
          // Ports for dynamic reconfiguration
          .DADDR(7'h0),
          .DCLK(1'b0),
          .DEN(1'b0),
          .DI(16'h0),
          .DO(),
          .DRDY(),
          .DWE(1'b0),
          // Phase shift signals
          .PSCLK(1'b0),
          .PSEN(1'b0),
          .PSINCDEC(1'b0),
          .PSDONE(),
          // Other control and status signals
          .CLKFBSTOPPED(),
          .CLKINSTOPPED(),
          .LOCKED(locked_pll),
          .PWRDWN(1'b0),
          // Do not reset MMCM on external reset, otherwise ILA disconnects at a
          // reset
          .RST(1'b0));

  // output buffering
  BUFGCE clk_fb_bufgce(.I(clk_fb_unbuf),
                       .O(clk_fb_buf));

  BUFGCE clk_aon_bufgce(.I(clk_aon_unbuf),
                        .O(clk_aon_buf));

  if (AddClkBuf == 1) begin : gen_clk_bufs
    BUFGCE clk_10_bufgce(.I(clk_10_unbuf),
                         .O(clk_10_buf));

    BUFGCE clk_48_bufgce(.I(clk_48_unbuf),
                         .O(clk_48_buf));

    BUFGCE clk_ibex_bufgce(.I(clk_ibex_unbuf),
                         .O(clk_ibex_buf));
  end else begin : gen_no_clk_bufs
    // BUFGs added by downstream modules, no need to add here
    assign clk_10_buf = clk_10_unbuf;
    assign clk_48_buf = clk_48_unbuf;
    assign clk_ibex_buf = clk_ibex_unbuf;
  end

  // outputs
  // clock
  assign clk_main_o = clk_10_buf;
  assign clk_48MHz_o = clk_48_buf;
  assign clk_aon_o = clk_aon_buf;
  assign clk_ibex_o = clk_ibex_buf;

  // reset
  assign rst_no = locked_pll & rst_ni & srst_ni;
endmodule
