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: 09e9824f43d6
Choose a base ref
...
head repository: whitequark/glasgow
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: f3b3bd728b58
Choose a head ref
  • 2 commits
  • 3 files changed
  • 1 contributor

Commits on Feb 6, 2019

  1. target.hardware: explicitly tristate unused pins.

    This was already fixed in 71bcdbb, but on revC, the default pullup
    on iCE40 IOs and the truth table of the level shifters means that any
    undriven OE FPGA pins will cause the corresponding level shifter to
    drive 1.
    whitequark committed Feb 6, 2019
    Copy the full SHA
    8f1c016 View commit details
  2. target.hardware: factor in the platform choose logic.

    This used to live in cli, which is definitely not the right place.
    This commit also fixes tests.
    whitequark committed Feb 6, 2019
    Copy the full SHA
    f3b3bd7 View commit details
Showing with 40 additions and 18 deletions.
  1. +9 −4 software/glasgow/applet/__init__.py
  2. +1 −7 software/glasgow/cli.py
  3. +30 −7 software/glasgow/target/hardware.py
13 changes: 9 additions & 4 deletions software/glasgow/applet/__init__.py
Original file line number Diff line number Diff line change
@@ -83,6 +83,7 @@ async def run(self, args):
from ..target.hardware import *
from ..device.simulation import *
from ..device.hardware import *
from ..platform import GlasgowPlatformRevAB


__all__ += ["GlasgowAppletTestCase", "synthesis_test", "applet_simulation_test",
@@ -184,7 +185,8 @@ def setUp(self):

def assertBuilds(self, access="direct", args=[]):
if access == "direct":
target = GlasgowHardwareTarget(multiplexer_cls=DirectMultiplexer)
target = GlasgowHardwareTarget(revision="A",
multiplexer_cls=DirectMultiplexer)
access_args = DirectArguments(applet_name=self.applet.name,
default_port="AB", pin_count=16)
else:
@@ -222,14 +224,17 @@ async def run_simulated_applet(self):
def _prepare_hardware_target(self, case, fixture, mode):
assert mode in ("record", "replay")

self.target = GlasgowHardwareTarget(multiplexer_cls=DirectMultiplexer)
self.applet.build(self.target, self._parsed_args)

if mode == "record":
self.device = GlasgowHardwareDevice()
self.device.demultiplexer = DirectDemultiplexer(self.device)
revision = self.device.revision
else:
self.device = None
revision = "A"

self.target = GlasgowHardwareTarget(revision=revision,
multiplexer_cls=DirectMultiplexer)
self.applet.build(self.target, self._parsed_args)

self._recording = False
self._recorders = []
8 changes: 1 addition & 7 deletions software/glasgow/cli.py
Original file line number Diff line number Diff line change
@@ -16,7 +16,6 @@
from ._version import get_versions
from .device import GlasgowDeviceError
from .device.config import GlasgowConfig
from .platform import GlasgowPlatformRevAB, GlasgowPlatformRevC
from .target.hardware import GlasgowHardwareTarget
from .gateware import GatewareBuildError
from .gateware.analyzer import TraceDecoder
@@ -285,12 +284,7 @@ def serial(arg):

# The name of this function appears in Verilog output, so keep it tidy.
def _applet(revision, args):
platform_cls = {
"A": GlasgowPlatformRevAB,
"B": GlasgowPlatformRevAB,
"C": GlasgowPlatformRevC,
}
target = GlasgowHardwareTarget(platform_cls=platform_cls[revision],
target = GlasgowHardwareTarget(revision=revision,
multiplexer_cls=DirectMultiplexer,
with_analyzer=hasattr(args, "trace") and args.trace)
applet = GlasgowApplet.all_applets[args.applet]()
37 changes: 30 additions & 7 deletions software/glasgow/target/hardware.py
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@
from ..gateware.registers import I2CRegisters
from ..gateware.fx2 import FX2Arbiter
from ..gateware.platform.lattice import special_overrides
from ..platform import GlasgowPlatformRevAB, GlasgowPlatformRevC
from .analyzer import GlasgowAnalyzer


@@ -48,8 +49,15 @@ def __init__(self, platform):
class GlasgowHardwareTarget(Module):
sys_clk_freq = 30e6

def __init__(self, platform_cls, multiplexer_cls=None, with_analyzer=False):
self.platform = platform_cls()
def __init__(self, revision, multiplexer_cls=None, with_analyzer=False):
if revision == "A":
self.platform = GlasgowPlatformRevAB()
elif revision == "B":
self.platform = GlasgowPlatformRevAB()
elif revision == "C":
self.platform = GlasgowPlatformRevC()
else:
raise ValueError("Unknown revision")

try:
unused = self.platform.request("unused")
@@ -67,14 +75,17 @@ def __init__(self, platform_cls, multiplexer_cls=None, with_analyzer=False):

self.submodules.fx2_arbiter = FX2Arbiter(self.platform.request("fx2"))

self.ports = {
"A": (8, lambda n: self.platform.request("port_a", n)),
"B": (8, lambda n: self.platform.request("port_b", n)),
}

if multiplexer_cls:
ports = {
"A": (8, lambda n: self.platform.request("port_a", n)),
"B": (8, lambda n: self.platform.request("port_b", n)),
}
pipes = "PQ"
self.submodules.multiplexer = multiplexer_cls(ports=ports, pipes=pipes,
self.submodules.multiplexer = multiplexer_cls(ports=self.ports, pipes="PQ",
registers=self.registers, fx2_arbiter=self.fx2_arbiter)
else:
self.multiplexer = None

if with_analyzer:
self.submodules.analyzer = GlasgowAnalyzer(self.registers, self.multiplexer)
@@ -87,6 +98,18 @@ def finalize(self, *args, **kwargs):
if self.analyzer:
self.analyzer._finalize_pin_events()

unused_pins = []
for width, req in self.ports.values():
for n in range(width):
try:
unused_pins.append(req(n))
except migen.build.generic_platform.ConstraintError:
pass
for unused_pin in unused_pins:
self.specials += TSTriple().get_tristate(unused_pin.io)
if hasattr(unused_pin, "oe"):
self.comb += unused_pin.oe.eq(0)

super().finalize(*args, **kwargs)

def get_fragment(self):