from amaranth import * from amaranth.sim import Simulator, Settle, Delay from hdl.utils import cmd, sim, step from hdl.lib.in_out_buff import InOutBuff 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_shiftreg_right(): dut = ShiftReg(8) def proc(): val = 0xAB yield dut.load_val.eq(val) yield dut.en.eq(0) yield dut.load.eq(1) yield from step() yield dut.load.eq(0) yield dut.en.eq(1) for _ in range(9): yield reg_val = yield dut.reg assert reg_val == val, f"Incorrect shift ---EXPECTED: {hex(val)} ---GOT: {hex(reg_val)}" val = val >> 1 sim(dut, proc) def test_shiftreg_left(): dut = ShiftReg(8) def proc(): val = 0xBD yield dut.load_val.eq(val) yield dut.en.eq(0) yield dut.load.eq(1) yield dut.right_left.eq(1) yield from step() yield dut.load.eq(0) yield dut.en.eq(1) for _ in range(9): yield reg_val = yield dut.reg assert reg_val == val, f"Incorrect shift ---EXPECTED: {hex(val)} ---GOT: {hex(reg_val)}" val = (val << 1) & 0xff sim(dut, proc) if __name__ == '__main__': shift_reg = ShiftReg(8) cmd(shift_reg)