Skip to content

Commit

Permalink
Parse UGNs, print IGNs, and some cleanup.
Browse files Browse the repository at this point in the history
  • Loading branch information
rslawson committed Feb 27, 2025
1 parent ecf4490 commit a089795
Showing 1 changed file with 83 additions and 15 deletions.
98 changes: 83 additions & 15 deletions bittide-instances/src/Bittide/Instances/Hitl/Driver/Demo.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,25 @@
{-# LANGUAGE OverloadedRecordDot #-}
{-# LANGUAGE QuasiQuotes #-}

module Bittide.Instances.Hitl.Driver.Demo where
module Bittide.Instances.Hitl.Driver.Demo (
OcdInitData (..),
driverFunc,
) where

import Clash.Prelude

import Bittide.Hitl
import Bittide.Instances.Hitl.Setup (demoRigInfo)
import Bittide.Instances.Hitl.Setup (demoRigInfo, fpgaSetup)
import Bittide.Instances.Hitl.Utils.Program
import Bittide.Instances.Hitl.Utils.Vivado

import Clash.Functor.Extra ((<<$>>))
import Control.Monad (forM_, zipWithM)
import Control.Monad.IO.Class
import Data.List.Extra (trim)
import Data.Maybe (fromMaybe)
import Data.Maybe (fromJust, fromMaybe)
import Data.String.Interpolate (i)
import GHC.Stack (HasCallStack)
import Project.FilePath
import Project.Handle
import System.Clock (Clock (Monotonic), diffTimeSpec, getTime, toNanoSecs)
Expand All @@ -34,12 +39,6 @@ import qualified Control.Monad.Trans.Control as CMTC
import qualified Data.List as L
import qualified System.Timeout.Lifted as STL

-- connect EBs over WB
-- read/write regs with MU, ensure that correct values show up
-- check over GDB too
-- no input data
-- just one test case

data OcdInitData = OcdInitData
{ muPort :: Int
, ccPort :: Int
Expand All @@ -50,6 +49,7 @@ data OcdInitData = OcdInitData
data TestStatus = TestRunning | TestDone Bool | TestTimeout deriving (Eq)

driverFunc ::
HasCallStack =>
String ->
[(HwTarget, DeviceInfo)] ->
VivadoM ExitCode
Expand Down Expand Up @@ -301,7 +301,7 @@ driverFunc testName targets = do
inner innerInit

muGetUgns ::
(HwTarget, DeviceInfo) -> ProcessStdIoHandles -> VivadoM [(Unsigned 64, Unsigned 64)]
(HwTarget, DeviceInfo) -> ProcessStdIoHandles -> VivadoM [(Integer, Integer)]
muGetUgns (_, d) gdb = do
let
mmioAddrs :: [String]
Expand All @@ -315,7 +315,7 @@ driverFunc testName targets = do
, "0x70000000"
]

readUgnMmio :: String -> IO (Unsigned 64, Unsigned 64)
readUgnMmio :: String -> IO (Integer, Integer)
readUgnMmio addr = do
let
startString = "START OF UGN (" <> addr <> ")"
Expand All @@ -331,9 +331,14 @@ driverFunc testName targets = do
$ readUntil gdb.stdoutHandle startString
gdbRead <-
tryWithTimeout "Reading UGN over GDB" 15_000_000 $ readUntil gdb.stdoutHandle endString
-- Temporary debug print of this so I can get a proper parsing setup going later:
let
outputLine = L.head $ L.lines $ trim gdbRead
outputDataWords = L.words $ trim $ outputLine
putStrLn $ "GDB output: {{\n" <> gdbRead <> "}}"
return (0, 0)
case L.drop (L.length outputDataWords - 2) outputDataWords of
[read -> txIJ, read -> rxIJ] -> return (txIJ, rxIJ)
other ->
fail $ "Could not read output data. Line: '" <> outputLine <> "', data: " <> show other

liftIO $ putStrLn $ "Getting UGNs for device " <> show d.deviceId
liftIO $ mapM readUgnMmio mmioAddrs
Expand Down Expand Up @@ -384,11 +389,74 @@ driverFunc testName targets = do
$ putStrLn
[i|Test case #{testName} stabilised on #{sCount} of #{L.length targets} targets|]

liftIO $ putStrLn "Doing GDB checks for each MU"
_ <- zipWithM muGetUgns targets muGdbs
liftIO $ putStrLn "Getting UGNs for all targets"
ugnPairsTable <- zipWithM muGetUgns targets muGdbs
liftIO $ putStrLn "Calculating IGNs for all targets"
liftIO $ printAllIgns @7 @8 ugnPairsTable fpgaSetup

let
finalExit =
fromMaybe ExitSuccess
$ L.find (/= ExitSuccess) [stabilityExitCode, gdbExitCode0, gdbExitCode1]
return finalExit

printAllIgns ::
forall m n.
HasCallStack =>
(KnownNat m, KnownNat n) =>
[[(Integer, Integer)]] ->
Vec n (FpgaId, Vec m (Index n)) ->
IO ()
printAllIgns ugnPairsTable fpgasTable = do
let
ugnsTable :: [[Integer]]
ugnsTable = uncurry (-) <<$>> ugnPairsTable
fpgasMap :: Vec n (Vec m (Index n))
fpgasMap = snd <$> fpgasTable
indicesM :: Vec m (Index m)
indicesM = pred <$> generateI (+ 1) 0
indicesN :: Vec n (Index n)
indicesN = pred <$> generateI (+ 1) 0
printIgns :: HasCallStack => Index n -> (FpgaId, Vec m (Index n)) -> IO (Vec m Integer)
printIgns rowI (myId, row) = do
putStrLn $ "Finding IGNs for " <> myId <> " (" <> show rowI <> ")"
putStrLn $ " My connections: " <> show row
let
rowIInteger :: Integer
rowIInteger = fromIntegral rowI
eqRowI :: HasCallStack => Integral a => a -> Bool
eqRowI (fromIntegral -> a) = a == rowIInteger
printIgn :: HasCallStack => Index m -> Index n -> IO Integer
printIgn colI otherRowI = do
putStrLn $ " Looking at column " <> show colI <> " => " <> show otherRowI
let
otherRow :: Vec m (Index n)
otherRow = fpgasMap !! otherRowI
otherRowName :: FpgaId
otherRowName = fst $ fpgasTable !! otherRowI
putStrLn $ " Row name: " <> otherRowName
putStrLn $ " Row contents: " <> show otherRow
let
myIndex :: Index m
myIndex = fromJust $ findIndex eqRowI otherRow
putStrLn $ " Other row has me at index: " <> show myIndex
let
myUgn = ugnsTable L.!! (fromIntegral rowI) L.!! (fromIntegral colI)
otherUgn = ugnsTable L.!! (fromIntegral otherRowI) L.!! (fromIntegral myIndex)
ign = myUgn + otherUgn
putStrLn
$ " The IGN for this link is: "
<> show myUgn
<> " + "
<> show otherUgn
<> " = "
<> show ign
return ign
igns <- sequence $ zipWith printIgn indicesM row
putStrLn $ "IGNs for FPGA " <> myId <> " (" <> show rowI <> "): " <> show igns
return igns

igns <- sequence $ zipWith printIgns indicesN fpgasTable
putStrLn "Final IGNs table:"
forM_ igns print
return ()

0 comments on commit a089795

Please sign in to comment.