gergoerdi
One level lower, you can use Clash's signal-level simulator. Basically it gives you a synchronous stream of signal values, either as a lazy list (for "offline" simulation), or as an automaton that you can turn the crank on by feeding it the next clock cycle's inputs (for "online" simulation, i.e. where you want to do IO to compute the next input from the previous outputs). So at this level, you'd take your Pong circuit and use the automaton interface of the simulator to feed the virtual "pushbutton" states computed from e.g. keypresses, and then consume the output to do the rendering. Or simulate the whole circuit end-to-end and feed its output into a VGA interpreter, which you also get to write in Haskell.
If you need to debug at the Verilog level, you can use Clashilator (https://github.com/gergoerdi/clashilator) to automate FFI-ing into a Verilator-generated simulation.
I chose the Compucolor II for its simplicity. Its original design goal of cheapness via very small number of components translates is a big win for my purposes because implementing many small special-purpose chips would bloat the book considerably, without adding too much extra value. With the Compucolor II, we can just take the Intel 8080 core from an earlier chapter, implement two custom chips, take the UART from another earlier chapter, and boom done.
In fact, I chose the Intel 8080 in the first place instead of the more widely used Z80 for the same reason: adding the Z80 extensions wouldn't bring anything new to the table, but would increase cruft. Turns out there's a small but reasonable number of 8080-based home computers (https://retrocomputing.stackexchange.com/q/11682/115).
However, the resulting circuit description is much harder to understand and extend than a more structured approach, so we rewrite it in a more principled manner by decomposing it into two parts: a `Input -> State -> State` circuit used as a register transfer enabled by the start of the vblank, and a `State -> Coordinate -> RGB` circuit connected to the video output signal generator. This has the added benefit that we can compile the same description as software Haskell instead of hardware Clash, and so we can use high-level simulation to run the bouncing ball in an SDL window.
Sample chapter 9 then creates a Pong game by just changing these two (pure, Haskell) functions slightly. With minimal changes, we go from idle animation to playable game!
https://news.ycombinator.com/item?id=23096338 https://news.ycombinator.com/item?id=9516217
Show HN: Retrocomputing with Clash: Haskell for FPGA Hardware Design
The real advantage of using Rust is in the actual program logic. E.g. the instructions are decoded into an algebraic datatype (in https://github.com/gergoerdi/chirp8-engine/blob/7623353a8bf0...) and then that is consumed in the virtual CPU (https://github.com/gergoerdi/chirp8-engine/blob/7623353a8bf0...). Rust's case-of-case optimization takes care of avoiding the intermediate data representation at runtime.
Rust on the MOS 6502: Beyond Fibonacci
Some hobbyist and educational FPGA dev boards do that, because handling PS/2 on the FPGA is so much easier than raw USB. Here is one example: https://reference.digilentinc.com/reference/programmable-log...
"The Auxiliary Function microcontroller (Microchip PIC24FJ128) provides the Nexys A7 with USB Embedded HID host capability. "
Here's code if you prefer that to slides: https://github.com/gergoerdi/hm-compo
I don't think that's true -- if you have principal types, you can just say in your language spec that the principal type is inferred.
Fisker: electric car battery with “500 miles range and 1 min charging”
MkPair :: a -> b -> Pair a b
not :: Bool -> Bool
succ :: Int -> Int
foo x = MkPair (succ x) (not x)
the error message will either complain that `x` has type `Bool` but it should be `Int`, or it will complain that `x` has type `Int` but it should be `Bool` -- depending on what implementation you use! For example, in Haskell, Hugs 98 will emit the first error message, but GHC 7.10 will emit the second (see the full example in my slides[2]). And in some sense, neither is right (and certainly neither is as helpful for the programmer as it could be).So next time you're implementing vanilla HM, maybe consider a compositional type system[3] instead, which can give the following, much more informative error message:
Cannot unify 'Int' with 'Bool' when unifying 'x':
Cannot unify 'Int' with 'Bool' in the following context:
MkPair (succ x) (not x)
Bool -> Pair Int Bool Bool
x :: Int Bool
I have a simple implementation here[4], and am about to release a new version which works on `haskell-src-ext`'s AST to support more of Haskell 98 syntax (but still for vanilla HM only).[1] https://gergo.erdi.hu/blog/2010-10-23-the_case_for_compositi... [2] https://gergo.erdi.hu/talks/2016-06-compty/CompTy.pdf [3] http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.25.8... [4] https://github.com/gergoerdi/hm-compo/blob/master/src/Langua...