diff --git a/src/main/scala/util/ClockDivider.scala b/src/main/scala/util/ClockDivider.scala index bbe07279..91a280fd 100644 --- a/src/main/scala/util/ClockDivider.scala +++ b/src/main/scala/util/ClockDivider.scala @@ -19,6 +19,12 @@ class ClockDivider2 extends BlackBox { val clk_in = Clock(INPUT) } } +class ClockDivider3 extends BlackBox { + val io = new Bundle { + val clk_out = Clock(OUTPUT) + val clk_in = Clock(INPUT) + } +} /** Divide the clock by power of 2 times. * @param pow2 divides the clock 2 ^ pow2 times diff --git a/vsim/Makefrag b/vsim/Makefrag index 1429ba1c..50e3a1a3 100644 --- a/vsim/Makefrag +++ b/vsim/Makefrag @@ -7,6 +7,7 @@ bb_vsrcs = \ $(base_dir)/vsrc/jtag_vpi.v \ $(base_dir)/vsrc/ClockDivider2.v \ + $(base_dir)/vsrc/ClockDivider3.v \ $(base_dir)/vsrc/AsyncResetReg.v \ sim_vsrcs = \ diff --git a/vsrc/ClockDivider3.v b/vsrc/ClockDivider3.v new file mode 100644 index 00000000..f9fba48c --- /dev/null +++ b/vsrc/ClockDivider3.v @@ -0,0 +1,37 @@ +// See LICENSE.SiFive for license details. + +/** This black-boxes a Clock Divider by 3. + * The output clock is phase-aligned to the input clock. + * Do NOT use this in synthesis; the duty cycle is 2:1. + * + * Because Chisel does not support + * blocking assignments, it is impossible + * to create a deterministic divided clock. + * + * @param clk_out Divided Clock + * @param clk_in Clock Input + * + */ + +module ClockDivider3 (output reg clk_out, input clk_in); + + reg delay; + + initial begin + clk_out = 1'b0; + delay = 1'b0; + end + + always @(posedge clk_in) begin + if (clk_out == 1'b0) begin + clk_out = 1'b1; + delay <= 1'b0; + end else if (delay == 1'b1) begin + clk_out = 1'b0; + delay <= 1'b0; + end else begin + delay <= 1'b1; + end + end + +endmodule // ClockDivider3