package Deserializer( mkDeserialize, IDeserializer(..), State(..)) where import ClkDivider import State interface (IDeserializer :: # -> # -> *) clkFreq baudRate = get :: Bit 8 putBitIn :: (Bit 1) -> Action {-# always_enabled, always_ready #-} mkDeserialize :: Handle -> Module (IDeserializer clkFreq baudRate) mkDeserialize fileHandle = do ftdiRxIn :: Wire(Bit 1) <- mkBypassWire shiftReg :: Reg(Bit 8) <- mkReg(0) ftdiState <- mkReg(IDLE) clkDivider :: (ClkDivider (TDiv clkFreq baudRate)) <- mkClkDivider fileHandle addRules $ rules {-# ASSERT fire when enabled #-} "IDLE" : when (ftdiState == IDLE), (ftdiRxIn == 0) ==> do clkDivider.reset ftdiState := ftdiState' ftdiState {-# ASSERT fire when enabled #-} "NOT IDLE" : when (ftdiState /= IDLE), (clkDivider.isAdvancing) ==> do ftdiState := ftdiState' ftdiState {-# ASSERT fire when enabled #-} "SAMPLING" : when DATA(n) <- ftdiState, n >= 0, n <= 7, let sampleTrigger = clkDivider.isHalfCycle in sampleTrigger ==> do shiftReg := ftdiRxIn ++ shiftReg[7:1] return $ interface IDeserializer {get = shiftReg when (ftdiState == STOP), (clkDivider.isAdvancing) ;putBitIn bit = ftdiRxIn := bit }