# Clash Shockwaves simulation hang

**URL:** <https://clash-lang.discourse.group/t/clash-shockwaves-simulation-hang/117>\
**Category:** Clash Help\
**Created:** [July 29, 2026, 8:23am UTC](https://clash-lang.discourse.group/t/clash-shockwaves-simulation-hang/117 "2026-07-29T08:23:23Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![east710](https://yyz2.discourse-cdn.com/free1/user_avatar/clash-lang.discourse.group/east710/32/36_2.png) [@east710](https://clash-lang.discourse.group/u/east710)\
**Post date:** [July 29, 2026, 8:23am UTC](https://clash-lang.discourse.group/t/clash-shockwaves-simulation-hang/117/1 "2026-07-29T08:23:23Z")

</div>

I’m writing a testbench for the uart module provided by Retroclash to get more familiar with Shockwave. It’s as follow

```haskell
{-# OPAQUE topEntity #-}
{-# ANN topEntity
  (Synthesize
    { t_name = "topEntity"
    , t_inputs =
      [ PortName "clk"
      , PortName "rst"
      , PortName "uart_rxd"
      ]
    , t_output = PortName "uart_txd"
    }) #-}
topEntity :: Clock System -> Reset System -> Signal System Bit -> Signal System Bit
topEntity clk rst rxD = withClockResetEnable clk rst enableGen $
  let
    input = rx @8 (SNat @115200) rxD
    buf = fifo input txReady
    (txD, txReady) = tx @8 (SNat @115200) buf
  in boolToBit <$> (not . bitToBool <$> txD)

testUART :: IO ()
testUART = do
  let out = topEntity clockGen resetGen (fromList $ [high, high, high, high] <> [low, high, low, high, low, low, low, low] <> Ls.repeat high)

  file <- dumpVCD (0, 10_000_000) (traceSignal "topEntity" out) []

  case file of
    Left msg -> error msg
    Right (vcd, meta) -> do
      writeFile "test.vcd" vcd
      writeFileJSON "test.json" meta

```

With the class derived as follow

```haskell
data TxState n = TxIdle | TxBusy Word32 (TxBit n)
  deriving (Show, Eq, Generic, NFDataX)

data TxBit n = TxStartBit (BitVector n) | TxDataBit (BitVector n) (Index n) | TxStopBit
  deriving (Show, Eq, Generic, NFDataX)

data RxState n = RxIdle | RxBusy Word32 (Maybe Bit) (RxBit n)
  deriving (Show, Eq, Generic, NFDataX)

data RxBit n = RxStartBit | RxDataBit (BitVector n) (Index n) | RxStopBit (BitVector n)
  deriving (Show, Eq, Generic, NFDataX)

deriving instance (KnownNat n, 1 <= n) => BitPack (TxBit n)
deriving instance (KnownNat n, 1 <= n) => BitPack (TxState n)
deriving instance (KnownNat n, 1 <= n) => Waveform (TxBit n)
deriving instance (KnownNat n, 1 <= n) => Waveform (TxState n)

deriving instance (KnownNat n, 1 <= n) => BitPack (RxBit n)
deriving instance (KnownNat n, 1 <= n) => BitPack (RxState n)
deriving instance (KnownNat n, 1 <= n) => Waveform (RxBit n)
deriving instance (KnownNat n, 1 <= n) => Waveform (RxState n)

```

But this will just hang until my laptop run out of memory. Did I misunderstand something and what should I do to get it to work?

---

<div class="post-metadata">

**Author:** ![Rowan](https://yyz2.discourse-cdn.com/free1/user_avatar/clash-lang.discourse.group/rowan/32/24_2.png) [@Rowan](https://clash-lang.discourse.group/u/Rowan)\
**Post date:** [July 29, 2026, 10:58am UTC](https://clash-lang.discourse.group/t/clash-shockwaves-simulation-hang/117/2 "2026-07-29T10:58:14Z")

</div>

I cannot reproduce this myself if I use your definition + copied over retroclash-lib uart.. It finishes fine. Could you upload your project somewhere so I or someone else can check that out?

---

<div class="post-metadata">

**Author:** ![marijn-qbaylogic](https://yyz2.discourse-cdn.com/free1/user_avatar/clash-lang.discourse.group/marijn-qbaylogic/32/73_2.png) [@marijn-qbaylogic](https://clash-lang.discourse.group/u/marijn-qbaylogic)\
**Post date:** [July 29, 2026, 12:03pm UTC](https://clash-lang.discourse.group/t/clash-shockwaves-simulation-hang/117/3 "2026-07-29T12:03:43Z")

</div>

I am noticing two weird things here:

- First of all, `dumpVCD`’s list of trace names to wait for is empty. This _should_ cause it to not evaluate anything, and then error when trying to produce a VCD without signals. I suspect, since it’s apparently not reproducible, something (a debug print statement maybe?) is causing your signal to be evaluated, and thus the trace is getting registered regardless.
- Secondly, you are trying to trace for _10 million clock cycles_. That’s not a timestamp in ps (which would have been 1000 cycles) - its unit is the GCD of the clock periods of all signals being traced (weird, I know, we’re working on completely rewriting `dumpVCD` and friends) which in a single-domain design amounts to the clock period.

Now, 10 million things _should_ be fine in terms of memory normally, but the system really wasn’t designed for this. `Bit` in particular uses LUTs in Shockwaves 1.0, which, when evaluated 10 million times, probably takes up a lot of space in memory.

Note that Shockwaves 1.1 (1.1.1 has recently been released) introduces _static LUTs_ i.e. not all values of a signal get translated - the LUT is fully predefined. I doubt you have switched yet, but if you’re creating a large number of `Bit`s, you really should.

(and yes, `Bit` really doesn’t strictly require a LUT at all, but it’s the easiest way to display `undefined` as `x` while also keeping the option to add custom styles for `1` and `0`)

Hope this helps!

---

<div class="post-metadata">

**Author:** ![east710](https://yyz2.discourse-cdn.com/free1/user_avatar/clash-lang.discourse.group/east710/32/36_2.png) [@east710](https://clash-lang.discourse.group/u/east710)\
**Post date:** [July 31, 2026, 6:58am UTC](https://clash-lang.discourse.group/t/clash-shockwaves-simulation-hang/117/4 "2026-07-31T06:58:48Z")

</div>

Thank you for testing it. I have rebooted my laptop and the test does run, though it consume a lot of ram (~15GB at peak). That’s why my laptop hang, not because of Shockwave itself.

---

<div class="post-metadata">

**Author:** ![east710](https://yyz2.discourse-cdn.com/free1/user_avatar/clash-lang.discourse.group/east710/32/36_2.png) [@east710](https://clash-lang.discourse.group/u/east710)\
**Post date:** [July 31, 2026, 7:04am UTC](https://clash-lang.discourse.group/t/clash-shockwaves-simulation-hang/117/5 "2026-07-31T07:04:57Z")

</div>

> [@marijn-qbaylogic](#):
>
> - First of all, `dumpVCD`’s list of trace names to wait for is empty. This _should_ cause it to not evaluate anything, and then error when trying to produce a VCD without signals.

Thank you for the very informative post.

The VCD output is always 10000 ps of nothing even though there was `topEntity` variable. I thought the signal being traced is the `topEntity` function provided as defined by `out`? How can I setup the testing for a top entity correctly?

> [@marijn-qbaylogic](#):
>
> - Secondly, you are trying to trace for _10 million clock cycles_. That’s not a timestamp in ps (which would have been 1000 cycles) - its unit is the GCD of the clock periods of all signals being traced

No wonder why it take up so much ram…

Looking forward to future releases.

---

<div class="post-metadata">

**Author:** ![marijn-qbaylogic](https://yyz2.discourse-cdn.com/free1/user_avatar/clash-lang.discourse.group/marijn-qbaylogic/32/73_2.png) [@marijn-qbaylogic](https://clash-lang.discourse.group/u/marijn-qbaylogic)\
**Post date:** [August 4, 2026, 8:54am UTC](https://clash-lang.discourse.group/t/clash-shockwaves-simulation-hang/117/6 "2026-08-04T08:54:45Z")

</div>

The dumpVCD function does not care that you have a `topEntity`. It simply evaluates the values of a signal, which causes signals to be registered as `traceSignal` gets evaluated, until it has found all the signals it is looking for.

The basic setup you have is correct: you take your DUT (`topEntity`), provide it with inputs, and feed the output to `dumpVCD` (`out`, wrapped in a `traceSignal`). You then still have to provide `dumpVCD` with a list of signals to look for: `["topEntity"]`. It will keep evaluating the signal until it finds a signal labeled `"topEntity"`, which should happen immediately since the `traceSignal` is the first thing evaluation encounters.

Also keep in mind that putting `"topEntity"` in there does not link it to `topEntity` in any way - it is simply the name you give to `out`.

---

<div class="post-metadata">

**Author:** ![east710](https://yyz2.discourse-cdn.com/free1/user_avatar/clash-lang.discourse.group/east710/32/36_2.png) [@east710](https://clash-lang.discourse.group/u/east710)\
**Post date:** [August 4, 2026, 9:57am UTC](https://clash-lang.discourse.group/t/clash-shockwaves-simulation-hang/117/7 "2026-08-04T09:57:58Z")

</div>

Thank you for the explanation, but I’m still confused.

From this [tutorial](https://github.com/clash-lang/clash-shockwaves/blob/main/docs/howto/START.md) it seems that if I left the signal list empty, `dumpVCD` would evaluate until the provided cycle was reached (10 million in my case). Whereas I’m always getting 10000 ps (which I assume is 1 clock cycle for 100 MHz clock) of `1`. How can I let it run for say 1000 cycles?

---

<div class="post-metadata">

**Author:** ![marijn-qbaylogic](https://yyz2.discourse-cdn.com/free1/user_avatar/clash-lang.discourse.group/marijn-qbaylogic/32/73_2.png) [@marijn-qbaylogic](https://clash-lang.discourse.group/u/marijn-qbaylogic)\
**Post date:** [August 4, 2026, 1:08pm UTC](https://clash-lang.discourse.group/t/clash-shockwaves-simulation-hang/117/8 "2026-08-04T13:08:44Z")

</div>

Ah, I see. I will fix that tutorial - it really should have the trace names.

The time provided is for creating the VCD only, and is completely unrelated to the forced evaluation used to obtain the signals. The forced evaluation of the provided signal is used to obtain references to the (infinite) signals, and their values in the provided time slice are stored in the VCD.

If you want to _display_ 1000 cycles, you should just use `dumpVCD (0,1000) …`. If you want to _force evaluation_ of the provided signal for those 1000 cycles, that’s currently not possible (well, you could of course do it manually, but `dumpVCD` won’t do that). The rewrite we’re working on has better options for that.

I am rather puzzled by the “10000ps of nothing” - does the VCD contain a signal? It should error otherwise. If the signal is empty, try switching to a binary viewer to see the actual data if Shockwaves is displaying nothing.

---

<div class="post-metadata">

**Author:** ![east710](https://yyz2.discourse-cdn.com/free1/user_avatar/clash-lang.discourse.group/east710/32/36_2.png) [@east710](https://clash-lang.discourse.group/u/east710)\
**Post date:** [August 4, 2026, 1:37pm UTC](https://clash-lang.discourse.group/t/clash-shockwaves-simulation-hang/117/9 "2026-08-04T13:37:27Z")

</div>

> [@marijn-qbaylogic](#):
>
> I will fix that tutorial - it really should have the trace names.

Thank you I would love to see more up to date docs and tutorials.

> [@marijn-qbaylogic](#):
>
> I am rather puzzled by the “10000ps of nothing” - does the VCD contain a signal?

It turns out this came from my misunderstanding of asynchronous communication… The time should be calculated from BAUD rate, not clock cycles… This works better

```haskell
testUART :: IO ()
testUART = do
  let out = topEntity clockGen resetGen (fromList stretch)

  file <- dumpVCD (0, 1_000_000) (traceSignal "topEntity" out) []

  case file of
    Left msg -> error msg
    Right (vcd, meta) -> do
      writeFile "test.vcd" vcd
      writeFileJSON "test.json" meta
  where
    cyclesPerBit = 10417
    frame = [low]
     <> [low,high,low,high,low,low,high,high]
     <> [high]
    stretch = Ls.concatMap (Ls.replicate cyclesPerBit) frame <> Ls.repeat high

```

The output seems correct: wait for 10 bits until the data is received, then transmit them. But the last 3 `high` is cut off even if I crank it to 20 million cycles for some reason.

 ![2026-08-04_23-53-33](https://global.discourse-cdn.com/free1/uploads/clash_lang/original/1X/1381ad38c63ab65730b5f590cc99d6d4f4cfbf86.png)

---

<div class="post-metadata">

**Author:** ![marijn-qbaylogic](https://yyz2.discourse-cdn.com/free1/user_avatar/clash-lang.discourse.group/marijn-qbaylogic/32/73_2.png) [@marijn-qbaylogic](https://clash-lang.discourse.group/u/marijn-qbaylogic)\
**Post date:** [August 4, 2026, 2:08pm UTC](https://clash-lang.discourse.group/t/clash-shockwaves-simulation-hang/117/10 "2026-08-04T14:08:48Z")

</div>

I currently do not have the time to go into what your design is actually, doing, but I suggest you trace both input and output, as well as any signals you can get to inside your `topEntity`:

(sorry, the code block fails to get formatted)

``` hs  
testUART :: IO ()  
testUART = do  
let out = topEntity clockGen resetGen (traceSignal “input” $ fromList stretch)

file ← dumpVCD (0, 1\_000\_000) (traceSignal “output” out) [“input”,“output”]

case file of  
Left msg → error msg  
Right (vcd, meta) → do  
writeFile “test.vcd” vcd  
writeFileJSON “test.json” meta  
where  
cyclesPerBit = 10417  
frame = [low]  
\<\> [low,high,low,high,low,low,high,high]  
\<\> [high]  
stretch = Ls.concatMap (Ls.replicate cyclesPerBit) frame \<\> Ls.repeat high  
```

Please let me know if there’s any particular documentation that’s missing or outdated. Shockwaves is still rather new, and not many people have used it yet. I have tried to write proper documentation but there might be gaps in there that I missed.

---

<div class="post-metadata">

**Author:** ![east710](https://yyz2.discourse-cdn.com/free1/user_avatar/clash-lang.discourse.group/east710/32/36_2.png) [@east710](https://clash-lang.discourse.group/u/east710)\
**Post date:** [August 4, 2026, 2:27pm UTC](https://clash-lang.discourse.group/t/clash-shockwaves-simulation-hang/117/11 "2026-08-04T14:27:45Z")

</div>

Oh it makes sense now… receive and transmit are the opposite of each other…

 ![2026-08-05_00-18-09](https://global.discourse-cdn.com/free1/uploads/clash_lang/original/1X/4b666730e513fcdf889b84fff48912f92a2d80c0.png)

Thank you for helping me figure this out… Electronics engineering is sooooo complicated.
