Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tcp test improvements #689

Draft
wants to merge 16 commits into
base: staging
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/synthesis/debug.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[
{"top": "vexRiscvTcpTest", "stage": "test"}
]
6 changes: 4 additions & 2 deletions bittide-instances/src/Bittide/Instances/Pnr/Ethernet.hs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import Bittide.Wishbone
import Protocols.Idle

type Baud = 921_600
type Kilo n = n * 1024
type BytesToWords bytes = DivRU bytes 4

baud :: SNat Baud
baud = SNat
Expand Down Expand Up @@ -126,8 +128,8 @@ vexRiscGmii SNat sysClk sysRst rxClk rxRst txClk txRst fwd =
:> 0b1001
:> Nil
)
(Undefined @(256 * 1024))
(Undefined @(64 * 1024))
(Undefined @(BytesToWords (Kilo 256)))
(Undefined @(BytesToWords (Kilo 64)))

vexRiscEthernet ::
Clock Basic125B ->
Expand Down
15 changes: 11 additions & 4 deletions bittide-instances/src/Project/Handle.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ import System.IO

import Test.Tasty.HUnit

import qualified Data.ByteString.Char8 as ByteString
import qualified Data.Char as Char
import qualified Data.Text as Text
import qualified Data.Text.Encoding as Text

data Error = Ok | Error String
data Filter = Continue | Stop Error

Expand All @@ -24,14 +29,16 @@ expectLine :: (HasCallStack) => Handle -> (String -> Filter) -> Assertion
expectLine = expectLine' ""
where
expectLine' s0 h f = do
line <- hGetLine h
line <-
fmap
(trimEnd . filter Char.isPrint . Text.unpack . Text.decodeUtf8Lenient)
(ByteString.hGetLine h)
let
trimmed = filter (/= '\NUL') (trimEnd line)
s1 = s0 <> "\n" <> line
cont = expectLine' s1 h f
if null trimmed
if null line
then cont
else case f trimmed of
else case f line of
Continue -> cont
Stop Ok -> pure ()
Stop (Error msg) -> do
Expand Down
6 changes: 6 additions & 0 deletions bittide-instances/tests/Wishbone/Time.hs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ import Text.Parsec.String
-- Qualified
import qualified Protocols.Df as Df

sim :: IO ()
sim = putStrLn simResult
where
simResult = chr . fromIntegral <$> mapMaybe Df.dataToMaybe uartStream
uartStream = sampleC def dut

