Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: whitequark/glasgow
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: ec5f4da1f9cb
Choose a base ref
...
head repository: whitequark/glasgow
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: a91aa0957299
Choose a head ref
  • 3 commits
  • 3 files changed
  • 1 contributor

Commits on Nov 28, 2018

  1. Copy the full SHA
    e0c6f86 View commit details
  2. Copy the full SHA
    d4fedf0 View commit details
  3. arch.lpc: new definitions.

    whitequark committed Nov 28, 2018
    Copy the full SHA
    a91aa09 View commit details
Showing with 97 additions and 8 deletions.
  1. +72 −0 software/glasgow/arch/lpc.py
  2. +3 −1 software/glasgow/cli.py
  3. +22 −7 software/glasgow/gateware/fx2.py
72 changes: 72 additions & 0 deletions software/glasgow/arch/lpc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Ref: Intel® Low Pin Count (LPC) Interface Specification
# Document Number: 251289-001

# Transaction format summary. Derived from chapters 5-7 of the specification. Note that
# the specification has plenty of typos, which have been (hopefully) corrected here.
#
# Target cycles
# -------------
#
# Memory read (peripheral driving DATA):
# START | CYCTYPE+DIR | ADDR[8] | TAR[2] | SYNC[n] | DATA[2] | TAR[2]
# I/O read (peripheral driving DATA):
# START | CYCTYPE+DIR | ADDR[4] | TAR[2] | SYNC[n] | DATA[2] | TAR[2]
# Memory write (host driving DATA):
# START | CYCTYPE+DIR | ADDR[8] | DATA[2] | TAR[2] | SYNC[n] | TAR[2]
# I/O write (host driving DATA):
# START | CYCTYPE+DIR | ADDR[4] | DATA[2] | TAR[2] | SYNC[n] | TAR[2]
#
# Firmware cycles
# ---------------
# Firmware memory read (peripheral driving DATA):
# START | IDSEL | ADDR[7] | MSIZE | TAR[2] | SYNC[n] | DATA[2m]
# Firmware memory write (host driving DATA):
# START | IDSEL | ADDR[7] | MSIZE | DATA[2m] | SYNC[n] | TAR[2]
#
# DMA cycles
# ----------
# DMA read (host driving DATA):
# START | CYCTYPE+DIR | CHANNEL | SIZE | ( DATA[2] | TAR[2] | SYNC | TAR[2] )[m]
# DMA write (peripheral driving DATA):
# START | CYCTYPE+DIR | CHANNEL | SIZE | TAR[2] | ( SYNC | DATA[2] )[m] | TAR[2]
#
# Bus master cycles
# -----------------
# Memory read (host driving DATA):
# START | TAR[2] | CYCTYPE+DIR | ADDR[8] | SIZE | TAR[2] | SYNC[n] | DATA[2m] | TAR[2]
# I/O read (host driving DATA):
# START | TAR[2] | CYCTYPE+DIR | ADDR[4] | SIZE | TAR[2] | SYNC[n] | DATA[2m] | TAR[2]
# Memory write (peripheral driving DATA):
# START | TAR[2] | CYCTYPE+DIR | ADDR[8] | SIZE | DATA[2m] | TAR[2] | SYNC[n] | TAR[2]
# I/O write (peripheral driving DATA):
# START | TAR[2] | CYCTYPE+DIR | ADDR[4] | SIZE | DATA[2m] | TAR[2] | SYNC[n] | TAR[2]

START_TARGET = 0b0000
START_BUS_MASTER_0 = 0b0010
START_BUS_MASTER_1 = 0b0011
START_FW_MEM_READ = 0b1101
START_FW_MEM_WRITE = 0b1110
STOP_ABORT = 0b1111

DIR_READ = 0b0
DIR_WRITE = 0b1

CYCTYPE_IO = 0b00
CYCTYPE_MEM = 0b01
CYCTYPE_DMA = 0b10

