aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/sim/rfnoc/sim_clock_gen.sv
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/sim/rfnoc/sim_clock_gen.sv')
-rw-r--r--fpga/usrp3/sim/rfnoc/sim_clock_gen.sv127
1 files changed, 127 insertions, 0 deletions
diff --git a/fpga/usrp3/sim/rfnoc/sim_clock_gen.sv b/fpga/usrp3/sim/rfnoc/sim_clock_gen.sv
new file mode 100644
index 000000000..ce7d4880a
--- /dev/null
+++ b/fpga/usrp3/sim/rfnoc/sim_clock_gen.sv
@@ -0,0 +1,127 @@
+//
+// Copyright 2019 Ettus Research, A National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+// Module: sim_clock_gen
+//
+// Description: This module generates a clock and reset signal for the purposes
+// of simulation. Both clock and reset are configurable at run time for
+// software-based simulation control.
+//
+
+
+
+module sim_clock_gen #(
+ parameter realtime PERIOD = 10.0, // Period in ns
+ parameter real DUTY_CYCLE = 0.5, // Duty cycle, in the range (0.0, 1.0)
+ parameter bit AUTOSTART = 1 // Start clock automatically at time 0
+) (
+ output bit clk,
+ output bit rst
+);
+ timeunit 1ns;
+ timeprecision 1ps;
+
+ realtime period = PERIOD;
+ real duty = DUTY_CYCLE;
+ realtime low_time = PERIOD * (1.0 - DUTY_CYCLE);
+ realtime high_time = PERIOD * DUTY_CYCLE;
+ bit toggle = AUTOSTART;
+ bit alive = 1;
+
+
+ //-----------------------
+ // Clock and Reset Tasks
+ //-----------------------
+
+ // Set the period and duty cycle for the clock
+ function void set_clock(real new_period, real new_duty);
+ low_time = new_period * (1.0 - new_duty);
+ high_time = new_period * new_duty;
+ endfunction
+
+ // Set the period, only, for the clock
+ function void set_period(real new_period);
+ set_clock(new_period, duty);
+ endfunction
+
+ // Set the duty cycle, only, for the clock
+ function void set_duty(real new_duty);
+ set_clock(period, new_duty);
+ endfunction
+
+ // Start toggling the clock
+ function void start();
+ toggle = 1;
+ endfunction
+
+ // Stop toggling the clock
+ function void stop();
+ toggle = 0;
+ endfunction
+
+ // Stop running the clock loop (no new simulation events will be created)
+ function void kill();
+ alive = 0;
+ endfunction
+
+ // Start running the clock loop (new simulation events will be created)
+ function void revive();
+ alive = 1;
+ endfunction
+
+ // Asynchronously assert the reset signal and synchronously deassert it after
+ // "length" clock cycles.
+ task reset(int length = 8);
+ fork
+ begin
+ rst <= 1;
+ repeat (length) @(posedge clk);
+ rst <= 0;
+ end
+ join_none
+
+ // Make sure rst asserts before we return
+ wait(rst);
+ endtask : reset
+
+ // Assert reset
+ task set_reset();
+ rst <= 1'b1;
+ endtask : set_reset
+
+ // Deassert reset
+ task clr_reset();
+ rst <= 1'b0;
+ endtask : clr_reset
+
+ // Wait for num rising edges of the clock
+ task clk_wait_r(int num = 1);
+ repeat(num) @(posedge clk);
+ endtask
+
+ // Wait for num falling edges of the clock
+ task clkd_wait_f(int num = 1);
+ repeat(num) @(negedge clk);
+ endtask
+
+
+ //--------------------------
+ // Clock Generation Process
+ //--------------------------
+
+ initial begin : clock_block
+ // Toggle the clock in a loop
+ forever begin : clock_loop
+ #(low_time);
+ if (toggle) clk = 0;
+
+ #(high_time);
+ if (toggle) clk = 1;
+
+ wait (alive);
+ end
+ end
+
+endmodule : sim_clock_gen \ No newline at end of file