{- | Run the timing module self test with processingElement and inspect it's uart output.
The test returns names of tests and a boolean indicating if the test passed.
-}
Expand Down
4 changes: 2 additions & 2 deletions bittide/src/Bittide/ProcessingElement.hs
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ processingElement ::
processingElement (PeConfig memMapConfig initI initD) = circuit $ \jtagIn -> do
(iBus0, dBus0) <- rvCircuit (pure low) (pure low) (pure low) -< jtagIn
iBus1 <-
ilaWb (SSymbol @"instructionBus") 2 D4096 onTransactionWb onTransactionWb -< iBus0
dBus1 <- ilaWb (SSymbol @"dataBus") 2 D4096 onTransactionWb onTransactionWb -< dBus0
ilaWb (SSymbol @"instructionBus") 2 D4096 onErrorWb onTransactionWb -< iBus0
dBus1 <- ilaWb (SSymbol @"dataBus") 2 D4096 onErrorWb onTransactionWb -< dBus0
([iMemBus, dMemBus], extBusses) <-
(splitAtC d2 <| singleMasterInterconnect memMapConfig) -< dBus1
wbStorage initD -< dMemBus
Expand Down
89 changes: 78 additions & 11 deletions bittide/src/Bittide/Wishbone.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
--
-- SPDX-License-Identifier: Apache-2.0
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedRecordDot #-}
{-# LANGUAGE PartialTypeSignatures #-}
Expand Down Expand Up @@ -29,6 +30,7 @@ import Data.Maybe
import Protocols
import Protocols.Wishbone

import Clash.Sized.Vector.ToTuple (VecToTuple (vecToTuple))
import qualified Protocols.Df as Df
import qualified Protocols.Wishbone as Wishbone

Expand Down Expand Up @@ -114,6 +116,9 @@ onRequestWb = liftA2 $ \m _ -> m.busCycle && m.strobe
onTransactionWb :: forall dom mode addrW a. WbToBool dom mode addrW a
onTransactionWb = liftA2 $ \m s -> m.busCycle && m.strobe && (s.acknowledge || s.err || s.stall || s.retry)

onErrorWb :: WbToBool dom mode addrW a
onErrorWb = liftA2 $ \m s -> m.busCycle && m.strobe && s.err

-- | busCycle && strobe && addr >= lower && addr < upper
inAddrRangeWb ::
forall dom mode addrW a.
Expand Down Expand Up @@ -540,9 +545,38 @@ wbToVec readableData WishboneM2S{..} = (writtenData, wbS2M)
| otherwise = repeat Nothing
wbS2M = (emptyWishboneS2M @(Bytes 4)){acknowledge, readData, err}

{- | Wishbone accessible circuit that contains a free running 64 bit counter. We can
observe this counter to get a sense of time, overflows should be accounted for by
the master.
data TimeCmd = Capture | WaitForCmp deriving (Eq, Generic, NFDataX, BitPack)
data TimeCmp = TimeEq | TimeNeq | TimeLt | TimeGt | TimeLte | TimeGte
deriving (Generic, NFDataX, BitPack)

{- | Wishbone accessible circuit that contains a free running 64 bit counter with stalling
capabilities.

The word-aligned address layout of the Wishbone interface is as follows:

+--------------+-------------------+--------------+-------------------+
| Field number | Field description | Field name | Offset (in bytes) |
+==============+===================+==============+===================+
| 0 | Timer command | 'timer_cmd' | 0x00 |
| 1 | Timer comparison | 'timer_cmp' | 0x04 |
| 2 | Scratchpad LSBs | n/a | 0x08 |
| 3 | Scratchpad MSBs | n/a | 0x0C |
| 4 | Frequency LSBs | n/a | 0x10 |
| 5 | Frequency MSBs | n/a | 0x14 |
| 6 | Comparison result | 'cmp_result' | 0x18 |
+--------------+-------------------+--------------+-------------------+

The register-level layout of the Wishbone interface is as follows:

+--------------+-------------------+--------------+---------------+-----------------+-------------------+----+
| Field number | Field description | Field name | Field type | Size (in bytes) | Offset (in bytes) | RW |
+==============+===================+==============+===============+=================+===================+====+
| 0 | Timer command | 'time_cmd' | 'TimeCmd' | 1 | 0x00 | W |
| 1 | Timer comparison | 'time_cmp' | 'TimeCmp' | 1 | 0x04 | RW |
| 2 | Scratchpad | 'scratchpad' | 'Unsigned 64' | 8 | 0x08 | R |
| 4 | Frequency | 'frequency' | 'Unsigned 64' | 8 | 0x10 | R |
| 6 | Comparison result | 'cmp_result' | 'Bool' | 1 | 0x18 | R |
+--------------+-------------------+--------------+---------------+-----------------+-------------------+----+
-}
timeWb ::
forall dom addrW.
Expand All @@ -551,18 +585,51 @@ timeWb ::
, 1 <= DomainPeriod dom
) =>
Circuit (Wishbone dom 'Standard addrW (Bytes 4)) ()
timeWb = Circuit $ \(wbM2S, _) -> (mealy goMealy (0, 0) wbM2S, ())
timeWb = Circuit $ \(wbM2S, _) -> (mealy goMealy (TimeGte, False, 0, 0) wbM2S, ())
where
goMealy (frozen, count :: Unsigned 64) wbM2S = ((nextFrozen, succ count), wbS2M)
goMealy (cmp0, reqCmp0, scratch0 :: Unsigned 64, count :: Unsigned 64) wbM2S =
((cmp1, reqCmp1, scratch1, succ count), wbS2M1)
where
freq = natToNum @(DomainToHz dom) :: Unsigned 64
nextFrozen = if isJust (head writes) then count else frozen
RegisterBank (splitAtI -> (frozenMsbs, frozenLsbs)) = getRegsBe @8 frozen

readVec :: Vec 7 (BitVector 32)
readVec =
0 -- Timer command is write-only, provide default 0 on read
:> (resize . pack $ cmp0)
:> pack scratchLsbs0
:> pack scratchMsbs0
:> pack freqLsbs
:> pack freqMsbs
:> (resize . pack $ runCmp)
:> Nil
(writes, wbS2M0) = wbToVec @4 @_ readVec wbM2S
(f0, f1, f2, f3, _f4, _f5, _f6) = vecToTuple writes

command :: Maybe TimeCmd
command = unpack . resize <$> f0
cmp1 = maybe cmp0 (unpack . resize) f1
cmdWaitForCmp = Just WaitForCmp == command
reqCmp1 = if reqCmp0 then not runCmp else cmdWaitForCmp

RegisterBank (splitAtI -> (scratchMsbs0, scratchLsbs0)) = getRegsBe @8 scratch0
scratch1 = case (bitCoerce f2, bitCoerce f3, command) of
(Just newLsbs, _, _) -> getDataBe $ RegisterBank (scratchMsbs0 ++ newLsbs)
(_, Just newMsbs, _) -> getDataBe $ RegisterBank (newMsbs ++ scratchLsbs0)
(_, _, Nothing) -> scratch0
(_, _, Just Capture) -> count
(_, _, Just WaitForCmp) -> scratch0

RegisterBank (splitAtI -> (freqMsbs, freqLsbs)) = getRegsBe @8 freq
(writes, wbS2M) =
wbToVec
(0 :> fmap pack (frozenLsbs :> frozenMsbs :> freqLsbs :> freqMsbs :> Nil))
wbM2S

runCmp = case cmp0 of
TimeEq -> scratch0 == count
TimeNeq -> scratch0 /= count
TimeLt -> scratch0 > count
TimeGt -> scratch0 < count
TimeLte -> scratch0 >= count
TimeGte -> scratch0 <= count
cmpResult = not reqCmp0 || runCmp -- if reqCmp0 then runCmp else True
wbS2M1 = wbS2M0{acknowledge = wbS2M0.acknowledge && cmpResult}

{- | Wishbone wrapper for DnaPortE2, adds extra register with wishbone interface
to access the DNA device identifier. The DNA device identifier is a 96-bit
Expand Down
2 changes: 1 addition & 1 deletion firmware-binaries/examples/smoltcp_client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ riscv = "^0.10"
heapless = { version = "0.8", default-features = false}
smoltcp = { git = "https://github.com/smoltcp-rs/smoltcp.git", rev = "dc08e0b42e668c331bb2b6f8d80016301d0efe03", default-features = false, features = ["medium-ethernet", "proto-ipv4", "socket-tcp", "socket-dhcpv4"] }
ufmt = "0.2.0"
log = {version = "0.4.21", features = ["max_level_off", "release_max_level_info"]}
log = {version = "0.4.22", features = ["max_level_off", "release_max_level_off"]}
4 changes: 2 additions & 2 deletions firmware-binaries/examples/smoltcp_client/memory.x
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ SPDX-License-Identifier: CC0-1.0

MEMORY
{
IMEM : ORIGIN = 0x80000000, LENGTH = 1024K
DMEM : ORIGIN = 0x10000000, LENGTH = 256K
IMEM : ORIGIN = 0x80000000, LENGTH = 255K
DMEM : ORIGIN = 0x10000000, LENGTH = 63K
}

REGION_ALIAS("REGION_TEXT", IMEM);
Expand Down
Loading
Loading