<commit_before>// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

//
// Interface: clk_rst_if
// Generic clock and reset interface for clock events in various utilities
// It also generates o_clk and o_rst_n signals for driving clk and rst_n in the tb. The advantage is
// clk and rst_n can be completely controlled in course of the simulation.
// This interface provides methods to set freq/period, wait for clk/rst_n, apply rst_n among other
// things. See individual method descriptions below.
// inout clk
// inout rst_n

interface clk_rst_if #(
  parameter string IfName = "main"
) (
  inout clk,
  inout rst_n
);

`ifndef VERILATOR
  // include macros and import pkgs
  `include "dv_macros.svh"
  `include "uvm_macros.svh"
  import uvm_pkg::*;
`endif

  // Enables clock to be generated and driven by this interface.
  bit drive_clk;

  // The internal output clock value.
  logic o_clk;

  // Enables the rst_n to be generated and driven by this interface.
  bit drive_rst_n;

  // The internal output reset value.
  logic o_rst_n;

  // Applies clock gating.
  bit clk_gate = 1'b0;

  // The nominal (chosen) frequency (as period in ps) of the driven clock (50MHz by default).
  int clk_period_ps = 20_000;

  // The variation of clock period (mimics uncalibrated clocks), to scale the nominal frequency
  // down. If set to non-zero value, the clock frequency is scaled randomly on every edge.
  int clk_freq_scaling_pc = 0;

  // The percentage chance of freq scaled down randomly on each edge.
  int clk_freq_scaling_chance_pc = 50;

  // Clock frequency is scaled down. This enables the frequency to be randomly scaled up as well.
  //
  // Note: If set, the randomness of the clock frequency being scaled up or down may result in a
  // bigger frequency distribution than the intended clk_freq_scaling_pc setting. For example, 50MHz
  // with 10% scaling may result in pulses that are < 45MHz and > 55MHz wide as well.
  bit clk_freq_scale_up = 1'b0;

  // The computed clock frequency in MHz.
  real clk_freq_mhz = 50;

  // The duty cycle of the clock period as percentage. If jitter and scaling is applied, then the
  // duty cycle will not be maintained.
  int duty_cycle = 50;

  // Maximum jitter applied to each period of the clock - this is expected to be about 20% or less
  // than the clock period.
  // The jitter is divided to two values - plus-jitter and minus-jitter.
  // Plus jitter is the possible time can be added to the clock period, while the minus jittter is
  // the possible time can be subtracted from the clock period.
  //         _________
  // _____:_| :     : |_:_______
  //
  // The actual jitter value is picked randomly within the window
  // {[-max_minus_jitter_ps:max_plus_jitter_ps]}
  // and is added to the time to next edge.
  int max_plus_jitter_ps = 1000;
  int max_minus_jitter_ps = 1000;

  // The percentage chance of jitter occurring on each edge. If 0 (default value), then jitter is
  // disabled altogether. If 100, jitter is computed and applied at every edge.
  int jitter_chance_pc = 0;

  // Internal signal indicating the clock half periods  need to be recomputed.
  bit recompute = 1'b1;

  // Internal signal indicating the amount of time for which the clock stays high / lo in the next
  // cycle.
  int clk_hi_ps;
  int clk_lo_ps;
  real clk_hi_modified_ps;
  real clk_lo_modified_ps;

  // If true, this is the only clock in the system; there is no need to add initial jitter.
  bit sole_clock = 1'b0;

  // use IfName as a part of msgs to indicate which clk_rst_vif instance
  string msg_id = $sformatf("[%m(clk_rst_if):%s]", IfName);

  clocking cb @(posedge clk);
  endclocking

  clocking cbn @(negedge clk);
  endclocking

  // Wait for 'n' clocks based of postive clock edge
  task automatic wait_clks(int num_clks);
    repeat (num_clks) @cb;
  endtask

  // Wait for 'n' clocks based of negative clock edge
  task automatic wait_n_clks(int num_clks);
    repeat (num_clks) @cbn;
  endtask

  // wait for rst_n to assert and then deassert
  task automatic wait_for_reset(bit wait_negedge = 1'b1, bit wait_posedge = 1'b1);
    if (wait_negedge && ($isunknown(rst_n) || rst_n === 1'b1)) @(negedge rst_n);
    if (wait_posedge && (rst_n === 1'b0)) @(posedge rst_n);
  endtask

  // set the clk frequency in khz
  function automatic void set_freq_khz(int freq_khz);
    clk_freq_mhz = $itor(freq_khz) / 1000;
    clk_period_ps = 1000_000 / clk_freq_mhz;<commit_msg>[dv] Add `wait_clks_or_rst` to `clk_rst_if`<commit_after>// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

//
// Interface: clk_rst_if
// Generic clock and reset interface for clock events in various utilities
// It also generates o_clk and o_rst_n signals for driving clk and rst_n in the tb. The advantage is
// clk and rst_n can be completely controlled in course of the simulation.
// This interface provides methods to set freq/period, wait for clk/rst_n, apply rst_n among other
// things. See individual method descriptions below.
// inout clk
// inout rst_n

interface clk_rst_if #(
  parameter string IfName = "main"
) (
  inout clk,
  inout rst_n
);

`ifndef VERILATOR
  // include macros and import pkgs
  `include "dv_macros.svh"
  `include "uvm_macros.svh"
  import uvm_pkg::*;
`endif

  // Enables clock to be generated and driven by this interface.
  bit drive_clk;

  // The internal output clock value.
  logic o_clk;

  // Enables the rst_n to be generated and driven by this interface.
  bit drive_rst_n;

  // The internal output reset value.
  logic o_rst_n;

  // Applies clock gating.
  bit clk_gate = 1'b0;

  // The nominal (chosen) frequency (as period in ps) of the driven clock (50MHz by default).
  int clk_period_ps = 20_000;

  // The variation of clock period (mimics uncalibrated clocks), to scale the nominal frequency
  // down. If set to non-zero value, the clock frequency is scaled randomly on every edge.
  int clk_freq_scaling_pc = 0;

  // The percentage chance of freq scaled down randomly on each edge.
  int clk_freq_scaling_chance_pc = 50;

  // Clock frequency is scaled down. This enables the frequency to be randomly scaled up as well.
  //
  // Note: If set, the randomness of the clock frequency being scaled up or down may result in a
  // bigger frequency distribution than the intended clk_freq_scaling_pc setting. For example, 50MHz
  // with 10% scaling may result in pulses that are < 45MHz and > 55MHz wide as well.
  bit clk_freq_scale_up = 1'b0;

  // The computed clock frequency in MHz.
  real clk_freq_mhz = 50;

  // The duty cycle of the clock period as percentage. If jitter and scaling is applied, then the
  // duty cycle will not be maintained.
  int duty_cycle = 50;

  // Maximum jitter applied to each period of the clock - this is expected to be about 20% or less
  // than the clock period.
  // The jitter is divided to two values - plus-jitter and minus-jitter.
  // Plus jitter is the possible time can be added to the clock period, while the minus jittter is
  // the possible time can be subtracted from the clock period.
  //         _________
  // _____:_| :     : |_:_______
  //
  // The actual jitter value is picked randomly within the window
  // {[-max_minus_jitter_ps:max_plus_jitter_ps]}
  // and is added to the time to next edge.
  int max_plus_jitter_ps = 1000;
  int max_minus_jitter_ps = 1000;

  // The percentage chance of jitter occurring on each edge. If 0 (default value), then jitter is
  // disabled altogether. If 100, jitter is computed and applied at every edge.
  int jitter_chance_pc = 0;

  // Internal signal indicating the clock half periods  need to be recomputed.
  bit recompute = 1'b1;

  // Internal signal indicating the amount of time for which the clock stays high / lo in the next
  // cycle.
  int clk_hi_ps;
  int clk_lo_ps;
  real clk_hi_modified_ps;
  real clk_lo_modified_ps;

  // If true, this is the only clock in the system; there is no need to add initial jitter.
  bit sole_clock = 1'b0;

  // use IfName as a part of msgs to indicate which clk_rst_vif instance
  string msg_id = $sformatf("[%m(clk_rst_if):%s]", IfName);

  clocking cb @(posedge clk);
  endclocking

  clocking cbn @(negedge clk);
  endclocking

  // Wait for 'n' clocks based of postive clock edge
  task automatic wait_clks(int num_clks);
    repeat (num_clks) @cb;
  endtask

  // Wait for 'n' clocks based of negative clock edge
  task automatic wait_n_clks(int num_clks);
    repeat (num_clks) @cbn;
  endtask

  // Wait for 'num_clks' clocks based on the positive clock edge or reset, whichever comes first.
  task automatic wait_clks_or_rst(int num_clks);
    fork
      wait_clks(num_clks);
      wait_for_reset(.wait_negedge(1'b1), .wait_posedge(1'b0));
    join_any
  endtask

  // wait for rst_n to assert and then deassert
  task automatic wait_for_reset(bit wait_negedge = 1'b1, bit wait_posedge = 1'b1);
    if (wait_negedge && ($isunknown(rst_n) || rst_n === 1'b1)) @(negedge rst_n);
    if (wait_posedge && (rst_n === 1'b0)) @(posedge rst_n);
  endtask

  // set the clk frequency in khz
  function automatic void set_freq_khz(int freq_khz);
    clk_freq_mhz = $itor(freq_khz) / 1000;
    clk_period_ps = 1000_000 / clk_freq_mhz;
{'fraction_non_alphanumeric': 0.0775871256527763, 'fraction_numerical': 0.014920601087072365, 'mean_word_length': 3.294736842105263, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 4, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6939138', 'n_tokens_mistral': 3214, 'n_tokens_neox': 2955, 'n_words': 1226}