Skip to content

Commit 117e2ba

Browse files
christiaanbkleinreactDigitalBrains1
authored
clash-ffi: fix example (#2445)
* Add missing SimAction arguments * Fix FFI example termination * Fix `ffi:example` CI It did not check the exit codes, continuing after an error and ultimately reporting success. `ffi:example` does not profit from having the `build` job's artifact available, so we remove that dependency. Now `ffi:example` can run earlier in the CI pipeline. `ffi:interface-tests` is moved to public runners as it runs in a single minute. --------- Co-authored-by: Felix Klein <[email protected]> Co-authored-by: Peter Lebbing <[email protected]>
1 parent 29ee170 commit 117e2ba

File tree

5 files changed

+88
-33
lines changed

5 files changed

+88
-33
lines changed

.ci/gitlab/test.yml

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,11 @@ prelude:doctests:
9696
script:
9797
- ./dist-newstyle/build/*/*/clash-prelude-*/t/doctests/build/doctests/doctests -j${THREADS}
9898

99+
ffi:interface-tests:
100+
extends: .test-nocache
101+
script:
102+
- ./dist-newstyle/build/*/*/clash-ffi-*/x/ffi-interface-tests/build/ffi-interface-tests/ffi-interface-tests --smallcheck-max-count 2000
103+
99104
# Tests run on local fast machines:
100105

101106
# Normally, this job is small. But it is flaky on GHC 9.2; it sometimes fails
@@ -133,18 +138,30 @@ suite:cores:
133138
- local
134139
- vivado-2022.1-standard
135140

136-
ffi:interface-tests:
137-
extends: .test-cache-local
141+
ffi:example:
142+
extends: .common-local
143+
stage: test
144+
needs: []
145+
before_script:
146+
- unset SNAPCRAFT_LOGIN_FILE
147+
- unset HACKAGE_PASSWORD
148+
- export THREADS=$(./.ci/effective_cpus.sh)
149+
- export CABAL_JOBS=$(./.ci/effective_cpus.sh)
150+
- export clash_lib_datadir=$(pwd)/clash-lib/
151+
- export clash_cosim_datadir=$(pwd)/clash-cosim/
152+
- export MASKBINS="$(mktemp -d)"
153+
- PATH="$MASKBINS:$PATH"
154+
- export
155+
- tar -xf cache.tar.zst -C / || true
156+
# The iverilog on CI cannot run the example, we only test it builds
157+
- ln -s /bin/true "$MASKBINS/iverilog"
158+
- ln -s /bin/true "$MASKBINS/vvp"
159+
- ls -al "$MASKBINS"
160+
- .ci/setup.sh
138161
script:
139-
- ./dist-newstyle/build/*/*/clash-ffi-*/x/ffi-interface-tests/build/ffi-interface-tests/ffi-interface-tests --smallcheck-max-count 2000
140-
141-
# Disabled for now. The test is faulty and so is the tested code. This will be
142-
# fixed later.
143-
#ffi:example:
144-
# extends: .test-cache-local
145-
# script:
146-
# - cabal build clash # ensure clash has been built (avoids some legacy cabal issue)
147-
# - cd clash-ffi/example && ./run-iverilog.sh
162+
- cd clash-ffi/example && ./run-iverilog.sh
163+
after_script:
164+
- tar -cf - /root/.cabal | zstd -T${THREADS} -3 > cache.tar.zst
148165

149166
# Tests run on local fast machines with Vivado installed. We only run these at night
150167
# to save resources - as Vivado is quite slow to execute.

clash-ffi/example/Simulate.hs

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import Data.Coerce (Coercible)
77
import Data.Typeable (Typeable)
88
import Data.Bits (complement)
99
import Data.List (intercalate, zip5)
10-
import Control.Monad (when, void)
10+
import Control.Exception (SomeException, try)
11+
import Control.Monad (void)
1112
import Control.Monad.IO.Class (liftIO)
1213
import Foreign.C.String (newCString)
1314
import Foreign.Marshal.Alloc (free)
@@ -23,6 +24,7 @@ import Clash.FFI.Monad
2324
import Clash.FFI.VPI.Info
2425
import Clash.FFI.VPI.IO
2526
import Clash.FFI.VPI.Callback
27+
import Clash.FFI.VPI.Control
2628
import Clash.FFI.VPI.Module
2729
import Clash.FFI.VPI.Object
2830
import Clash.FFI.VPI.Port
@@ -106,16 +108,6 @@ ffiMain = runSimAction $ do
106108
putStrLn " STEP ; CLK ; RST ; ENB ; OPC ; RESULT"
107109
putStrLn "------;------;------;------;----------------------;----------------------"
108110

109-
void $ registerCallback
110-
CallbackInfo
111-
{ cbReason = EndOfSimulation
112-
, cbRoutine = const $ do
113-
runSimAction (putStrLn "" >> putStrLn "[ Simulation done ]")
114-
return 0
115-
, cbIndex = 0
116-
, cbData = B.empty
117-
}
118-
119111
nextCB ReadWriteSynch 0 assignInputs
120112

121113
where
@@ -130,7 +122,7 @@ ffiMain = runSimAction $ do
130122
4 -> "<=>" -- mixed input-output
131123
_ -> "x" -- no direction
132124

133-
assignInputs :: (?state :: State) => SimAction
125+
assignInputs :: (?state :: State) => SimAction ()
134126
assignInputs = do
135127
SimTime time <- receiveTime Sim $ Just top
136128

@@ -171,7 +163,7 @@ assignInputs = do
171163
sendValue port (BitVectorVal SNat $ pack v) $ InertialDelay $ SimTime 0
172164
return $ Just v
173165

174-
readOutputs :: (?state :: State) => SimAction
166+
readOutputs :: (?state :: State) => SimAction ()
175167
readOutputs = do
176168
SimTime time <- receiveTime Sim $ Just top
177169
receiveValue VectorFmt dataOut >>= \case
@@ -182,9 +174,15 @@ readOutputs = do
182174
}
183175
_ -> return ()
184176

