Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Platform clock definitions are very inflexible #86

Closed
whitequark opened this issue Jun 5, 2019 · 3 comments
Closed

Platform clock definitions are very inflexible #86

whitequark opened this issue Jun 5, 2019 · 3 comments
Milestone

Comments

@whitequark
Copy link
Contributor

Right now, platform clocks are defined like this:

class TinyFPGABXPlatform(LatticeICE40Platform):
    device     = "iCE40LP8K"
    package    = "CM81"
    clocks     = [
        ("clk16", 16e6),
    ]
    resources  = [
        Resource("clk16", 0, Pins("B2", dir="i"),
                 extras={"IO_STANDARD": "SB_LVCMOS33"}),
        # ...
    ]

There is a problem though: it is only possible to declare a top-level resource as a clock (i.e. not a subsignal). Something like Versa has this resource in oMigen:

    ("eth_clocks", 0,
        Subsignal("tx", Pins("P19")),
        Subsignal("rx", Pins("L20")),
        IOStandard("LVCMOS25")
    ),

which has custom code to add clock constraints in do_finalize.

@whitequark
Copy link
Contributor Author

whitequark commented Jun 5, 2019

I propose that instead of declaring a resource or subsignal a clock at the top level, it would be done as follows:

class TinyFPGABXPlatform(LatticeICE40Platform):
    device     = "iCE40LP8K"
    package    = "CM81"
    resources  = [
        Resource("clk16", 0, Pins("B2", dir="i"),
                 extras={"IO_STANDARD": "SB_LVCMOS33"},
                 frequency=16e6),
        # ...
    ]

Bikeshed: maybe this would be slightly more elegant?

class TinyFPGABXPlatform(LatticeICE40Platform):
    device     = "iCE40LP8K"
    package    = "CM81"
    resources  = [
        Resource("clk16", 0, Pins("B2", dir="i"), Clock(16e6),
                 Extras(IO_STANDARD="SB_LVCMOS33")),
        # ...
    ]

The implementation would be similar to the current one: the platform.request("clk16") call would discover the Clock element in the resource description, and automatically call platform.add_frequency_constraint. Of course, if a clock does not have a fixed frequency, it is always possible to omit the Clock element and add the constraint manually.

@cr1901
Copy link
Contributor

cr1901 commented Jun 5, 2019

Just to add a data point: Some platforms, TinyFPGA A in particular, don't actually have a clock pin, instead relying on the FPGA's internal oscillator. I did some things I'm not exactly proud of to get it to play nice with omigen, even if the commit was accepted.

So if there is a way to more nicely support internal clock constraints or otherwise without a do_finalize dance or request overload, I'm open to feedback.

@whitequark
Copy link
Contributor Author

Right, so that's a related but different situation: defining frequency constraints on ports and on nets. Currently nextpnr is deficient in that it does not allow to reliably define a frequency constraint on a net, so we're going to have to teach platform.add_frequency_constraint to distinguish ports and nets, and only support for ports will be an absolute requirement for any new platform.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants