# Function¶

## Introduction¶

The ways you can use Scala functions to generate hardware are radically different than VHDL/Verilog for many reasons:

• You can instantiate registers, combinatorial logic and components inside them.

• You don’t have to play with `process`/`@always` that limit the scope of assignment of signals

• Everything is passed by reference, which allows easy manipulation.
For example you can give a bus to a function as an argument, then the function can internaly read/write to it.
You can also return a Component, a Bus, or anything else from scala and the scala world.

## RGB to gray¶

For example if you want to convert a Red/Green/Blue color into greyscale by using coefficients, you can use functions to apply them:

```// Input RGB color
val r, g, b = UInt(8 bits)

// Define a function to multiply a UInt by a scala Float value.
def coef(value: UInt, by: Float): UInt = (value * U((255*by).toInt, 8 bits) >> 8)

// Calculate the gray level
val gray = coef(r, 0.3f) + coef(g, 0.4f) + coef(b, 0.3f)
```

For instance if you define a simple Valid Ready Payload bus, you can then define some useful functions inside of it.

```class MyBus(payloadWidth: Int) extends Bundle with IMasterSlave {
val valid   = Bool

// define the direction of the data in a master mode
override des asMaster(): Unit = {
}

// Connect that to this
def <<(that: MyBus): Unit = {
this.valid   := that.valid
}

// Connect this to the FIFO input, return the fifo output
def queue(size: Int): MyBus = {
val fifo = new MyBusFifo(payloadWidth, size)
fifo.io.push << this
return fifo.io.pop
}
}

class MyBusFifo(payloadWidth: Int, depth: Int) extends Component {

val io = new Bundle {