Merge branch 'master' into tweaks
This commit is contained in:
commit
b695ab5292
37
src/main/scala/uncore/tilelink2/Example.scala
Normal file
37
src/main/scala/uncore/tilelink2/Example.scala
Normal file
@ -0,0 +1,37 @@
|
||||
// See LICENSE for license details.
|
||||
|
||||
package uncore.tilelink2
|
||||
|
||||
import Chisel._
|
||||
|
||||
case class ExampleParams(num: Int, address: BigInt)
|
||||
|
||||
trait ExampleBundle
|
||||
{
|
||||
val params: ExampleParams
|
||||
val gpio = UInt(width = params.num)
|
||||
}
|
||||
|
||||
trait ExampleModule extends HasRegMap
|
||||
{
|
||||
val params: ExampleParams
|
||||
val io: ExampleBundle
|
||||
val interrupts: Vec[Bool]
|
||||
|
||||
val state = RegInit(UInt(0))
|
||||
val pending = RegInit(UInt(0xf, width = 4))
|
||||
|
||||
io.gpio := state
|
||||
interrupts := pending.toBools
|
||||
|
||||
regmap(
|
||||
0 -> Seq(
|
||||
RegField(params.num, state)),
|
||||
1 -> Seq(
|
||||
RegField.w1ToClear(4, pending, state)))
|
||||
}
|
||||
|
||||
// Create a concrete TL2 version of the abstract Example slave
|
||||
class TLExample(p: ExampleParams) extends TLRegisterRouter(p.address, 4)(
|
||||
new TLRegBundle(p, _) with ExampleBundle)(
|
||||
new TLRegModule(p, _, _) with ExampleModule)
|
@ -1,37 +0,0 @@
|
||||
// See LICENSE for license details.
|
||||
|
||||
package uncore.tilelink2
|
||||
|
||||
import Chisel._
|
||||
|
||||
case class GPIOParams(num: Int, address: BigInt)
|
||||
|
||||
trait GPIOBundle
|
||||
{
|
||||
val params: GPIOParams
|
||||
val gpio = UInt(width = params.num)
|
||||
}
|
||||
|
||||
trait GPIOModule extends HasRegMap
|
||||
{
|
||||
val params: GPIOParams
|
||||
val io: GPIOBundle
|
||||
val interrupts: Vec[Bool]
|
||||
|
||||
val state = RegInit(UInt(0))
|
||||
val pending = RegInit(UInt(0xf, width = 4))
|
||||
|
||||
io.gpio := state
|
||||
interrupts := pending.toBools
|
||||
|
||||
regmap(
|
||||
0 -> Seq(
|
||||
RegField(params.num, state)),
|
||||
1 -> Seq(
|
||||
RegField.w1ToClear(4, pending, state)))
|
||||
}
|
||||
|
||||
// Create a concrete TL2 version of the abstract GPIO slave
|
||||
class TLGPIO(p: GPIOParams) extends TLRegisterRouter(p.address, 4)(
|
||||
new TLRegBundle(p, _) with GPIOBundle)(
|
||||
new TLRegModule(p, _, _) with GPIOModule)
|
@ -4,6 +4,8 @@ package uncore.tilelink2
|
||||
|
||||
import Chisel._
|
||||
|
||||
import uncore.util.{SimpleRegIO}
|
||||
|
||||
case class RegReadFn private(combinational: Boolean, fn: (Bool, Bool) => (Bool, Bool, UInt))
|
||||
object RegReadFn
|
||||
{
|
||||
@ -81,6 +83,15 @@ object RegField
|
||||
// Setting takes priority over clearing.
|
||||
def w1ToClear(n: Int, reg: UInt, set: UInt): RegField =
|
||||
RegField(n, reg, RegWriteFn((valid, data) => { reg := ~(~reg | Mux(valid, data, UInt(0))) | set; Bool(true) }))
|
||||
|
||||
// This RegField wraps an explicit register
|
||||
// (e.g. Black-Boxed Register) to create a R/W register.
|
||||
def rwReg(n: Int, bb: SimpleRegIO) : RegField =
|
||||
RegField(n, bb.q, RegWriteFn((valid, data) => {
|
||||
bb.en := valid
|
||||
bb.d := data
|
||||
Bool(true)
|
||||
}))
|
||||
}
|
||||
|
||||
trait HasRegMap
|
||||
|
84
src/main/scala/uncore/util/BlackBoxRegs.scala
Normal file
84
src/main/scala/uncore/util/BlackBoxRegs.scala
Normal file
@ -0,0 +1,84 @@
|
||||
package uncore.util
|
||||
|
||||
import Chisel._
|
||||
|
||||
import cde.{Parameters}
|
||||
import junctions.{ParameterizedBundle}
|
||||
|
||||
/** This black-boxes an Async Reset
|
||||
* Reg.
|
||||
*
|
||||
* Because Chisel doesn't support
|
||||
* parameterized black boxes,
|
||||
* we unfortunately have to
|
||||
* instantiate a number of these.
|
||||
*
|
||||
* Do not confuse an asynchronous
|
||||
* reset signal with an asynchronously
|
||||
* reset reg. You should still
|
||||
* properly synchronize your reset
|
||||
* deassertion.
|
||||
*
|
||||
* @param d Data input
|
||||
* @param q Data Output
|
||||
* @param clk Clock Input
|
||||
* @param rst Reset Input
|
||||
*
|
||||
* @param init Value to write at Reset.
|
||||
* This is a constant,
|
||||
* but this construction
|
||||
* will likely make backend flows
|
||||
* and lint tools unhappy.
|
||||
*
|
||||
*/
|
||||
|
||||
class AsyncResetReg extends BlackBox {
|
||||
|
||||
val io = new Bundle {
|
||||
val d = Bool(INPUT)
|
||||
val q = Bool(OUTPUT)
|
||||
|
||||
val clk = Clock(INPUT)
|
||||
val rst = Bool(INPUT)
|
||||
|
||||
val init = Bool(INPUT)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class SimpleRegIO(val w: Int)(implicit val p: Parameters) extends ParameterizedBundle()(p){
|
||||
|
||||
val d = UInt(INPUT, width = w)
|
||||
val q = UInt(OUTPUT, width = w)
|
||||
|
||||
val en = Bool(INPUT)
|
||||
|
||||
}
|
||||
|
||||
class AsyncResetRegVec(val w: Int, val init: Int)(implicit val p: Parameters) extends Module {
|
||||
|
||||
val io = new SimpleRegIO(w)(p)
|
||||
|
||||
val bb_q = Wire(UInt(width = w))
|
||||
val bb_d = Wire(UInt(width = w))
|
||||
|
||||
val init_val = Wire(UInt(width = w))
|
||||
init_val := UInt(init, width = w)
|
||||
|
||||
val async_regs = List.fill(w)(Module (new AsyncResetReg))
|
||||
|
||||
bb_q := (async_regs.map(_.io.q)).asUInt()
|
||||
bb_d := Mux(io.en , io.d , bb_q)
|
||||
|
||||
io.q := bb_q
|
||||
|
||||
|
||||
for ((reg, idx) <- async_regs.zipWithIndex) {
|
||||
reg.io.clk := clock
|
||||
reg.io.rst := reset
|
||||
reg.io.init := init_val(idx)
|
||||
reg.io.d := bb_d(idx)
|
||||
}
|
||||
|
||||
}
|
@ -6,7 +6,8 @@
|
||||
|
||||
bb_vsrcs = $(base_dir)/vsrc/DebugTransportModuleJtag.v \
|
||||
$(base_dir)/vsrc/jtag_vpi.v \
|
||||
$(base_dir)/vsrc/AsyncMailbox.v
|
||||
$(base_dir)/vsrc/AsyncMailbox.v \
|
||||
$(base_dir)/vsrc/AsyncResetReg.v
|
||||
|
||||
sim_vsrcs = \
|
||||
$(generated_dir)/$(MODEL).$(CONFIG).v \
|
||||
|
51
vsrc/AsyncResetReg.v
Normal file
51
vsrc/AsyncResetReg.v
Normal file
@ -0,0 +1,51 @@
|
||||
|
||||
|
||||
/** This black-boxes an Async Reset
|
||||
* Reg.
|
||||
*
|
||||
* Because Chisel doesn't support
|
||||
* parameterized black boxes,
|
||||
* we unfortunately have to
|
||||
* instantiate a number of these.
|
||||
*
|
||||
* Do not confuse an asynchronous
|
||||
* reset signal with an asynchronously
|
||||
* reset reg. You should still
|
||||
* properly synchronize your reset
|
||||
* deassertion.
|
||||
*
|
||||
* @param d Data input
|
||||
* @param q Data Output
|
||||
* @param clk Clock Input
|
||||
* @param rst Reset Input
|
||||
*
|
||||
* @param init Value to write at Reset.
|
||||
* This is a constant,
|
||||
* but this construction
|
||||
* will likely make backend flows
|
||||
* and lint tools unhappy.
|
||||
*
|
||||
*/
|
||||
|
||||
module AsyncResetReg (
|
||||
input d,
|
||||
output reg q,
|
||||
|
||||
input clk,
|
||||
input rst,
|
||||
|
||||
input init);
|
||||
|
||||
always @(posedge clk or posedge rst) begin
|
||||
|
||||
if (rst) begin
|
||||
q <= init;
|
||||
end else begin
|
||||
q <= d;
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
endmodule // AsyncResetReg
|
||||
|
Loading…
Reference in New Issue
Block a user