from amaranth import * from amaranth.sim import Simulator, Settle, Delay from hdl.utils import cmd class ShiftReg(Elaboratable): def __init__(self, width): self.name = "shift_reg" self.load_val = Signal(width, reset=0, reset_less=True) self.load = Signal() self.reg = Signal(width) self.en = Signal() self.right_left = Signal() ports_in = [self.load_val, self.en, self.load, self.right_left] ports_out = [self.reg] self.ports = {'in': ports_in, 'out': ports_out} def elaborate(self, platform): m = Module() with m.If(self.load): m.d.sync += self.reg.eq(self.load_val) with m.Else(): with m.If(self.en): with m.If(self.right_left): m.d.sync += self.reg.eq(self.reg << 1) with m.Else(): m.d.sync += self.reg.eq(self.reg >> 1) return m def test_shift_reg(filename="out.vcd"): dut = ShiftReg(8) def proc1(): val = 0xAB yield dut.load_val.eq(val) yield dut.en.eq(0) yield dut.load.eq(1) yield yield Settle() yield dut.load.eq(0) yield dut.en.eq(1) for _ in range(9): reg_val = yield dut.reg assert reg_val == val, f"Incorrect shift ---EXPECTED: {hex(val)} ---GOT: {hex(reg_val)}" val = val >> 1 yield yield Settle() val = 0xBD yield dut.load_val.eq(val) yield dut.load.eq(1) yield dut.right_left.eq(1) yield yield Settle() yield dut.load.eq(0) for _ in range(9): reg_val = yield dut.reg assert reg_val == val, f"Incorrect shift ---EXPECTED: {hex(val)} ---GOT: {hex(reg_val)}" val = (val << 1) & 0xff yield yield Settle() sim = Simulator(dut) sim.add_clock(1e-6) sim.add_sync_process(proc1) with sim.write_vcd(filename): sim.run() if __name__ == '__main__': shift_reg = ShiftReg(8) cmd(shift_reg, test_shift_reg)