예제 #1
0
def test_cpu(sync_sim):
    m = nm.Module()
    reg = 2
    cpu_inst = m.submodules.cpu = cpu.CPU(debug_reg=reg)

    link_reg = 5
    program = [
        encoding.IType.encode(1, reg, encoding.IntRegImmFunct.ADDI, reg,
                              encoding.Opcode.OP_IMM),
        # jump back to the previous instruction for infinite loop
        encoding.JType.encode(0x1ffffc, link_reg)
    ]

    imem = nm.Memory(width=32, depth=1024, init=program)
    imem_rp = m.submodules.imem_rp = imem.read_port(domain="sync")
    m.d.comb += [
        imem_rp.addr.eq(cpu_inst.imem_addr[2:]),
        cpu_inst.imem_data.eq(imem_rp.data),
    ]

    def testbench():
        for _ in range(20):
            yield

    sync_sim(m, testbench)
예제 #2
0
    def elaborate(self, platform):
        m = nm.Module()
        tx_div = nm.Signal(range(self.divider))
        tx_reg = nm.Signal(self.n + 2, reset=1)
        tx_cnt = nm.Signal(range(self.n + 3))
        m.d.comb += self.tx_o.eq(tx_reg[0])
        with m.If(tx_cnt == 0):
            # Idle
            with m.If(self.valid):
                m.d.sync += [
                    tx_reg.eq(nm.Cat(0, self.data, 1)),
                    tx_cnt.eq(self.n + 2),
                    tx_div.eq(self.divider - 1),
                ]
        with m.Else():
            # Transmitting
            with m.If(tx_div != 0):
                # Wait for clock divider
                m.d.sync += tx_div.eq(tx_div - 1)
            with m.Else():
                # Update output state
                m.d.sync += [
                    tx_reg.eq(nm.Cat(tx_reg[1:], 1)),
                    tx_cnt.eq(tx_cnt - 1),
                    tx_div.eq(self.divider - 1),
                ]

        return m