SIZE_1_BYTE = 0b00
SIZE_2_BYTE = 0b01
SIZE_4_BYTE = 0b11

SYNC_READY = 0b0000
SYNC_SHORT_WAIT = 0b0101
SYNC_LONG_WAIT = 0b0110
SYNC_READY_MORE = 0b1001
SYNC_ERROR = 0b1010

MSIZE_1_BYTE = 0b0000
MSIZE_2_BYTE = 0b0001
MSIZE_4_BYTE = 0b0010
MSIZE_16_BYTE = 0b0100
MSIZE_128_BYTE = 0b0111
4 changes: 3 additions & 1 deletion software/glasgow/cli.py
Original file line number Diff line number Diff line change
@@ -592,13 +592,15 @@ async def run_applet():

if args.action == "build":
target, applet = _applet(args)
logger.info("building bitstream for applet %r", args.applet)
if args.type in ("v", "verilog"):
logger.info("building Verilog for applet %r", args.applet)
target.get_verilog().write(args.filename or args.applet + ".v")
if args.type in ("bin", "bitstream"):
logger.info("building bitstream for applet %r", args.applet)
with open(args.filename or args.applet + ".bin", "wb") as f:
f.write(target.get_bitstream(debug=True))
if args.type in ("zip", "archive"):
logger.info("building archive for applet %r", args.applet)
with target.get_build_tree() as tree:
if args.filename:
basename, = os.path.splitext(args.filename)
29 changes: 22 additions & 7 deletions software/glasgow/gateware/fx2.py
Original file line number Diff line number Diff line change
@@ -27,6 +27,7 @@
from migen.genlib.fsm import *
from migen.genlib.cdc import MultiReg
from migen.genlib.fifo import _FIFOInterface, AsyncFIFO, SyncFIFO, SyncFIFOBuffered
from migen.genlib.resetsync import AsyncResetSynchronizer


__all__ = ["FX2Arbiter"]
@@ -287,17 +288,31 @@ def _make_fifo(self, arbiter_side, logic_side, cd_logic, reset, depth, wrapper):
assert isinstance(cd_logic, ClockDomain)

fifo = wrapper(ClockDomainsRenamer({
arbiter_side: "sys",
arbiter_side: "arbiter",
logic_side: "logic",
})(AsyncFIFO(8, depth)))

# Note that for the reset to get asserted AND deasserted, the logic clock domain must
# have a running clock. This is because, while AsyncResetSynchronizer is indeed
# asynchronous, the registers in the FIFO logic clock domain reset synchronous
# to the logic clock, as this is how Migen handles clock domain reset signals.
#
# If the logic clock domain does not have a single clock transition between assertion
# and deassertion of FIFO reset, and the FIFO has not been empty at the time when
# reset has been asserted, stale data will be read from the FIFO after deassertion.
#
# This can lead to all sorts of framing issues, and is rather unfortunate, but at
# the moment I do not know of a way to fix this, since Migen does not support
# asynchronous resets.
fifo.clock_domains.cd_arbiter = ClockDomain(reset_less=reset is None)
fifo.clock_domains.cd_logic = ClockDomain(reset_less=reset is None)
fifo.comb += [
fifo.cd_arbiter.clk.eq(ClockSignal()),
fifo.cd_logic.clk.eq(cd_logic.clk),
]
if reset is not None:
raise NotImplementedError("reset not yet implemented for async FIFOs")

fifo.clock_domains.cd_logic = ClockDomain()
self.comb += fifo.cd_logic.clk.eq(cd_logic.clk)
if cd_logic.rst is not None:
self.comb += fifo.cd_logic.rst.eq(cd_logic.rst)
fifo.comb += fifo.cd_arbiter.rst.eq(reset)
fifo.specials += AsyncResetSynchronizer(fifo.cd_logic, reset)

self.submodules += fifo
return fifo