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

Accessing input pin directly (Intel) #503

Closed
H-S-S-11 opened this issue Oct 9, 2020 · 6 comments
Closed

Accessing input pin directly (Intel) #503

H-S-S-11 opened this issue Oct 9, 2020 · 6 comments
Labels

Comments

@H-S-S-11
Copy link
Contributor

H-S-S-11 commented Oct 9, 2020

For the Stratix IV PLL (I assume it also applies to altpll in general), the input clock can't be driven by a combinational block. When instantiating a PLL, I can't find any way of driving it directly from the input pin. Using platform.request() explicitly creates a module with an altiobuf, which confuses quartus by placing buffers that get synthesised as combinational blocks (LUTs) in the clock path.

Nmigen code:

Instance \
        (
            pll_module_name,

            i_inclk0=platform.request("clk50", 1, dir="-"),
            o_c0=clk200,
        ))```

The generated code shows the problem:

```verilog
module pin_clk50_1(clk50_1__io, clk50_1__i);
  (* keep = 1 *)
  output clk50_1__i;
  input clk50_1__io;
  altiobuf_in #(
    .enable_bus_hold("FALSE"),
    .number_of_channels(1'h1),
    .use_differential_mode("FALSE")
  ) clk50_1 (
    .datain(clk50_1__io),
    .dataout(clk50_1__i)
  );
endmodule

module top(pwm_0__io, clk50_1__io);
  wire clk50_1__i;
  input clk50_1__io;
  wire clk200;
pin_clk50_1 pin_clk50_1 (
    .clk50_1__i(clk50_1__i),
    .clk50_1__io(clk50_1__io)
  );
SIV_pll_200M \clk200$1  (
    .c0(clk200),
    .inclk0(clk50_1__i)
  );`

Since quartus automatically places an iobuf, the pin_ module isn't necessary at all here: the pll input should be clk50_1__io. Instantiating a PLL needs a way of directly accessing the underlying pin, without any buffers. This can be done with dir="-" when requesting a new clock, but on platforms with one clock this may not be possible
@whitequark
Copy link
Member

Use platform.request("clk50", 1, dir="-") instead of platform.request("clk50", 1).i.

@H-S-S-11
Copy link
Contributor Author

H-S-S-11 commented Oct 9, 2020

Ah my bad: I sort of changed what I was asking halfway through, I should edit the original question to make it a bit more clear. Basically I'm asking how you would do this on a platform with one clock: if the sync domain has already requested the default clock ("clk50", 0), how would one go about using that clock input directly (ie without an iobuf)?

@whitequark
Copy link
Member

whitequark commented Oct 9, 2020

You can't. This is for a few reasons, mostly because the automatically requested clock is designed to have power-on reset logic inserted as well, which will break your PLL clocking anyway.

@H-S-S-11
Copy link
Contributor Author

H-S-S-11 commented Oct 9, 2020

Ah ok thank you, I see. I suppose it's not likely to cause a limitation as any chip with a PLL probably has multiple clock inputs anyway but that's worth knowing.

@H-S-S-11 H-S-S-11 closed this as completed Oct 9, 2020
@whitequark
Copy link
Member

In general you want to wire the reset of the clock domain you're driving with a PLL to the "locked" output of the PLL, not to the power-on reset.

@H-S-S-11
Copy link
Contributor Author

H-S-S-11 commented Oct 9, 2020

Got it, that would make sense for clock domain sync purposes.

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

No branches or pull requests

2 participants