Ejemplo n.º 1
0
def main():
    cfu = make_cfu()
    new_verilog = verilog.convert(cfu, name='Cfu', ports=cfu.ports)
    old_verilog = read_file()
    if new_verilog != old_verilog:
        with open(VERILOG_FILENAME, "w") as f:
            f.write(new_verilog)
Ejemplo n.º 2
0
def main():
    gen_list = list(make_cfu_fns.keys()).sort()
    parser = argparse.ArgumentParser(description='Generate cfu.v')
    parser.add_argument(
        'gen',
        metavar='GEN',
        type=str,
        choices=gen_list,
        help=f'Which kind of CFU to generate - one of {gen_list}')
    parser.add_argument('--specialize-nx',
                        action='store_true',
                        help='Generate code for Crosslink/NX-17.')
    args = parser.parse_args()
    if args.gen not in make_cfu_fns.keys():
        print(f'Unexpected GEN {args.gen}')
        sys.exit(5)
    cfu = make_cfu_fns[args.gen](specialize_nx=args.specialize_nx)

    new_verilog = verilog.convert(cfu, name='Cfu', ports=cfu.ports)
    old_verilog = read_file()
    if new_verilog != old_verilog:
        with open(VERILOG_FILENAME, "w") as f:
            f.write(new_verilog)
Ejemplo n.º 3
0
            self.take_branch
        ]

    def elaborate(self, platform: Platform) -> Module:
        m = Module()

        with m.Switch(self.br_insn):
            with m.Case(BInsn.BEQ):
                m.d.comb += self.take_branch.eq(self.in1 == self.in2)
            with m.Case(BInsn.BNE):
                m.d.comb += self.take_branch.eq(self.in1 != self.in2)
            with m.Case(BInsn.BLT):
                m.d.comb += self.take_branch.eq(self.in1.as_signed() < self.in2.as_signed())
            with m.Case(BInsn.BGE):
                m.d.comb += self.take_branch.eq(self.in1.as_signed() >= self.in2.as_signed())
            with m.Case(BInsn.BLTU):
                m.d.comb += self.take_branch.eq(self.in1 < self.in2)
            with m.Case(BInsn.BGEU):
                m.d.comb += self.take_branch.eq(self.in1 >= self.in2)
            with m.Default():
                m.d.comb += self.take_branch.eq(0)

        return m


if __name__ == "__main__":
    br = Branch(xlen=XLEN.RV32)

    with open("branch.v", "w") as file:
        file.write(verilog.convert(br, ports=br.ports()))
Ejemplo n.º 4
0
            yield uart.tx_data.eq(0x5A)
            yield uart.tx_rdy.eq(1)
            yield
            yield uart.tx_rdy.eq(0)
            yield
            assert not (yield uart.tx_ack)

            for _ in range(uart.divisor * 12): yield

            assert (yield uart.tx_ack)
            assert (yield uart.rx_rdy)
            assert not (yield uart.rx_err)
            assert (yield uart.rx_data) == 0x5A

            yield uart.rx_ack.eq(1)
            yield
            yield uart.rx_ack.eq(0)
            yield
            assert not (yield uart.rx_rdy)

        sim.add_sync_process(transmit_proc)

        with sim.write_vcd("uart.vcd", "uart.gtkw"):
            sim.run()

    if args.action == "generate":
        from amaranth.back import verilog

        print(verilog.convert(uart, ports=ports))
Ejemplo n.º 5
0
                m.d.comb += self.o_out.eq(Mux(alt_func & self.i_op,
                                              self.i_in1 - self.i_in2,
                                              self.i_in1 + self.i_in2))
            with m.Case(Funct3.OR):
                m.d.comb += self.o_out.eq(self.i_in1 | self.i_in2)
            with m.Case(Funct3.AND):
                m.d.comb += self.o_out.eq(self.i_in1 & self.i_in2)
            with m.Case(Funct3.XOR):
                m.d.comb += self.o_out.eq(self.i_in1 ^ self.i_in2)
            with m.Case(Funct3.SLT):
                m.d.comb += self.o_out.eq(Mux(self.i_in1.as_signed() < self.i_in2.as_signed(),
                                              0b1, 0b0))
            with m.Case(Funct3.SLTU):
                m.d.comb += self.o_out.eq(Mux(self.i_in1 < self.i_in2, 0b1, 0b0))
            with m.Case(Funct3.SLL):
                m.d.comb += self.o_out.eq(self.i_in1 << self.i_in2[:5])
            with m.Case(Funct3.SR):
                # Funct7 is only valid if instruction type is OP or OP-IMM
                m.d.comb += self.o_out.eq(Mux(alt_func & (self.i_op | self.i_op_imm), 
                                              self.i_in1.as_signed() >> self.i_in2[:5],
                                              self.i_in1 >> self.i_in2[:5]))

        return m


