Skip to content

Instantly share code, notes, and snippets.

@urish
Last active November 30, 2024 19:32
Show Gist options
  • Save urish/8cc23afe61449c10b70d9f23454912ee to your computer and use it in GitHub Desktop.
Save urish/8cc23afe61449c10b70d9f23454912ee to your computer and use it in GitHub Desktop.
from ttboard.demoboard import DemoBoard
from ttboard.mode import RPMode
import ttboard.cocotb.dut
REG_PC = 0
REG_SP = 1
REG_EXEC = 2
REG_STACK_TOP = 3
class SpellController(ttboard.cocotb.dut.DUT):
def __init__(self, tt: DemoBoard):
super().__init__('Spell')
self.tt = tt
self.i_run = self.new_bit_attribute(tt.ui_in, 0)
self.i_step = self.new_bit_attribute(tt.ui_in, 1)
self.i_load = self.new_bit_attribute(tt.ui_in, 2)
self.i_dump = self.new_bit_attribute(tt.ui_in, 3)
self.i_shift_in = self.new_bit_attribute(tt.ui_in, 4)
self.i_reg_sel_0 = self.new_bit_attribute(tt.ui_in, 5)
self.i_reg_sel_1 = self.new_bit_attribute(tt.ui_in, 6)
self.o_cpu_sleep = self.new_bit_attribute(tt.uo_out, 0)
self.o_cpu_stop = self.new_bit_attribute(tt.uo_out, 1)
self.o_wait_delay = self.new_bit_attribute(tt.uo_out, 2)
self.o_shift_out = self.new_bit_attribute(tt.uo_out, 3)
self.i_run.value = 0
self.i_step.value = 0
self.i_load.value = 0
self.i_dump.value = 0
self.i_shift_in.value = 0
self.i_reg_sel_0.value = 0
self.i_reg_sel_1.value = 0
def ensure_cpu_stopped(self):
while int(self.o_cpu_stop) == 0:
self.tt.clock_project_once()
def stopped(self):
return int(self.o_cpu_stop) == 0
def sleeping(self):
return int(self.o_cpu_stop) == 1
def set_reg_sel(self, value: int):
self.i_reg_sel_0.value = value & 1
self.i_reg_sel_1.value = (value >> 1) & 1
def write_reg(self, reg: int, value: int):
for i in range(8):
self.i_shift_in.value = (value >> (7 - i)) & 1
self.tt.clock_project_once()
self.set_reg_sel(reg)
self.i_load.value = 1
self.tt.clock_project_once()
self.i_load.value = 0
self.tt.clock_project_once()
def read_reg(self, reg: int):
self.set_reg_sel(reg)
self.i_dump.value = 1
self.tt.clock_project_once()
self.i_dump.value = 0
value = 0
for i in range(8):
self.tt.clock_project_once()
value |= int(self.o_shift_out) << (7 - i)
return value
def execute(self, wait=True):
self.ensure_cpu_stopped()
self.i_run.value = 1
self.i_step.value = 0
self.tt.clock_project_once()
self.i_run.value = 0
self.tt.clock_project_once()
if wait:
self.ensure_cpu_stopped()
def single_step(self):
self.ensure_cpu_stopped()
self.i_run.value = 1
self.i_step.value = 1
self.tt.clock_project_once()
self.i_step.value = 0
self.i_run.value = 0
self.tt.clock_project_once()
self.ensure_cpu_stopped()
def exec_opcode(self, opcode):
int_opcode = ord(opcode) if type(opcode) == str else int(opcode)
self.ensure_cpu_stopped()
self.write_reg(REG_EXEC, int_opcode)
self.ensure_cpu_stopped()
def read_stack_top(self):
return self.read_reg(REG_STACK_TOP)
def push(self, value: int):
self.ensure_cpu_stopped()
self.write_reg(REG_STACK_TOP, value)
def read_pc(self):
return self.read_reg(REG_PC)
def set_pc(self, value: int):
self.write_reg(REG_PC, value)
def read_sp(self):
return self.read_reg(REG_SP)
def set_sp(self, value: int):
self.write_reg(REG_SP, value)
def set_sp_read_stack(self, index: int):
self.set_sp(index)
return self.read_stack_top()
def write_progmem(self, addr: int, value: Union[int, str]):
"""
Writes a value to progmem by executing an instruction on the CPU.
"""
int_value = ord(value) if type(value) == str else int(value)
self.push(int_value)
self.push(addr)
self.exec_opcode("!")
def write_program(self, opcodes, offset=0):
for index, opcode in enumerate(opcodes):
self.write_progmem(offset + index, opcode)
def run():
global spell
tt = DemoBoard.get()
tt.mode = RPMode.ASIC_RP_CONTROL
tt.shuttle.tt_um_urish_spell.enable()
spell = SpellController(tt)
tt.reset_project(True)
tt.clock_project_once()
tt.reset_project(False)
# fmt: off
test_program = [
1, 55, 119, 1, 54, 119, 250, 44, 3, 61
# 127, 58, 119, 0, 129, 57, 57, 244, 62, 116, 109, 59, 119, 250,
# 44, 0, 59, 119, 25, 44, 11, 64, 3, 61
]
# fmt: on
spell.write_program(test_program)
print("Start")
spell.execute(False)
tt.clock_project_PWM(10_000_000) # 10 MHz
run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment