Skip to content

Commit

Permalink
Write configs to MU PEs and observe results.
Browse files Browse the repository at this point in the history
  • Loading branch information
rslawson committed Feb 28, 2025
1 parent 9b6917e commit 0edb810
Showing 1 changed file with 83 additions and 10 deletions.
93 changes: 83 additions & 10 deletions bittide-instances/src/Bittide/Instances/Hitl/Driver/Demo.hs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ import Bittide.Instances.Hitl.Utils.Vivado
import Bittide.Instances.Ugns (fullChainConfiguration)

import Clash.Functor.Extra ((<<$>>))
import Control.Concurrent (threadDelay)
import Control.Monad (forM_, zipWithM)
import Control.Monad.IO.Class
import Data.List.Extra (trim)
import Data.Maybe (fromJust, fromMaybe)
import Data.String.Interpolate (i)
import GHC.Stack (HasCallStack)
import Numeric (showHex)
import Project.FilePath
import Project.Handle
import System.Clock (Clock (Monotonic), diffTimeSpec, getTime, toNanoSecs)
Expand All @@ -52,6 +54,8 @@ data OcdInitData = OcdInitData

data TestStatus = TestRunning | TestDone Bool | TestTimeout deriving (Eq)

type StartDelay = 20 -- seconds

driverFunc ::
(HasCallStack) =>
String ->
Expand All @@ -69,6 +73,16 @@ driverFunc testName targets = do
let
hitlDir = projectDir </> "_build/hitl/" <> testName

-- 500ms after start of R/W test
delayUntil = startTime + snatToNum (SNat @StartDelay) + fromIntegral (500_000_000 :: Int)
waitUntilDelay :: IO ()
waitUntilDelay = do
now <- getTime Monotonic
let delayAmt = toNanoSecs (delayUntil - now) `quot` 1000
if now >= delayUntil
then return ()
else threadDelay (fromIntegral delayAmt)

calcTimeSpentMs = (`div` 1_000_000) . toNanoSecs . diffTimeSpec startTime <$> getTime Monotonic

getTargetIndex :: HwTarget -> Int
Expand Down Expand Up @@ -346,6 +360,61 @@ driverFunc testName targets = do
liftIO $ putStrLn $ "Getting UGNs for device " <> show d.deviceId
liftIO $ mapM readUgnMmio mmioAddrs

