diff --git a/bittide-instances/data/openocd/vexriscv-2chain.tcl b/bittide-instances/data/openocd/vexriscv-2chain.tcl index 6a215f1d7..30c904037 100644 --- a/bittide-instances/data/openocd/vexriscv-2chain.tcl +++ b/bittide-instances/data/openocd/vexriscv-2chain.tcl @@ -11,6 +11,26 @@ if { $user_gdb_port_b == "" } { error "Required environment variable 'DEV_B_GDB' not set." } +set user_tcl_port_a [env DEV_A_TCL] +if { $user_tcl_port_a == "" } { + error "Required environment variable 'DEV_A_TCL' not set." +} + +set user_tcl_port_b [env DEV_B_TCL] +if { $user_tcl_port_b == "" } { + error "Required environment variable 'DEV_B_TCL' not set." +} + +set user_tel_port_a [env DEV_A_TEL] +if { $user_tel_port_a == "" } { + error "Required environment variable 'DEV_A_TEL' not set." +} + +set user_tel_port_b [env DEV_B_TEL] +if { $user_tel_port_b == "" } { + error "Required environment variable 'DEV_B_TEL' not set." +} + set git_top_level [string trim [exec git rev-parse --show-toplevel]] set _ENDIAN little @@ -29,11 +49,15 @@ set _CHIPNAME vexrisc_ocd jtag newtap $_CHIPNAME chain0 -expected-id $_CPUTAPID -irlen 4 -ircapture 0x1 -irmask 0x0F jtag newtap $_CHIPNAME chain1 -expected-id $_CPUTAPID -irlen 4 -ircapture 0x1 -irmask 0x03 -target create $_CHIPNAME.cpu1 vexriscv -endian $_ENDIAN -chain-position $_CHIPNAME.bridge1 -gdb-port $user_gdb_port_b +target create $_CHIPNAME.cpu1 vexriscv -endian $_ENDIAN -chain-position $_CHIPNAME.chain1 -gdb-port $user_gdb_port_a +tcl_port $user_tcl_port_a +telnet_port $user_tel_port_a vexriscv readWaitCycles 10 vexriscv cpuConfigFile [file join $git_top_level clash-vexriscv clash-vexriscv example-cpu ExampleCpu.yaml] -target create $_CHIPNAME.cpu0 vexriscv -endian $_ENDIAN -chain-position $_CHIPNAME.bridge0 -gdb-port $user_gdb_port_a +target create $_CHIPNAME.cpu0 vexriscv -endian $_ENDIAN -chain-position $_CHIPNAME.chain0 -gdb-port $user_gdb_port_b +tcl_port $user_tcl_port_b +telnet_port $user_tel_port_b vexriscv readWaitCycles 10 vexriscv cpuConfigFile [file join $git_top_level clash-vexriscv clash-vexriscv example-cpu ExampleCpu.yaml] diff --git a/bittide-instances/src/Bittide/Instances/Hitl/Demo.hs b/bittide-instances/src/Bittide/Instances/Hitl/Demo.hs index 0fb50d18e..acafe33aa 100644 --- a/bittide-instances/src/Bittide/Instances/Hitl/Demo.hs +++ b/bittide-instances/src/Bittide/Instances/Hitl/Demo.hs @@ -53,17 +53,19 @@ import Bittide.SharedTypes (Bytes) import Bittide.Switch (switchC) import Bittide.SwitchDemoProcessingElement (switchDemoPeWb) import Bittide.Transceiver (transceiverPrbsN) -import Bittide.Wishbone (readDnaPortE2Wb, timeWb) +import Bittide.Wishbone (readDnaPortE2Wb, timeWb, whoAmIC) import Clash.Annotations.TH (makeTopEntity) import Clash.Cores.Xilinx.GTH (ibufds_gte3) +import Clash.Cores.Xilinx.Ila (Depth (..), IlaConfig (..), ila, ilaConfig) import Clash.Cores.Xilinx.Unisim.DnaPortE2 (simDna2) import Clash.Cores.Xilinx.VIO (vioProbe) import Clash.Cores.Xilinx.Xpm.Cdc (xpmCdcArraySingle, xpmCdcSingle) import Clash.Functor.Extra ((<<$>>)) +import Clash.Sized.Extra (unsignedToSigned) +import Clash.Sized.Vector.ToTuple (vecToTuple) import Clash.Xilinx.ClockGen (clockWizardDifferential) import Protocols -import Protocols.Idle import Protocols.Wishbone import System.FilePath (()) import VexRiscv (DumpVcd (..), Jtag, JtagIn (..), JtagOut (..)) @@ -130,11 +132,26 @@ calendarConfig = repetitions = natToNum @((LinkCount + 1) * 3) @(Unsigned 8) {- FOURMOLU_ENABLE -} -muConfig :: SimpleManagementConfig 10 +muConfig :: SimpleManagementConfig 11 muConfig = SimpleManagementConfig PeConfig - { memMapConfig = 0b100 :> 0b010 :> 0b110 :> 0b101 :> repeat 0 + { memMapConfig = + 0b1000 -- IMEM + :> 0b1100 -- DMEM + :> 0b1101 -- timeWb + :> 0b1110 -- whoAmI + :> 0b1001 -- peWb + :> 0b1010 -- switchWb + :> 0b1011 -- dnaWb + :> 0b0001 -- UGN0 + :> 0b0010 -- UGN1 + :> 0b0011 -- UGN2 + :> 0b0100 -- UGN3 + :> 0b0101 -- UGN4 + :> 0b0110 -- UGN5 + :> 0b0111 -- UGN6 + :> Nil , initI = Undefined @(Div (64 * 1024) 4) , initD = Undefined @(Div (64 * 1024) 4) , iBusTimeout = d0 @@ -144,13 +161,13 @@ muConfig = NoDumpVcd ccConfig :: - SwControlCConfig CccStabilityCheckerMargin (CccStabilityCheckerFramesize Basic125) 0 + SwControlCConfig CccStabilityCheckerMargin (CccStabilityCheckerFramesize Basic125) 1 ccConfig = SwControlCConfig SNat SNat PeConfig - { memMapConfig = 0b100 :> 0b010 :> 0b110 :> 0b101 :> Nil + { memMapConfig = 0b100 :> 0b010 :> 0b110 :> 0b101 :> 0b111 :> Nil , initI = Undefined @(Div (64 * 1024) 4) , initD = Undefined @(Div (64 * 1024) 4) , iBusTimeout = d0 @@ -201,19 +218,125 @@ dut :: , "fifoUnderflowsSticky" ::: Signal Basic125 Bool ) dut refClk refRst skyClk rxNs rxPs allProgrammed miso jtagIn = - ( transceivers.txNs - , transceivers.txPs - , handshakesCompleteFree - , frequencyAdjustments - , spiDone - , spiOut - , jtagOut - , transceiversFailedAfterUp - , allStable - , fifoOverflowsSticky - , fifoUnderflowsSticky - ) + hwSeqX + debugIla + ( transceivers.txNs + , transceivers.txPs + , handshakesCompleteFree + , frequencyAdjustments + , spiDone + , spiOut + , jtagOut + , transceiversFailedAfterUp + , allStable + , fifoOverflowsSticky + , fifoUnderflowsSticky + ) where + debugIla :: Signal Basic125 () + debugIla = + setName @"demoDebugIla" + ila + ( ilaConfig + $ "trigger_fdi_dd" + :> "capture_fdi_dd" + -- Important step 1 signals + :> "dd_spiDone" + :> "dd_spiErr" + -- Important step 2 signals + :> "dd_handshakesCompleteFree" + -- Important step 3 signals + :> "dd_txStarts" + -- Important step 4 signals + -- Important step 5 signals + :> "dd_allStable" + -- Important step 6 signals + :> "dd_ebReadys" + -- Other + :> "dd_transceiversFailedAfterUp" + :> "dd_nFincs" + :> "dd_nFdecs" + :> "dd_netFincs" + :> "dd_dDiff0" + :> "dd_dDiff1" + :> "dd_dDiff2" + :> "dd_dDiff3" + :> "dd_dDiff4" + :> "dd_dDiff5" + :> "dd_dDiff6" + :> Nil + ) + { depth = D32768 + } + refClk + (unsafeToActiveLow handshakeRstFree) + captureFlag + spiDone + spiErr + (bundle transceivers.handshakesCompleteFree) + (bundle $ xpmCdcArraySingle bittideClk refClk <$> txStarts) + allStable + (bundle $ xpmCdcArraySingle bittideClk refClk <$> ebReadys) + transceiversFailedAfterUp + nFincs + nFdecs + (fmap unsignedToSigned nFincs - fmap unsignedToSigned nFdecs) + dDiff0 + dDiff1 + dDiff2 + dDiff3 + dDiff4 + dDiff5 + dDiff6 + + captureFlag = + riseEvery + refClk + spiRst + enableGen + (SNat @(PeriodToCycles Basic125 (Milliseconds 2))) + + nFincs :: Signal Basic125 (Unsigned 32) + nFincs = + regEn + refClk + refRst + enableGen + (0 :: Unsigned 32) + ( isFalling + refClk + refRst + enableGen + False + ((== Just SpeedUp) <$> callistoResult.maybeSpeedChangeC) + ) + (satSucc SatBound <$> nFincs) + + nFdecs :: Signal Basic125 (Unsigned 32) + nFdecs = + regEn + refClk + refRst + enableGen + (0 :: Unsigned 32) + ( isFalling + refClk + refRst + enableGen + False + ((== Just SlowDown) <$> callistoResult.maybeSpeedChangeC) + ) + (satSucc SatBound <$> nFdecs) + + ( dDiff0 + , dDiff1 + , dDiff2 + , dDiff3 + , dDiff4 + , dDiff5 + , dDiff6 + ) = vecToTuple domainDiffs + -- Step 1, wait for SPI: (_, _, spiState, spiOut) = withClockResetEnable refClk spiRst enableGen @@ -351,7 +474,7 @@ dut refClk refRst skyClk rxNs rxPs allProgrammed miso jtagIn = [muJtagFree, ccJtag] <- jtagChain -< jtag muJtagTx <- unsafeJtagSynchronizer refClk bittideClk -< muJtagFree - [peWb, switchWb, dnaWb, ugn0, ugn1, ugn2, ugn3, ugn4, ugn5, ugn6] <- + [muWhoAmI, peWb, switchWb, dnaWb, ugn0, ugn1, ugn2, ugn3, ugn4, ugn5, ugn6] <- withClockResetEnable bittideClk handshakeRstTx @@ -399,7 +522,14 @@ dut refClk refRst skyClk rxNs rxPs allProgrammed miso jtagIn = (readDnaPortE2Wb simDna2) -< dnaWb - (swCcOut, ccM2S) <- + withClockResetEnable + bittideClk + handshakeRstTx + enableGen + (whoAmIC 0x746d_676d) + -< muWhoAmI + + (swCcOut, [ccWhoAmI]) <- withClockResetEnable refClk handshakeRstFree @@ -407,7 +537,12 @@ dut refClk refRst skyClk rxNs rxPs allProgrammed miso jtagIn = (callistoSwClockControlC @LinkCount @CccBufferSize NoDumpVcd ccConfig) -< (ccJtag, reframe, mask, dc) - idleSink -< ccM2S + withClockResetEnable + refClk + handshakeRstFree + enableGen + (whoAmIC 0x6363_7773) + -< ccWhoAmI idC -< (swCcOut, [tx0, tx1, tx2, tx3, tx4, tx5, tx6]) @@ -432,7 +567,7 @@ dut refClk refRst skyClk rxNs rxPs allProgrammed miso jtagIn = delay refClk enableGen minBound $ speedChangeToStickyPins refClk - handshakeRstFree + (unsafeFromActiveLow allProgrammed) enableGen (SNat @Si539xHoldTime) callistoResult.maybeSpeedChangeC @@ -465,10 +600,10 @@ dut refClk refRst skyClk rxNs rxPs allProgrammed miso jtagIn = (_, fifoUnderflowsTx, fifoOverflowsTx, ebModes, rxDatasEbs) = unzip5 rxFifos fifoOverflowsFree :: Signal Basic125 Overflow - fifoOverflowsFree = and <$> xpmCdcArraySingle bittideClk refClk (bundle fifoOverflowsTx) + fifoOverflowsFree = or <$> xpmCdcArraySingle bittideClk refClk (bundle fifoOverflowsTx) fifoUnderflowsFree :: Signal Basic125 Underflow - fifoUnderflowsFree = and <$> xpmCdcArraySingle bittideClk refClk (bundle fifoUnderflowsTx) + fifoUnderflowsFree = or <$> xpmCdcArraySingle bittideClk refClk (bundle fifoUnderflowsTx) fifoOverflowsSticky :: Signal Basic125 Bool fifoOverflowsSticky = sticky refClk handshakeRstFree fifoOverflowsFree @@ -498,7 +633,7 @@ demoTest :: , "JTAG" ::: Signal Basic125 JtagOut ) demoTest boardClkDiff refClkDiff rxns rxps miso jtagIn = - (txns, txps, unbundle swFincFdecs, spiDone, spiOut, jtagOut) + hwSeqX testIla (txns, txps, unbundle swFincFdecs, spiDone, spiOut, jtagOut) where boardClk :: Clock Ext200 boardClk = ibufds_gte3 boardClkDiff @@ -513,30 +648,31 @@ demoTest boardClkDiff refClkDiff rxns rxps miso jtagIn = unbundle $ setName @"vioHitlt" $ vioProbe - ("probe_test_done" :> "probe_test_success" :> Nil) + ("probe_test_done" :> "probe_test_success" :> "probe_handshakes_done" :> Nil) ("probe_test_start" :> "probe_all_programmed" :> Nil) (False, False) refClk (testStart .&&. testDone) -- done (testStart .&&. testSuccess) -- success + handshakesDone testReset :: Reset Basic125 testReset = unsafeFromActiveLow testStart `orReset` refRst ( txns :: TransceiverWires GthTxS LinkCount , txps :: TransceiverWires GthTxS LinkCount - , _handshakesDone :: Signal Basic125 Bool + , handshakesDone :: Signal Basic125 Bool , swFincFdecs :: Signal Basic125 (Bool, Bool) , spiDone :: Signal Basic125 Bool , spiOut :: (Signal Basic125 Bool, Signal Basic125 Bit, Signal Basic125 Bool) , jtagOut :: Signal Basic125 JtagOut , transceiversFailedAfterUp :: Signal Basic125 Bool , allStable :: Signal Basic125 Bool - , noFifoOverflows :: Signal Basic125 Bool - , noFifoUnderflows :: Signal Basic125 Bool + , fifoOverflows :: Signal Basic125 Bool + , fifoUnderflows :: Signal Basic125 Bool ) = dut refClk testReset boardClk rxns rxps allProgrammed miso jtagIn fifoSuccess :: Signal Basic125 Bool - fifoSuccess = noFifoUnderflows .&&. noFifoOverflows + fifoSuccess = not <$> (fifoUnderflows .||. fifoOverflows) endSuccess :: Signal Basic125 Bool endSuccess = trueFor (SNat @(Seconds 5)) refClk testReset (allStable .&&. fifoSuccess) @@ -546,6 +682,49 @@ demoTest boardClkDiff refClkDiff rxns rxps miso jtagIn = testSuccess :: Signal Basic125 Bool testSuccess = allStable .&&. fifoSuccess .&&. fmap not transceiversFailedAfterUp + + testIla :: Signal Basic125 () + testIla = + setName @"demoTestIla" + ila + ( ilaConfig + $ "trigger_fdi_dt" + :> "capture_fdi_dt" + :> "dt_handshakesDone" + :> "dt_all_programmed" + :> "dt_swFincFdecs" + :> "dt_spiDone" + :> "dt_spiOut" + :> "dt_jtagOut" + :> "dt_transceiversFailedAfterUp" + :> "dt_allStable" + :> "dt_fifoOverflows" + :> "dt_fifoUnderflows" + :> Nil + ) + { depth = D32768 + } + refClk + handshakesDone + captureFlag + handshakesDone + allProgrammed + swFincFdecs + spiDone + (bundle spiOut) + jtagOut + transceiversFailedAfterUp + allStable + fifoOverflows + fifoUnderflows + + captureFlag :: Signal Basic125 Bool + captureFlag = + riseEvery + refClk + testReset + enableGen + (SNat @(PeriodToCycles Basic125 (Milliseconds 2))) {-# OPAQUE demoTest #-} makeTopEntity 'demoTest diff --git a/bittide-instances/src/Bittide/Instances/Hitl/Driver/Demo.hs b/bittide-instances/src/Bittide/Instances/Hitl/Driver/Demo.hs index 29186e976..12f9b9531 100644 --- a/bittide-instances/src/Bittide/Instances/Hitl/Driver/Demo.hs +++ b/bittide-instances/src/Bittide/Instances/Hitl/Driver/Demo.hs @@ -15,12 +15,11 @@ import Bittide.Instances.Hitl.Setup (demoRigInfo) import Bittide.Instances.Hitl.Utils.Program import Bittide.Instances.Hitl.Utils.Vivado -import Control.Exception (catch) -import Control.Monad (zipWithM) +import Control.Monad (forM_, zipWithM) import Control.Monad.IO.Class +import Data.List.Extra (trim) import Data.Maybe (fromMaybe) import Data.String.Interpolate (i) -import Numeric (showHex) import Project.FilePath import Project.Handle import System.Clock (Clock (Monotonic), diffTimeSpec, getTime, toNanoSecs) @@ -85,13 +84,27 @@ driverFunc testName targets = do fail $ "Timeout while performing action: " <> actionName Just r -> pure r + deassertAllProgrammed :: (HwTarget, DeviceInfo) -> VivadoM () + deassertAllProgrammed (hwT, d) = do + liftIO $ putStrLn $ "Deasserting all programmed probe on " <> show d.deviceId + openHardwareTarget hwT + updateVio "vioHitlt" [("probe_all_programmed", "0")] + + assertTestStart :: (HwTarget, DeviceInfo) -> VivadoM () + assertTestStart (hwT, d) = do + liftIO $ putStrLn $ "Asserting test start probe on " <> show d.deviceId + openHardwareTarget hwT + updateVio "vioHitlt" [("probe_test_start", "1")] + getHandshakesStatus :: [(HwTarget, DeviceInfo)] -> [Bool] -> VivadoM [Bool] getHandshakesStatus [] _ = return [] getHandshakesStatus _ [] = return [] getHandshakesStatus ((hwT, d) : hwtdRest) (handsShaken : hsRest) = do let getRest = getHandshakesStatus hwtdRest hsRest if handsShaken - then getRest + then do + rest <- getRest + return $ handsShaken : rest else do openHardwareTarget hwT vals <- readVio "vioHitlt" ["probe_handshakes_done"] @@ -154,32 +167,12 @@ driverFunc testName targets = do , ("DEV_B_TEL", show telnetPortCC) ] hSetBuffering ocd.stderrHandle LineBuffering - flip - catch - ( \(e :: IOError) -> do - putStrLn $ "Failed on reading OpenOCD stderr: " <> show e - flip catch (\(_ :: IOError) -> return ()) $ do - so <- hGetContents ocd.stdoutHandle - putStrLn $ "OpenOCD leftover stdout:\n" <> so - flip catch (\(_ :: IOError) -> return ()) $ do - se <- hGetContents ocd.stderrHandle - putStrLn $ "OpenOCD leftover stderr:\n" <> se - fail (show e) - ) - $ tryWithTimeout "Waiting for OpenOCD to start" 15_000_000 + tryWithTimeout "Waiting for OpenOCD to start" 15_000_000 $ expectLine ocd.stderrHandle openOcdWaitForHalt let ocdProcName = "OpenOCD (" <> show d.deviceId <> ")" - ocdClean1 = do - flip catch (\(e :: IOError) -> putStrLn $ "Failed to read from stdout: " <> show e) $ do - so <- hGetContents ocd.stdoutHandle - putStrLn $ "OpenOCD leftover stdout:\n" <> so - flip catch (\(e :: IOError) -> putStrLn $ "Failed to read from stderr: " <> show e) $ do - se <- hGetContents ocd.stderrHandle - putStrLn $ "OpenOCD leftover stderr:\n" <> se - ocdClean0 - awaitProcessTermination ocdProcName ocdPh (Just 5_000_000) + ocdClean1 = ocdClean0 >> awaitProcessTermination ocdProcName ocdPh (Just 10_000_000) return $ OcdInitData gdbPortMU gdbPortCC ocd ocdClean1 @@ -189,18 +182,75 @@ driverFunc testName targets = do (gdb, gdbPh, gdbClean0) <- Gdb.startGdbH hSetBuffering gdb.stdinHandle LineBuffering + hSetBuffering gdb.stdoutHandle LineBuffering Gdb.setLogging gdb $ hitlDir "gdb-" <> binName <> "-" <> show (getTargetIndex hwT) <> ".log" Gdb.setFile gdb $ firmwareBinariesDir "riscv32imc" Release binName Gdb.setTarget gdb gdbPort + Gdb.setTimeout gdb Nothing + Gdb.runCommands gdb.stdinHandle ["echo connected to target device"] let gdbProcName = "GDB (" <> binName <> ", " <> show d.deviceId <> ")" - gdbClean1 = gdbClean0 >> awaitProcessTermination gdbProcName gdbPh (Just 5_000_000) + gdbClean1 = gdbClean0 >> awaitProcessTermination gdbProcName gdbPh (Just 10_000_000) return (gdb, gdbClean1) + ccGdbCheck :: (HwTarget, DeviceInfo) -> ProcessStdIoHandles -> VivadoM ExitCode + ccGdbCheck (_, _) gdb = do + liftIO + $ Gdb.runCommands + gdb.stdinHandle + ["echo START OF WHOAMI\\n", "x/4cb 0xE0000000", "echo END OF WHOAMI\\n"] + _ <- + liftIO + $ tryWithTimeout "Waiting for GDB to be ready to proceed" 15_000_000 + $ readUntil gdb.stdoutHandle "START OF WHOAMI" + gdbRead <- + liftIO + $ tryWithTimeout "Reading CC whoami over GDB" 15_000_000 + $ readUntil gdb.stdoutHandle "END OF WHOAMI" + let + idLine = trim . L.head . lines $ trim gdbRead + success = idLine == "(gdb) 0xe0000000:\t115 's'\t119 'w'\t99 'c'\t99 'c'" + liftIO $ putStrLn [i|Output from CC whoami probe:\n#{idLine}|] + return $ if success then ExitSuccess else ExitFailure 1 + + foldExitCodes :: VivadoM (Int, ExitCode) -> ExitCode -> VivadoM (Int, ExitCode) + foldExitCodes prev code = do + (count, acc) <- prev + return + $ if code == ExitSuccess + then (count + 1, acc) + else (count, code) + + assertAllProgrammed :: (HwTarget, DeviceInfo) -> VivadoM () + assertAllProgrammed (hwT, d) = do + liftIO $ putStrLn $ "Asserting all programmed probe on " <> show d.deviceId + openHardwareTarget hwT + updateVio "vioHitlt" [("probe_all_programmed", "1")] + + muGdbCheck :: (HwTarget, DeviceInfo) -> ProcessStdIoHandles -> VivadoM ExitCode + muGdbCheck (_, _) gdb = do + liftIO + $ Gdb.runCommands + gdb.stdinHandle + ["echo START OF WHOAMI\\n", "x/4cb 0xE0000000", "echo END OF WHOAMI\\n"] + _ <- + liftIO + $ tryWithTimeout "Waiting for GDB to be ready to proceed" 15_000_000 + $ readUntil gdb.stdoutHandle "START OF WHOAMI" + gdbRead <- + liftIO + $ tryWithTimeout "Reading MU whoami over GDB" 15_000_000 + $ readUntil gdb.stdoutHandle "END OF WHOAMI" + let + idLine = trim . L.head . lines $ trim gdbRead + success = idLine == "(gdb) 0xe0000000:\t109 'm'\t103 'g'\t109 'm'\t116 't'" + liftIO $ putStrLn [i|Output from MU whoami probe:\n#{idLine}|] + return $ if success then ExitSuccess else ExitFailure 1 + getTestsStatus :: [(HwTarget, DeviceInfo)] -> [TestStatus] -> Integer -> VivadoM [TestStatus] getTestsStatus [] _ _ = return [] @@ -250,33 +300,12 @@ driverFunc testName targets = do else inner new inner innerInit - foldExitCodes :: VivadoM (Int, ExitCode) -> ExitCode -> VivadoM (Int, ExitCode) - foldExitCodes prev code = do - (count, acc) <- prev - return - $ if code == ExitSuccess - then (count + 1, acc) - else (count, code) - - muGdbCheck :: (HwTarget, DeviceInfo) -> ProcessStdIoHandles -> VivadoM ExitCode - muGdbCheck (_, d) gdb = do - let - devIdString = show d.deviceId - expectedDna = showHex d.dna "" - -- Need to find out what the appropriate invocation is for GDB to get the correct string - -- out from MMIO. - liftIO $ Gdb.runCommands gdb.stdinHandle ["x/12sb 0xa0000000", "echo END OF DNA\\n"] - gdbRead <- - liftIO - $ tryWithTimeout "Reading DNA over GDB" 60_000_000 - $ readUntil gdb.stdoutHandle "END OF DNA" - -- Also need to find out what the output looks like in order to write a proper comparison. - -- For now, just print what each of them are. - liftIO $ putStrLn [i|Expected DNA for device #{devIdString}: #{expectedDna}|] - liftIO $ putStrLn [i|Output from DNA probe:\n#{gdbRead}|] - return ExitSuccess - - tryWithTimeout "Wait for handshakes successes from all boards" 15_000_000 awaitHandshakes + liftIO + $ putStrLn + "All programmed pin may be asserted from previous test - deasserting on all targets." + forM_ targets deassertAllProgrammed + forM_ targets assertTestStart + tryWithTimeout "Wait for handshakes successes from all boards" 30_000_000 awaitHandshakes brackets (liftIO <$> L.zipWith initOpenOcds targets [0 ..]) (liftIO . (.cleanup)) $ \initOcdsData -> do let muPorts = (.muPort) <$> initOcdsData @@ -286,29 +315,39 @@ driverFunc testName targets = do (liftIO . snd) $ \initCCGdbsData -> do let ccGdbs = fst <$> initCCGdbsData + liftIO $ putStrLn "Checking for MMIO access to SwCC CPUs over GDB..." + gdbExitCodes0 <- zipWithM ccGdbCheck targets ccGdbs + (gdbCount0, gdbExitCode0) <- + L.foldl foldExitCodes (pure (0, ExitSuccess)) gdbExitCodes0 + liftIO + $ putStrLn + [i|CC GDB testing passed on #{gdbCount0} of #{L.length targets} targets|] liftIO $ mapM_ ((errorToException =<<) . Gdb.loadBinary) ccGdbs brackets (liftIO <$> L.zipWith (initGdbs "management-unit") muPorts targets) (liftIO . snd) $ \initMUGdbsData -> do let muGdbs = fst <$> initMUGdbsData + liftIO $ putStrLn "Checking for MMIO access to MU CPUs over GDB..." + gdbExitCodes1 <- zipWithM muGdbCheck targets muGdbs + (gdbCount1, gdbExitCode1) <- + L.foldl foldExitCodes (pure (0, ExitSuccess)) gdbExitCodes1 + liftIO + $ putStrLn + [i|MU GDB testing passed on #{gdbCount1} of #{L.length targets} targets|] liftIO $ mapM_ ((errorToException =<<) . Gdb.loadBinary) muGdbs + liftIO $ mapM_ Gdb.continue ccGdbs + forM_ targets assertAllProgrammed testResults <- awaitTestCompletions 60_000 (sCount, stabilityExitCode) <- L.foldl foldExitCodes (pure (0, ExitSuccess)) testResults liftIO $ putStrLn [i|Test case #{testName} stabilised on #{sCount} of #{L.length targets} targets|] - liftIO $ putStrLn "Checking for MMIO access over GDB..." - gdbExitCodes <- zipWithM muGdbCheck targets ccGdbs - (gdbCount, gdbExitCode) <- - L.foldl foldExitCodes (pure (0, ExitSuccess)) gdbExitCodes - liftIO - $ putStrLn - [i|GDB testing passed on #{gdbCount} of #{L.length targets} targets|] + let finalExit = fromMaybe ExitSuccess - $ L.find (/= ExitSuccess) [stabilityExitCode, gdbExitCode] + $ L.find (/= ExitSuccess) [stabilityExitCode, gdbExitCode0, gdbExitCode1] return finalExit diff --git a/bittide/src/Bittide/Wishbone.hs b/bittide/src/Bittide/Wishbone.hs index 9bfeff36c..b9ff28b4d 100644 --- a/bittide/src/Bittide/Wishbone.hs +++ b/bittide/src/Bittide/Wishbone.hs @@ -706,3 +706,29 @@ watchDogWb name timeout@SNat | wdTimeout = trace ("watchDogWb - " <> name <> ": " <> show wbM2S0) 0 | wbM2S0.busCycle && wbM2S0.strobe = succ cnt0 | otherwise = 0 + +wbAlwaysAckWith :: + forall nBytes addrW. + ( KnownNat nBytes + , 1 <= nBytes + , KnownNat addrW + ) => + Bytes nBytes -> + WishboneM2S addrW nBytes (Bytes nBytes) -> + WishboneS2M (Bytes nBytes) +wbAlwaysAckWith dat _ = (emptyWishboneS2M @(Bytes nBytes)){acknowledge = True, readData = dat} + +whoAmIC :: + forall dom addrW. + ( KnownDomain dom + , HiddenClockResetEnable dom + , KnownNat addrW + ) => + BitVector 32 -> + Circuit (Wishbone dom 'Standard addrW (Bytes 4)) () +whoAmIC whoAmI = Circuit go + where + go :: + (Fwd (Wishbone dom 'Standard addrW (Bytes 4)), ()) -> + (Bwd (Wishbone dom 'Standard addrW (Bytes 4)), ()) + go (m2s, ()) = (wbAlwaysAckWith whoAmI <$> m2s, ()) diff --git a/firmware-binaries/management-unit/memory.x b/firmware-binaries/management-unit/memory.x index 5efdfa0ce..d40653969 100644 --- a/firmware-binaries/management-unit/memory.x +++ b/firmware-binaries/management-unit/memory.x @@ -7,7 +7,7 @@ SPDX-License-Identifier: CC0-1.0 MEMORY { IMEM : ORIGIN = 0x80000000, LENGTH = 64K - DMEM : ORIGIN = 0x40000000, LENGTH = 64K + DMEM : ORIGIN = 0xC0000000, LENGTH = 64K } REGION_ALIAS("REGION_TEXT", IMEM);