diff --git a/bittide-instances/src/Bittide/Instances/Hitl/LinkConfiguration.hs b/bittide-instances/src/Bittide/Instances/Hitl/LinkConfiguration.hs index 3828a0c72..b5e973472 100644 --- a/bittide-instances/src/Bittide/Instances/Hitl/LinkConfiguration.hs +++ b/bittide-instances/src/Bittide/Instances/Hitl/LinkConfiguration.hs @@ -37,7 +37,6 @@ import Bittide.Hitl import Bittide.Instances.Hitl.Setup import Clash.Annotations.TH (makeTopEntity) -import Clash.Cores.Xilinx.GTH import Clash.Cores.Xilinx.Xpm.Cdc.Handshake.Extra import Clash.Cores.Xilinx.Xpm.Cdc.Single import Clash.Xilinx.ClockGen @@ -45,6 +44,7 @@ import Data.Maybe (fromMaybe, isJust) import qualified Bittide.Transceiver as Transceiver import qualified Bittide.Transceiver.ResetManager as ResetManager +import qualified Clash.Cores.Xilinx.GTH as Gth {- | Checks whether the received index matches with the corresponding entry in 'Bittide.Instances.Hitl.Setup.fpgaSetup' and sychronizes @@ -115,11 +115,11 @@ transceiversStartAndObserve :: "SYSCLK" ::: Clock Basic125 -> "RST_LOCAL" ::: Reset Basic125 -> "MY_INDEX" ::: Signal Basic125 (Index FpgaCount) -> - "GTH_RX_NS" ::: TransceiverWires GthRxS LinkCount -> - "GTH_RX_PS" ::: TransceiverWires GthRxS LinkCount -> + "GTH_RX_NS" ::: Gth.Wires GthRxS GthRx LinkCount -> + "GTH_RX_PS" ::: Gth.Wires GthRxS GthRx LinkCount -> "MISO" ::: Signal Basic125 Bit -> - ( "GTH_TX_NS" ::: TransceiverWires GthTxS LinkCount - , "GTH_TX_PS" ::: TransceiverWires GthTxS LinkCount + ( "GTH_TX_NS" ::: Gth.Wires GthTxS GthTx LinkCount + , "GTH_TX_PS" ::: Gth.Wires GthTxS GthTx LinkCount , "allReady" ::: Signal Basic125 Bool , "success" ::: Signal Basic125 Bool , "stats" ::: Vec LinkCount (Signal Basic125 ResetManager.Statistics) @@ -209,11 +209,11 @@ linkConfigurationTest :: "SMA_MGT_REFCLK_C" ::: DiffClock Ext200 -> "SYSCLK_125" ::: DiffClock Ext125 -> "SYNC_IN" ::: Signal Basic125 Bool -> - "GTH_RX_NS" ::: TransceiverWires GthRxS LinkCount -> - "GTH_RX_PS" ::: TransceiverWires GthRxS LinkCount -> + "GTH_RX_NS" ::: Gth.Wires GthRxS GthRx LinkCount -> + "GTH_RX_PS" ::: Gth.Wires GthRxS GthRx LinkCount -> "MISO" ::: Signal Basic125 Bit -> - ( "GTH_TX_NS" ::: TransceiverWires GthTxS LinkCount - , "GTH_TX_PS" ::: TransceiverWires GthTxS LinkCount + ( "GTH_TX_NS" ::: Gth.Wires GthTxS GthTx LinkCount + , "GTH_TX_PS" ::: Gth.Wires GthTxS GthTx LinkCount , "SYNC_OUT" ::: Signal Basic125 Bool , "spiDone" ::: Signal Basic125 Bool , "" @@ -225,7 +225,7 @@ linkConfigurationTest :: linkConfigurationTest refClkDiff sysClkDiff syncIn rxns rxps miso = (txns, txps, syncOut, spiDone, spiOut) where - refClk = ibufds_gte3 refClkDiff :: Clock Ext200 + refClk = Gth.ibufds_gte3 refClkDiff :: Clock Ext200 (sysClk, sysRst) = clockWizardDifferential sysClkDiff noReset -- the test starts with a valid configuration coming in diff --git a/bittide-instances/src/Bittide/Instances/Hitl/Setup.hs b/bittide-instances/src/Bittide/Instances/Hitl/Setup.hs index 505781d4d..24b1bae63 100644 --- a/bittide-instances/src/Bittide/Instances/Hitl/Setup.hs +++ b/bittide-instances/src/Bittide/Instances/Hitl/Setup.hs @@ -9,7 +9,6 @@ module Bittide.Instances.Hitl.Setup ( FpgaCount, LinkCount, FpgaId, - TransceiverWires, -- * Topology allHwTargets, @@ -36,12 +35,6 @@ type FpgaCount = 8 :: Nat type LinkCount = FpgaCount - 1 -{- | Data wires from/to transceivers. No logic should be inserted on these -wires. Should be considered asynchronous to one another - even though their -domain encodes them as related. --} -type TransceiverWires dom n = Signal dom (BitVector n) - channelNames :: Vec LinkCount String channelNames = "X0Y10" :> "X0Y9" :> "X0Y16" :> "X0Y17" :> "X0Y18" :> "X0Y19" :> "X0Y11" :> Nil diff --git a/bittide-instances/src/Bittide/Instances/Hitl/SwCcTopologies.hs b/bittide-instances/src/Bittide/Instances/Hitl/SwCcTopologies.hs index 3a66b5039..319015bd7 100644 --- a/bittide-instances/src/Bittide/Instances/Hitl/SwCcTopologies.hs +++ b/bittide-instances/src/Bittide/Instances/Hitl/SwCcTopologies.hs @@ -72,7 +72,6 @@ import Bittide.Instances.Hitl.Setup import Clash.Annotations.TH (makeTopEntity) import Clash.Class.Counter -import Clash.Cores.Xilinx.GTH import Clash.Cores.Xilinx.Ila (Depth (..), IlaConfig (..), ila, ilaConfig) import Clash.Cores.Xilinx.VIO import Clash.Cores.Xilinx.Xpm (xpmCdcArraySingle) @@ -87,6 +86,7 @@ import qualified Bittide.ClockControl.StabilityChecker as SI import qualified Bittide.Instances.Hitl.Driver.SwCcTopologies as D import qualified Bittide.Transceiver as Transceiver import qualified Bittide.Transceiver.ResetManager as ResetManager +import qualified Clash.Cores.Xilinx.GTH as Gth import qualified Data.Map.Strict as Map (fromList) {- $setup @@ -228,15 +228,15 @@ topologyTest :: "SMA_MGT_REFCLK_C" ::: Clock Ext200 -> "SYSCLK" ::: Clock Basic125 -> "ILA_CTRL" ::: IlaControl Basic125 -> - "GTH_RX_NS" ::: TransceiverWires GthRxS LinkCount -> - "GTH_RX_PS" ::: TransceiverWires GthRxS LinkCount -> + "GTH_RX_NS" ::: Gth.Wires GthRxS GthRx LinkCount -> + "GTH_RX_PS" ::: Gth.Wires GthRxS GthRx LinkCount -> "MISO" ::: Signal Basic125 Bit -> "TEST_CFG" ::: Signal Basic125 TestConfig -> "PROG_EN" ::: Reset Basic125 -> "CALIBRATED_SHIFT" ::: Signal Basic125 FincFdecCount -> "JTAG" ::: Signal Basic125 JtagIn -> - ( "GTH_TX_NS" ::: TransceiverWires GthTxS LinkCount - , "GTH_TX_PS" ::: TransceiverWires GthTxS LinkCount + ( "GTH_TX_NS" ::: Gth.Wires GthTxS GthTx LinkCount + , "GTH_TX_PS" ::: Gth.Wires GthTxS GthTx LinkCount , "FINC_FDEC" ::: Signal Basic125 (FINC, FDEC) , "CALLISTO_RESULT" ::: Signal Basic125 (CallistoResult LinkCount) , "CALLISTO_RESET" ::: Reset Basic125 @@ -756,12 +756,12 @@ swCcTopologyTest :: "SMA_MGT_REFCLK_C" ::: DiffClock Ext200 -> "SYSCLK_125" ::: DiffClock Ext125 -> "SYNC_IN" ::: Signal Basic125 Bool -> - "GTH_RX_NS" ::: TransceiverWires GthRxS LinkCount -> - "GTH_RX_PS" ::: TransceiverWires GthRxS LinkCount -> + "GTH_RX_NS" ::: Gth.Wires GthRxS GthRx LinkCount -> + "GTH_RX_PS" ::: Gth.Wires GthRxS GthRx LinkCount -> "MISO" ::: Signal Basic125 Bit -> "JTAG" ::: Signal Basic125 JtagIn -> - ( "GTH_TX_NS" ::: TransceiverWires GthTxS LinkCount - , "GTH_TX_PS" ::: TransceiverWires GthTxS LinkCount + ( "GTH_TX_NS" ::: Gth.Wires GthTxS GthTx LinkCount + , "GTH_TX_PS" ::: Gth.Wires GthTxS GthTx LinkCount , "" ::: ( "FINC" ::: Signal Basic125 Bool , "FDEC" ::: Signal Basic125 Bool @@ -778,7 +778,7 @@ swCcTopologyTest :: swCcTopologyTest refClkDiff sysClkDiff syncIn rxns rxps miso jtagIn = hwSeqX tleDebugIla (txns, txps, unbundle swFincFdecs, syncOut, spiDone, spiOut, jtagOut) where - refClk = ibufds_gte3 refClkDiff :: Clock Ext200 + refClk = Gth.ibufds_gte3 refClkDiff :: Clock Ext200 (sysClk, sysRst) = clockWizardDifferential sysClkDiff noReset ilaControl@IlaControl{..} = ilaPlotSetup IlaPlotSetup{..} startTest = isJust <$> testConfig @@ -954,12 +954,12 @@ swCcOneTopologyTest :: "SMA_MGT_REFCLK_C" ::: DiffClock Ext200 -> "SYSCLK_125" ::: DiffClock Ext125 -> "SYNC_IN" ::: Signal Basic125 Bool -> - "GTH_RX_NS" ::: TransceiverWires GthRxS LinkCount -> - "GTH_RX_PS" ::: TransceiverWires GthRxS LinkCount -> + "GTH_RX_NS" ::: Gth.Wires GthRxS GthRx LinkCount -> + "GTH_RX_PS" ::: Gth.Wires GthRxS GthRx LinkCount -> "MISO" ::: Signal Basic125 Bit -> "JTAG" ::: Signal Basic125 JtagIn -> - ( "GTH_TX_NS" ::: TransceiverWires GthTxS LinkCount - , "GTH_TX_PS" ::: TransceiverWires GthTxS LinkCount + ( "GTH_TX_NS" ::: Gth.Wires GthTxS GthTx LinkCount + , "GTH_TX_PS" ::: Gth.Wires GthTxS GthTx LinkCount , "" ::: ( "FINC" ::: Signal Basic125 Bool , "FDEC" ::: Signal Basic125 Bool diff --git a/bittide-instances/src/Bittide/Instances/Hitl/Transceivers.hs b/bittide-instances/src/Bittide/Instances/Hitl/Transceivers.hs index d187b5e97..00df0fc90 100644 --- a/bittide-instances/src/Bittide/Instances/Hitl/Transceivers.hs +++ b/bittide-instances/src/Bittide/Instances/Hitl/Transceivers.hs @@ -35,12 +35,12 @@ import Bittide.Instances.Hitl.Setup import Bittide.Transceiver import Clash.Annotations.TH (makeTopEntity) -import Clash.Cores.Xilinx.GTH import Clash.Cores.Xilinx.Xpm.Cdc.Single (xpmCdcSingle) import Clash.Xilinx.ClockGen import Data.Maybe (fromMaybe, isJust) import qualified Bittide.Transceiver.ResetManager as ResetManager +import qualified Clash.Cores.Xilinx.GTH as Gth import qualified Clash.Explicit.Prelude as E import qualified Data.List as L import qualified Data.Map as Map @@ -84,11 +84,11 @@ goTransceiversUpTest :: "SMA_MGT_REFCLK_C" ::: Clock Ext200 -> "SYSCLK" ::: Clock Basic125 -> "RST_LOCAL" ::: Reset Basic125 -> - "GTH_RX_NS" ::: TransceiverWires GthRxS LinkCount -> - "GTH_RX_PS" ::: TransceiverWires GthRxS LinkCount -> + "GTH_RX_NS" ::: Gth.Wires GthRxS GthRx LinkCount -> + "GTH_RX_PS" ::: Gth.Wires GthRxS GthRx LinkCount -> "MISO" ::: Signal Basic125 Bit -> - ( "GTH_TX_NS" ::: TransceiverWires GthTxS LinkCount - , "GTH_TX_PS" ::: TransceiverWires GthTxS LinkCount + ( "GTH_TX_NS" ::: Gth.Wires GthTxS GthTx LinkCount + , "GTH_TX_PS" ::: Gth.Wires GthTxS GthTx LinkCount , "allUp" ::: Signal Basic125 Bool , "anyErrors" ::: Signal Basic125 Bool , "stats" ::: Vec LinkCount (Signal Basic125 ResetManager.Statistics) @@ -182,11 +182,11 @@ transceiversUpTest :: "SMA_MGT_REFCLK_C" ::: DiffClock Ext200 -> "SYSCLK_125" ::: DiffClock Ext125 -> "SYNC_IN" ::: Signal Basic125 Bool -> - "GTH_RX_NS" ::: TransceiverWires GthRxS LinkCount -> - "GTH_RX_PS" ::: TransceiverWires GthRxS LinkCount -> + "GTH_RX_NS" ::: Gth.Wires GthRxS GthRx LinkCount -> + "GTH_RX_PS" ::: Gth.Wires GthRxS GthRx LinkCount -> "MISO" ::: Signal Basic125 Bit -> - ( "GTH_TX_NS" ::: TransceiverWires GthTxS LinkCount - , "GTH_TX_PS" ::: TransceiverWires GthTxS LinkCount + ( "GTH_TX_NS" ::: Gth.Wires GthTxS GthTx LinkCount + , "GTH_TX_PS" ::: Gth.Wires GthTxS GthTx LinkCount , "SYNC_OUT" ::: Signal Basic125 Bool , "spiDone" ::: Signal Basic125 Bool , "" @@ -198,7 +198,7 @@ transceiversUpTest :: transceiversUpTest refClkDiff sysClkDiff syncIn rxns rxps miso = (txns, txps, syncOut, spiDone, spiOut) where - refClk = ibufds_gte3 refClkDiff :: Clock Ext200 + refClk = Gth.ibufds_gte3 refClkDiff :: Clock Ext200 (sysClk, sysRst) = clockWizardDifferential sysClkDiff noReset diff --git a/bittide/src/Bittide/Transceiver.hs b/bittide/src/Bittide/Transceiver.hs index 02e4b2530..77fa5878e 100644 --- a/bittide/src/Bittide/Transceiver.hs +++ b/bittide/src/Bittide/Transceiver.hs @@ -178,9 +178,9 @@ data Outputs n tx rx txS free = Outputs -- ^ See 'Output.txReady' , txSamplings :: Vec n (Signal tx Bool) -- ^ See 'Output.txSampling' - , txPs :: Signal txS (BitVector n) + , txPs :: Gth.Wires txS tx n -- ^ See 'Output.txP' - , txNs :: Signal txS (BitVector n) + , txNs :: Gth.Wires txS tx n -- ^ See 'Output.txN' , rxClocks :: Vec n (Clock rx) -- ^ See 'Output.rxClock' @@ -196,7 +196,7 @@ data Outputs n tx rx txS free = Outputs -- ^ See 'Output.stats' } -data Output tx rx tx1 rx1 txS free serializedData = Output +data Output tx rx tx1 rx1 txS free = Output { txOutClock :: Clock tx1 -- ^ Must be routed through xilinxGthUserClockNetworkTx or equivalent to get usable clocks , txReset :: Reset tx @@ -207,9 +207,9 @@ data Output tx rx tx1 rx1 txS free serializedData = Output -- 'Input.txStart' to be asserted before starting to send 'txData'. , txSampling :: Signal tx Bool -- ^ Data is sampled from 'Input.txData' - , txP :: Signal txS serializedData + , txP :: Gth.Wire txS tx -- ^ Transmit data (and implicitly a clock), positive - , txN :: Signal txS serializedData + , txN :: Gth.Wire txS tx -- ^ Transmit data (and implicitly a clock), negative , rxOutClock :: Clock rx1 -- ^ Must be routed through xilinxGthUserClockNetworkRx or equivalent to get usable clocks @@ -227,7 +227,7 @@ data Output tx rx tx1 rx1 txS free serializedData = Output -- ^ Statistics exported by 'ResetManager.resetManager'. Useful for debugging. } -data Input tx rx tx1 rx1 ref free rxS serializedData = Input +data Input tx rx tx1 rx1 ref free rxS = Input { clock :: Clock free -- ^ Any "always on" clock , reset :: Reset free @@ -246,8 +246,8 @@ data Input tx rx tx1 rx1 ref free rxS serializedData = Input -- ^ Channel name, example \"X0Y18\" , clockPath :: String -- ^ Clock path, example \"clk0-2\" - , rxN :: Signal rxS serializedData - , rxP :: Signal rxS serializedData + , rxN :: Gth.Wire rxS rx + , rxP :: Gth.Wire rxS rx , txData :: Signal tx (BitVector 64) -- ^ Data to transmit to the neighbor. Is first sampled one cycle after both -- 'Input.txStart' and 'Output.txReady' are asserted. Is continuously sampled @@ -274,9 +274,9 @@ data Inputs tx rx ref free rxS n = Inputs -- ^ See 'Input.channelName' , clockPaths :: Vec n String -- ^ See 'Input.clockPath' - , rxNs :: Signal rxS (BitVector n) + , rxNs :: Gth.Wires rxS rx n -- ^ See 'Input.rxN' - , rxPs :: Signal rxS (BitVector n) + , rxPs :: Gth.Wires rxS rx n -- ^ See 'Input.rxP' , txDatas :: Vec n (Signal tx (BitVector 64)) -- ^ See 'Input.txData' @@ -330,8 +330,8 @@ transceiverPrbsN opts inputs@Inputs{clock, reset, refClock} = , rxResets = map (.rxReset) outputs , rxDatas = map (.rxData) outputs , -- transceiver - txPs = pack <$> bundle (map (.txP) outputs) - , txNs = pack <$> bundle (map (.txN) outputs) + txPs = Gth.packWires (map (.txP) outputs) + , txNs = Gth.packWires (map (.txN) outputs) , -- free linkUps = map (.linkUp) outputs , linkReadys = map (.linkReady) outputs @@ -347,14 +347,14 @@ transceiverPrbsN opts inputs@Inputs{clock, reset, refClock} = -- this zipWithN became unusably slow when using more then ~4 transceivers. -- Unfortunately this means debugIla is broken now, when using more then 1 transceiver. outputs = - (go txClockNw) - <$> (iterateI (+ 1) 0) -- Note that the target type is only 3 bits, so this will + go txClockNw + <$> iterateI (+ 1) 0 -- Note that the target type is only 3 bits, so this will -- wrap around after 8 transceivers. This is fine, as we -- only use this for debugging. <*> inputs.channelNames <*> inputs.clockPaths - <*> (unbundle (unpack <$> inputs.rxNs)) - <*> (unbundle (unpack <$> inputs.rxPs)) + <*> Gth.unpackWires inputs.rxNs + <*> Gth.unpackWires inputs.rxPs <*> inputs.txDatas <*> inputs.txStarts <*> inputs.rxReadys @@ -416,12 +416,12 @@ transceiverPrbs :: , KnownDomain free ) => Config free -> - Input tx rx tx1 rx1 ref free rxS (BitVector 1) -> - Output tx rx tx1 rx1 txS free (BitVector 1) + Input tx rx tx1 rx1 ref free rxS -> + Output tx rx tx1 rx1 txS free transceiverPrbs = transceiverPrbsWith Gth.gthCore transceiverPrbsWith :: - forall tx rx tx1 rx1 ref free txS rxS serializedData. + forall tx rx tx1 rx1 ref free txS rxS. ( HasSynchronousReset tx , HasDefinedInitialValues tx , HasSynchronousReset rx @@ -435,10 +435,10 @@ transceiverPrbsWith :: , KnownDomain ref , KnownDomain free ) => - Gth.GthCore tx1 tx rx1 rx ref free txS rxS serializedData -> + Gth.GthCore tx1 tx rx1 rx ref free txS rxS -> Config free -> - Input tx rx tx1 rx1 ref free rxS serializedData -> - Output tx rx tx1 rx1 txS free serializedData + Input tx rx tx1 rx1 ref free rxS -> + Output tx rx tx1 rx1 txS free transceiverPrbsWith gthCore opts args@Input{clock, reset} = when opts.debugIla debugIla `hwSeqX` result where @@ -524,8 +524,8 @@ transceiverPrbsWith gthCore opts args@Input{clock, reset} = { txSampling = txUserData , rxData = mux rxUserData (Just <$> alignedRxData0) (pure Nothing) , txReady = withLockRxTx rxReadyNeighborSticky - , txN - , txP + , txN = txN + , txP = txP , txOutClock , txReset , rxOutClock @@ -550,10 +550,10 @@ transceiverPrbsWith gthCore opts args@Input{clock, reset} = , reset_rx_done , _txpmaresetdone_out , _rxpmaresetdone_out - , (rxCtrl0 :: Signal rx (BitVector 16)) - , (rxCtrl1 :: Signal rx (BitVector 16)) - , (rxCtrl2 :: Signal rx (BitVector 8)) - , (rxCtrl3 :: Signal rx (BitVector 8)) + , rxCtrl0 :: Signal rx (BitVector 16) + , rxCtrl1 :: Signal rx (BitVector 16) + , rxCtrl2 :: Signal rx (BitVector 8) + , rxCtrl3 :: Signal rx (BitVector 8) ) = gthCore args.channelName diff --git a/bittide/src/Clash/Cores/Xilinx/GTH/Internal.hs b/bittide/src/Clash/Cores/Xilinx/GTH/Internal.hs index a0e321fa4..3a469a647 100644 --- a/bittide/src/Clash/Cores/Xilinx/GTH/Internal.hs +++ b/bittide/src/Clash/Cores/Xilinx/GTH/Internal.hs @@ -2,7 +2,11 @@ -- -- SPDX-License-Identifier: Apache-2.0 {-# LANGUAGE BangPatterns #-} +{-# LANGUAGE DuplicateRecordFields #-} +{-# LANGUAGE NamedFieldPuns #-} +{-# LANGUAGE OverloadedRecordDot #-} {-# LANGUAGE QuasiQuotes #-} +{-# LANGUAGE NoFieldSelectors #-} module Clash.Cores.Xilinx.GTH.Internal where @@ -28,7 +32,63 @@ import Clash.Cores.Xilinx.Xpm.Cdc.Internal ( type TX_DATA_WIDTH = 64 type RX_DATA_WIDTH = 64 -type GthCore txUser txUser2 rxUser rxUser2 refclk0 freerun txS rxS serializedData = +{- | Data wires from/to transceivers. No logic should be inserted on these +wires. Should be considered asynchronous to one another - even though their +domain encodes them as related. +-} +data Wires (line :: Domain) (logic :: Domain) n = Wires + { dats :: "" ::: Signal line (BitVector n) + -- ^ Wires routed to the transceivers + , datsSimulation :: "" ::: SimOnly (Signal logic (Vec n (BitVector 64))) + -- ^ Simulation only construct holding sent data in the domain of the user + -- transmit domain. + } + +-- | Data wire from/to transceivers +data Wire (line :: Domain) (logic :: Domain) = Wire + { dat :: "" ::: Signal line Bit + -- ^ Wires routed to the transceivers + , datSimulation :: "" ::: SimOnly (Signal logic (BitVector 64)) + -- ^ Simulation only construct holding sent data in the domain of the user + -- transmit domain. + } + +-- | Map over the 'datSimulation' field of a 'Wire' +mapDatSimulation :: + (Signal logic (BitVector 64) -> Signal logic (BitVector 64)) -> + Wire line logic -> + Wire line logic +mapDatSimulation f (Wire{dat, datSimulation}) = + Wire{dat = dat, datSimulation = f <$> datSimulation} + +-- | Pack multiple 'Wire's into a 'Wires' +packWires :: + forall line logic n. + (KnownNat n) => + Vec n (Wire line logic) -> + Wires line logic n +packWires ins = Wires{dats, datsSimulation} + where + dats = fmap pack $ bundle $ map (.dat) ins + datsSimulation = bundle <$> mapM (.datSimulation) ins + +-- | Unpack a 'Wires' into multiple 'Wire's +unpackWires :: + forall line logic n. + (KnownNat n) => + Wires line logic n -> + Vec n (Wire line logic) +unpackWires Wires{dats, datsSimulation} = + zipWith + Wire + (unbundle (fmap unpack dats)) + (map SimOnly (unbundle (unSimOnly datsSimulation))) + +-- | Strip "SimOnly" constructor +unSimOnly :: SimOnly a -> a +unSimOnly (SimOnly x) = x + +type GthCore txUser txUser2 rxUser rxUser2 refclk0 freerun txS rxS = ( KnownDomain txUser , KnownDomain txUser2 , KnownDomain rxUser @@ -42,8 +102,8 @@ type GthCore txUser txUser2 rxUser rxUser2 refclk0 freerun txS rxS serializedDat String -> -- | refClkSpec String -> - "gthrxn_in" ::: Signal rxS serializedData -> - "gthrxp_in" ::: Signal rxS serializedData -> + "gthrxn_in" ::: Wire rxS rxUser2 -> + "gthrxp_in" ::: Wire rxS rxUser2 -> "gtwiz_reset_clk_freerun_in" ::: Clock freerun -> "gtwiz_reset_all_in" ::: Reset freerun -> "gtwiz_reset_rx_datapath_in" ::: Reset freerun -> @@ -56,8 +116,8 @@ type GthCore txUser txUser2 rxUser rxUser2 refclk0 freerun txS rxS serializedDat "rxusrclk_in" ::: Clock rxUser -> "rxusrclk2_in" ::: Clock rxUser2 -> "gtwiz_userclk_rx_active_in" ::: Signal rxUser2 (BitVector 1) -> - ( "gthtxn_out" ::: Signal txS serializedData - , "gthtxp_out" ::: Signal txS serializedData + ( "gthtxn_out" ::: Wire txS txUser2 + , "gthtxp_out" ::: Wire txS txUser2 , "txoutclk_out" ::: Clock txUser , "rxoutclk_out" ::: Clock rxUser , "gtwiz_userdata_rx_out" ::: Signal rxUser2 (BitVector RX_DATA_WIDTH) @@ -71,16 +131,16 @@ type GthCore txUser txUser2 rxUser rxUser2 refclk0 freerun txS rxS serializedDat , "rxctrl3_out" ::: Signal rxUser2 (BitVector 8) ) -gthCore :: GthCore txUser txUser2 rxUser rxUser2 refclk0 freerun txS rxS (BitVector 1) +gthCore :: GthCore txUser txUser2 rxUser rxUser2 refclk0 freerun txS rxS gthCore !_channel !_refClkSpec - !_gthrxn_in + gthrxn_in !_gthrxp_in !_gtwiz_reset_clk_freerun_in !_gtwiz_reset_all_in !_gtwiz_reset_rx_datapath_in - !_gtwiz_userdata_tx_in + !gtwiz_userdata_tx_in !_txctrl2_in !_gtrefclk0_in !_ @@ -89,19 +149,19 @@ gthCore !_ !_ !_ = - ( undefined - , undefined - , undefined - , undefined - , undefined - , undefined - , undefined - , undefined - , undefined - , undefined - , undefined - , undefined - , undefined + ( Wire (pure 0) (SimOnly gtwiz_userdata_tx_in) + , Wire (pure 0) (SimOnly gtwiz_userdata_tx_in) + , clockGen + , clockGen + , unSimOnly gthrxn_in.datSimulation + , pure 1 + , pure 1 + , pure 1 + , pure 1 + , pure 0 + , pure 0 + , pure 0 + , pure 0 ) {-# OPAQUE gthCore #-} {-# ANN gthCore hasBlackBox #-} diff --git a/bittide/tests/Tests/Transceiver.hs b/bittide/tests/Tests/Transceiver.hs index 194bf98c0..dbca3ebea 100644 --- a/bittide/tests/Tests/Transceiver.hs +++ b/bittide/tests/Tests/Transceiver.hs @@ -15,12 +15,10 @@ import Clash.Prelude (withClock) import Hedgehog import Bittide.Arithmetic.Time (PeriodToCycles) -import Bittide.SharedTypes (Bytes) import Clash.Annotations.Primitive (dontTranslate) import Clash.Cores.Xilinx.GTH (GthCore) import Clash.Hedgehog.Sized.Index (genIndex) import Clash.Signal.Internal (Signal ((:-))) -import Data.Maybe (fromMaybe) import Data.Proxy (Proxy (Proxy)) import Data.Sequence (Seq ((:<|), (:|>))) import Test.Tasty (TestTree, adjustOption, testGroup) @@ -29,6 +27,7 @@ import Test.Tasty.Hedgehog (HedgehogTestLimit (HedgehogTestLimit), testPropertyN import qualified Bittide.Transceiver as Transceiver import qualified Bittide.Transceiver.ResetManager as ResetManager import qualified Bittide.Transceiver.WordAlign as WordAlign +import qualified Clash.Cores.Xilinx.GTH as Gth import qualified Data.List as List import qualified Data.Sequence as Seq import qualified Hedgehog.Gen as Gen @@ -89,7 +88,7 @@ gthCoreMock :: Natural -> -- Offset Index 8 -> - GthCore tx tx rx rx ref free tx rx (Maybe (BitVector 64)) + GthCore tx tx rx rx ref free tx rx gthCoreMock _name nRxResetCycles @@ -112,8 +111,8 @@ gthCoreMock _rx1Clk rx2Clk _rxActive = - ( txSerial - , txSerial + ( Gth.Wire (pure 0) (SimOnly txWord) + , Gth.Wire (pure 0) (SimOnly txWord) , txOutClk , rxOutClk , rxWord @@ -130,11 +129,8 @@ gthCoreMock rxWord = withClock rxClk $ WordAlign.aligner WordAlign.dealignLsbFirst (pure False) (pure offset) - $ fromMaybe - <$> noise rxClk - <*> rxSerial - - txSerial = Just <$> txWord + $ Gth.unSimOnly + $ rxSerial.datSimulation registerRx = register rxClk rxRstRx enableGen registerTx = register txClk txRstAll enableGen @@ -169,7 +165,7 @@ data Input tx rx = Input } dut :: - forall freeA freeB txA txB ref n. + forall freeA freeB txA txB ref. ( KnownDomain ref , HasSynchronousReset txA , HasDefinedInitialValues txA @@ -185,16 +181,16 @@ dut :: -- | Number of word clock cycles delay from B -> A Natural -> ResetManager.Config -> - GthCore txA txA txB txB ref freeA txA txB (Maybe (Bytes n)) -> - GthCore txB txB txA txA ref freeB txB txA (Maybe (Bytes n)) -> + GthCore txA txA txB txB ref freeA txA txB -> + GthCore txB txB txA txA ref freeB txB txA -> Clock freeA -> Reset freeA -> Clock freeB -> Reset freeB -> Input txA txB -> Input txB txA -> - ( Transceiver.Output txA txB txA txB txA freeA (Maybe (Bytes n)) - , Transceiver.Output txB txA txB txA txB freeB (Maybe (Bytes n)) + ( Transceiver.Output txA txB txA txB txA freeA + , Transceiver.Output txB txA txB txA txB freeB ) dut abDelay @@ -226,7 +222,7 @@ dut , transceiverIndex = 0 , channelName = "A" , clockPath = "clkA" - , rxN = delaySeqN baDelay Nothing outputB.txN + , rxN = Gth.mapDatSimulation (delaySeqN baDelay 0) outputB.txN , rxP = error "A: rxP not used in simulation" , txData = inputA.dat , txStart = inputA.txStart @@ -250,7 +246,7 @@ dut , transceiverIndex = 1 , channelName = "B" , clockPath = "clkB" - , rxN = delaySeqN abDelay Nothing outputA.txN + , rxN = Gth.mapDatSimulation (delaySeqN abDelay 0) outputA.txN , rxP = error "B: rxP not used in simulation" , txData = inputB.dat , txStart = inputB.txStart @@ -258,12 +254,12 @@ dut } type DutTestFunc txA txB free = - Transceiver.Output txA txB txA txB txA free (Maybe (BitVector 64)) -> - Transceiver.Output txB txA txB txA txB free (Maybe (BitVector 64)) -> + Transceiver.Output txA txB txA txB txA free -> + Transceiver.Output txB txA txB txA txB free -> PropertyT IO () type InputFunc txA txB free = - Transceiver.Output txA txB txA txB txA free (Maybe (BitVector 64)) -> + Transceiver.Output txA txB txA txB txA free -> Input txA txB dutRandomized :: @@ -323,7 +319,6 @@ dutRandomized f inputA inputB Proxy = property $ do @txA @txB @RefIsUnused - @8 abDelay baDelay resetManagerConfig