Thursday, April 25, 2024

Kansas Lava to Simulate Circuits

Kansas Lava is a Haskell library that provides abstractions and powerful combinations to describe and simulate hardware circuits. Hardware descriptions are strongly typed and provide a means to describe hardware in a clear manner and express values that flow between components. You can describe both sequential and combinatorial circuits using Kansas Lava. To install the same on Fedora 20 (x86_64), follow the steps described below:

Download petersen/cabal-install repo from https://copr.fedoraproject.org/coprs/petersen/cabal-install/. If you do not have wget installed on your system, install it first using the following command:

 [stextbox id=”grey”]# yum install wget[/stextbox]

You can then run the following from /etc/yum.repos.d directory:

 [stextbox id=”grey”]$ wget https://copr.fedoraproject.org/
coprs/petersen/cabal-install/repo/
fedora-20-i386/petersen-cabal-install-
fedora-20-i386.repo[/stextbox]

- Advertisement -

Install cabal-install and Git.

 [stextbox id=”grey”]# yum install cabal-install git[/stextbox]

Download petersen/ghc-7.8 repo from https://copr.fedoraproject.org/coprs/petersen/ghc-7.8/ to /etc/yum.repos.d using:

- Advertisement -

 [stextbox id=”grey”]# wget https://copr.fedoraproject.org/
coprs/petersen/ghc-7.8/repo/fedora-
rawhide-i386/petersen-ghc-7.8-fedora-
rawhide-i386.repo[/stextbox]

Install Glasgow Haskell compiler (GHC) using:

 [stextbox id=”grey”]# yum install ghc[/stextbox]

Update the cabal local package list and install sized types using:

 [stextbox id=”grey”]$ cabal update
$ cabal install sized-types[/stextbox]

Obtain the latest Kansas Lava code from GitHub using:

 [stextbox id=”grey”]$ git clone https://github.com/ku-fpg/
kansas-lava.git[/stextbox]

Enter the following into the checked out Kansas Lava directory, compile and install the same as follows:

 [stextbox id=”grey”]$ cabal install –only-dependencies
$ cabal build
$ cabal install[/stextbox]

The tool can help verify the behaviour of a circuit in simulation, generate VHDL for synthesis and also validate whether the generated VHDL is the same as the simulated circuit.

A simple code for the half adder combinatorial circuit is given below:

 [stextbox id=”grey”]

import Language.KansasLava

halfAdd :: Signal i Bool -> Signal i
Bool -> (Signal i Bool, Signal i Bool)
halfAdd a b = (carry, sum)
where carry = a `and2` b
sum = a `xor2` b

[/stextbox]

Execute the above example using Glasgow Haskell compiler (GHCi):

 [stextbox id=”grey”]$ ghci halfAdd.hs
ghci> halfAdd low high
(low,high)
ghci> halfAdd high high
(high,low)[/stextbox]

Kansas Lava implements the idea of an undefined Signal, where binary functions like and2, or2 and xor2 are short circuited. With unknown values, these function as hardware gates.

 [stextbox id=”grey”]

ghci> :m + Language.KansasLava

ghci> undefinedS `or2` low
?
ghci> undefinedS `or2` high
high
ghci> undefinedS `and2` low
low
ghci> undefinedS `and2` high
?
ghci> undefinedS `xor2` low
?
ghci> undefinedS `xor2` high
?

[/stextbox]

mux is a function that can be used to select an input. With low input, it picks the first argument in the tuple, and with high input, it picks the second argument in the tuple.

 [stextbox id=”grey”]

ghci> :m + Language.KansasLava

ghci> mux low (0,1) :: Signal c Int
0
ghci> mux high (0,1) :: Signal c Int
1

[/stextbox]

Kansas Lava provides a number of instance declarations and overloadings for the signal module.

 [stextbox id=”grey”]

instance (Num a, Rep a) => Num (Signal
i a)

instance (Bounded a, Rep a) => Bounded
(Signal i a)

instance (Show a, Bits a, Rep a) => Bits
(Signal i a)

[/stextbox]

The overloading enables you to use Haskell expressions with Signal c and can be helpful in describing hardware signals.

 [stextbox id=”grey”]

ghci> :m + Language.KansasLava

ghci> 2 :: Signal c Int
2
ghci> 2 * 4 :: Signal c Int
8

ghci> :m + Data.Bits
ghci> 8 `shiftR` 2 :: Signal c Int
2

[/stextbox]

