Add poly1305 stage

This commit is contained in:
Byron Lathi
2025-11-01 20:53:02 -07:00
parent 2102cb41f4
commit d5035c6c81
8 changed files with 356 additions and 5 deletions

View File

@@ -16,4 +16,10 @@ tests:
modules:
- "poly1305_friendly_modular_mult"
sources: sources.list
waves: True
- name: "poly1305_stage"
toplevel: "poly1305_stage"
modules:
- "poly1305_stage"
sources: sources.list
waves: True

View File

@@ -78,7 +78,7 @@ async def test_sanity(dut):
await tb.cycle_reset()
count = 1024
count = 1
for _ in range(count):
await tb.write_input(random.randint(1,2**128-1), random.randint(0, 2**130-6))

View File

@@ -0,0 +1,110 @@
import logging
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import Timer, RisingEdge, FallingEdge
from cocotb.queue import Queue
from cocotbext.axi import AxiStreamBus, AxiStreamSource
from modulo_theory import friendly_modular_mult
import random
PRIME = 2**130-5
CLK_PERIOD = 4
class TB:
def __init__(self, dut):
self.dut = dut
self.log = logging.getLogger("cocotb.tb")
self.log.setLevel(logging.INFO)
self.input_queue = Queue()
self.expected_queue = Queue()
self.output_queue = Queue()
cocotb.start_soon(Clock(self.dut.i_clk, CLK_PERIOD, units="ns").start())
cocotb.start_soon(self.run_input())
cocotb.start_soon(self.run_output())
self.index = 0
self.accumulators = [0, 0]
async def cycle_reset(self):
await self._cycle_reset(self.dut.i_rst, self.dut.i_clk)
async def _cycle_reset(self, rst, clk):
rst.setimmediatevalue(0)
await RisingEdge(clk)
await RisingEdge(clk)
rst.value = 1
await RisingEdge(clk)
await RisingEdge(clk)
rst.value = 0
await RisingEdge(clk)
await RisingEdge(clk)
async def write_input(self, msg: int, r_power: int, clear_acc: int):
await self.input_queue.put((msg, r_power, clear_acc))
if clear_acc:
expected_result = friendly_modular_mult((msg) % PRIME, r_power)
else:
expected_result = friendly_modular_mult((msg + self.accumulators[self.index]) % PRIME, r_power)
self.accumulators[self.index] = expected_result
await self.expected_queue.put(expected_result)
self.index = 1 if self.index == 0 else 0
async def run_input(self):
while True:
msg, r_power, clear_acc = await self.input_queue.get()
self.dut.i_valid.value = 1
self.dut.i_r_power.value = r_power
self.dut.i_message.value = msg
self.dut.i_clear_acc.value = clear_acc
while True:
await RisingEdge(self.dut.i_clk)
if (self.dut.o_ready.value == 1):
break
self.dut.i_valid.value = 0
self.dut.i_r_power.value = 0
self.dut.i_message.value = 0
self.dut.i_clear_acc.value = 0
async def run_output(self):
while True:
await RisingEdge(self.dut.i_clk)
if self.dut.o_valid.value:
await self.output_queue.put(self.dut.o_result.value.integer)
@cocotb.test
async def test_sanity(dut):
tb = TB(dut)
await tb.cycle_reset()
count = 1024
for _ in range(count):
clr = 1 if random.randint(0,10) == 0 else 0
await tb.write_input(random.randint(1,2**128-1), random.randint(0, 2**130-6), clr)
fail = False
for _ in range(count):
sim_val = await tb.expected_queue.get()
dut_val = await tb.output_queue.get()
if sim_val != dut_val:
tb.log.info(f"{_} {sim_val:x} -> {dut_val:x}")
fail = True
assert not fail