if __name__ == "__main__":
    alu = ALU(xlen=XLEN.RV32)

    with open("alu.v", "w") as file:
        file.write(verilog.convert(alu, ports=alu.ports()))
Ejemplo n.º 6
0
    # Disabled counter should not overflow.
    yield dut.en.eq(0)
    for _ in range(30):
        yield
        assert not (yield dut.ovf)

    # Once enabled, the counter should overflow in 25 cycles.
    yield dut.en.eq(1)
    for _ in range(25):
        yield
        assert not (yield dut.ovf)
    yield
    assert (yield dut.ovf)

    # The overflow should clear in one cycle.
    yield
    assert not (yield dut.ovf)


sim = Simulator(dut)
sim.add_clock(1e-6)  # 1 MHz
sim.add_sync_process(bench)
with sim.write_vcd("up_counter.vcd"):
    sim.run()
# --- CONVERT ---
from amaranth.back import verilog

top = UpCounter(25)
with open("up_counter.v", "w") as f:
    f.write(verilog.convert(top, ports=[top.en, top.ovf]))
Ejemplo n.º 7
0
class Counter(Elaboratable):
    def __init__(self, width):
        self.v = Signal(width, reset=2**width - 1)
        self.o = Signal()
        self.en = Signal()

    def elaborate(self, platform):
        m = Module()
        m.d.sync += self.v.eq(self.v + 1)
        m.d.comb += self.o.eq(self.v[-1])
        return EnableInserter(self.en)(m)


ctr = Counter(width=16)

print(verilog.convert(ctr, ports=[ctr.o, ctr.en]))

sim = Simulator(ctr)
sim.add_clock(1e-6)


def ce_proc():
    yield
    yield
    yield
    yield ctr.en.eq(1)
    yield
    yield
    yield
    yield ctr.en.eq(0)
    yield
Ejemplo n.º 8
0
        m.d.comb += ex_hazard.eq(self.i_reg_wr_MEM & (self.i_rd_MEM != 0))
        m.d.comb += ex_rs1_hazard.eq(self.i_rd_MEM == self.i_rs1_EX)
        m.d.comb += ex_rs2_hazard.eq(self.i_rd_MEM == self.i_rs2_EX)
        m.d.comb += mem_hazard.eq(self.i_reg_wr_WB & (self.i_rd_WB != 0))
        m.d.comb += mem_rs1_hazard.eq(self.i_rd_WB == self.i_rs1_EX)
        m.d.comb += mem_rs2_hazard.eq(self.i_rd_WB == self.i_rs2_EX)

        # EX hazard
        with m.If(ex_hazard):
            with m.If(ex_rs1_hazard):
                m.d.comb += self.o_fwdA.eq(0b10)
            with m.If(ex_rs2_hazard):
                m.d.comb += self.o_fwdB.eq(0b10)

        # MEM hazard
        with m.If(mem_hazard):
            with m.If(mem_rs1_hazard & ~(ex_hazard & ex_rs1_hazard)):
                m.d.comb += self.o_fwdA.eq(0b01)
            with m.If(mem_rs2_hazard & ~(ex_hazard & ex_rs2_hazard)):
                m.d.comb += self.o_fwdB.eq(0b01)

        return m


if __name__ == "__main__":
    fwd = Forwarding(xlen=XLEN.RV32)

    with open("fwd.v", "w") as file:
        file.write(verilog.convert(fwd, ports=fwd.ports()))