muReadPeBuffer :: (HwTarget, DeviceInfo) -> ProcessStdIoHandles -> IO ()
muReadPeBuffer (_, d) gdb = do
putStrLn $ "Reading PE buffer from device " <> show d.deviceId
let
startString = "START OF PEBUF (" <> show d.deviceId <> ")"
endString = "END OF PEBUF (" <> show d.deviceId <> ")"
bufferSize :: Integer
bufferSize = (snatToNum (SNat @FpgaCount)) * 3
Gdb.runCommands
gdb.stdinHandle
[ "printf \"" <> startString <> "\\n\""
, [i|x/#{bufferSize}xg 0x90000038|]
, "printf \"" <> endString <> "\\n\""
]
_ <-
tryWithTimeout "Waiting for GDB to be ready for PE buffer readout" 15_000_000
$ readUntil gdb.stdoutHandle startString
bufInit <-
tryWithTimeout "PE buffer readout" 15_000_000 $ readUntil gdb.stdoutHandle endString
putStrLn $ "PE buffer readout:\n" <> bufInit

muWriteCfg ::
(HwTarget, DeviceInfo) ->
ProcessStdIoHandles ->
Ugns.PeConfig (Unsigned 64) (Index 9) ->
VivadoM ()
muWriteCfg target@(_, d) gdb cfg = do
let
splitSections str = (a1, b)
where
(a0, b) = L.splitAt (L.length str - 8) str
a1 = if L.null a0 then "" else a0
startWriteAtS = showHex cfg.startWriteAt ""
(startWriteAtMsbs, startWriteAtLsbs) = splitSections startWriteAtS
writeForNS = showHex cfg.writeForN ""
(writeForNMsbs, writeForNLsbs) = splitSections writeForNS
startReadAtS = showHex cfg.startReadAt ""
(startReadAtMsbs, startReadAtLsbs) = splitSections startReadAtS
readForNS = showHex cfg.startReadAt ""
(readForNMsbs, readForNLsbs) = splitSections readForNS
liftIO $ do
muReadPeBuffer target gdb
putStrLn $ "Writing config to device " <> show d.deviceId
Gdb.runCommands
gdb.stdinHandle
[ "set {char[4]}(0x90000000) = 0x" <> startReadAtLsbs
, "set {char[4]}(0x90000004) = 0x" <> startReadAtMsbs
, "set {char[4]}(0x90000008) = 0x" <> readForNLsbs
, "set {char[4]}(0x9000000C) = 0x" <> readForNMsbs
, "set {char[4]}(0x90000010) = 0x" <> startWriteAtLsbs
, "set {char[4]}(0x90000014) = 0x" <> startWriteAtMsbs
, "set {char[4]}(0x90000018) = 0x" <> writeForNLsbs
, "set {char[4]}(0x9000001C) = 0x" <> writeForNMsbs
]

liftIO
$ putStrLn
"All programmed pin may be asserted from previous test - deasserting on all targets."
Expand Down Expand Up @@ -399,7 +468,7 @@ driverFunc testName targets = do
liftIO $ putStrLn "Calculating IGNs for all targets"
liftIO $ printAllIgns ugnPairsTableV fpgaSetup
let
startOffset :: SNat (PeriodToCycles GthTx (Seconds 20))
startOffset :: SNat (PeriodToCycles GthTx (Seconds StartDelay))
startOffset = SNat
chainConfig :: Vec FpgaCount (Ugns.PeConfig (Unsigned 64) (Index 9))
chainConfig =
Expand All @@ -411,6 +480,9 @@ driverFunc testName targets = do
liftIO $ do
putStrLn "Calculated the following configs for the switch processing elements:"
forM_ chainConfig print
_ <- sequenceA $ L.zipWith3 muWriteCfg targets muGdbs (toList chainConfig)
liftIO waitUntilDelay
_ <- liftIO $ sequenceA $ L.zipWith muReadPeBuffer targets muGdbs

let
finalExit =
Expand Down Expand Up @@ -480,21 +552,22 @@ printAllIgns ugnPairsTable fpgasTable = do
largest = maximum allList
largestLen :: Int
largestLen = L.length $ show largest
coords :: Vec (n + 1) (Vec m (Index (n + 1), Index m))
coords = (\ind -> (,) ind <$> indicesM) <$> indicesN
printIgn :: Index (n + 1) -> Index m -> IO ()
coords :: Vec (n + 1) (Vec (n + 1) (Index (n + 1), Index (n + 1)))
coords = (\ind -> (,) ind <$> indicesN) <$> indicesN
printIgn :: Index (n + 1) -> Index (n + 1) -> IO ()
printIgn row fpgaNum = do
let
fpgaNumI = fromIntegral fpgaNum :: Integer
col = fromJust $ findIndex ((==) fpgaNumI . fromIntegral) (fpgasMap !! row)
ign = igns !! row !! col
str = if (fromIntegral row :: Integer) == (fromIntegral col :: Integer)
then L.replicate largestLen 'x'
else show ign
str =
if (fromIntegral row :: Integer) == fpgaNumI
then L.replicate largestLen 'x'
else show ign
pad = L.replicate (largestLen - L.length str) ' '
if col == maxBound
then putStrLn [i|#{pad}#{str}|]
else putStr [i|#{pad}#{str}, |]
if fpgaNum == maxBound
then putStrLn [i|#{pad}#{str}|]
else putStr [i|#{pad}#{str}, |]

putStrLn "Final IGNs table:"
forM_ coords $ flip forM_ (uncurry printIgn)
Expand Down

0 comments on commit 0edb810

Please sign in to comment.