From 550bc0eee54e687b0913155d5ae1210c3aa0a38d Mon Sep 17 00:00:00 2001 From: Hans Baier Date: Mon, 8 May 2023 05:41:56 +0700 Subject: [PATCH] add QMTech XC7K325T board, add seven segment display to daughterboard --- .../platforms/qmtech_daughterboard.py | 58 ++++++++++++++++ litex_boards/platforms/qmtech_xc7k325t.py | 39 ++++++++--- litex_boards/targets/qmtech_xc7k325t.py | 67 +++---------------- 3 files changed, 98 insertions(+), 66 deletions(-) diff --git a/litex_boards/platforms/qmtech_daughterboard.py b/litex_boards/platforms/qmtech_daughterboard.py index 7c06e7a..59714db 100644 --- a/litex_boards/platforms/qmtech_daughterboard.py +++ b/litex_boards/platforms/qmtech_daughterboard.py @@ -1,5 +1,63 @@ +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2023 Kazumoto Kojima +# Copyright (c) 2023 Hans Baier +# +# SPDX-License-Identifier: BSD-2-Clause + from litex.build.generic_platform import Subsignal, Pins, IOStandard, Misc +# SevenSeg ----------------------------------------------------------------------------------------- +from migen import * +from migen.genlib.misc import WaitTimer + +from litex.soc.interconnect.csr import AutoCSR, CSRStorage + +class SevenSeg(Module, AutoCSR): + def __init__(self, segs, sels, sys_clk_freq, period=1e-2): + self.segs = segs + self.sels = sels + + n = len(sels) + self._out = CSRStorage(4*n, description="7 Seg LEDs Control.") + xdigits = Signal(4*n) + select = Signal(n) + count = Signal(max=n) + table = [ + 0x3f, 0x06, 0x5b, 0x4f, + 0x66, 0x6d, 0x7d, 0x07, + 0x7f, 0x6f, 0x77, 0x7c, + 0x39, 0x5e, 0x79, 0x71 + ] + abcdefg = Signal(8) + hexa = Signal(4) + cases = {} + for i in range(16): + cases[i] = abcdefg.eq(table[i]) + + self.comb += Case(hexa, cases) + + timer = WaitTimer(int(period*sys_clk_freq/(2*n))) + self.submodules += timer + self.comb += timer.wait.eq(~timer.done) + self.sync += If(timer.done, + If(count == n-1, + count.eq(0), + select.eq(1 << (n-1)), + xdigits.eq(self._out.storage) + ).Else( + count.eq(count + 1), + select.eq(select >> 1), + xdigits.eq(xdigits >> 4) + ) + ) + self.comb += [ + hexa.eq(xdigits[0:4]), + segs.eq(~abcdefg), + sels.eq(select) + ] + class QMTechDaughterboard: """ the QMTech daughterboard contains standard peripherals diff --git a/litex_boards/platforms/qmtech_xc7k325t.py b/litex_boards/platforms/qmtech_xc7k325t.py index ba2ffe6..0b34ce1 100644 --- a/litex_boards/platforms/qmtech_xc7k325t.py +++ b/litex_boards/platforms/qmtech_xc7k325t.py @@ -1,6 +1,9 @@ # # This file is part of LiteX-Boards. # +# Copyright (c) 2023 Kazumoto Kojima +# Copyright (c) 2023 Hans Baier +# # SPDX-License-Identifier: BSD-2-Clause from litex.build.generic_platform import Pins, Subsignal, IOStandard, Misc @@ -13,14 +16,23 @@ _io = [ # Clk / Rst ("clk50", 0, Pins("F22"), IOStandard("LVCMOS33")), + # The core board does not have a USB serial on it, + # so you will have to attach an USB to serial adapter + # on these pins + ("gpio_serial", 0, + Subsignal("tx", Pins("J2:7")), + Subsignal("rx", Pins("J2:8")), + IOStandard("LVCMOS33") + ), + # SPIFlash # S25FL256L - #("spiflash4x", 0, # clock needs to be accessed through STARTUPE2 - # Subsignal("cs_n", Pins("C23")), - # Subsignal("clk", Pins("C8")), - # Subsignal("dq", Pins("B24", "A25", "B22", "A22")), - # IOStandard("LVCMOS33") - #), + ("spiflash4x", 0, # clock needs to be accessed through STARTUPE2 + Subsignal("cs_n", Pins("C23")), + Subsignal("clk", Pins("C8")), + Subsignal("dq", Pins("B24", "A25", "B22", "A22")), + IOStandard("LVCMOS33") + ), # DDR3 SDRAM # MT41J128M16JT-125K @@ -125,24 +137,31 @@ class Platform(XilinxPlatform): default_clk_name = "clk50" default_clk_period = 1e9/50e6 - core_resources = [ + core_resources_daughterboard = [ ("onboard_led_1", 0, Pins("J26"), IOStandard("LVCMOS33")), ("onboard_led_2", 0, Pins("H26"), IOStandard("LVCMOS33")), ("cpu_reset", 0, Pins("AD21"), IOStandard("LVCMOS33")), ] - def __init__(self, toolchain="yosys+nexpnr", with_daughterboard=False): + core_resources_standalone = [ + ("user_led", 0, Pins("J26"), IOStandard("LVCMOS33")), + ("user_led", 1, Pins("H26"), IOStandard("LVCMOS33")), + ("cpu_reset", 0, Pins("AD21"), IOStandard("LVCMOS33")), + ] + + def __init__(self, toolchain="vivado", with_daughterboard=False): device = "xc7k325tffg676-1" io = _io connectors = _connectors - io += self.core_resources - if with_daughterboard: + io += self.core_resources_daughterboard from litex_boards.platforms.qmtech_daughterboard import QMTechDaughterboard daughterboard = QMTechDaughterboard(IOStandard("LVCMOS33")) io += daughterboard.io connectors += daughterboard.connectors + else: + io += self.core_resources_standalone XilinxPlatform.__init__(self, device, io, connectors, toolchain=toolchain) diff --git a/litex_boards/targets/qmtech_xc7k325t.py b/litex_boards/targets/qmtech_xc7k325t.py index c89d1b6..974a52a 100755 --- a/litex_boards/targets/qmtech_xc7k325t.py +++ b/litex_boards/targets/qmtech_xc7k325t.py @@ -1,8 +1,10 @@ #!/usr/bin/env python3 - # # This file is part of LiteX-Boards. # +# Copyright (c) 2023 Kazumoto Kojima +# Copyright (c) 2023 Hans Baier +# # SPDX-License-Identifier: BSD-2-Clause import os @@ -25,55 +27,6 @@ from litedram.phy import s7ddrphy from liteeth.phy.mii import LiteEthPHYMII -# SevenSeg ----------------------------------------------------------------------------------------- -from migen.genlib.misc import WaitTimer -from litex.soc.interconnect.csr import * - -class SevenSeg(Module, AutoCSR): - def __init__(self, segs, sels, sys_clk_freq, period=1e-2): - self.segs = segs - self.sels = sels - - n = len(sels) - self._out = CSRStorage(4*n, description="7 Seg LEDs Control.") - xdigits = Signal(4*n) - select = Signal(n) - count = Signal(max=n) - table = [ - 0x3f, 0x06, 0x5b, 0x4f, - 0x66, 0x6d, 0x7d, 0x07, - 0x7f, 0x6f, 0x77, 0x7c, - 0x39, 0x5e, 0x79, 0x71 - ] - abcdefg = Signal(8) - hexa = Signal(4) - cases = {} - for i in range(16): - cases[i] = abcdefg.eq(table[i]) - - self.comb += Case(hexa, cases) - - timer = WaitTimer(int(period*sys_clk_freq/(2*n))) - self.submodules += timer - self.comb += timer.wait.eq(~timer.done) - self.sync += If(timer.done, - If(count == n-1, - count.eq(0), - select.eq(1 << (n-1)), - xdigits.eq(self._out.storage) - ).Else( - count.eq(count + 1), - select.eq(select >> 1), - xdigits.eq(xdigits >> 4) - ) - ) - self.comb += [ - hexa.eq(xdigits[0:4]), - segs.eq(~abcdefg), - sels.eq(select) - ] - - # CRG ---------------------------------------------------------------------------------------------- class _CRG(Module): @@ -112,7 +65,7 @@ class _CRG(Module): # BaseSoC ------------------------------------------------------------------------------------------ class BaseSoC(SoCCore): - def __init__(self, toolchain="yosys+nextpnr", sys_clk_freq=int(100e6), with_daughterboard=False, + def __init__(self, toolchain="vivado", sys_clk_freq=int(100e6), with_daughterboard=False, with_ethernet=False, with_etherbone=False, eth_ip="192.168.1.50", eth_dynamic_ip=False, local_ip="", remote_ip="", with_led_chaser=True, with_video_terminal=False, with_video_framebuffer=False, with_video_colorbars=False, @@ -198,10 +151,12 @@ class BaseSoC(SoCCore): pads = platform.request_all("user_led"), sys_clk_freq = sys_clk_freq) - self.submodules.sevenseg = SevenSeg( - segs = platform.request_all("seven_seg"), - sels = platform.request_all("seven_seg_ctl"), - sys_clk_freq = sys_clk_freq) + if (with_daughterboard): + from litex_boards.platforms.qmtech_daughterboard import SevenSeg + self.submodules.sevenseg = SevenSeg( + segs = platform.request_all("seven_seg"), + sels = platform.request_all("seven_seg_ctl"), + sys_clk_freq = sys_clk_freq) if not with_daughterboard and kwargs["uart_name"] == "serial": kwargs["uart_name"] = "jtag_serial" @@ -210,7 +165,7 @@ class BaseSoC(SoCCore): def main(): parser = argparse.ArgumentParser(description="LiteX SoC on QMTech XC7K325T") - parser.add_argument("--toolchain", default="yosys+nextpnr", help="FPGA toolchain (vivado, symbiflow or yosys+nextpnr).") + parser.add_argument("--toolchain", default="vivado", help="FPGA toolchain (vivado, symbiflow or yosys+nextpnr).") parser.add_argument("--build", action="store_true", help="Build bitstream.") parser.add_argument("--load", action="store_true", help="Load bitstream.") parser.add_argument("--sys-clk-freq", default=100e6, help="System clock frequency.")