The clock class can change a signal with time and is used for sequential values. It provides two important functions: register and delay. The register function accepts an initial value and an input sequence as arguments, while delay function is similar to register function with the initial value undefined. Register function behaves like D edge-triggered flip-flop with an internal clock. toS function converts a set of values into a signal. For example,

 [stextbox id=”grey”]

ghci> :m + Language.KansasLava

ghci> let xs = toS [1..5] :: Seq Int
ghci> xs
1 | 2 | 3 | 4 | 5 | ? .
ghci> delay xs
? | 1 | 2 | 3 | 4 | 5 | ? .
ghci> register 10 xs
10 | 1 | 2 | 3 | 4 | 5 | ? .

[/stextbox]

Kansas Lava has support for both fixed-width signed and unsigned numbers. An unsigned X4 is a 4-bit unsigned number.

 [stextbox id=”grey”]

ghci> :m + Data.Sized.Matrix
ghci> :m + Data.Sized.Unsigned

ghci> 100 :: U4
4

ghci> :m + Data.Sized.Signed

ghci> 100 :: S8
100
ghci> 100 + 100 :: S8
-56
ghci> [minBound..maxBound] :: [U4]
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]

[/stextbox]

It also provides support for fixed-width matrices. A matrix with four elements of boolean type is represented by Matrix U2 bool. These are useful when specifying irregular-sized values in hardware.

 [stextbox id=”grey”]

ghci> :m + Data.Sized.Matrix

ghci> let m = matrix [1,2,3,4] ::
Matrix U2 Int

ghci> :m + Data.Array.IArray

ghci> m ! 1
2
ghci> m ! 0
1

[/stextbox]

The pack utility provides a means to combine multiple signals into a single signal, and the unpack combinator does the reverse. These allow flexible-type representation of data in the program. For example,

 [stextbox id=”grey”]

ghci> :m + Language.KansasLava

ghci> let p = toS (cycle [False, True])
:: Seq Bool
ghci> let q = toS [1..] :: Seq Int
ghci> let pq = pack (p, q) :: Seq (Bool,
Int)
ghci> takeS 2 pq
(low,1) | (high,2) | (?,?) .

[/stextbox]

Apart from signal types, circuits can also be built from Haskell functions.

Consider a ROM that stores the cube of a value. funMapXXX function when used directly is similar to an asynchronous ROM.

 [stextbox id=”grey”]

ghci> :m + Language.KansasLava
ghci> :set -XScopedTypeVariables

ghci> let cubeROM = funMapXXX(\(x::Int)
-> return(x*x*x))

ghci> takeS 5 $ cubeROM $ toS [1..] ::
Seq Int
1 | 8 | 27 | 64 | 125 | ? .

[/stextbox]

Kansas Lava also provides various coerce functions that can be used between two signal types, as long as both types have the same bit-width. For example,

 [stextbox id=”grey”]

ghci> :m + Language.KansasLava

ghci> let a = toS (cycle [False, True])
:: Seq Bool
ghci> takeS 5 a
low | high | low | high | low | ? .

ghci> takeS 5 $ (unsigned) a :: Seq Int
0 | 1 | 0 | 1 | 0 | ? .

[/stextbox]

Circuits can be debugged using probes, which present a way to observe intermediate values in shallow embedded circuits without modifying the circuit interface. These are inserted in the function using probeS function.

 [stextbox id=”grey”]

ghci> :m + Language.KansasLava

ghci> setProbesAsTrace (appendFile
“DEBUG”)
ghci> let xs = toS (cycle [False, True])
:: Seq Bool
ghci> let ys = probeS “ys” (takeS 5 $
(unsigned) xs :: Seq Int)
ghci> takeS 5 ys
0 | 1 | 0 | 1 | 0 | ? .
ghci> :!cat DEBUG
ys(0)0
ys(1)1
ys(2)0
ys(3)1
ys(4)0

[/stextbox]

An important purpose of Kansas Lava is to produce useful VHDL. Hardware descriptions are converted into efficient VHDL. Kansas Lava programs are extracted into a Kansas Lava entity graph (KLEG), which is an abstract representation of the netlist. This can be optimised and written into VHDL. The generic netlist rendering tool can also target Verilog. Kansas Lava can also generate and execute a VHDL test bench. mkTestbench function can be used to generate a test bench.

SHARE YOUR THOUGHTS & COMMENTS

Unique DIY Projects

Electronics News

Truly Innovative Tech

MOst Popular Videos

Electronics Components

Calculators