from amaranth import * from amaranth.sim import Simulator, Settle, Delay from enum import Enum, unique from hdl.utils import cmd, step, sim from hdl.lib.in_out_buff import InOutBuff # used for timing analysis from hdl.core.alu import ALUFlags, ALU @unique class JumpOpCodes(Enum): j_eq = 0 j_ne = 1 j_lt_u = 2 j_lte_u = 3 j_lt_s = 4 j_lte_s = 5 class HDL(Elaboratable): def __init__(self, **kargs): self.alu_flags = Signal(ALU().alu_flags.width, reset_less=True) self.jump_op = Signal(3, reset_less=True) self.jump = Signal(reset_less=True) # true if jump condition is met ports_in = [self.alu_flags, self.jump_op] ports_out = [self.jump] self.ports = {'in': ports_in, 'out': ports_out} self.sim = kargs["sim"] if "sim" in kargs else False def elaborate(self, platform=None): m = Module() # dummy sync for simulation only needed if there is no other sequential logic if self.sim == True: dummy = Signal() m.d.sync += dummy.eq(~dummy) with m.Switch(self.jump_op): with m.Case(JumpOpCodes.j_eq.value): m.d.comb += self.jump.eq(self.alu_flags[ALUFlags.zero]) with m.Case(JumpOpCodes.j_ne.value): m.d.comb += self.jump.eq(~self.alu_flags[ALUFlags.zero]) with m.Case(JumpOpCodes.j_lt_u.value): m.d.comb += self.jump.eq(self.alu_flags[ALUFlags.negative] & ~self.alu_flags[ALUFlags.zero]) with m.Case(JumpOpCodes.j_lte_u.value): m.d.comb += self.jump.eq(self.alu_flags[ALUFlags.negative] | self.alu_flags[ALUFlags.zero]) with m.Case(JumpOpCodes.j_lt_s.value): pass with m.Case(JumpOpCodes.j_lte_s.value): pass with m.Case(): m.d.comb += self.jump.eq(0) return m # test addition def test_hdl(): dut = HDL(sim=True) def proc(): yield from step #step clock yield Settle() #needed if for combinatorial logic yield dut.something #read value sim(dut, proc) if __name__ == '__main__': hdl = InOutBuff(HDL()) cmd(hdl)