Skip to content
Open
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
1 change: 1 addition & 0 deletions bittide-instances/bittide-instances.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ library
Bittide.Instances.Pnr.Si539xSpi
Bittide.Instances.Pnr.Switch
Bittide.Instances.Pnr.Synchronizer
Bittide.Instances.Tests.ClockControlWb
Bittide.Instances.Tests.ElasticBufferWb
Bittide.Instances.Tests.NestedInterconnect
Bittide.Instances.Tests.RegisterWb
Expand Down
4 changes: 3 additions & 1 deletion bittide-instances/src/Bittide/Instances/MemoryMaps.hs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import qualified Bittide.Instances.Hitl.Si539xConfiguration as Si539xConfigurati
import qualified Bittide.Instances.Hitl.SoftUgnDemo.MemoryMaps as SoftUgnDemo
import qualified Bittide.Instances.Hitl.SwitchDemo.MemoryMaps as SwitchDemo
import qualified Bittide.Instances.Hitl.SwitchDemoGppe.MemoryMaps as SwitchDemoGppe
import qualified Bittide.Instances.Tests.ClockControlWb as ClockControlWb
import qualified Bittide.Instances.Tests.ElasticBufferWb as ElasticBufferWb
import qualified Bittide.Instances.Tests.NestedInterconnect as NestedInterconnect
import qualified Bittide.Instances.Tests.RegisterWb as RegisterWb
Expand All @@ -42,7 +43,8 @@ $( do
-- Add new memory maps here --
-------------------------------
let memoryMaps =
[ ("Ethernet", vexRiscvEthernetMM)
[ ("ClockControlWb", ClockControlWb.dutMm)
, ("Ethernet", vexRiscvEthernetMM)
, ("ElasticBufferWbTest", ElasticBufferWb.dutMM)
, ("Freeze", freezeMM)
, ("NestedInterconnect", NestedInterconnect.nestedInterconnectMm)
Expand Down
94 changes: 94 additions & 0 deletions bittide-instances/src/Bittide/Instances/Tests/ClockControlWb.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
-- SPDX-FileCopyrightText: 2026 Google LLC
--
-- SPDX-License-Identifier: Apache-2.0
module Bittide.Instances.Tests.ClockControlWb where

import Clash.Prelude

import Bittide.ClockControl.Registers (ClockControlData, clockControlWb)
import Bittide.Cpus.Riscv32imc (vexRiscv0)
import Bittide.DoubleBufferedRam
import Bittide.Instances.Hitl.Setup hiding (linkMask)
import Bittide.ProcessingElement
import Bittide.ProcessingElement.Util
import Bittide.SharedTypes (withBittideByteOrder)
import Bittide.Wishbone hiding (MemoryMap)
import Clash.Class.BitPackC (ByteOrder (BigEndian))
import GHC.Stack (HasCallStack)
import Project.FilePath
import Protocols
import Protocols.Idle
import Protocols.MemoryMap
import System.FilePath
import System.IO.Unsafe (unsafePerformIO)
import VexRiscv (DumpVcd (NoDumpVcd))

linkMask :: BitVector LinkCount
linkMask = 0b1011011

linksOk :: BitVector LinkCount
linksOk = 0b1111000

dataCounts :: Vec LinkCount (Signed 32)
dataCounts = iterateI (satSucc SatWrap) 0

type IMemWords = DivRU (64 * 1024) 4
type DMemWords = DivRU (32 * 1024) 4

dut ::
(HasCallStack) =>
Circuit (ToConstBwd Mm) (Df System (BitVector 8), CSignal System (ClockControlData LinkCount))
dut =
Comment on lines +38 to +41
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you made this

Suggested change
dut ::
(HasCallStack) =>
Circuit (ToConstBwd Mm) (Df System (BitVector 8), CSignal System (ClockControlData LinkCount))
dut =
dut ::
(HasCallStack) =>
Circuit (ToConstBwd Mm, ()) (Df System (BitVector 8), CSignal System (ClockControlData LinkCount))
dut =

then below you could use getMMAny to get the memory map and unMemmap to get a circuit without the memory map, meaning less juggling of functions and Circuit wrappers

withBittideByteOrder
$ withClockResetEnable clockGen (resetGenN d2) enableGen
$ circuit
$ \mm -> do
(uartRx, jtag) <- idleSource
[uartBus, (mmCC, ccWb)] <- processingElement NoDumpVcd peConfig -< (mm, jtag)
(uartTx, _uartStatus) <- uartInterfaceWb d2 d2 uartBytes -< (uartBus, uartRx)

ccd <-
clockControlWb
(pure linkMask)
(pure linksOk)
(pure <$> dataCounts)
-< (mmCC, ccWb)

idC -< (uartTx, ccd)
where
peConfig = unsafePerformIO $ do
root <- findParentContaining "cabal.project"
let
elfDir = root </> firmwareBinariesDir "riscv32imc" Release
elfPath = elfDir </> "clock-control-wb"
pure
PeConfig
{ cpu = vexRiscv0
, initI =
Reloadable @IMemWords
$ Vec
$ unsafePerformIO
$ vecFromElfInstr BigEndian elfPath
, initD =
Reloadable @DMemWords
$ Vec
$ unsafePerformIO
$ vecFromElfData BigEndian elfPath
, iBusTimeout = d0
, dBusTimeout = d0
, includeIlaWb = False
}
{-# OPAQUE dut #-}

dutMm :: (HasCallStack) => MemoryMap
dutMm = mm
where
Circuit circuitFn = dut
(SimOnly mm, _) = circuitFn ((), (pure $ deepErrorX "uart_bwd", ()))

dutNoMm ::
(HasCallStack) => Circuit () (Df System (BitVector 8), CSignal System (ClockControlData LinkCount))
dutNoMm = Circuit circuitFnNoMm
where
Circuit circuitFn = dut
circuitFnNoMm (fwdL, bwdR) = let (_, fwdR) = circuitFn (fwdL, bwdR) in ((), fwdR)
74 changes: 4 additions & 70 deletions bittide-instances/tests/Tests/ClockControlWb.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,21 @@ import Clash.Explicit.Prelude hiding (PeriodToCycles, many)

-- external imports

import Bittide.Cpus.Riscv32imc (vexRiscv0)
import Clash.Class.BitPackC (ByteOrder (BigEndian))
import Clash.Signal (withClockResetEnable)
import Data.Char (chr)
import Data.Maybe (catMaybes, mapMaybe)
import Data.String.Interpolate
import Project.FilePath
import Protocols
import Protocols.Idle
import Protocols.MemoryMap
import System.FilePath
import System.IO.Unsafe (unsafePerformIO)
import Test.Tasty
import Test.Tasty.HUnit
import Test.Tasty.TH
import Text.Parsec
import Text.Parsec.String
import VexRiscv (DumpVcd (NoDumpVcd))

-- internal imports
import Bittide.Arithmetic.Time (PeriodToCycles)
import Bittide.ClockControl.Registers (ClockControlData (clockMod), clockControlWb)
import Bittide.DoubleBufferedRam
import Bittide.ClockControl.Registers (ClockControlData (clockMod))
import Bittide.Instances.Hitl.Setup (LinkCount)
import Bittide.ProcessingElement
import Bittide.ProcessingElement.Util
import Bittide.SharedTypes (withBittideByteOrder)
import Bittide.Wishbone
import Bittide.Instances.Tests.ClockControlWb

-- qualified imports
import qualified Data.List as L
Expand All @@ -61,7 +48,7 @@ sim =
putStr
$ fmap (chr . fromIntegral)
$ catMaybes
$ fst (sampleC def dut)
$ fst (sampleC def dutNoMm)

case_clock_control_wb_self_test :: Assertion
case_clock_control_wb_self_test = do
Expand Down Expand Up @@ -89,7 +76,7 @@ case_clock_control_wb_self_test = do
assertEqual "Expected and actual differ" expected actual
where
uartString = chr . fromIntegral <$> catMaybes uartStream
(uartStream, ccData) = sampleC def dut
(uartStream, ccData) = sampleC def dutNoMm

type Margin = SNat 2
type Framesize = PeriodToCycles System (Seconds 1)
Expand All @@ -103,68 +90,15 @@ framesize = SNat
linkCount :: Int
linkCount = snatToNum (SNat @LinkCount)

linkMask :: BitVector LinkCount
linkMask = 0b1011011

linksOk :: BitVector LinkCount
linksOk = 0b1111000

linkMaskPopcnt :: Int
linkMaskPopcnt = fromIntegral $ popCount linkMask

dataCounts :: Vec LinkCount (Signed 27)
dataCounts = iterateI (satSucc SatWrap) 0

expectedDataCounts :: [(Int, Int)]
expectedDataCounts = L.zip [0 ..] $ toList $ applyMask linkMask dataCounts
where
applyMask m = zipWith go (bitCoerce m)
go m v = if m then fromIntegral v else 0

dut :: Circuit () (Df System (BitVector 8), CSignal System (ClockControlData LinkCount))
dut =
withBittideByteOrder
$ withClockResetEnable clockGen (resetGenN d2) enableGen
$ circuit
$ \_unit -> do
(uartRx, jtag) <- idleSource
[ uartBus
, (mmCC, ccWb)
] <-
processingElement NoDumpVcd peConfig -< (mm, jtag)
(uartTx, _uartStatus) <- uartInterfaceWb d2 d2 uartBytes -< (uartBus, uartRx)

mm <- ignoreMM

ccd <-
clockControlWb
(pure linkMask)
(pure linksOk)
(pure <$> dataCounts)
-< (mmCC, ccWb)

idC -< (uartTx, ccd)
where
peConfig = unsafePerformIO $ do
root <- findParentContaining "cabal.project"
let
elfDir = root </> firmwareBinariesDir "riscv32imc" Release
elfPath = elfDir </> "clock-control-wb"
(iMem, dMem) <- vecsFromElf @IMemWords @DMemWords BigEndian elfPath Nothing
pure
PeConfig
{ cpu = vexRiscv0
, initI = Reloadable (Vec iMem)
, initD = Reloadable (Vec dMem)
, iBusTimeout = d0
, dBusTimeout = d0
, includeIlaWb = False
}
{-# OPAQUE dut #-}

type IMemWords = DivRU (64 * 1024) 4
type DMemWords = DivRU (32 * 1024) 4

-- | Parse the output of the UART
resultParser :: Parser SerialResult
resultParser = do
Expand Down
5 changes: 5 additions & 0 deletions firmware-binaries/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,8 @@ members = [
"demos/switch-demo2-gppe",
]
resolver = "2"

[workspace.lints.clippy]
format_push_string = "forbid"
print_literal = "forbid"
uninlined_format_args = "forbid"
3 changes: 3 additions & 0 deletions firmware-binaries/demos/clock-control/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ edition = "2021"
license = "Apache-2.0"
authors = ["Google LLC"]

[lints]
workspace = true

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
Expand Down
3 changes: 3 additions & 0 deletions firmware-binaries/demos/soft-ugn-gppe/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ edition = "2021"
license = "Apache-2.0"
authors = ["Google LLC"]

[lints]
workspace = true

[dependencies]
riscv-rt = "0.11.0"
bittide-sys = { path = "../../../firmware-support/bittide-sys" }
Expand Down
5 changes: 3 additions & 2 deletions firmware-binaries/demos/soft-ugn-gppe/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ fn main() -> ! {
}

#[panic_handler]
#[allow(clippy::empty_loop)]
fn panic_handler(_: &core::panic::PanicInfo) -> ! {
loop {}
loop {
continue;
}
}
3 changes: 3 additions & 0 deletions firmware-binaries/demos/soft-ugn-mu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ edition = "2021"
license = "Apache-2.0"
authors = ["Google LLC"]

[lints]
workspace = true

[dependencies]
riscv-rt = "0.11.0"
bittide-sys = { path = "../../../firmware-support/bittide-sys" }
Expand Down
4 changes: 3 additions & 1 deletion firmware-binaries/demos/soft-ugn-mu/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,5 +187,7 @@ fn main() -> ! {

#[panic_handler]
fn panic_handler(_: &PanicInfo) -> ! {
loop {}
loop {
continue;
}
}
3 changes: 3 additions & 0 deletions firmware-binaries/demos/switch-demo1-boot/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ edition = "2021"
license = "Apache-2.0"
authors = ["Google LLC"]

[lints]
workspace = true

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
Expand Down
10 changes: 6 additions & 4 deletions firmware-binaries/demos/switch-demo1-boot/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,14 @@ fn main() -> ! {
}

uwriteln!(uart, "Going into infinite loop..").unwrap();
#[allow(clippy::empty_loop)]
loop {}
loop {
continue;
}
}

#[panic_handler]
fn panic_handler(_info: &PanicInfo) -> ! {
#[allow(clippy::empty_loop)]
loop {}
loop {
continue;
}
}
3 changes: 3 additions & 0 deletions firmware-binaries/demos/switch-demo1-mu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ edition = "2021"
license = "Apache-2.0"
authors = ["Google LLC"]

[lints]
workspace = true

[dependencies]
riscv-rt = "0.11.0"
bittide-sys = { path = "../../../firmware-support/bittide-sys" }
Expand Down
5 changes: 3 additions & 2 deletions firmware-binaries/demos/switch-demo1-mu/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ fn main() -> ! {

#[panic_handler]
fn panic_handler(_: &PanicInfo) -> ! {
#[allow(clippy::empty_loop)]
loop {}
loop {
continue;
}
}
3 changes: 3 additions & 0 deletions firmware-binaries/demos/switch-demo2-gppe/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ edition = "2021"
license = "Apache-2.0"
authors = ["Google LLC"]

[lints]
workspace = true

[dependencies]
riscv-rt = "0.11.0"
bittide-sys = { path = "../../../firmware-support/bittide-sys" }
Expand Down
10 changes: 6 additions & 4 deletions firmware-binaries/demos/switch-demo2-gppe/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,19 @@ use riscv_rt::entry;
const INSTANCES: hal::DeviceInstances = unsafe { hal::DeviceInstances::new() };

#[cfg_attr(not(test), entry)]
#[allow(clippy::empty_loop)]
fn main() -> ! {
let uart = &mut INSTANCES.uart;

ufmt::uwriteln!(uart, "Hello!").unwrap();

loop {}
loop {
continue;
}
}

#[panic_handler]
#[allow(clippy::empty_loop)]
fn panic_handler(_: &core::panic::PanicInfo) -> ! {
loop {}
loop {
continue;
}
}
3 changes: 3 additions & 0 deletions firmware-binaries/demos/switch-demo2-mu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ edition = "2021"
license = "Apache-2.0"
authors = ["Google LLC"]

[lints]
workspace = true

[dependencies]
riscv-rt = "0.11.0"
bittide-sys = { path = "../../../firmware-support/bittide-sys" }
Expand Down
Loading