import logging
|
|
import random
|
|
import cocotb
|
|
import pprint
|
|
from Vai import VaiDriver, VaiReceiver
|
|
from cocotb.clock import Clock
|
|
from cocotb.triggers import FallingEdge, RisingEdge, Timer, ReadOnly
|
|
from Crypto.Cipher import AES
|
|
from Crypto.Util.number import long_to_bytes, getRandomNBitInteger
|
|
import binascii
|
|
|
|
|
|
# Reset coroutine
|
|
async def reset_dut(reset_n, duration_ns):
|
|
reset_n.value = 0
|
|
await Timer(duration_ns, units="ns")
|
|
reset_n.value = 1
|
|
|
|
|
|
@cocotb.test()
|
|
async def test_aes_enc(dut):
|
|
""" Test AES encryption """
|
|
|
|
clkedge = RisingEdge(dut.clk_i)
|
|
|
|
# Connect reset
|
|
reset = dut.reset_i
|
|
|
|
# Instantiate VAI driver & receiver
|
|
_input = [dut.mode_i, dut.key_i, dut.data_i]
|
|
vai_driver = VaiDriver(dut.clk_i, _input, dut.valid_i, dut.accept_o)
|
|
vai_receiver = VaiReceiver(dut.clk_i, dut.data_o, dut.valid_o, dut.accept_i)
|
|
|
|
# Drive input defaults (setimmediatevalue to avoid x asserts)
|
|
dut.mode_i.setimmediatevalue(0)
|
|
dut.key_i.setimmediatevalue(0)
|
|
dut.data_i.setimmediatevalue(0)
|
|
dut.valid_i.setimmediatevalue(0)
|
|
dut.accept_i.setimmediatevalue(0)
|
|
|
|
clock = Clock(dut.clk_i, 10, units="ns") # Create a 10 ns period clock
|
|
cocotb.start_soon(clock.start()) # Start the clock
|
|
|
|
# Execution will block until reset_dut has completed
|
|
dut._log.info("Hold reset")
|
|
await reset_dut(reset, 100)
|
|
dut._log.info("Released reset")
|
|
|
|
# Test 10 AES calculations
|
|
for i in range(10):
|
|
await clkedge
|
|
_key = getRandomNBitInteger(128)
|
|
_data = getRandomNBitInteger(128)
|
|
# Drive AES inputs
|
|
await vai_driver.send([0, _key, _data])
|
|
# Calc reference data
|
|
_aes = AES.new(long_to_bytes(_key), AES.MODE_ECB)
|
|
_ref = _aes.encrypt(long_to_bytes(_data))
|
|
# Get DUT output data
|
|
_rec = await vai_receiver.receive()
|
|
assert _rec.buff == _ref, f"Encrypt error, got {_rec.buff}, expected {_ref}"
|
|
|
|
|
|
@cocotb.test()
|
|
async def test_aes_dec(dut):
|
|
""" Test AES decryption """
|
|
|
|
clkedge = RisingEdge(dut.clk_i)
|
|
|
|
# Connect reset
|
|
reset = dut.reset_i
|
|
|
|
# Instantiate VAI driver & receiver
|
|
_input = [dut.mode_i, dut.key_i, dut.data_i]
|
|
vai_driver = VaiDriver(dut.clk_i, _input, dut.valid_i, dut.accept_o)
|
|
vai_receiver = VaiReceiver(dut.clk_i, dut.data_o, dut.valid_o, dut.accept_i)
|
|
|
|
# Drive input defaults (setimmediatevalue to avoid x asserts)
|
|
dut.mode_i.setimmediatevalue(0)
|
|
dut.key_i.setimmediatevalue(0)
|
|
dut.data_i.setimmediatevalue(0)
|
|
dut.valid_i.setimmediatevalue(0)
|
|
dut.accept_i.setimmediatevalue(0)
|
|
|
|
clock = Clock(dut.clk_i, 10, units="ns") # Create a 10 ns period clock
|
|
cocotb.start_soon(clock.start()) # Start the clock
|
|
|
|
# Execution will block until reset_dut has completed
|
|
dut._log.info("Hold reset")
|
|
await reset_dut(reset, 100)
|
|
dut._log.info("Released reset")
|
|
|
|
# Test 10 AES calculations
|
|
for i in range(10):
|
|
await clkedge
|
|
_key = getRandomNBitInteger(128)
|
|
_data = getRandomNBitInteger(128)
|
|
# Drive AES inputs
|
|
await vai_driver.send([1, _key, _data])
|
|
# Calc reference data
|
|
_aes = AES.new(long_to_bytes(_key), AES.MODE_ECB)
|
|
_ref = _aes.decrypt(long_to_bytes(_data))
|
|
# Get DUT output data
|
|
_rec = await vai_receiver.receive()
|
|
assert _rec.buff == _ref, f"Decrypt error, got {_rec.buff}, expected {_ref}"
|