Skip to content

Commit

Permalink
clocks: add TestClockSource test harness clock generators
Browse files Browse the repository at this point in the history
  • Loading branch information
hcook committed Nov 13, 2019
1 parent efb32e3 commit aa11060
Showing 1 changed file with 87 additions and 0 deletions.
87 changes: 87 additions & 0 deletions src/main/scala/clocks/TestClockSource.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package freechips.rocketchip.clocks

import chisel3._
import chisel3.util.HasBlackBoxInline
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.diplomacy._

class ClockSourceIO extends Bundle {
val power = Input(Bool())
val gate = Input(Bool())
val clk = Output(Clock())
}

/** This clock source is only intended to be used in test harnesses, and does not work correctly in verilator. */
class ClockSourceAtFreq(val freqMHz: Double) extends BlackBox(Map(
"PERIOD_PS" -> core.DoubleParam(1000000/freqMHz)
)) with HasBlackBoxInline {
val io = IO(new ClockSourceIO)

setInline("ClockSourceAtFreq.v",
s"""
|module ClockSourceAtFreq #(parameter PERIOD_PS="") (
| input power,
| input gate,
| output clk);
| timeunit 1ps/1ps;
|
| reg clk_i;
| initial
| clk_i = 1'b0;
| always
| clk_i = #(PERIOD_PS/2.0) ~clk_i & (power & ~gate);
| assign
| clk = clk_i;
|endmodule
|""".stripMargin)
}

/** This clock source is only intended to be used in test harnesses, and does not work correctly in verilator. */
class ClockSourceAtFreqFromPlusArg(val plusArgName: String) extends BlackBox
with HasBlackBoxInline {
val io = IO(new ClockSourceIO)

override def desiredName = s"ClockSourceAtFreqFromPlusArg$plusArgName"

setInline(s"$desiredName.v",
s"""
|module $desiredName (
| input power,
| input gate,
| output clk);
| timeunit 1ps/1ps;
|
| reg clk_i;
| real FREQ_MHZ;
| real PERIOD_PS;
| initial begin
| clk_i = 1'b0;
| if (!$$value$$plusargs("$plusArgName=%d", FREQ_MHZ)) begin
| FREQ_MHZ = 100.0;
| end
| PERIOD_PS = 1000000.0 / FREQ_MHZ;
| forever #(PERIOD_PS/2.0) clk_i = ~clk_i & (power & ~gate);
| end
| assign clk = clk_i;
|endmodule
|""".stripMargin)
}

/** This clock source is only intended to be used in test harnesses, and does not work correctly in verilator. */
class TestClockSource(freqs: Seq[Option[Double]])(implicit p: Parameters) extends LazyModule {

val node = ClockSourceNode(freqs.map(f =>
ClockSourceParameters(give = f.map(ff => ClockParameters(freqMHz = ff)))))

lazy val module = new LazyModuleImp(this) {
node.out.zipWithIndex.foreach { case ((bundle, edge), i) =>
val source = Module(edge.source.give.map(f =>
new ClockSourceAtFreq(f.freqMHz)
).getOrElse(new ClockSourceAtFreqFromPlusArg(s"CLOCKFREQMHZ$i"))).io
source.power := true.B
source.gate := false.B
bundle.clock := source.clk
bundle.reset := reset
}
}
}

0 comments on commit aa11060

Please sign in to comment.