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

A little help with defining platform pins? #278

Closed
RobertBaruch opened this issue Nov 30, 2019 · 2 comments
Closed

A little help with defining platform pins? #278

RobertBaruch opened this issue Nov 30, 2019 · 2 comments
Labels

Comments

@RobertBaruch
Copy link

I'm looking at the ice40hx8k, and I vaguely understand the blinky example, but it's not really clear from that, nor from the source, how to define and use my own resources and pins.

  1. It seems there must be a default clock defined, and it seems to be used for a reset delay. Also, it vaguely seems to be connected to the sync domain.

    a. What if I don't have a sync domain? What if I have instead two clock domains named ph1 and ph2? I can define these resources, but how do I say which is connected to ph1.clk and which is ph2.clk? And what about their resets -- how are pins configured as the resets (not talking about CRESET_B which seems to reload the entire FPGA configuration)?

    # For ice40hx8k ball functions, see 
    # https://www.latticesemi.com/view_document?document_id=49386
    # also https://www.latticesemi.com/-/media/LatticeSemi/Documents/UserManuals/EI/EB85.ashx?document_id=50373

    default_clk = "clk_J3"
    resources = [
        Resource("clk_J3", 0, Pins("J3", dir="i"), Clock(12e6),
                 Attrs(GLOBAL=True, IO_STANDARD="SB_LVCMOS")), # GBIN6
        Resource("clk_G1", 0, Pins("G1", dir="i"), Clock(12e6),
                 Attrs(GLOBAL=True, IO_STANDARD="SB_LVCMOS")), # GBIN7
    ]
    ...
    ph1 = ClockDomain("ph1")
    ph2 = ClockDomain("ph2", clk_edge="neg")
    ...
    m.domains.ph1 = ph1
    m.domains.ph2 = ph2
    ...
    # How do I connect clk_J3 to ph1, and clk_G1 to ph2?
  1. How do I declare a pin to be used as an input? Like this?
    resources = [
        ...
        Resource("mice", 0, Pins("H1", dir="i"),
                 Attrs(IO_STANDARD="SB_LVCMOS")), # IOL_14B
        ...
    ]

And do I use it like this?

    rodent0 = platform.request("mice", 0)
    i_eated_it = Signal()
    kitten_present = Signal()
    ...
    m.d.comb += i_eated_it.eq(rodent0.i & kitten_present)

I'm pretty sure I understand the following correctly, but I'd like some confirmation:

  1. It seems the directions are i, o, io, oe. Going from what I think I see in plat.py, I think these mean input, output, bidirectional, and tristate output, right?

  2. Is an input accessed via <signal>.i? Output via <signal>.o? A tristate via <signal>.o for the output and <signal>.oe for the output enable? And a bidirectional via <signal>.o for the output, <signal>.i for the input, and <signal>.oe for the direction (0 = input, 1 = output)?

  3. For pins with invert=True, is it correct that <signal>.i is the invert of the signal present on the physical pin? And that <signal>.o is likewise the invert of the signal that will be output to the physical pin?

@whitequark
Copy link
Contributor

  1. It seems there must be a default clock defined, and it seems to be used for a reset delay. Also, it vaguely seems to be connected to the sync domain.

Correct. The default clock/reset mechanism works as follows. If your HDL uses the sync domain, and this domain does not already exist, it is created, its clock is connected to the resource designated default_clk, and its reset is connected to a device-specific synchronization mechanism that coordinates power-on reset, and (if any) the resource designated default_rst. On Xilinx this mechanism is a BUFGCE (as recommended), on iCE40 it works around a silicon bug, elsewhere it's just a reset synchronizer.

What if I don't have a sync domain?

If your HDL never uses the sync domain, or if you explicitly define a sync domain using m.domains += ClockDomain("sync", ...) then nothing happens on its own. You should connect the clocks of your domain(s) to pins or perhaps oscillator instances.

If you do not have a default_clk, your HDL uses the sync domain, and does not define it, then an exception will stop the build.

  1. I can define these resources, but how do I say which is connected to ph1.clk and which is ph2.clk? And what about their resets -- how are pins configured as the resets (not talking about CRESET_B which seems to reload the entire FPGA configuration)?

There is fundamentally nothing special about clocks and resets. You can do something like

m.domains.ph1 = ph1 = ClockDomain("ph1", clk_edge="pos")
m.domains.ph1 = ph2 = ClockDomain("ph2", clk_edge="neg")
clk = platform.request("some_clk")
rst = platform.request("some_rst")
m.d.comb += [
  ph1.clk.eq(clk.i),
  ph2.clk.eq(clk.i),
  ph1.rst.eq(rst.i),
  ph2.rst.eq(rst.i),
]
  1. How do I declare a pin to be used as an input? Like this?

Yes, if the pin will always be an input (in most cases, the pin direction is well-known). In the rare case where for some reason you want to have a GPIO resource (not a connector), you can omit dir in the board file, and provide it to platform.request, like platform.request("foo", dir="i"). It is recommended to always declare the direction in the board file, since this reduces opportunity for a mistake.

And do I use it like this?

Yes. The default resource number is 0, so for singleton resources (one you're pretty sure you will only have one of), you can omit it.

  • It seems the directions are i, o, io, oe. Going from what I think I see in plat.py, I think these mean input, output, bidirectional, and tristate output, right?
  • Is an input accessed via <signal>.i? Output via <signal>.o? A tristate via <signal>.o for the output and <signal>.oe for the output enable? And a bidirectional via <signal>.o for the output, <signal>.i for the input, and <signal>.oe for the direction (0 = input, 1 = output)?
  • For pins with invert=True, is it correct that <signal>.i is the invert of the signal present on the physical pin? And that <signal>.o is likewise the invert of the signal that will be output to the physical pin?

All correct.

@RobertBaruch
Copy link
Author

Thank you, that definitely helps me, especially the hint about default_rst.

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

No branches or pull requests

2 participants