How to generate testbench for a combinational circuit?

Hi,

Is there an example showing how to generate a verilog/vhdl testbench for a combinational circuit?

Also, I assign undefined value to model verilog’s (z, x) state. How can I match for that for an expected output in testbench?

Context: I am trying to build a simple combinational circuit for a 8-to-3 priority encoder, which is part of my ongoing attempt at building bunch of circuits in verilog and in clash to compare and understand them.

module PriorityEncoder.PriorityEncoder where

import Clash.Prelude
import Clash.Explicit.Testbench


type Channels = BitVector 8
type Selected = Unsigned 3

priorityEncoder :: (Bit, Channels) -> Selected
priorityEncoder (enable, channels) =
    if bitToBool enable then
        if channels .&. 0b10000000 /= 0 then 7
        else if channels .&. 0b01000000 /= 0 then 6
        else if channels .&. 0b00100000 /= 0 then 5
        else if channels .&. 0b00010000 /= 0 then 4
        else if channels .&. 0b00001000 /= 0 then 3
        else if channels .&. 0b00000100 /= 0 then 2
        else if channels .&. 0b00000010 /= 0 then 1
        else if channels .&. 0b00000001 /= 0 then 0
        else undefined
    else undefined

topEntity :: (Bit, Channels) -> Selected
topEntity = priorityEncoder


testbench :: Vec 2 Bool
testbench =  done
    where
        inputs = (1 :: Bit, 0b01111111 :: Channels) :> (0, 0b00111111) :> Nil
        expectedOutputs = (6 :: Selected) :> undefined :> Nil
        outputs = map topEntity inputs
        done = zipWith (==) outputs expectedOutputs


-- Mark testbench as top entity to generate Verilog testbench
{-# ANN testbench
  (Synthesize
    { t_name   = "testbench"
    , t_inputs = []
    , t_output = PortName "done"
    }) #-}

To test a combinatorial function you could use fmap (or liftA2, liftA3, …) to lift it to work on Signals, and then use the stimuliGenerator and outputVerifier to test the that lifted function.
See for example T1715.hs

As for dealing with x and z, the normal outputVerifier is defined in terms of assert.
And assert is implemented in Verilog using the ===/!== operators which means it will check that the inputs are exactly the same, including x and z bits.
This might be want you want.
But it could be problematic, if you have to deal with z bits.
As there isn’t really a standard way in clash to create z bits in Verilog.
All undefined bits are rendered in Verilog as xs.

Alternatively there are outputVerifier/assertBitVector, these will consider any x or z bits in the expected input as don’t bits, and will just ignore those bit position when checking values.

1 Like