|
|
@ -0,0 +1,105 @@ |
|
|
|
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}" |