Page 1

Page 2

# Today

## Examples covering these topics

• Functions
• Lists
• Connection patterns
• Sequential circuits
Page 3

Page 4

# Functions in Haskell

## Two ways to handle multiple arguments

• Pairing arguments
• ```f1 (x,y) = nand2(x,y)
g1 (x,y) = x+y
```
• One argument at a time
• ```f2 x y = nand2(x,y)
g2 x y = x+y
```
• The latter solution is common in the Haskell libraries. It makes it easier to use a function without giving all arguments at once.
• ```map (g2 3) [4,5,6] = [7,8,9] ```
Page 5

# Function types in Haskell

## The two ways to handle multiple arguments is reflected in the types

• ```f1 :: (Bit,Bit) -> Bit
f1 (x,y) = nand2(x,y)

g1 :: (Int,Int) -> Int
g1 (x,y) = x+y

f2 :: Bit -> (Bit -> Bit)
f2 x y = nand2(x,y)

g2 :: Int -> Int -> Int
g2 x y = x+y
```
• `g2 3 :: Int->Int`
• `map (g2 3) :: [Int]->[Int]`
Page 6

Page 7

# Serial composition of circuits

• We could do this
• ```serial ((circ1,circ2),inp) = out
where
mid = circ1 inp
out = circ2 mid
```
• Or this
• ```serial (circ1,circ2) inp = out
where
mid = circ1 inp
out = circ2 mid
```
• From the Lava library
• ```serial circ1 circ2 inp = out
where
mid = circ1 inp
out = circ2 mid

circ1 ->- circ2 = serial circ1 circ2
```
• Pipelines: `c1 ->- c2 ->- c3 -> c4`
Page 8

Page 9

# Parallel composition of circuits

## From the Lava library

• ```par f g (inp1,inp2) = (out1,out2)
where
out1 = f inp1
out2 = g inp2

f -|- g = par f g
```
• What is the type?
Page 10

# Composition of circuits

## We have also seen

• The `map` function
• `map f [x1,x2,...,xn] = [f x1,f x2,...,f xn]`
• The `row` function

• More connection patterns later
Page 11

# Feedback and sequential circuits

## First example

• ```bad inp = out
where
out = nand2(inp,out)
```
• This doesn't work, try it in Lava...
• `simulate bad low`
• `simulate bad high`
Page 12

# Delay in VHDL

• Signal assignments have no delay by default:
• `out <= a nand b;`
• Delay can be introduced explicitly:
• `out <= a nand b after 4ns;`
Page 13

# Delay in Lava

• The logical gates in the Lava library are "ideal" and have zero delay.
• Delay has to be modelled explicitly:
• `delay init s`
• Delays the signal `s` by one "clock cycle".
• The output during the first "clock cycle" is `init`.
Page 14

# Feedback and sequential circuits

## Second example

• ```nand2D = nand2 ->- delay low

good a = out
where
out = nand2D(a,out)
```
• Works better, but...
• `simulate good high`
• ...we need the to use the sequence simulator
• `simulateSeq good [high,high,high,high]`
Page 15

# Creating longer sequences for simulations

## Sequences are lists, so we can use any list function in Haskell

• ```low5 = replicate 5 low
high5 = replicate 5 high
```
• Example:
• ```simulateSeq good (high5++low5++high5) ```
• The operator `++` joins two lists
Page 16

# List functions

## We have seen

• `zipp :: ([a],[b]) -> [(a,b)]`
• `unzipp :: [(a,b)] -> ([a],[b])`
• `replicate :: Int -> a -> [a]`
• `++ :: [a] -> [a] -> [a]`
• `map :: (a->b) -> ([a] -> [b])`
Page 17

## But all lists are built from two basic operators on lists

• `[]`: the empty list
• `x : xs`: adding one more element to the front of a list
• Example: `3:[4,5,6] = [3,4,5,6]`
• In fact `[3,4,5,6]` is just a shorthand for `3:4:5:6:[]`
Page 18

Page 19

Page 20

# Consuming lists

• How do functions with list arguments work?
• Example 1: the function `sum` sums a list of numbers
• `sum :: [Int] -> Int`
• `sum [] = 0`
• `sum [7,5,3,6] = 7+5+3+6 = 21`
• How does `sum` work?
• ```sum [7,5,3,6] = 7 + sum [5,3,6]
= 7 + 5 + sum [3,6]
= 7 + 5 + 3 + sum [6]
= 7 + 5 + 3 + 6 + sum []
= 7 + 5 + 3 + 6 + 0
= 21
```
Page 21

Page 22

# Consuming lists 2

• Example 2: the function `minimum` finds the minimum number in a list
• `minimum [7,3,6] = 3`
• `minimum [] = ??` we want to leave it undefined
• `minimum [7] = 7`
• Assume we have `min2 :: (Int,Int) -> Int`
• How does `minimum` work?
• ```minimum [7,3,6] = min2(7,minimum [3,6])
= min2(7,min2(3,minimum [6]))
= min2(7,min2(3,6))
= min2(7,3)
= 3
```
Page 23

Page 24

# Exercise

## Zero detection

• Define a generic circuit that
• inputs a bit vector, and
• outputs `high` if all bits are zero.
• ```zero_detect :: [Bit] -> Bit ```
• Simple solution first
• Also think about circuit depth and delay