def elaborate(self, platform): m = Module() # Generate our domain clocks/resets. #m.submodules.car = platform.clock_domain_generator() m.submodules.car = LunaECP5DomainGenerator() # Create our USB-to-serial converter. ulpi = platform.request("usb0") m.submodules.usb_serial = usb_serial = \ USBSerialDevice(bus=ulpi, idVendor=0x16d0, idProduct=0x0f3b, manufacturer_string="GsD", product_string="ButterStick r1.0") m.d.comb += [ # Place the streams into a loopback configuration... usb_serial.tx.payload.eq(usb_serial.rx.payload), usb_serial.tx.valid.eq(usb_serial.rx.valid), usb_serial.tx.first.eq(usb_serial.rx.first), usb_serial.tx.last.eq(usb_serial.rx.last), usb_serial.rx.ready.eq(usb_serial.tx.ready), # ... and always connect by default. usb_serial.connect.eq(1) ] return m
def __init__(self, bus): from luna.full_devices import USBSerialDevice self.in_ready = Signal() self.tx_empty = Signal() self.parity_err = Signal() self.frame_err = Signal() self.overflow = Signal() self.data_avail = Signal() self.out_ready = Signal() self.status = Cat(self.in_ready, self.tx_empty, self.parity_err, self.frame_err, self.overflow, self.data_avail, Const(0), self.out_ready ) self.tx = Signal(8) self.tx_ready = Signal() self.rx = Signal(8) self.rx_ready = Signal() self.serial = USBSerialDevice(bus=bus, idVendor=1337, idProduct=1337, manufacturer_string="potatocore", product_string="intel 8080 serial port" )
def __init__(self, bus): from luna.full_devices import USBSerialDevice self.serial = USBSerialDevice(bus=bus, idVendor=1337, idProduct=1337, manufacturer_string="potatocore", product_string="intel 8080 serial port") self.i_fifo = AsyncFIFO(width=8, depth=8, r_domain="usb", w_domain="sync") self.o_fifo = AsyncFIFO(width=8, depth=8, r_domain="sync", w_domain="usb")
def elaborate(self, platform): m = Module() # Create our USB-to-serial converter. ulpi = platform.request(platform.default_usb_connection) m.submodules.usb_serial = usb_serial = USBSerialDevice( bus=ulpi, idVendor=0x16D0, idProduct=0x0F3B) m.d.comb += [ # Place the streams into a loopback configuration... usb_serial.tx.payload.eq(usb_serial.rx.payload), usb_serial.tx.valid.eq(usb_serial.rx.valid), usb_serial.tx.first.eq(usb_serial.rx.first), usb_serial.tx.last.eq(usb_serial.rx.last), usb_serial.rx.ready.eq(usb_serial.tx.ready), # ... and always connect by default. usb_serial.connect.eq(1), ] return m
def elaborate(self, platform): m = Module() m.submodules.car = platform.clock_domain_generator() sync_n = ClockDomain("sync_n", clk_edge="neg") m.d.comb += [ sync_n.clk.eq(ClockSignal("sync")), sync_n.rst.eq(ResetSignal("sync")) ] m.domains.sync_n = sync_n # Create our USB-to-serial converter. usb0 = platform.request(platform.default_usb_connection) m.submodules.usb_serial = usb_serial = \ USBSerialDevice(bus=usb0, idVendor=0x16d0, idProduct=0x0f3b) m.submodules.usb_to_sys_fifo = usb_to_sys_fifo = AsyncFIFO( width=(usb_serial.rx.payload.width + 2), depth=2, r_domain="sync_n", w_domain="usb") m.submodules.sys_to_usb_fifo = sys_to_usb_fifo = AsyncFIFO( width=(usb_serial.tx.payload.width + 2), depth=2, r_domain="usb", w_domain="sync_n") m.d.comb += [ usb_serial.tx.payload.eq(sys_to_usb_fifo.r_data[2:]), usb_serial.tx.valid.eq(sys_to_usb_fifo.r_rdy), usb_serial.tx.first.eq(sys_to_usb_fifo.r_data[0]), usb_serial.tx.last.eq(sys_to_usb_fifo.r_data[1]), sys_to_usb_fifo.r_en.eq(usb_serial.tx.ready), usb_to_sys_fifo.w_data[2:].eq(usb_serial.rx.payload), usb_to_sys_fifo.w_en.eq(usb_serial.rx.valid), usb_to_sys_fifo.w_data[0].eq(usb_serial.rx.first), usb_to_sys_fifo.w_data[1].eq(usb_serial.rx.last), usb_serial.rx.ready.eq(usb_to_sys_fifo.w_rdy), # ... and always connect by default. usb_serial.connect.eq(1) ] m.submodules.instruction_file_r = instruction_file_r = Memory( width=8, depth=len(self.brainfuck_code), init=self.brainfuck_code).read_port() register_file_mem = Memory(width=usb_serial.rx.payload.width, depth=self.brainfuck_array_size) m.submodules.register_file_r = register_file_r = register_file_mem.read_port( ) m.submodules.register_file_w = register_file_w = register_file_mem.write_port( ) m.submodules.CPU = CPU = Brainfuck_processor( len(self.brainfuck_code), data_width=register_file_r.data.width, i_addr_width=instruction_file_r.addr.width, d_addr_width=register_file_r.addr.width, stack_depth=32) m.d.comb += [ sys_to_usb_fifo.w_data[0].eq(1), sys_to_usb_fifo.w_data[1].eq(1), sys_to_usb_fifo.w_data[2:].eq(CPU.output_stream.data), sys_to_usb_fifo.w_en.eq(CPU.output_stream.valid), CPU.output_stream.ready.eq(sys_to_usb_fifo.w_rdy), CPU.input_stream.data.eq(usb_to_sys_fifo.r_data[2:]), CPU.input_stream.valid.eq(usb_to_sys_fifo.r_rdy), usb_to_sys_fifo.r_en.eq(CPU.input_stream.ready), instruction_file_r.addr.eq(CPU.instruction_port.addr), CPU.instruction_port.r_data.eq(instruction_file_r.data), register_file_r.addr.eq(CPU.data_port.addr), CPU.data_port.r_data.eq(register_file_r.data), register_file_w.addr.eq(CPU.data_port.addr), register_file_w.data.eq(CPU.data_port.w_data), register_file_w.en.eq(CPU.data_port.w_en) ] rgb = platform.request('rgb_led', 0) red_led = rgb.r green_led = rgb.g blue_led = rgb.b m.submodules.pwm0 = pwm0 = PWM(8) m.submodules.pwm1 = pwm1 = PWM(8) m.submodules.pwm2 = pwm2 = PWM(8) m.d.comb += [ pwm0.dutyCycle.eq(102), pwm1.dutyCycle.eq(101), pwm2.dutyCycle.eq(100), red_led.o.eq(Mux(instruction_file_r.addr[0], pwm0.pwm, 0)), green_led.o.eq(Mux(CPU.error, pwm1.pwm, 0)), blue_led.o.eq(Mux(CPU.error, pwm2.pwm, 0)), ] return m
def elaborate(self, platform): m = Module() if (platform != None): # Create and check clocks m.submodules.clocks = ML505LunaClockDomains() led = platform.request("led", 0) timer = Signal(range(int(12e6//2)), reset_less=True) flop = Signal(reset_less=True) m.d.comb += led.o.eq(flop) with m.If(timer == 0): m.d.usb_io += timer.eq(int( (12e6) //2) - 1) m.d.usb_io += flop.eq(~flop) with m.Else(): m.d.usb_io += timer.eq(timer - 1) if platform != None: # Add USB connector platform.add_resources([ Resource("usb_gpio", 0, Subsignal("d_p", Pins("12", conn=("gpio", 0) )), Subsignal("d_n", Pins("14", conn=("gpio", 0) )), Subsignal("pullup", Pins("16", conn=("gpio", 0), dir="o")), Attrs(IOSTANDARD="LVCMOS33"), ), ]) # Instantiate the serial converter direct_usb = platform.request("usb_gpio") m.submodules.usb_serial = usb_serial = \ USBSerialDevice(bus=direct_usb, idVendor=0x16d0, idProduct=0x0f3b) m.d.comb += [ # Place the streams into a loopback configuration... usb_serial.tx.payload .eq(usb_serial.rx.payload), usb_serial.tx.valid .eq(usb_serial.rx.valid), usb_serial.tx.first .eq(usb_serial.rx.first), usb_serial.tx.last .eq(usb_serial.rx.last), usb_serial.rx.ready .eq(usb_serial.tx.ready), # ... and always connect by default. usb_serial.connect .eq(Const(1)) ] # Sync counter to test ILA counter = Signal(5, reset_less=True) trigger = Signal() m.d.usb_io += [ counter.eq(counter+1), ] with m.If(counter==0): m.d.usb_io += [ trigger.eq(~trigger), ] # Instantiate ILA uart_divisor = int(48e6/9600) m.submodules.serial_ila = self.serial_ila = serial_ila = AsyncSerialILA( signals=[counter, trigger, direct_usb.d_p.i, direct_usb.d_n.i, direct_usb.pullup.o], sample_depth=100, divisor=uart_divisor, sample_rate=48e6, domain="usb_io", samples_pretrigger=50) m.d.comb += serial_ila.trigger.eq(trigger) if (platform != None): platform.add_resources([ Resource("uart_tx", 0, Pins("4", conn=("gpio", 0), dir ="o" ), Attrs(IOSTANDARD="LVCMOS33") ), ]) tx = platform.request("uart_tx") m.d.comb += [ tx.o.eq(serial_ila.tx), ] return m
def elaborate(self, platform): # see https://github.com/BracketMaster/nmigen-tinyfpgabx/blob/master/serial_fsm.py m = Module() # THIS WAS MISSING (20200905) FAIL m.submodules.bridge = self._bridge # The usb device ulpi = platform.request(platform.default_usb_connection) usb_serial = USBSerialDevice(bus=ulpi, idVendor=0x16D0, idProduct=0x0F3B) m.submodules.usb_serial = usb_serial # use fifos for data m.submodules.rx_fifo = self._rx_fifo m.submodules.tx_fifo = self._tx_fifo m.d.comb += usb_serial.connect.eq(1) # with m.If(self._enable.w_stb): # m.d.sync += [usb_serial.connect.eq(self._enable.w_data)] # m.d.sync += [usb_serial.connect.eq(1)] # fifod RX m.d.comb += [ # hooks the csr to the inside of the rx fifo self._rx_data.r_data.eq(self._rx_fifo.r_data), self._rx_rdy.r_data.eq(self._rx_fifo.r_rdy), self._rx_fifo.r_en.eq(self._rx_data.r_stb), # usb to the outside of the fifo self._rx_fifo.w_data.eq(usb_serial.rx.payload), self._rx_fifo.w_en.eq(usb_serial.rx.valid), usb_serial.rx.ready.eq(self._rx_fifo.w_rdy), ] # fifod TX # needs a state machine # connect the csr to the inner fifo m.d.comb += [ self._tx_fifo.w_data.eq(self._tx_data.w_data), self._tx_fifo.w_en.eq(self._tx_data.w_stb), self._tx_rdy.r_data.eq(self._tx_fifo.w_rdy), ] tx_fifo = self._tx_fifo tx_usb = usb_serial.tx counter = Signal(8) max_bytes = 8 # max number of bytes in a packet with m.FSM(name="TX"): with m.State("FIRST"): # there is stuff to move with m.If(tx_fifo.r_rdy & tx_usb.ready): m.d.sync += [ tx_usb.valid.eq(1), counter.eq(0), tx_usb.first.eq(1), tx_usb.last.eq(0), ] m.next = "BODY" with m.State("BODY"): m.d.sync += [tx_usb.first.eq(0), tx_usb.last.eq(0)] with m.If(tx_fifo.r_rdy & tx_usb.ready): m.d.sync += [ counter.eq(counter + 1), tx_usb.payload.eq(tx_fifo.r_data), tx_fifo.r_en.eq(1), ] with m.If(counter == max_bytes): m.next = "LAST" with m.If(tx_fifo.r_rdy == False): m.d.sync += [tx_usb.last.eq(1)] m.next = "LAST" with m.State("LAST"): m.d.sync += [tx_usb.valid.eq(0), tx_fifo.r_en.eq(0)] m.next = "FIRST" return m
def elaborate(self, platform): if platform is not None: self.glitch_trigger_out = platform.request("glitch_trig") self.target_reset = platform.request("target_reset") else: self.glitch_trigger_out = Signal() self.target_reset = Signal() counter = Signal(16) glitch_trigger = Signal() TIME_PER_CLOCK = 1 / 48e6 # 48mhz clk counter_glitch = Signal(17) glitch_duration = Signal.like(counter_glitch, reset=int(1e-6 // TIME_PER_CLOCK)) # 1.25 worked glitch_start_min_clocks = int(0e-6 // TIME_PER_CLOCK) glitch_start_max_clocks = int(180e-6 // TIME_PER_CLOCK) glitch_start_clocks = Signal.like(counter_glitch, reset=glitch_start_min_clocks) reset_duration = int(100e-6 // TIME_PER_CLOCK) m = Module() if platform: # Generate our domain clocks/resets. m.submodules.car = platform.clock_domain_generator() # Create our USB-to-serial converter. ulpi = platform.request(platform.default_usb_connection) m.submodules.usb_serial = usb_serial = \ USBSerialDevice(bus=ulpi, idVendor=0x16d0, idProduct=0x0f3b) m.d.comb += [ # Place the streams into a loopback configuration... usb_serial.tx.payload.eq(usb_serial.rx.payload + 1), usb_serial.tx.valid.eq(usb_serial.rx.valid), usb_serial.tx.first.eq(usb_serial.rx.first), usb_serial.tx.last.eq(usb_serial.rx.last), #usb_serial.rx.ready .eq(usb_serial.tx.ready), # ... and always connect by default. usb_serial.connect.eq(1) ] GLITCH_ADJ_CLOCKS = 1 GLITCH_MAX_CLOCKS = int(5e-6 // TIME_PER_CLOCK) # USB commands usb_char = Signal.like(usb_serial.rx.payload) with m.FSM(name="USB"): with m.State("IDLE"): m.d.comb += [ usb_serial.rx.ready.eq(True), ] with m.If(usb_serial.rx.valid): m.d.comb += [ usb_serial.rx.ready.eq(False), ] m.d.sync += usb_char.eq(usb_serial.rx.payload) m.next = "PARSING" with m.State("PARSING"): m.d.comb += [ usb_serial.rx.ready.eq(True), ] m.next = "IDLE" with m.If(usb_char == ord(b"q")): m.d.sync += glitch_duration.eq( Mux(glitch_duration > GLITCH_ADJ_CLOCKS, glitch_duration - GLITCH_ADJ_CLOCKS, GLITCH_ADJ_CLOCKS)) with m.Elif(usb_char == ord(b"w")): m.d.sync += glitch_duration.eq( Mux( glitch_duration < (GLITCH_MAX_CLOCKS - GLITCH_ADJ_CLOCKS), glitch_duration + GLITCH_ADJ_CLOCKS, GLITCH_MAX_CLOCKS)) #m.d.sync += self.glitch_trigger_out.o.eq(usb_char[0]) m.d.sync += counter.eq(counter + 1) m.d.comb += self.target_reset.o.eq(~(counter < reset_duration)) m.d.comb += self.glitch_trigger_out.o.eq(~glitch_trigger) with m.FSM(): with m.State("IDLE"): m.d.comb += glitch_trigger.eq(False) with m.If(counter == 0): m.d.sync += counter_glitch.eq(0) m.next = "ARMED" with m.State("ARMED"): m.d.sync += counter_glitch.eq(counter_glitch + 1) #print(type(reset_duration), glitch_start) m.d.comb += glitch_trigger.eq(False) with m.If(counter >= reset_duration + glitch_start_clocks): m.next = "GLITCHING" with m.State("GLITCHING"): m.d.sync += counter_glitch.eq(counter_glitch + 1) m.d.comb += glitch_trigger.eq(True) with m.If(counter >= reset_duration + glitch_start_clocks + glitch_duration): m.next = "IDLE" with m.If(glitch_start_clocks >= glitch_start_max_clocks): m.d.sync += glitch_start_clocks.eq( glitch_start_min_clocks) #m.d.sync += glitch_duration.eq(glitch_duration + 1) with m.Else(): m.d.sync += glitch_start_clocks.eq( glitch_start_clocks + int(0.05e-6 // TIME_PER_CLOCK)) print("ok") return m