예제 #3
0
    def elaborate(self, platform):
        m = nm.Module()
        clk_freq = platform.default_clk_frequency
        speed = int(clk_freq // (1 << 4))
        frame_counter = nm.Signal(range(speed), reset=speed - 1)
        stepctr = nm.Signal(4)
        step = nm.Signal(3)

        matrix = m.submodules.matrix = LEDMatrix(4, 8, clk_freq)

        with m.If(stepctr >= 8):
            m.d.comb += step.eq(7 - stepctr[0:3])
        with m.Else():
            m.d.comb += step.eq(stepctr)

        m.d.comb += [
            matrix.columns[0].eq(1 << step),
            matrix.columns[1].eq(1 << step | 2 << step),
            matrix.columns[2].eq(~0 ^ 4 << step),
            matrix.columns[3].eq(~0 ^ (1 << step | 8 << step)),
        ]

        with m.If(frame_counter == 0):
            m.d.sync += [
                stepctr.eq(stepctr + 1),
                frame_counter.eq(frame_counter.reset)
            ]
        with m.Else():
            m.d.sync += [frame_counter.eq(frame_counter - 1)]
        return m
예제 #4
0
    def elaborate(self, platform):
        m = nm.Module()

        # Use OSCG so we can still clock with PHYs in reset
        # (otherwise, the PHYs stop running the XO).
        m.domains.sync = cd_osc = nm.ClockDomain("sync")
        m.submodules.oscg = nm.Instance("OSCG", p_DIV=12, o_OSC=cd_osc.clk)

        # Hold PHYs in reset
        m.d.comb += platform.request("eth_common").rst.eq(1)

        # Hold SDRAM in WE to prevent it driving DQ and leave clock low.
        sdram = platform.request("sdram")
        m.d.comb += sdram.we.eq(1), sdram.clk.eq(0)

        # Flash LED
        led = platform.request("led")
        ctr = nm.Signal(22)
        m.d.sync += ctr.eq(ctr + 1)
        m.d.comb += led.o.eq(ctr[-1])

        # UART on unknown outputs
        v = nm.Signal()
        p = nm.Signal()
        m.d.sync += p.eq(ctr[-4]), v.eq(p != ctr[-4])
        for idx, pin in enumerate(platform.outputs):
            print(f"{idx:02X} {pin}")
            uart = UART(idx)
            m.submodules += uart
            pin = platform.request(pin)
            m.d.comb += pin.o.eq(uart.tx_o), uart.valid.eq(v)

        return m
예제 #5
0
    def elaborate(self, _):
        m = nm.Module()
        registers = nm.Memory(
                width=self.register_width,
                depth=self.num_registers)

        rp1 = m.submodules.rp1 = registers.read_port(domain="comb")
        rp2 = m.submodules.rp2 = registers.read_port(domain="comb")
        debug_rp = m.submodules.debug_rp = registers.read_port(domain="comb")
        wp = m.submodules.wp = registers.write_port(domain="sync")

        # The first register, x0, has a special function: Reading it always
        # returns 0 and writes to it are ignored.
        # https://github.com/riscv/riscv-asm-manual/blob/master/riscv-asm.md
        m.d.comb += wp.en.eq(
                nm.Mux(self.write_select == 0, 0, self.write_enable))

        m.d.comb += [
                rp1.addr.eq(self.read_select_1),
                rp2.addr.eq(self.read_select_2),
                wp.addr.eq(self.write_select),
                debug_rp.addr.eq(self.debug_reg),
                self.read_data_1.eq(rp1.data),
                self.read_data_2.eq(rp2.data),
                wp.data.eq(self.write_data),
                self.debug_out.eq(debug_rp.data),
        ]

        return m
예제 #6
0
    def elaborate(self, _):
        m = nm.Module()

        with m.Switch(self.op):
            with m.Case(ALUOp.ADD):
                m.d.comb += self.o.eq(self.a + self.b)
            with m.Case(ALUOp.SUB):
                m.d.comb += self.o.eq(self.a - self.b)
        return m
예제 #7
0
def test_jtype_same_offset_out_as_in(comb_sim, offset):
    m = nm.Module()
    jal = nm.Const(encoding.JType.encode(offset, 5), shape=32)
    extended_offset = int(f"{offset:021b}"[0] * 11 + f"{offset:021b}", 2)
    assert (extended_offset & 0x1ffffe) == offset

    def testbench():
        assert (yield encoding.JType(jal).immediate()) == extended_offset

    comb_sim(m, testbench)
예제 #8
0
    def elaborate(self, platform):
        m = nm.Module()

        cd_sync = nm.ClockDomain("sync")
        m.domains += cd_sync

        clk100 = platform.request("clk100")
        cd_fast = nm.ClockDomain("fast")
        m.domains += cd_fast
        m.d.comb += cd_fast.clk.eq(clk100.i)

        m.submodules.pll = nm.Instance("SB_PLL40_CORE",
                                       p_FEEDBACK_PATH="SIMPLE",
                                       p_DIVR=3,
                                       p_DIVF=40,
                                       p_DIVQ=6,
                                       p_FILTER_RANGE=2,
                                       i_RESETB=1,
                                       i_BYPASS=0,
                                       i_REFERENCECLK=clk100.i,
                                       o_PLLOUTCORE=cd_sync.clk)

        reg = 2
        cpu_inst = m.submodules.cpu = cpu.CPU(debug_reg=reg)
        link_reg = 5
        program = [
            encoding.IType.encode(1, reg, encoding.IntRegImmFunct.ADDI, reg,
                                  encoding.Opcode.OP_IMM),
            # jump back to the previous instruction for infinite loop
            encoding.JType.encode(0x1ffffc, link_reg)
        ]

        imem = nm.Memory(width=32, depth=256, init=program)
        imem_rp = m.submodules.imem_rp = imem.read_port()
        m.d.comb += [
            imem_rp.addr.eq(cpu_inst.imem_addr),
            cpu_inst.imem_data.eq(imem_rp.data),
        ]

        dmem = nm.Memory(width=32, depth=256)
        dmem_rp = m.submodules.dmem_rp = dmem.read_port(transparent=False,
                                                        domain="fast")
        dmem_wp = m.submodules.dmem_wp = dmem.write_port(domain="fast")
        m.d.comb += [
            dmem_rp.addr.eq(cpu_inst.dmem_r_addr),
            cpu_inst.dmem_r_data.eq(dmem_rp.data),
            dmem_wp.addr.eq(cpu_inst.dmem_w_addr),
            dmem_wp.data.eq(cpu_inst.dmem_w_data),
        ]

        colours = ["b", "g", "o", "r"]
        leds = nm.Cat(platform.request(f"led_{c}") for c in colours)
        m.d.sync += leds.eq(cpu_inst.debug_out[13:17])

        return m
예제 #9
0
def test_itype_same_immediate_out_as_in(comb_sim, imm):
    m = nm.Module()
    addi = nm.Const(encoding.IType.encode(imm, 1, encoding.IntRegImmFunct.ADDI,
                                          2, encoding.Opcode.OP_IMM),
                    shape=32)
    extended_imm = int(f"{imm:012b}"[0] * 20 + f"{imm:012b}", 2)
    assert (extended_imm & 0x7ff) == imm

    def testbench():
        assert (yield encoding.IType(addi).immediate()) == extended_imm

    comb_sim(m, testbench)
예제 #10
0
    def elaborate(self, _):
        m = nm.Module()

        m.d.comb += self.pc_inc.eq(self.pc + INSTR_BYTES)
        m.d.sync += self.pc.eq(self.pc_next)

        with m.If(self.load):
            m.d.comb += self.pc_next.eq(self.input_address)
        with m.Else():
            m.d.comb += self.pc_next.eq(self.pc_inc)

        return m
예제 #11
0
    def elaborate(self, _):
        m = nm.Module()
        m.d.comb += self.dmem_r_addr.eq(self.byte_address[2:])

        with m.Switch(self.address_mode):
            with m.Case(AddressMode.BYTE):
                m.d.comb += self.load_value.eq(
                    self.dmem_r_data.word_select(self.byte_address[0:2], 8))
            with m.Case(AddressMode.HALF):
                m.d.comb += self.load_value.eq(
                    self.dmem_r_data.word_select(self.byte_address[1], 16))
            with m.Case(AddressMode.WORD):
                m.d.comb += self.load_value.eq(self.dmem_r_data)

        return m
예제 #12
0
    def elaborate(self, _):
        m = nm.Module()

        alu_inst = m.submodules.alu = alu.ALU(32)
        dmem = m.submodules.dmem = data_memory.DataMemory()
        idec = m.submodules.idec = instruction_decoder.InstructionDecoder()
        pc = m.submodules.pc = program_counter.ProgramCounter()
        rf = m.submodules.rf = register_file.RegisterFile(
            debug_reg=self.debug_reg)

        m.d.comb += [
            rf.read_select_1.eq(idec.rf_read_select_1),
            rf.read_select_2.eq(idec.rf_read_select_2),
            rf.write_enable.eq(idec.rf_write_enable),
            rf.write_select.eq(idec.rf_write_select),
            alu_inst.a.eq(idec.alu_imm),
            alu_inst.op.eq(idec.alu_op),
            self.dmem_r_addr.eq(dmem.dmem_r_addr),
            dmem.byte_address.eq(alu_inst.o),
            dmem.signed.eq(idec.dmem_signed),
            dmem.address_mode.eq(idec.dmem_address_mode),
            dmem.dmem_r_data.eq(self.dmem_r_data),
            pc.load.eq(idec.pc_load),
            pc.input_address.eq(alu_inst.o),
            self.imem_addr.eq(pc.pc_next),
            idec.instr.eq(self.imem_data),
            self.debug_out.eq(rf.debug_out),
        ]

        with m.Switch(idec.rd_mux_op):
            with m.Case(instruction_decoder.RdValue.PC_INC):
                m.d.comb += rf.write_data.eq(pc.pc_inc)
            with m.Case(instruction_decoder.RdValue.ALU_OUTPUT):
                m.d.comb += rf.write_data.eq(alu_inst.o)
            with m.Case(instruction_decoder.RdValue.LOAD):
                m.d.comb += rf.write_data.eq(dmem.load_value)

        with m.Switch(idec.alu_mux_op):
            with m.Case(instruction_decoder.ALUInput.READ_DATA_1):
                m.d.comb += alu_inst.b.eq(rf.read_data_1)
            with m.Case(instruction_decoder.ALUInput.PC):
                m.d.comb += alu_inst.b.eq(pc.pc)

        return m
예제 #13
0
파일: ledmatrix.py 프로젝트: zx64/fpga
    def elaborate(self, platform):
        m = nm.Module()

        matrix = platform.request("led_matrix", 0)
        cols = matrix.columns
        rows = matrix.rows

        row_idx = nm.Signal(range(len(rows)))

        m.d.comb += [
            cols.eq(self.columns[row_idx]),
            rows.eq(1 << row_idx),
        ]

        with m.If(self.row_counter == 0):
            m.d.sync += [
                self.row_counter.eq(self.row_counter.reset),
                row_idx.eq(row_idx + 1),
            ]
        with m.Else():
            m.d.sync += [self.row_counter.eq(self.row_counter - 1)]

        return m
예제 #14
0
    def elaborate(self, _):
        m = nm.Module()

        opcode = encoding.opcode(self.instr)
        m.d.comb += self.rf_write_select.eq(encoding.rd(self.instr))
        m.d.comb += self.rf_read_select_1.eq(encoding.rs1(self.instr))
        m.d.comb += self.rf_read_select_2.eq(encoding.rs2(self.instr))

        with m.Switch(opcode):
            with m.Case(encoding.Opcode.OP_IMM):
                m.d.comb += self.rf_write_enable.eq(1)

                itype = encoding.IType(self.instr)
                with m.Switch(itype.funct()):
                    with m.Case(encoding.IntRegImmFunct.ADDI):
                        m.d.comb += [
                            self.pc_load.eq(0),
                            self.alu_op.eq(alu.ALUOp.ADD),
                            self.alu_imm.eq(itype.immediate()),
                            self.rd_mux_op.eq(RdValue.ALU_OUTPUT),
                            self.alu_mux_op.eq(ALUInput.READ_DATA_1),
                        ]

            with m.Case(encoding.Opcode.JAL):
                m.d.comb += self.rf_write_enable.eq(1)

                jtype = encoding.JType(self.instr)
                m.d.comb += [
                    self.pc_load.eq(1),
                    self.alu_op.eq(alu.ALUOp.ADD),
                    self.alu_imm.eq(jtype.immediate()),
                    self.rd_mux_op.eq(RdValue.PC_INC),
                    self.alu_mux_op.eq(ALUInput.PC)
                ]

        return m
예제 #15
0
    def elaborate(self, _):
        m = nm.Module()
        shamt_width = 5

        with m.Switch(self.op):
            with m.Case(ALUOp.ADD):
                m.d.comb += self.o.eq(self.a + self.b)
            with m.Case(ALUOp.SUB):
                m.d.comb += self.o.eq(self.a - self.b)
            with m.Case(ALUOp.AND):
                m.d.comb += self.o.eq(self.a & self.b)
            with m.Case(ALUOp.OR):
                m.d.comb += self.o.eq(self.a | self.b)
            with m.Case(ALUOp.XOR):
                m.d.comb += self.o.eq(self.a ^ self.b)
            with m.Case(ALUOp.SLL):
                m.d.comb += self.o.eq(self.b << self.a[:shamt_width])
            with m.Case(ALUOp.SRL):
                m.d.comb += self.o.eq(self.b >> self.a[:shamt_width])
            with m.Case(ALUOp.SRA):
                m.d.comb += self.o.eq(
                    self.b.as_signed() >> self.a[:shamt_width])

        return m
예제 #16
0
파일: testnmigen.py 프로젝트: zx64/fpga
 def elaborate(self, platform):
     m = nm.Module()
     m.d.comb += self.output.eq(~self.input)
     return m
예제 #17
0
    def elaborate(self, _):
        m = nm.Module()

        opcode = encoding.opcode(self.instr)
        m.d.comb += self.rf_write_select.eq(encoding.rd(self.instr))
        m.d.comb += self.rf_read_select_1.eq(encoding.rs1(self.instr))
        m.d.comb += self.rf_read_select_2.eq(encoding.rs2(self.instr))

        with m.Switch(opcode):
            with m.Case(encoding.Opcode.OP_IMM):
                m.d.comb += self.rf_write_enable.eq(1)

                itype = encoding.IType(self.instr)
                with m.Switch(itype.funct()):
                    m.d.comb += [
                        self.pc_load.eq(0),
                        self.rd_mux_op.eq(RdValue.ALU_OUTPUT),
                        self.alu_mux_op.eq(ALUInput.READ_DATA_1),
                    ]

                    with m.Case(encoding.IntRegImmFunct.ADDI):
                        m.d.comb += [
                            self.alu_op.eq(alu.ALUOp.ADD),
                            self.alu_imm.eq(itype.immediate()),
                        ]

                    with m.Case(encoding.IntRegImmFunct.XORI):
                        m.d.comb += [
                            self.alu_op.eq(alu.ALUOp.XOR),
                            self.alu_imm.eq(itype.immediate()),
                        ]

                    with m.Case(encoding.IntRegImmFunct.ORI):
                        m.d.comb += [
                            self.alu_op.eq(alu.ALUOp.OR),
                            self.alu_imm.eq(itype.immediate()),
                        ]

                    with m.Case(encoding.IntRegImmFunct.ORI):
                        m.d.comb += [
                            self.alu_op.eq(alu.ALUOp.OR),
                            self.alu_imm.eq(itype.immediate()),
                        ]

                    with m.Case(encoding.IntRegImmFunct.ANDI):
                        m.d.comb += [
                            self.alu_op.eq(alu.ALUOp.AND),
                            self.alu_imm.eq(itype.immediate()),
                        ]

                    with m.Case(encoding.IntRegImmFunct.SLLI):
                        m.d.comb += [
                            self.alu_op.eq(alu.ALUOp.SLL),
                            self.alu_imm.eq(itype.shift_amount()),
                        ]

                    with m.Case(encoding.IntRegImmFunct.SRLI_OR_SRAI):
                        m.d.comb += self.alu_imm.eq(itype.shift_amount())
                        with m.Switch(itype.right_shift_type()):
                            with m.Case(encoding.RightShiftType.SRLI):
                                m.d.comb += self.alu_op.eq(alu.ALUOp.SRL)
                            with m.Case(encoding.RightShiftType.SRAI):
                                m.d.comb += self.alu_op.eq(alu.ALUOp.SRA)

            with m.Case(encoding.Opcode.JAL):
                m.d.comb += self.rf_write_enable.eq(1)

                jtype = encoding.JType(self.instr)
                m.d.comb += [
                    self.pc_load.eq(1),
                    self.alu_op.eq(alu.ALUOp.ADD),
                    self.alu_imm.eq(jtype.immediate()),
                    self.rd_mux_op.eq(RdValue.PC_INC),
                    self.alu_mux_op.eq(ALUInput.PC),
                ]

            with m.Case(encoding.Opcode.LOAD):
                m.d.comb += [
                    self.rf_write_enable.eq(1),
                    self.pc_load.eq(0),
                    self.alu_op.eq(alu.ALUOp.ADD),
                    self.alu_imm.eq(itype.immediate()),
                    self.rd_mux_op.eq(RdValue.LOAD),
                    self.alu_mux_op.eq(ALUInput.READ_DATA_1),
                ]

                itype = encoding.IType(self.instr)
                funct = itype.funct()
                with m.If(funct == encoding.LoadFunct.LW):
                    m.d.comb += self.dmem_address_mode.eq(
                        data_memory.AddressMode.WORD)
                with m.Elif((funct == encoding.LoadFunct.LH)
                            | (funct == encoding.LoadFunct.LHU)):
                    m.d.comb += self.dmem_address_mode.eq(
                        data_memory.AddressMode.HALF)
                with m.Elif((funct == encoding.LoadFunct.LB)
                            | (funct == encoding.LoadFunct.LBU)):
                    m.d.comb += self.dmem_address_mode.eq(
                        data_memory.AddressMode.BYTE)

                m.d.comb += self.dmem_signed.eq(funct[2] == 0)

        return m