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: m-labs/migen
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 408a85f0226e
Choose a base ref
...
head repository: m-labs/migen
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: ccf63038cc40
Choose a head ref
  • 4 commits
  • 6 files changed
  • 2 contributors

Commits on Apr 2, 2016

  1. migen/build/platforms: adding apf6sp Armadeus Platform

    Signed-off-by: Fabien Marteau <fabien.marteau@armadeus.com>
    Martoni authored and sbourdeauducq committed Apr 2, 2016
    Copy the full SHA
    7cb3634 View commit details
  2. migen/genlib: little module documentation

    Signed-off-by: Fabien Marteau <fabien.marteau@armadeus.com>
    Martoni authored and sbourdeauducq committed Apr 2, 2016
    Copy the full SHA
    dc724f9 View commit details
  3. migen/fhdl: better error messages

    Signed-off-by: Fabien Marteau <fabien.marteau@armadeus.com>
    Martoni authored and sbourdeauducq committed Apr 2, 2016
    Copy the full SHA
    1acfa57 View commit details
  4. build/xilinx/ise: Use separate TNM_NET for period and TIG constraints.

    Because ISE is retarded, if you have anything other than period constraints on
    a TNM_NET (such as a TIG), then it is unable to trace the constraints through
    any of the clock elements like PLLs and DCMs. It will generate the following
    warning instead;
    
    > ConstraintSystem - TNM : *** was distributed to a DCM but new TNM constraints
    > were not derived. The requirement for derived TNM constraints is that the
    > distributed TNM is referenced by no more than a single PERIOD constraint.
    > Non-PERIOD referencers are also not allowed.
    
    The requirements for the TNM to be derived is described at
    [Timing Constraints User Guide - UG612 (v 11.1.1) April 29, 2009](http://www.xilinx.com/support/documentation/sw_manuals/xilinx11/ug612.pdf):
    
     * The TNM group is used in exactly one PERIOD specification.
     * The TNM group is not used in any FROM-TO or OFFSET specifications.
     * The TNM group is not referenced in any user group definition.
    
    The fix is described in http://www.xilinx.com/support/answers/40007.html ||
    http://www.xilinx.com/support/answers/37782.html
    
    Create two TNM Groups for your input clock. One used for the FROM-TO
    constraints and the other for the PERIOD propagation.
    
    Fixes #43
    mithro authored and sbourdeauducq committed Apr 2, 2016
    2
    Copy the full SHA
    ccf6303 View commit details
Showing with 280 additions and 7 deletions.
  1. +247 −0 migen/build/platforms/apf6sp.py
  2. +20 −5 migen/build/xilinx/ise.py
  3. +6 −1 migen/fhdl/specials.py
  4. +1 −1 migen/fhdl/structure.py
  5. +4 −0 migen/genlib/cdc.py
  6. +2 −0 migen/genlib/io.py
247 changes: 247 additions & 0 deletions migen/build/platforms/apf6sp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
""" Platform definitions for apf6sp board by Armadeus System """
from migen import *
from migen.fhdl import *
from migen.build.generic_platform import *
from migen.build.altera import AlteraPlatform

_io = [("pcie_x1", 0,
Subsignal("clk_p", Pins("V4"), IOStandard("1.5-V PCML")),
Subsignal("clk_n", Pins("U4"), IOStandard("1.5-V PCML")),
Subsignal("rx_p", Pins("AA2"), IOStandard("1.5-V PCML")),
Subsignal("rx_n", Pins("AA1"), IOStandard("1.5-V PCML")),
Subsignal("tx_p", Pins("Y4"), IOStandard("1.5-V PCML")),
Subsignal("tx_n", Pins("Y3"), IOStandard("1.5-V PCML")),
Subsignal("perst", Pins("R17"), IOStandard("2.5 V")),
Subsignal("npor", Pins("R16"), IOStandard("2.5 V"))),

("pcie_clk", 0,
Subsignal("p", Pins("V4"), IOStandard("1.5-V PCML")),
Subsignal("n", Pins("U4"), IOStandard("1.5-V PCML"))),

("ddram", 0,
Subsignal("a", Pins("C11 B11 A8 A7 " +
"D11 E11 F8 E7 " +
"D9 D8 B6 B5 C8 " +
"B8 H6"), IOStandard("SSTL-135")),

Subsignal("ba", Pins("C6 C10 C9"), IOStandard("SSTL-135")),

Subsignal("ras_n", Pins("A9"), IOStandard("SSTL-135")),
Subsignal("cas_n", Pins("A10"), IOStandard("SSTL-135")),
Subsignal("cs_n", Pins("H8"), IOStandard("SSTL-135")),
Subsignal("we_n", Pins("E6"), IOStandard("SSTL-135")),

Subsignal("dm", Pins("A15 C19 C21 F12 " +
"E12 B12 B13 C13 " +
"D13 C14 A14 E14 " +
"F15 B18 A17 C15 " +
"C16 B16 C18 D17 " +
"E16 A20 A22 E17 " +
"D18 B20 C20"), IOStandard("SSTL-135")),

Subsignal("dqs_n",
Pins("G8 H12 G14"),
IOStandard("SSTL-135")),

Subsignal("dqs",
Pins("H9 G12 G15"),
IOStandard("SSTL-135")),

Subsignal("ck", Pins("J9"), IOStandard("SSTL-135")),
Subsignal("ck_n", Pins("J8"), IOStandard("SSTL-135")),
Subsignal("cke", Pins("B15"), IOStandard("SSTL-135")),
Subsignal("odt", Pins("A13"), IOStandard("SSTL-135")),

Subsignal("reset_n", Pins("B22"), IOStandard("SSTL-135")),
Subsignal("oct_rzqin", Pins("A12"), IOStandard("SSTL-135")))]

_connector = [
("HIROSE",
{"CLKIN0": "T10",
"CLKIN_1N": "R9",
"CLKIN_1P": "P9",
"CLKIN_2N": "R15",
"CLKIN_2P": "T15",
"CLKOUT0": "R10",
"CLKOUT_1N": "G17",
"CLKOUT_1P": "G18",
"CLKOUT_2N": "AB22",
"CLKOUT_2P": "AA22",
"D0": "M10",
"D1": "K15",
"D2": "L9",
"D3": "L15",
"LVDS_RX_N0": "AA9",
"LVDS_RX_P0": "Y9",
"LVDS_RX_N1": "U10",
"LVDS_RX_P1": "U11",
"LVDS_RX_N2": "U8",
"LVDS_RX_P2": "V9",
"LVDS_RX_N3": "U12",
"LVDS_RX_P3": "T12",
"LVDS_RX_N4": "W13",
"LVDS_RX_P4": "V13",
"LVDS_RX_N5": "W12",
"LVDS_RX_P5": "Y12",
"LVDS_RX_N6": "Y14",
"LVDS_RX_P6": "W14",
"LVDS_RX_N7": "U16",
"LVDS_RX_P7": "U17",
"LVDS_RX_N8": "Y16",
"LVDS_RX_P8": "Y17",
"LVDS_RX_N9": "W16",
"LVDS_RX_P9": "W17",
"LVDS_RX_N10": "V18",
"LVDS_RX_P10": "W18",
"LVDS_RX_N11": "V19",
"LVDS_RX_P11": "V20",
"LVDS_RX_N12": "T18",
"LVDS_RX_P12": "T17",
"LVDS_RX_N13": "J18",
"LVDS_RX_P13": "J17",
"LVDS_RX_N14": "K19",
"LVDS_RX_P14": "L18",
"LVDS_RX_N15": "L20",
"LVDS_RX_P15": "L19",
"LVDS_RX_N16": "P19",
"LVDS_RX_P16": "R19",
"LVDS_TX_N0": "W11",
"LVDS_TX_P0": "Y11",
"LVDS_TX_N1": "R12",
"LVDS_TX_P1": "T13",
"LVDS_TX_N2": "AA13",
"LVDS_TX_P2": "AB13",
"LVDS_TX_N3": "AB10",
"LVDS_TX_P3": "AB11",
"LVDS_TX_N4": "Y10",
"LVDS_TX_P4": "AA10",
"LVDS_TX_N5": "AA15",
"LVDS_TX_P5": "Y15",
"LVDS_TX_N6": "AB15",
"LVDS_TX_P6": "AB16",
"LVDS_TX_N7": "R11",
"LVDS_TX_P7": "P12",
"LVDS_TX_N8": "AA17",
"LVDS_TX_P8": "AB17",
"LVDS_TX_N9": "AB18",
"LVDS_TX_P9": "AA18",
"LVDS_TX_N10": "AA19",
"LVDS_TX_P10": "Y19",
"LVDS_TX_N11": "R21",
"LVDS_TX_P11": "R20",
"LVDS_TX_N12": "AB20",
"LVDS_TX_P12": "AB21",
"LVDS_TX_N13": "AA20",
"LVDS_TX_P13": "Y20",
"LVDS_TX_N14": "U21",
"LVDS_TX_P14": "U22",
"LVDS_TX_N15": "R22",
"LVDS_TX_P15": "T22",
"LVDS_TX_N16": "G21",
"LVDS_TX_P16": "G22",
"XCVR_RX_N0": "W1",
"XCVR_RX_P0": "W2",
"XCVR_RX_N1": "R1",
"XCVR_RX_P1": "R2",
"XCVR_RX_N2": "L1",
"XCVR_RX_P2": "L2",
"XCVR_TX_N0": "U1",
"XCVR_TX_P0": "U2",
"XCVR_TX_N1": "N1",
"XCVR_TX_P1": "N2",
"XCVR_TX_N2": "J1",
"XCVR_TX_P2": "J2",
}
)]

class Platform(AlteraPlatform):
""" Apf6sp platform """
default_clk_name = "pcie_clk"
default_clk_period = 8

def __init__(self, toolchain="quartus"):
AlteraPlatform.__init__(self, "5CGXFC4C7U19C8", _io, _connector)


class PciePllClockedModule(Module):
""" This function add the pcie PLL as main clock for modules.
See http://www.armadeus.com/wiki/index.php?title=IMX6-CycloneV_interface_description#Clocking_without_PCIe
for the explainations
"""

def __init__(self, platform):
cd_sys = ClockDomain(name="cd_sys", reset_less=True)
self.clock_domains += cd_sys

pcie_clk = platform.request("pcie_clk")
pci_clk_sig = Signal()

self.specials += Instance("ALT_INBUF_DIFF", name="ibuf_diff",
i_i=pcie_clk.p,
i_ibar=pcie_clk.n,
o_o=pci_clk_sig)
self.specials += Instance("altera_pll",
i_rst=0,
o_outclk=cd_sys.clk,
i_refclk=pci_clk_sig,

p_fractional_vco_multiplier="false",
p_reference_clock_frequency="125.0 MHz",
p_operation_mode="direct",
p_number_of_clocks=Instance.PreformattedParam("1"),
p_output_clock_frequency0="62.500000 MHz",
p_phase_shift0="0 ps",
p_duty_cycle0=Instance.PreformattedParam("50"),
p_output_clock_frequency1="0 MHz",
p_phase_shift1="0 ps",
p_duty_cycle1=Instance.PreformattedParam("50"),
p_output_clock_frequency2="0 MHz",
p_phase_shift2="0 ps",
p_duty_cycle2=Instance.PreformattedParam("50"),
p_output_clock_frequency3="0 MHz",
p_phase_shift3="0 ps",
p_duty_cycle3=Instance.PreformattedParam("50"),
p_output_clock_frequency4="0 MHz",
p_phase_shift4="0 ps",
p_duty_cycle4=Instance.PreformattedParam("50"),
p_output_clock_frequency5="0 MHz",
p_phase_shift5="0 ps",
p_duty_cycle5=Instance.PreformattedParam("50"),
p_output_clock_frequency6="0 MHz",
p_phase_shift6="0 ps",
p_duty_cycle6=Instance.PreformattedParam("50"),
p_output_clock_frequency7="0 MHz",
p_phase_shift7="0 ps",
p_duty_cycle7=Instance.PreformattedParam("50"),
p_output_clock_frequency8="0 MHz",
p_phase_shift8="0 ps",
p_duty_cycle8=Instance.PreformattedParam("50"),
p_output_clock_frequency9="0 MHz",
p_phase_shift9="0 ps",
p_duty_cycle9=Instance.PreformattedParam("50"),
p_output_clock_frequency10="0 MHz",
p_phase_shift10="0 ps",
p_duty_cycle10=Instance.PreformattedParam("50"),
p_output_clock_frequency11="0 MHz",
p_phase_shift11="0 ps",
p_duty_cycle11=Instance.PreformattedParam("50"),
p_output_clock_frequency12="0 MHz",
p_phase_shift12="0 ps",
p_duty_cycle12=Instance.PreformattedParam("50"),
p_output_clock_frequency13="0 MHz",
p_phase_shift13="0 ps",
p_duty_cycle13=Instance.PreformattedParam("50"),
p_output_clock_frequency14="0 MHz",
p_phase_shift14="0 ps",
p_duty_cycle14=Instance.PreformattedParam("50"),
p_output_clock_frequency15="0 MHz",
p_phase_shift15="0 ps",
p_duty_cycle15=Instance.PreformattedParam("50"),
p_output_clock_frequency16="0 MHz",
p_phase_shift16="0 ps",
p_duty_cycle16=Instance.PreformattedParam("50"),
p_output_clock_frequency17="0 MHz",
p_phase_shift17="0 ps",
p_pll_subtype="General",
p_pll_type="General",
p_duty_cycle17=Instance.PreformattedParam("50"))
25 changes: 20 additions & 5 deletions migen/build/xilinx/ise.py
Original file line number Diff line number Diff line change
@@ -193,12 +193,27 @@ def build(self, platform, fragment, build_dir="build", build_name="top",

return vns

# ISE is broken and you must use *separate* TNM_NET objects for period
# constraints and other constraints otherwise it will be unable to trace
# them through clock objects like DCM and PLL objects.

def add_period_constraint(self, platform, clk, period):
platform.add_platform_command("""NET "{clk}" TNM_NET = "GRP{clk}";
TIMESPEC "TS{clk}" = PERIOD "GRP{clk}" """ + str(period) + """ ns HIGH 50%;""",
clk=clk)
platform.add_platform_command(
"""
NET "{clk}" TNM_NET = "PRD{clk}";
TIMESPEC "TS{clk}" = PERIOD "PRD{clk}" {period} ns HIGH 50%;
""",
clk=clk,
period=str(period),
)

def add_false_path_constraint(self, platform, from_, to):
platform.add_platform_command(
"""TIMESPEC "TS{from_}TO{to}" = FROM "GRP{from_}" TO "GRP{to}" TIG;""",
from_=from_, to=to)
"""
NET "{from_}" TNM_NET = "TIG{from_}";
NET "{to}" TNM_NET = "TIG{to}";
TIMESPEC "TS{from_}TO{to}" = FROM "TIG{from_}" TO "TIG{to}" TIG;
""",
from_=from_,
to=to,
)
7 changes: 6 additions & 1 deletion migen/fhdl/specials.py
Original file line number Diff line number Diff line change
@@ -111,7 +111,12 @@ def __init__(self, of, *items, name="", synthesis_directive=None, **kwargs):
self.items = list(items)
self.synthesis_directive = synthesis_directive
for k, v in sorted(kwargs.items(), key=itemgetter(0)):
item_type, item_name = k.split("_", maxsplit=1)
try:
item_type, item_name = k.split("_", maxsplit=1)
except ValueError:
raise TypeError("Wrong format for value '" + str(k) +
"', format should be 'type_name'")

item_class = {
"i": Instance.Input,
"o": Instance.Output,
2 changes: 1 addition & 1 deletion migen/fhdl/structure.py
Original file line number Diff line number Diff line change
@@ -136,7 +136,7 @@ def wrap(value):
if isinstance(value, (bool, int)):
value = Constant(value)
if not isinstance(value, _Value):
raise TypeError("Object is not a Migen value")
raise TypeError("Object '" + str(value) + "'is not a Migen value")
return value


4 changes: 4 additions & 0 deletions migen/genlib/cdc.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
"""
Clock domain crossing module
"""

from migen.fhdl.structure import *
from migen.fhdl.module import Module
from migen.fhdl.specials import Special
2 changes: 2 additions & 0 deletions migen/genlib/io.py
Original file line number Diff line number Diff line change
@@ -38,6 +38,8 @@ def lower(dr):


class CRG(Module):
""" Clock and Reset Generator """

def __init__(self, clk, rst=0):
self.clock_domains.cd_sys = ClockDomain()
self.clock_domains.cd_por = ClockDomain(reset_less=True)