def elaborate(self, platform): m = Module() # Create our clock domains. m.domains.fast = self.fast = ClockDomain() m.domains.sync = self.sync = ClockDomain() m.domains.ulpi = self.ulpi = ClockDomain() # Call the hook that will create any submodules necessary for all clocks. self.create_submodules(m, platform) # Generate and connect up our clocks. m.d.comb += [ self.clk_ulpi.eq(self.generate_ulpi_clock(m, platform)), self.clk_sync.eq(self.generate_sync_clock(m, platform)), self.clk_fast.eq(self.generate_fast_clock(m, platform)), ClockSignal(domain="fast").eq(self.clk_fast), ClockSignal(domain="sync").eq(self.clk_sync), ClockSignal(domain="ulpi").eq(self.clk_ulpi), ] # Call the hook that will connect up our reset signals. self.create_ulpi_reset(m, platform) return m
def elaborate(self, platform): m = Module() # Create our domains... m.domains.usb = ClockDomain() m.domains.usb_io = ClockDomain() m.domains.fast = ClockDomain() # ... and create our 12 MHz USB clock. m.submodules.pll = Instance( "SB_PLL40_CORE", i_REFERENCECLK=ClockSignal("sync"), i_RESETB=Const(1), i_BYPASS=Const(0), o_PLLOUTCORE=ClockSignal("usb"), # Create a 24 MHz PLL clock... p_FEEDBACK_PATH="SIMPLE", p_DIVR=0, p_DIVF=15, p_DIVQ=5, p_FILTER_RANGE=4, # ... and divide it by half to get 12 MHz. p_PLLOUT_SELECT="GENCLK_HALF") # We'll use our 48MHz clock for everything _except_ the usb_io domain... m.d.comb += [ ClockSignal("usb_io").eq(ClockSignal("sync")), ClockSignal("fast").eq(ClockSignal("sync")) ] return m
def elaborate(self, platform): # For virtual platforms just use a regular counter if platform is None: m = Module() counter = Signal(2) domain = getattr(m.d, self.indomain) domain += counter.eq(counter + 1) m.domains += ClockDomain(self.outdomain, reset_less=True) m.d.comb += ClockSignal(self.outdomain).eq(counter[1]) return m m = Module() clkin = Signal() # Buffered output of input clock, into PLL clkfbout = Signal() # Unbuffered feedback out of PLL clkfbout_buf = Signal() # Buffered feedback into PLL clkout = Signal() # Unbuffered output from PLL div4clk = Signal() # Buffered output of output clock m.submodules.clockdiv = Instance("PLLE2_ADV", p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="ZHOLD", p_STARTUP_WAIT="FALSE", p_DIVCLK_DIVIDE=1, p_CLKFBOUT_MULT=4, p_CLKFBOUT_PHASE=0.000, p_CLKOUT0_DIVIDE=16, p_CLKOUT0_PHASE=0.000, p_CLKOUT0_DUTY_CYCLE=0.500, p_CLKIN1_PERIOD=4.000, o_CLKFBOUT=clkfbout, o_CLKOUT0=clkout, i_CLKFBIN=clkfbout_buf, i_CLKIN1=clkin, i_CLKIN2=0, i_CLKINSEL=1, i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_PWRDWN=0, i_RST=0) m.submodules.inbuf = Instance("BUFG", i_I=ClockSignal(self.indomain), o_O=clkin) m.submodules.outbuf = Instance("BUFG", i_I=clkout, o_O=div4clk) m.submodules.clockfb = Instance("BUFG", i_I=clkfbout, o_O=clkfbout_buf) m.domains += ClockDomain(self.outdomain, reset_less=True) m.d.comb += ClockSignal(self.outdomain).eq(div4clk) return m
def elaborate(self, platform): m = Module() # Create our domains... m.domains.sync = ClockDomain() m.domains.usb = ClockDomain() m.domains.usb_io = ClockDomain() m.domains.fast = ClockDomain() # ... create our 48 MHz IO and 12 MHz USB clock... m.submodules.pll = Instance( "SB_PLL40_2F_CORE", i_REFERENCECLK=platform.request(platform.default_clk), i_RESETB=Const(1), i_BYPASS=Const(0), o_PLLOUTCOREA=ClockSignal("sync"), o_PLLOUTCOREB=ClockSignal("usb"), # Create a 48 MHz PLL clock... p_FEEDBACK_PATH="SIMPLE", p_PLLOUT_SELECT_PORTA="GENCLK", p_PLLOUT_SELECT_PORTB="SHIFTREG_0deg", p_DIVR=0, p_DIVF=47, p_DIVQ=4, p_FILTER_RANGE=1, ) # We'll use our 48MHz clock for everything _except_ the usb domain... m.d.comb += [ ClockSignal("usb_io").eq(ClockSignal("sync")), ClockSignal("fast").eq(ClockSignal("sync")) ] return m
def elaborate(self, platform): m = Module() # Create our domains; but don't do anything else for them, for now. m.domains.usb = ClockDomain() m.domains.fast = ClockDomain() return m
def elaborate(self, platform): m = Module() # Create our domains; but don't do anything else for them, for now. m.domains.usb = ClockDomain() m.domains.fast = ClockDomain() # Handle USB PHY resets. m.submodules.usb_reset = controller = PHYResetController() m.d.comb += [ResetSignal("usb").eq(controller.phy_reset)] return m
def elaborate(self, platform): m = Module() locked = Signal() # Create our domains... m.domains.sync = ClockDomain() m.domains.usb = ClockDomain() m.domains.usb_io = ClockDomain() m.domains.fast = ClockDomain() # ... create our 48 MHz IO and 12 MHz USB clock... clk48 = Signal() clk12 = Signal() m.submodules.pll = Instance("SB_PLL40_2F_CORE", i_REFERENCECLK = platform.request(platform.default_clk), i_RESETB = Const(1), i_BYPASS = Const(0), o_PLLOUTCOREA = clk48, o_PLLOUTCOREB = clk12, o_LOCK = locked, # Create a 48 MHz PLL clock... p_FEEDBACK_PATH = "SIMPLE", p_PLLOUT_SELECT_PORTA = "GENCLK", p_PLLOUT_SELECT_PORTB = "SHIFTREG_0deg", p_DIVR = 0, p_DIVF = 47, p_DIVQ = 4, p_FILTER_RANGE = 1, ) # ... and constrain them to their new frequencies. platform.add_clock_constraint(clk48, 48e6) platform.add_clock_constraint(clk12, 12e6) # We'll use our 48MHz clock for everything _except_ the usb domain... m.d.comb += [ ClockSignal("usb") .eq(clk12), ClockSignal("sync") .eq(clk48), ClockSignal("usb_io") .eq(clk48), ClockSignal("fast") .eq(clk48), ResetSignal("usb") .eq(~locked), ResetSignal("sync") .eq(~locked), ResetSignal("usb_io") .eq(~locked), ResetSignal("fast") .eq(~locked) ] return m
def elaborate(self, platform): m = Module() # Create RMII clock domain from RMII clock input cd = ClockDomain("rmii", reset_less=True) m.d.comb += cd.clk.eq(self.rmii.ref_clk) m.domains.rmii = cd # Create RX write and TX read ports for RMII use rx_port_w = self.rx_mem.write_port(domain="rmii") tx_port_r = self.tx_mem.read_port(domain="rmii", transparent=False) m.submodules += [self.rx_port, rx_port_w, self.tx_port, tx_port_r] m.d.comb += [self.rx_port.en.eq(1), tx_port_r.en.eq(1)] # Create submodules for PHY and RMII m.submodules.phy_manager = phy_manager = PHYManager( self.clk_freq, self.phy_addr, self.phy_rst, self.mdio.mdio, self.mdio.mdc) m.submodules.stretch = stretch = PulseStretch(int(1e6)) rmii_rx = RMIIRx(self.mac_addr, rx_port_w, self.rmii.crs_dv, self.rmii.rxd0, self.rmii.rxd1) rmii_tx = RMIITx(tx_port_r, self.rmii.txen, self.rmii.txd0, self.rmii.txd1) # Create FIFOs to interface to RMII modules rx_fifo = AsyncFIFO(width=11 + self.rx_port.addr.nbits, depth=4) tx_fifo = AsyncFIFO(width=11 + self.tx_port.addr.nbits, depth=4) m.d.comb += [ # RX FIFO rx_fifo.din.eq(Cat(rmii_rx.rx_offset, rmii_rx.rx_len)), rx_fifo.we.eq(rmii_rx.rx_valid), Cat(self.rx_offset, self.rx_len).eq(rx_fifo.dout), rx_fifo.re.eq(self.rx_ack), self.rx_valid.eq(rx_fifo.readable), # TX FIFO tx_fifo.din.eq(Cat(self.tx_offset, self.tx_len)), tx_fifo.we.eq(self.tx_start), Cat(rmii_tx.tx_offset, rmii_tx.tx_len).eq(tx_fifo.dout), tx_fifo.re.eq(rmii_tx.tx_ready), rmii_tx.tx_start.eq(tx_fifo.readable), # Other submodules phy_manager.phy_reset.eq(self.phy_reset), self.link_up.eq(phy_manager.link_up), stretch.trigger.eq(self.rx_valid), self.eth_led.eq(stretch.pulse), ] rdr = DomainRenamer({"read": "sync", "write": "rmii"}) wdr = DomainRenamer({"write": "sync", "read": "rmii"}) rr = DomainRenamer("rmii") m.submodules.rx_fifo = rdr(rx_fifo) m.submodules.tx_fifo = wdr(tx_fifo) m.submodules.rmii_rx = rr(rmii_rx) m.submodules.rmii_tx = rr(rmii_tx) return m
def elaborate(self, platform): m = Module() m.submodules.clock = self._clock m.submodules.efb = self.efb m.domains += ClockDomain("sync") m.d.comb += ClockSignal("sync").eq(self._clock.out) return m
def formal(cls) -> Tuple[Module, List[Signal]]: m = Module() ph = ClockDomain("ph") clk = ClockSignal("ph") m.domains += ph m.d.sync += clk.eq(~clk) s = IC_7416374(clk="ph") m.submodules += s with m.If(s.n_oe): m.d.comb += Assert(s.q == 0) with m.If(~s.n_oe & Rose(clk)): m.d.comb += Assert(s.q == Past(s.d)) with m.If(~s.n_oe & Fell(clk) & ~Past(s.n_oe)): m.d.comb += Assert(s.q == Past(s.q)) sync_clk = ClockSignal("sync") sync_rst = ResetSignal("sync") # Make sure the clock is clocking m.d.comb += Assume(sync_clk == ~Past(sync_clk)) # Don't want to test what happens when we reset. m.d.comb += Assume(~sync_rst) m.d.comb += Assume(~ResetSignal("ph")) return m, [sync_clk, sync_rst, s.n_oe, s.q, s.d]
def elaborate(self, platform): m = Module() locked = Signal() # Create our domains... m.domains.sync = ClockDomain() m.domains.pol = ClockDomain() # clocks 50 MHz circuit # 1 MHz update frequency motor clk50 = Signal() # clk1 = Signal() # details see iCE40 sysCLOCK PLL Design and Usage # settings comment out are for SB_PLL40_2F_CORE m.submodules.pll = \ Instance("SB_PLL40_CORE", i_REFERENCECLK=platform.request(platform.default_clk), i_RESETB=Const(1), # i_BYPASS=Const(0), o_PLLOUTGLOBAL=clk50, o_LOCK=locked, # Create a 50 MHz PLL clock... p_FEEDBACK_PATH="SIMPLE", # internally generated PLL # p_PLLOUT_SELECT_PORTA="GENCLK", # p_PLLOUT_SELECT_PORTB="SHIFTREG_0deg", p_DIVR=0, p_DIVF=7, p_DIVQ=4, p_FILTER_RANGE=5, ) # ... and constrain them to their new frequencies. platform.add_clock_constraint(clk50, 50e6) # platform.add_clock_constraint(clk1, 1e6) # We'll use our 50MHz clock for everything _except_ the polynomal # which create ticks for the motors m.d.comb += [ # ClockSignal("pol").eq(clk1), ClockSignal("sync").eq(clk50), # ResetSignal("pol").eq(~locked), ResetSignal("sync").eq(~locked), ] return m
def elaborate(self, platform): m = Module() # Create our domains... m.domains.sync = ClockDomain() m.domains.usb = ClockDomain() m.domains.usb_io = ClockDomain() m.domains.fast = ClockDomain() # ... ensure our clock is never instantiated with a Global buffer. platform.lookup(platform.default_clk).attrs['GLOBAL'] = False # ... create our 48 MHz IO and 12 MHz USB clocks... clk48 = Signal() clk12 = Signal() m.submodules.pll = Instance( "SB_PLL40_2F_PAD", i_PACKAGEPIN=platform.request(platform.default_clk, dir="i"), i_RESETB=Const(1), i_BYPASS=Const(0), o_PLLOUTGLOBALA=clk48, o_PLLOUTGLOBALB=clk12, # Create a 48 MHz PLL clock... p_FEEDBACK_PATH="SIMPLE", p_PLLOUT_SELECT_PORTA="GENCLK", p_PLLOUT_SELECT_PORTB="SHIFTREG_0deg", p_DIVR=0, p_DIVF=63, p_DIVQ=4, p_FILTER_RANGE=1, ) # ... and constrain them to their new frequencies. platform.add_clock_constraint(clk48, 48e6) platform.add_clock_constraint(clk12, 12e6) # We'll use our 48MHz clock for everything _except_ the usb domain... m.d.comb += [ ClockSignal("usb_io").eq(clk48), ClockSignal("fast").eq(clk48), ClockSignal("sync").eq(clk48), ClockSignal("usb").eq(clk12) ] return m
def elaborate(self, platform): m = Module() # pins ft_clkout_i = platform.request("ft_clkout_i") ft_wr_n_o = platform.request("ft_wr_n_o") ft_txe_n_i = platform.request("ft_txe_n_i") ft_suspend_n_i = platform.request("ft_suspend_n_i") ft_oe_n_o = platform.request("ft_oe_n_o") ft_rd_n_o = platform.request("ft_rd_n_o") ft_siwua_n_o = platform.request("ft_siwua_n_o") ft_data_io = platform.request("ft_data_io") ext1 = platform.request("ext1") pa_en_n_o = platform.request("pa_en_n_o") # clock domains m.domains += ClockDomain("clk60") m.d.comb += ClockSignal("clk60").eq(ft_clkout_i.i) # signals ctr = Signal(8, reset=0) ctr_last = Signal(8, reset=0) ft_txe_last = Signal(1, reset=0) # submodules m.submodules.fifo = fifo = AsyncFIFO(width=8, depth=1024, r_domain="clk60", w_domain="sync") # logic m.d.comb += [ ft_oe_n_o.o.eq(1), ft_rd_n_o.o.eq(1), ft_siwua_n_o.o.eq(1), ft_data_io.oe.eq(1), pa_en_n_o.o.eq(1), ] m.d.comb += [ ft_data_io.o.eq(fifo.r_data), fifo.w_data.eq(ctr), ] with m.If(fifo.w_rdy): m.d.comb += fifo.w_en.eq(1) m.d.sync += ctr.eq(ctr + 1) with m.Else(): m.d.comb += fifo.w_en.eq(0) with m.If(~ft_txe_n_i & ft_suspend_n_i & fifo.r_rdy): m.d.comb += ft_wr_n_o.o.eq(0) m.d.clk60 += fifo.r_en.eq(1) with m.Else(): m.d.comb += ft_wr_n_o.o.eq(1) m.d.clk60 += fifo.r_en.eq(0) return m
def elaborate(self, platform): m = Module() # Create our clock domains. m.domains.sync = ClockDomain() m.domains.usb = ClockDomain() m.submodules.usb_reset = controller = PHYResetController() m.d.comb += [ ResetSignal("usb").eq(controller.phy_reset), self.usb_holdoff.eq(controller.phy_stop) ] # Attach Clock domains m.d.comb += [ ClockSignal(domain="sync").eq(self.clk_sync), ClockSignal(domain="usb").eq(self.clk_usb), ResetSignal("sync").eq(self.rst_sync), ] # Attach usb module m.submodules.usb0 = self.usb0 m.d.comb += [ # Wire up streams self.usb0.tx.valid.eq(self.tx.valid), self.usb0.tx.first.eq(self.tx.first), self.usb0.tx.last.eq(self.tx.last), self.usb0.tx.payload.eq(self.tx.payload), # -- self.tx.ready.eq(self.usb0.tx.ready), self.rx.valid.eq(self.usb0.rx.valid), self.rx.first.eq(self.usb0.rx.first), self.rx.last.eq(self.usb0.rx.last), self.rx.payload.eq(self.usb0.rx.payload), # -- self.usb0.rx.ready.eq(self.rx.ready), # ... and always connect by default. self.usb0.connect.eq(1) ] return m
def setup(validator: Optional[Base]): result = CliSetup( Module(), Core(validator), ClockDomain("ph1"), ClockSignal("ph1"), ) result.m.submodules.core = result.core result.m.domains.ph1 = result.ph1 result.ph1.rst = result.core.Rst return result
def elaborate(self, platform: Platform): led1 = platform.request("led", 0) led2 = platform.request("led", 1) led3 = platform.request("led", 2) led4 = platform.request("led", 3) ft600_resource = platform.request("ft600") m = Module() # Connect pseudo power pins for the FT600 and DDR3 banks pseudo_power = platform.request("pseudo_power") m.d.comb += pseudo_power.ddr.o.eq(Repl(1, len(pseudo_power.ddr))) m.d.comb += pseudo_power.ft.o.eq(Repl(1, len(pseudo_power.ft))) m.submodules.pll = ECP5PLL(clock_signal_name="pll_clk25", clock_config=[ ECP5PLLConfig("sync", 25), ]) m.domains += ClockDomain("ft600") m.d.comb += ClockSignal("ft600").eq(ft600_resource.clk) m.submodules.ft600 = ft600 = DomainRenamer("ft600")(FT600( ft600_resource, )) m.submodules.fifo = fifo = AsyncFIFOBuffered(width=16, depth=2048, r_domain="ft600", w_domain="sync") # FT to Write FIFO m.d.comb += ft600.input_payload.eq(fifo.r_data) m.d.comb += fifo.r_en.eq(ft600.input_ready) m.d.comb += ft600.input_valid.eq(fifo.r_rdy) # Write data into FIFO m.d.comb += fifo.w_data.eq(0xABCD) m.d.comb += fifo.w_en.eq(1) led_counter = Signal(10) with m.If(fifo.w_rdy): m.d.sync += led_counter.eq(led_counter + 1) # Connect LEDs m.d.comb += led1.o.eq(ft600_resource.write) m.d.comb += led2.o.eq(ft600_resource.txe) m.d.comb += led3.o.eq(fifo.w_level > 2000) m.d.comb += led4.o.eq(led_counter[-1]) return m
def elaborate(self, platform): m = Module() # Set up PLL to multiply 25MHz clock to 100MHz clock m.submodules.pll = pll = SB_PLL40_PAD(0, 31, 3, 2) pll.packagepin = platform.request("clk25") pll.plloutglobal = Signal() # Set up clock domain on output of PLL cd = ClockDomain("sync", reset_less=True) m.d.comb += cd.clk.eq(pll.plloutglobal) m.domains += cd # Ethernet MAC phy = platform.request("phy") rmii = platform.request("rmii") mdio = platform.request("mdio") mac_addr = "02:44:4E:30:76:9E" mac = MAC(100e6, 0, mac_addr, rmii, mdio, phy.rst, phy.led) m.submodules.mac = mac # Explicitly zero unused inputs in MAC m.d.comb += [ mac.phy_reset.eq(0), ] # User data stuff user = User() m.submodules.user = user # IP stack ip4_addr = "10.1.1.5" m.submodules.ipstack = ipstack = IPStack(mac_addr, ip4_addr, 16, 1735, mac.rx_port, mac.tx_port, user.mem_r_port, user.mem_w_port) m.d.comb += [ mac.tx_start.eq(ipstack.tx_start), mac.tx_len.eq(ipstack.tx_len), mac.tx_offset.eq(ipstack.tx_offset), ipstack.rx_valid.eq(mac.rx_valid), ipstack.rx_len.eq(mac.rx_len), ipstack.rx_offset.eq(mac.rx_offset), mac.rx_ack.eq(ipstack.rx_ack), ipstack.user_tx.eq(user.transmit_packet), user.transmit_ready.eq(ipstack.user_ready), user.packet_received.eq(ipstack.user_rx), ] return m
def elaborate(self, platform): m = Module() # create domains for the producer and consumer m.domains.producer = ClockDomain() m.domains.consumer = ClockDomain() # attach submodules m.submodules.producer = producer = self.producer m.submodules.consumer = consumer = self.consumer m.submodules.fifo = fifo = self.fifo # producer <> fifo m.d.comb += producer.w_rdy_i.eq(fifo.w_rdy) m.d.comb += fifo.w_en.eq(producer.w_en_o) m.d.comb += fifo.w_data.eq(producer.w_data_o) # consumer <> fifo m.d.comb += consumer.r_rdy_i.eq(fifo.r_rdy) m.d.comb += consumer.r_data_i.eq(fifo.r_data) m.d.comb += fifo.r_en.eq(consumer.r_en_o) return m
def elaborate(self, platform): m = Module() # pins ft_clkout_i = platform.request("ft_clkout_i") ft_wr_n_o = platform.request("ft_wr_n_o") ft_wr_n_o.o.reset = 1 ft_txe_n_i = platform.request("ft_txe_n_i") ft_suspend_n_i = platform.request("ft_suspend_n_i") ft_oe_n_o = platform.request("ft_oe_n_o") ft_rd_n_o = platform.request("ft_rd_n_o") ft_siwua_n_o = platform.request("ft_siwua_n_o") ft_data_io = platform.request("ft_data_io") ext1 = platform.request("ext1") pa_en_n_o = platform.request("pa_en_n_o") # clock domains m.domains += ClockDomain("clk60") m.d.comb += ClockSignal("clk60").eq(ft_clkout_i.i) # signals ctr = Signal(8, reset=0) ctr_last = Signal(8, reset=0) ft_txe_last = Signal(1, reset=0) # sync + comb logic with m.If(~ft_txe_n_i.i & ft_suspend_n_i.i): m.d.clk60 += [ft_wr_n_o.o.eq(0), ctr.eq(ctr + 1), ctr_last.eq(ctr)] with m.Elif(ft_txe_n_i.i & ~ft_txe_last): m.d.clk60 += [ctr.eq(ctr_last), ft_wr_n_o.o.eq(1)] with m.Else(): m.d.clk60 += [ft_wr_n_o.o.eq(1)] m.d.clk60 += [ft_txe_last.eq(ft_txe_n_i.i)] m.d.comb += [ ft_oe_n_o.o.eq(1), ft_rd_n_o.o.eq(1), ft_siwua_n_o.o.eq(1), ft_data_io.o.eq(ctr), ft_data_io.oe.eq(1), pa_en_n_o.o.eq(1), ] return m
def elaborate(self, _: Platform) -> Module: """Implements the logic of a transparent latch.""" m = Module() internal_reg = Signal(self.size, reset=0, reset_less=True) # Local clock domain so we can clock data into the # internal memory on the negative edge of le. le_clk = ClockDomain("le_clk", clk_edge="neg", local=True) m.domains.le_clk = le_clk le_clk.clk = self.le m.d.le_clk += internal_reg.eq(self.data_in) m.d.comb += self.data_out.eq(Mux(self.n_oe, 0, internal_reg)) with m.If(self.le & ~self.n_oe): m.d.comb += self.data_out.eq(self.data_in) return m
def elaborate(self, platform): m = Module() # Set up PLL m.submodules.pll = pll = SB_PLL40_PAD(0, 31, 3, 2) pll.packagepin = platform.request("clk25") pll.plloutglobal = Signal() # Set up clock domain on PLL output cd = ClockDomain("sync", reset_less=True) m.d.comb += cd.clk.eq(pll.plloutglobal) m.domains += cd # Create LED blinker in PLL clock domain blinker = LEDBlinker(24) m.submodules.led_blinker = blinker m.d.comb += platform.request("user_led").eq(blinker.led) return m
def elaborate(self, platform): """ Generate the SF tester. """ m = Module() # Grab our I/O connectors. clk = platform.request("clk2") port_b = platform.request("port_b_bus", dir="o") # TODO: also blink r0.2+'s LEDs # Grab our clock signal, and attach it to the main clock domain. m.domains.sync = ClockDomain() m.d.comb += ClockSignal().eq(clk.i) # Increment port_b every clock cycle, for now. m.d.sync += port_b.o.eq(port_b.o + 1) # Return our elaborated module. return m
def elaborate(self, _: Platform) -> Module: """Implements the logic of an asynchronous memory. Essentially implements the wr-controlled write cycle, where the oe signal doesn't matter. We can't really implement the delays involved, so be safe with your signals :) """ m = Module() # Local clock domain so we can clock data into the memory # on the positive edge of n_wr. wr_clk = ClockDomain("wr_clk", local=True) m.domains.wr_clk = wr_clk wr_clk.clk = self.n_wr m.d.comb += self.data_out.eq(0) with m.If(~self.n_oe & self.n_wr): m.d.comb += self.data_out.eq(self._mem[self.addr]) m.d.wr_clk += self._mem[self.addr].eq(self.data_in) return m
def elaborate(self, platform): m = Module() if platform is not None: # platform.default_clk_frequency is in Hz coeff = self._calc_freq_coefficients( platform.default_clk_frequency / 1_000_000, self.freq_out) # clk_pin = platform.request(platform.default_clk) lock = Signal() pll = Instance( "SB_PLL40_CORE", p_FEEDBACK_PATH='SIMPLE', p_DIVR=coeff.divr, p_DIVF=coeff.divf, p_DIVQ=coeff.divq, p_FILTER_RANGE=0b001, p_DELAY_ADJUSTMENT_MODE_FEEDBACK='FIXED', p_FDA_FEEDBACK=0b0000, p_DELAY_ADJUSTMENT_MODE_RELATIVE='FIXED', p_FDA_RELATIVE=0b0000, p_SHIFTREG_DIV_MODE=0b00, p_PLLOUT_SELECT='GENCLK', p_ENABLE_ICEGATE=0b0, i_REFERENCECLK=ClockSignal(), o_PLLOUTCORE=ClockSignal(self.domain_name), i_RESETB=ResetSignal(), i_BYPASS=Const(0), o_LOCK=lock, ) rs = ResetSynchronizer(~lock, domain=self.domain_name) m.submodules += [pll, rs] m.domains += ClockDomain(self.domain_name) return m
def formal(cls) -> Tuple[Module, List[Signal]]: m = Module() ph = ClockDomain("ph") clk = ClockSignal("ph") m.domains += ph m.d.sync += clk.eq(~clk) s = IC_reg32_with_mux(clk="ph", N=2, faster=True) m.submodules += s sync_clk = ClockSignal("sync") sync_rst = ResetSignal("sync") with m.If(Rose(clk)): with m.Switch(~Past(s.n_sel)): with m.Case(0b11): m.d.comb += Assert(0) with m.Case(0b01): m.d.comb += Assert(s.q == Past(s.d[0])) with m.Case(0b10): m.d.comb += Assert(s.q == Past(s.d[1])) with m.Default(): m.d.comb += Assert(s.q == Past(s.q)) # Make sure the clock is clocking m.d.comb += Assume(sync_clk == ~Past(sync_clk)) # Don't want to test what happens when we reset. m.d.comb += Assume(~sync_rst) m.d.comb += Assume(~ResetSignal("ph")) m.d.comb += Assume(s.n_sel != 0) return m, [sync_clk, sync_rst, s.d[0], s.d[1], s.n_sel, s.q]
if __name__ == "__main__": parser = main_parser() parser.add_argument("--insn") args = parser.parse_args() verification: Optional[Verification] = None if args.insn is not None: module = importlib.import_module(f"formal.formal_{args.insn}") formal_class = getattr(module, "Formal") verification = formal_class() m = Module() m.submodules.core = core = Core(verification) m.domains.ph1 = ph1 = ClockDomain("ph1") rst = Signal() ph1clk = ClockSignal("ph1") ph1.rst = rst if verification is not None: # Cycle counter cycle2 = Signal(6, reset_less=True) m.d.ph1 += cycle2.eq(cycle2 + 1) # Force a reset # m.d.comb += Assume(rst == (cycle2 < 8)) with m.If(cycle2 == 20): m.d.ph1 += Cover(core.formalData.snapshot_taken
def elaborate(self, platform): m = Module() m.domains += ClockDomain("rx", reset_less=True) m.d.comb += ClockSignal("rx").eq(self.rx_clock) return m
def elaborate(self, platform): m = Module() # Grab our default input clock. input_clock = platform.request(platform.default_clk, dir="i") # Create our domains; but don't do anything else for them, for now. m.domains.sync = ClockDomain() m.domains.usb = ClockDomain() m.domains.usb_io = ClockDomain() m.domains.fast = ClockDomain() m.submodules.pll = Instance( "EHXPLLL", # Clock in. i_CLKI=input_clock, # Generated clock outputs. o_CLKOP=ClockSignal("sync"), o_CLKOS=ClockSignal("usb"), # Status. #o_LOCK=self._pll_lock, # PLL parameters... p_PLLRST_ENA="DISABLED", p_INTFB_WAKE="DISABLED", p_STDBY_ENABLE="DISABLED", p_DPHASE_SOURCE="DISABLED", p_CLKOS3_FPHASE=0, p_CLKOS3_CPHASE=0, p_CLKOS2_FPHASE=0, p_CLKOS2_CPHASE=7, p_CLKOS_FPHASE=0, p_CLKOS_CPHASE=5, p_CLKOP_FPHASE=0, p_CLKOP_CPHASE=5, p_PLL_LOCK_MODE=0, p_CLKOS_TRIM_DELAY="0", p_CLKOS_TRIM_POL="FALLING", p_CLKOP_TRIM_DELAY="0", p_CLKOP_TRIM_POL="FALLING", p_OUTDIVIDER_MUXD="DIVD", p_CLKOS3_ENABLE="DISABLED", p_OUTDIVIDER_MUXC="DIVC", p_CLKOS2_ENABLE="DISABLED", p_OUTDIVIDER_MUXB="DIVB", p_CLKOS_ENABLE="ENABLED", p_OUTDIVIDER_MUXA="DIVA", p_CLKOP_ENABLE="ENABLED", p_CLKOS3_DIV=1, p_CLKOS2_DIV=8, p_CLKOS_DIV=48, p_CLKOP_DIV=12, p_CLKFB_DIV=1, p_CLKI_DIV=1, p_FEEDBK_PATH="CLKOP", # Internal feedback. i_CLKFB=ClockSignal("sync"), # Control signals. i_RST=0, i_PHASESEL0=0, i_PHASESEL1=0, i_PHASEDIR=1, i_PHASESTEP=1, i_PHASELOADREG=1, i_STDBY=0, i_PLLWAKESYNC=0, # Output Enables. i_ENCLKOP=0, i_ENCLKOS=0, i_ENCLKOS2=0, i_ENCLKOS3=0, # Synthesis attributes. a_FREQUENCY_PIN_CLKI="48.000000", a_FREQUENCY_PIN_CLKOS="48.000000", a_FREQUENCY_PIN_CLKOP="12.000000", a_ICP_CURRENT="12", a_LPF_RESISTOR="8") # We'll use our 48MHz clock for everything _except_ the usb domain... m.d.comb += [ ClockSignal("usb_io").eq(ClockSignal("sync")), ClockSignal("fast").eq(ClockSignal("sync")) ] return m
def formal(cls) -> Tuple[Module, List[Signal]]: """Formal verification for the async memory. Note that you MUST have multiclock on in the sby file, because there is more than one clock in the system -- the default formal clock and the local clock inside the memory. """ m = Module() m.submodules.mem = mem = AsyncMemory(width=32, addr_lines=5) # Assume "good practices": # * n_oe and n_wr are never simultaneously 0, and any changes # are separated by at least a cycle to allow buffers to turn off. # * memory address remains stable throughout a write cycle, and # is also stable just before a write cycle. m.d.comb += Assume(mem.n_oe | mem.n_wr) # Paren placement is very important! While Python logical operators # and, or have lower precedence than ==, the bitwise operators # &, |, ^ have *higher* precedence. It can be confusing when it looks # like you're writing a boolean expression, but you're actually writing # a bitwise expression. with m.If(Fell(mem.n_oe)): m.d.comb += Assume((mem.n_wr == 1) & (Past(mem.n_wr) == 1)) with m.If(Fell(mem.n_wr)): m.d.comb += Assume((mem.n_oe == 1) & (Past(mem.n_oe) == 1)) with m.If(Rose(mem.n_wr) | (mem.n_wr == 0)): m.d.comb += Assume(Stable(mem.addr)) m.d.comb += Cover((mem.data_out == 0xAAAAAAAA) & (Past(mem.data_out) == 0xBBBBBBBB)) # Make sure that when the output is disabled, the output is zero, and # when enabled, it's whatever we're pointing at in memory. with m.If(mem.n_oe == 1): m.d.comb += Assert(mem.data_out == 0) with m.Else(): m.d.comb += Assert(mem.data_out == mem._mem[mem.addr]) # If we just wrote data, make sure that cell that we pointed at # for writing now contains the data we wrote. with m.If(Rose(mem.n_wr)): m.d.comb += Assert(mem._mem[Past(mem.addr)] == Past(mem.data_in)) # Pick an address, any address. check_addr = AnyConst(5) # We assert that unless that address is written, its data will not # change. To know when we've written the data, we have to create # a clock domain to let us save the data when written. saved_data_clk = ClockDomain("saved_data_clk") m.domains.saved_data_clk = saved_data_clk saved_data_clk.clk = mem.n_wr saved_data = Signal(32) with m.If(mem.addr == check_addr): m.d.saved_data_clk += saved_data.eq(mem.data_in) with m.If(Initial()): m.d.comb += Assume(saved_data == mem._mem[check_addr]) m.d.comb += Assume(mem.n_wr == 1) with m.Else(): m.d.comb += Assert(saved_data == mem._mem[check_addr]) return m, [mem.addr, mem.data_in, mem.n_wr, mem.n_oe]
def elaborate(self, platform): m = Module() cpu = Core() m.submodules += cpu m.domains.ph1 = ph1 = ClockDomain("ph1") m.domains.ph2 = ph2 = ClockDomain("ph2", clk_edge="neg") # Hook up clocks and reset to pins if not SLOWCLK: clk1 = platform.request("clk1") clk2 = platform.request("clk2") rst = platform.request("rst") m.d.comb += [ ph1.rst.eq(rst.i), ph2.rst.eq(rst.i), ph1.clk.eq(clk1.i), ph2.clk.eq(clk2.i), ] if SLOWCLK: clk_freq = platform.default_clk_frequency timer = Signal(range(0, int(clk_freq // 2)), reset=int(clk_freq // 2) - 1) tick = Signal() sync = ClockDomain() with m.If(timer == 0): m.d.sync += timer.eq(timer.reset) m.d.sync += tick.eq(~tick) with m.Else(): m.d.sync += timer.eq(timer - 1) m.d.comb += [ ph1.rst.eq(sync.rst), ph2.rst.eq(sync.rst), ph1.clk.eq(tick), ph2.clk.eq(~tick), ] # Hook up address lines to pins addr = [] for i in range(16): pin = platform.request("addr", i) m.d.comb += pin.o.eq(cpu.Addr[i]) addr.append(pin) data = [] if not FAKEMEM: # Hook up data in/out + direction to pins for i in range(8): pin = platform.request("data", i) m.d.comb += pin.o.eq(cpu.Dout[i]) m.d.ph2 += cpu.Din[i].eq(pin.i) data.append(pin) if FAKEMEM: with m.Switch(cpu.Addr): for a, d in mem.items(): with m.Case(a): m.d.comb += cpu.Din.eq(d) with m.Default(): m.d.comb += cpu.Din.eq(0x00) for i in range(8): pin = platform.request("led", i) m.d.comb += pin.o.eq(cpu.Addr[i]) rw = platform.request("rw") m.d.comb += rw.o.eq(cpu.RW) nIRQ = platform.request("n_irq") nNMI = platform.request("n_nmi") m.d.ph2 += cpu.IRQ.eq(~nIRQ) m.d.ph2 += cpu.NMI.eq(~nNMI) ba = platform.request("ba") m.d.comb += ba.o.eq(cpu.BA) m.d.comb += rw.oe.eq(~cpu.BA) for i in range(len(addr)): m.d.comb += addr[i].oe.eq(~cpu.BA) for i in range(len(data)): m.d.comb += data[i].oe.eq(~cpu.BA & ~cpu.RW) return m