Add Verilog MMIO GCD peripheral example
This commit is contained in:
48
generators/example/src/main/resources/vsrc/GCDMMIOBlackBox.v
Normal file
48
generators/example/src/main/resources/vsrc/GCDMMIOBlackBox.v
Normal file
@@ -0,0 +1,48 @@
|
||||
// DOC include start: GCD portlist
|
||||
module GCDMMIOBlackBox
|
||||
#(parameter WIDTH)
|
||||
(
|
||||
input clock,
|
||||
input reset,
|
||||
output input_ready,
|
||||
input input_valid,
|
||||
input [WIDTH-1:0] x,
|
||||
input [WIDTH-1:0] y,
|
||||
input output_ready,
|
||||
output output_valid,
|
||||
output reg [WIDTH-1:0] gcd
|
||||
);
|
||||
// DOC include end: GCD portlist
|
||||
|
||||
localparam S_IDLE = 2'b00, S_RUN = 2'b01, S_DONE = 2'b10;
|
||||
|
||||
reg [1:0] state;
|
||||
reg [WIDTH-1:0] tmp;
|
||||
|
||||
assign input_ready = state == S_IDLE;
|
||||
assign output_valid = state == S_DONE;
|
||||
|
||||
always @(posedge clock) begin
|
||||
if (reset)
|
||||
state <= S_IDLE;
|
||||
else if (state == S_IDLE && input_valid)
|
||||
state <= S_RUN;
|
||||
else if (state == S_RUN && tmp == 0)
|
||||
state <= S_DONE;
|
||||
else if (state == S_DONE && output_ready)
|
||||
state <= S_IDLE;
|
||||
end
|
||||
|
||||
always @(posedge clock) begin
|
||||
if (state == S_IDLE && input_valid) begin
|
||||
gcd <= x;
|
||||
tmp <= y;
|
||||
end else if (state == S_RUN) begin
|
||||
if (gcd > tmp)
|
||||
gcd <= gcd - tmp;
|
||||
else
|
||||
tmp <= tmp - gcd;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule // GCDMMIOBlackBox
|
||||
@@ -87,6 +87,14 @@ class WithPWMAXI4Top extends Config((site, here, up) => {
|
||||
Module(LazyModule(new TopWithPWMAXI4()(p)).module)
|
||||
})
|
||||
|
||||
/**
|
||||
* Class to specify a top level BOOM and/or Rocket system with a TL-attached GCD device
|
||||
*/
|
||||
class WithGCDTop extends Config((site, here, up) => {
|
||||
case BuildTop => (clock: Clock, reset: Bool, p: Parameters) =>
|
||||
Module(LazyModule(new TopWithGCD()(p)).module)
|
||||
})
|
||||
|
||||
/**
|
||||
* Class to specify a top level BOOM and/or Rocket system with a block device
|
||||
*/
|
||||
|
||||
98
generators/example/src/main/scala/GCDMMIOBlackBox.scala
Normal file
98
generators/example/src/main/scala/GCDMMIOBlackBox.scala
Normal file
@@ -0,0 +1,98 @@
|
||||
package example
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import chisel3.core.{IntParam, Reset}
|
||||
import freechips.rocketchip.amba.axi4._
|
||||
import freechips.rocketchip.subsystem.BaseSubsystem
|
||||
import freechips.rocketchip.config.{Parameters, Field}
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.regmapper.{HasRegMap, RegField}
|
||||
import freechips.rocketchip.tilelink._
|
||||
import freechips.rocketchip.util.UIntIsOneOf
|
||||
|
||||
// DOC include start: GCD blackbox
|
||||
class GCDMMIOBlackBox(w: Int) extends BlackBox(Map("WIDTH" -> IntParam(w))) with HasBlackBoxResource {
|
||||
val io = IO(new Bundle {
|
||||
val clock = Input(Clock())
|
||||
val reset = Input(Bool())
|
||||
val input_ready = Output(Bool())
|
||||
val input_valid = Input(Bool())
|
||||
val x = Input(UInt(w.W))
|
||||
val y = Input(UInt(w.W))
|
||||
val output_ready = Input(Bool())
|
||||
val output_valid = Output(Bool())
|
||||
val gcd = Output(UInt(w.W))
|
||||
})
|
||||
|
||||
addResource("/vsrc/GCDMMIOBlackBox.v")
|
||||
}
|
||||
// DOC include end: GCD blackbox
|
||||
|
||||
// DOC include start: GCD instance regmap
|
||||
case class GCDParams(address: BigInt, beatBytes: Int, width: Int)
|
||||
|
||||
trait GCDModule extends HasRegMap {
|
||||
implicit val p: Parameters
|
||||
def params: GCDParams
|
||||
val clock: Clock
|
||||
val reset: Reset
|
||||
|
||||
val impl = Module(new GCDMMIOBlackBox(params.width))
|
||||
|
||||
// How many clock cycles in a PWM cycle?
|
||||
val x = Reg(UInt(params.width.W))
|
||||
val y = Wire(new DecoupledIO(impl.io.y))
|
||||
val gcd = Wire(new DecoupledIO(impl.io.gcd))
|
||||
val status = Cat(impl.io.input_ready, impl.io.output_valid)
|
||||
|
||||
impl.io.clock := clock
|
||||
impl.io.reset := reset.asBool
|
||||
impl.io.x := x
|
||||
impl.io.y := y.bits
|
||||
impl.io.input_valid := y.valid
|
||||
y.ready := impl.io.input_ready
|
||||
|
||||
gcd.bits := impl.io.gcd
|
||||
gcd.valid := impl.io.output_valid
|
||||
impl.io.output_ready := gcd.ready
|
||||
|
||||
regmap(
|
||||
0x00 -> Seq(
|
||||
RegField.r(2, status)), // a read-only register capturing current status
|
||||
0x04 -> Seq(
|
||||
RegField.w(params.width, x)), // a plain, write-only register
|
||||
0x08 -> Seq(
|
||||
RegField.w(params.width, y)), // write-only, y.valid is set on write
|
||||
0x0C -> Seq(
|
||||
RegField.r(params.width, gcd))) // read-only, gcd.ready is set on read
|
||||
}
|
||||
// DOC include end: GCD instance regmap
|
||||
|
||||
// DOC include start: GCD cake
|
||||
class GCD(c: GCDParams)(implicit p: Parameters)
|
||||
extends TLRegisterRouter(
|
||||
c.address, "gcd", Seq("ucbbar,gcd"),
|
||||
beatBytes = c.beatBytes)(
|
||||
new TLRegBundle(c, _))(
|
||||
new TLRegModule(c, _, _) with GCDModule)
|
||||
|
||||
trait HasPeripheryGCD { this: BaseSubsystem =>
|
||||
implicit val p: Parameters
|
||||
|
||||
private val address = 0x2000
|
||||
private val portName = "gcd"
|
||||
private val gcdWidth = 32
|
||||
|
||||
val gcd = LazyModule(new GCD(
|
||||
GCDParams(address, pbus.beatBytes, gcdWidth))(p))
|
||||
|
||||
pbus.toVariableWidthSlave(Some(portName)) { gcd.node }
|
||||
}
|
||||
|
||||
trait HasPeripheryGCDModuleImp extends LazyModuleImp {
|
||||
implicit val p: Parameters
|
||||
val outer: HasPeripheryGCD
|
||||
}
|
||||
|
||||
// DOC include end: GCD cake
|
||||
@@ -57,6 +57,13 @@ class PWMAXI4RocketConfig extends Config(
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new freechips.rocketchip.system.BaseConfig)
|
||||
|
||||
class GCDRocketConfig extends Config( // add MMIO GCD module
|
||||
new WithGCDTop ++
|
||||
new WithBootROM ++
|
||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new freechips.rocketchip.system.BaseConfig)
|
||||
|
||||
class SimBlockDeviceRocketConfig extends Config(
|
||||
new testchipip.WithBlockDevice ++ // add block-device module to peripherybus
|
||||
new WithSimBlockDeviceTop ++ // use top with block-device IOs and connect to simblockdevice
|
||||
|
||||
@@ -53,6 +53,16 @@ class TopWithPWMAXI4Module(l: TopWithPWMAXI4) extends TopModule(l)
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------
|
||||
|
||||
class TopWithGCD(implicit p: Parameters) extends Top
|
||||
with HasPeripheryGCD {
|
||||
override lazy val module = new TopWithGCDModule(this)
|
||||
}
|
||||
|
||||
class TopWithGCDModule(l: TopWithGCD) extends TopModule(l)
|
||||
with HasPeripheryGCDModuleImp
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------
|
||||
|
||||
class TopWithBlockDevice(implicit p: Parameters) extends Top
|
||||
with HasPeripheryBlockDevice {
|
||||
override lazy val module = new TopWithBlockDeviceModule(this)
|
||||
|
||||
Reference in New Issue
Block a user