Merge pull request #293 from ucb-bar/async_clk_utils
Add some async/clock utilities
This commit is contained in:
		@@ -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
 | 
			
		||||
		Reference in New Issue
	
	Block a user