Add some async/clock utilities
This commit is contained in:
parent
f7121a2a5b
commit
1308680f75
@ -50,3 +50,44 @@ object AsyncDecoupledFrom
|
||||
AsyncDecoupledCrossing(from_clock, from_reset, from_source, scope.clock, scope.reset, depth, sync)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Because Chisel/FIRRTL does not allow us
|
||||
* to directly assign clocks from Signals,
|
||||
* we need this black box module.
|
||||
* This may even be useful because some back-end
|
||||
* flows like to have this sort of transition
|
||||
* flagged with a special cell or module anyway.
|
||||
*/
|
||||
|
||||
class SignalToClock extends BlackBox {
|
||||
val io = new Bundle {
|
||||
val signal_in = Bool(INPUT)
|
||||
val clock_out = Clock(OUTPUT)
|
||||
}
|
||||
|
||||
// io.clock_out := io.signal_in
|
||||
}
|
||||
|
||||
object SignalToClock {
|
||||
def apply(signal: Bool): Clock = {
|
||||
val s2c = Module(new SignalToClock)
|
||||
s2c.io.signal_in := signal
|
||||
s2c.io.clock_out
|
||||
}
|
||||
}
|
||||
|
||||
class ClockToSignal extends BlackBox {
|
||||
val io = new Bundle {
|
||||
val clock_in = Clock(INPUT)
|
||||
val signal_out = Bool(OUTPUT)
|
||||
}
|
||||
}
|
||||
|
||||
object ClockToSignal {
|
||||
def apply(clk: Clock): Bool = {
|
||||
val c2s = Module(new ClockToSignal)
|
||||
c2s.io.clock_in := clk
|
||||
c2s.io.signal_out
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ package uncore.tilelink2
|
||||
|
||||
import Chisel._
|
||||
import junctions._
|
||||
import uncore.util.{AsyncResetRegVec}
|
||||
|
||||
// A very simple flow control state machine, run in the specified clock domain
|
||||
class BusyRegisterCrossing(clock: Clock, reset: Bool)
|
||||
@ -130,3 +131,56 @@ class RegisterReadCrossing[T <: Data](gen: T, sync: Int = 3) extends Module {
|
||||
crossing.io.deq.ready := io.master_port.request.valid && !reg.io.busy
|
||||
crossing.io.enq.valid := Bool(true)
|
||||
}
|
||||
|
||||
/** Wrapper to create an
|
||||
* asynchronously reset
|
||||
* slave register which
|
||||
* can be both read
|
||||
* and written using
|
||||
* crossing FIFOs.
|
||||
*/
|
||||
|
||||
object AsyncRWSlaveRegField {
|
||||
|
||||
def apply(slave_clock: Clock,
|
||||
slave_reset: Bool,
|
||||
width: Int,
|
||||
init: Int,
|
||||
master_allow: Bool = Bool(true),
|
||||
slave_allow: Bool = Bool(true)
|
||||
): (UInt, RegField) = {
|
||||
|
||||
val async_slave_reg = Module(new AsyncResetRegVec(width, init))
|
||||
async_slave_reg.reset := slave_reset
|
||||
async_slave_reg.clock := slave_clock
|
||||
|
||||
val wr_crossing = Module (new RegisterWriteCrossing(UInt(width = width)))
|
||||
|
||||
val scope = Module (new AsyncScope())
|
||||
|
||||
wr_crossing.io.master_clock := scope.clock
|
||||
wr_crossing.io.master_reset := scope.reset
|
||||
wr_crossing.io.master_allow := master_allow
|
||||
wr_crossing.io.slave_clock := slave_clock
|
||||
wr_crossing.io.slave_reset := slave_reset
|
||||
wr_crossing.io.slave_allow := slave_allow
|
||||
|
||||
async_slave_reg.io.en := wr_crossing.io.slave_valid
|
||||
async_slave_reg.io.d := wr_crossing.io.slave_register
|
||||
|
||||
val rd_crossing = Module (new RegisterReadCrossing(UInt(width = width )))
|
||||
|
||||
rd_crossing.io.master_clock := scope.clock
|
||||
rd_crossing.io.master_reset := scope.reset
|
||||
rd_crossing.io.master_allow := master_allow
|
||||
rd_crossing.io.slave_clock := slave_clock
|
||||
rd_crossing.io.slave_reset := slave_reset
|
||||
rd_crossing.io.slave_allow := slave_allow
|
||||
|
||||
rd_crossing.io.slave_register := async_slave_reg.io.q
|
||||
|
||||
(async_slave_reg.io.q, RegField(width, rd_crossing.io.master_port, wr_crossing.io.master_port))
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -9,6 +9,9 @@ bb_vsrcs = $(base_dir)/vsrc/DebugTransportModuleJtag.v \
|
||||
$(base_dir)/vsrc/AsyncMailbox.v \
|
||||
$(base_dir)/vsrc/AsyncResetReg.v \
|
||||
$(base_dir)/vsrc/ClockDivider.v \
|
||||
$(base_dir)/vsrc/ClockToSignal.v \
|
||||
$(base_dir)/vsrc/SignalToClock.v \
|
||||
|
||||
|
||||
sim_vsrcs = \
|
||||
$(generated_dir)/$(MODEL).$(CONFIG).v \
|
||||
|
19
vsrc/ClockToSignal.v
Normal file
19
vsrc/ClockToSignal.v
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
/* This blackbox is needed by
|
||||
* Chisel in order to do type conversion.
|
||||
* It may be useful for some synthesis flows
|
||||
* as well which require special
|
||||
* flagging on conversion from data to clock.
|
||||
*/
|
||||
|
||||
|
||||
module ClockToSignal(
|
||||
output signal_out,
|
||||
input clock_in
|
||||
);
|
||||
|
||||
|
||||
assign signal_out = clock_in;
|
||||
|
||||
endmodule // ClockToSignal
|
||||
|
18
vsrc/SignalToClock.v
Normal file
18
vsrc/SignalToClock.v
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
/* This blackbox is needed by
|
||||
* Chisel in order to do type conversion.
|
||||
* It may be useful for some synthesis flows
|
||||
* as well which require special
|
||||
* flagging on conversion from data to clock.
|
||||
*/
|
||||
|
||||
|
||||
module SignalToClock (
|
||||
output clock_out,
|
||||
input signal_in
|
||||
);
|
||||
|
||||
|
||||
assign clock_out = signal_in;
|
||||
|
||||
endmodule // SignalToClock
|
Loading…
Reference in New Issue
Block a user