Add Verilog MMIO GCD peripheral example

This commit is contained in:
Albert Magyar
2019-09-25 19:32:34 -07:00
parent aa7fd5ada0
commit c2ce173195
9 changed files with 371 additions and 1 deletions

View 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

View File

@@ -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
*/

View 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

View File

@@ -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

View File

@@ -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)