185-
when (steps > 0) $ do
177+
if (steps > 0) then do
186178
let ?state = ?state { steps = steps - 1 }
187179
nextCB ReadWriteSynch 1 assignInputs
180+
else do
181+
putStrLn ""
182+
putStrLn "[ Simulation done ]"
183+
184+
liftIO $ void $ try @SomeException $ runSimAction
185+
$ controlSimulator $ Finish NoDiagnostics
188186

189187
where
190188
State{..} = ?state
@@ -228,8 +226,8 @@ updates = Updates 0 Nothing Nothing Nothing Nothing Nothing
228226
nextCB ::
229227
(Maybe Object -> Time -> CallbackReason) ->
230228
Int64 ->
231-
SimAction ->
232-
SimAction
229+
SimAction () ->
230+
SimAction ()
233231
nextCB reason time action =
234232
void $ registerCallback
235233
CallbackInfo
@@ -248,11 +246,11 @@ getByName m name = do
248246
liftIO $ free ref
249247
return obj
250248

251-
putStr :: String -> SimAction
249+
putStr :: String -> SimAction ()
252250
putStr = simPutStr . B.pack
253251

254-
putStrLn :: String -> SimAction
252+
putStrLn :: String -> SimAction ()
255253
putStrLn = simPutStrLn . B.pack
256254

257-
print :: Show a => a -> SimAction
255+
print :: Show a => a -> SimAction ()
258256
print = simPutStrLn . B.pack . show

clash-ffi/example/cabal.project

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
packages: . .. ../../clash-ghc ../../clash-lib ../../clash-prelude
2+
3+
write-ghc-environment-files: always

clash-ffi/example/run-iverilog.sh

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@ EXAMPLES=../../examples
2727

2828
###############################
2929

30-
${CABAL} build clash-ffi-example
31-
${CLASH} --verilog -i${EXAMPLES} ${EXAMPLES}/Calculator.hs
32-
${IVERILOG} verilog/Calculator.topEntity/topEntity.v -o Calculator.vvp
30+
${CABAL} build clash-ffi-example || exit $?
31+
${CLASH} --verilog -i${EXAMPLES} ${EXAMPLES}/Calculator.hs || exit $?
32+
${IVERILOG} verilog/Calculator.topEntity/topEntity.v -o Calculator.vvp \
33+
|| exit $?
3334
echo ""
3435
echo "Running Icarus Verilog VVP runtime engine:"
3536
echo ""

clash-ffi/example/run-vsim.sh

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/bin/sh
2+
3+
# This is just a minimalistic script for demonstrating the process of
4+
# running the clash-ffi example using the ModelSim / QuestaSim runtime
5+
# engine. The script is not designed to work in any possible system
6+
# environment and may not work immediately for you. It is intended to
7+
# serve as an easy starter instead. Adapt it to your needs if it's not
8+
# working out-of-the-box for you.
9+
10+
###############################
11+
12+
# Adjust these variables if the tools are not in your PATH already
13+
14+
# Cabal
15+
# https://www.haskell.org/cabal
16+
CABAL=cabal
17+
# Clash
18+
# https://github.com/clash-lang/clash-compiler
19+
CLASH="${CABAL} run clash --"
20+
# ModelSim / QuestaSim binaries
21+
VLIB=vlib
22+
VLOG=vlog
23+
VSIM=vsim
24+
# Clash examples folder
25+
# https://github.com/clash-lang/clash-compiler/tree/master/examples
26+
EXAMPLES=../../examples
27+
28+
###############################
29+
30+
${CABAL} build clash-ffi-example || exit $?
31+
${CLASH} --verilog -i${EXAMPLES} ${EXAMPLES}/Calculator.hs || exit $?
32+
${VLIB} work || exit $?
33+
${VLOG} verilog/Calculator.topEntity/topEntity.v || exit $?
34+
echo ""
35+
echo "Running Simulation Runtime Engine:"
36+
echo ""
37+
${VSIM} -no_autoacc -c -do "onfinish exit; run -all" topEntity -pli lib/libclash-ffi-example.vpl

0 commit comments

Comments
 (0)