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

Incorrect PLL-BUFG-BUFGMUX handling #1645

Open
rw1nkler opened this issue Aug 21, 2020 · 1 comment
Open

Incorrect PLL-BUFG-BUFGMUX handling #1645

rw1nkler opened this issue Aug 21, 2020 · 1 comment

Comments

@rw1nkler
Copy link
Contributor

rw1nkler commented Aug 21, 2020

During the work on merging #1419 I figured out that the basic BUFGMUX example works differently on Arty Board and Nexys Video.

The example uses three LEDs:

  • led[2] - blinks with slow frequency
  • led[1] - blinks with high frequency
  • led[0] - blinks with the same frequency as led[2] or led[1] depending on sw[0] state.

On the Arty Board, the example works as intended. On Nexys Video, when the switch is set to led[2] frequency, the led[0] stops to blink. The same error was occurring for the Basys3 board.

The failing example was the following:

module top (
    input  wire clk,

    input  wire [7:0] sw,
    output wire [7:0] led,
);
    wire O_LOCKED;
    wire RST;

    wire clk0;
    wire clk1;
    wire clk_out;
    wire clk_fb_i;
    wire clk_fb_o;

    reg [25:0] cnt_clk_out;
    reg [25:0] cnt_clk0;
    reg [25:0] cnt_clk1;

    assign RST = 1'b0;

    BUFG bufg0 (
        .I(clk_fb_i),
        .O(clk_fb_o)
    );

    wire clk_ibuf;
    IBUF ibuf0 (
        .I(clk),
        .O(clk_ibuf)
    );

    wire clk_bufg;
    BUFG bufg1 (
        .I(clk_ibuf),
        .O(clk_bufg)
    );

    PLLE2_ADV #(
        .BANDWIDTH          ("HIGH"),
        .COMPENSATION       ("ZHOLD"),

        .CLKIN1_PERIOD      (10.0),  // 100MHz

        .CLKFBOUT_MULT      (8),
        .CLKOUT0_DIVIDE     (8),
        .CLKOUT1_DIVIDE     (8 * 4),

        .STARTUP_WAIT       ("FALSE"),

        .DIVCLK_DIVIDE      (1)
    )
    pll (
        .CLKIN1     (clk_bufg),
        .CLKINSEL   (1),

        .RST        (RST),
        .PWRDWN     (0),
        .LOCKED     (O_LOCKED),

        .CLKFBIN    (clk_fb_i),
        .CLKFBOUT   (clk_fb_o),

        .CLKOUT0    (clk0),
        .CLKOUT1    (clk1)
    );

    wire clk0_bufg;
    BUFG bufg2 (
        .I(clk0),
        .O(clk0_bufg)
    );

    wire clk1_bufg;
    BUFG bufg3 (
        .I(clk1),
        .O(clk1_bufg)
    );

    BUFGMUX bufgmux (
      .I0(clk0_bufg),
      .I1(clk1_bufg),
      .S(sw[0]),
      .O(clk_out)
    );

    always @(posedge clk_out) begin
        cnt_clk_out <= cnt_clk_out + 1'b1;
    end
    assign led[0] = cnt_clk_out[25];

    always @(posedge clk0_bufg) begin
        cnt_clk0 <= cnt_clk0 + 1'b1;
    end
    assign led[1] = cnt_clk0[25];

    always @(posedge clk1_bufg) begin
        cnt_clk1 <= cnt_clk1 + 1'b1;
    end
    assign led[2] = cnt_clk1[25];
endmodule

It turned out that the problem is related to the intermediate BUFG, which connects PLL and BUFGMUX. Since the BUFGMUX is also a buffer, I removed the additional BUFG, which resolved the problem. Nevertheless, the failing example can be handled properly by Vivado.

In SymbiFlow the correct BUFGMUX nets are connected through BUFHCE. For some reason, the failing net in case of Nexys Video is connected directly to BUFG output.

A correct BUFGMUX input net:
correct

A failing BUFGMUX input net:
failure

Both examples were passing the diff_fasm step. In the recent BUFGMUX test, the additional BUFG has been removed which resolved the issue. Still, the inconsistent behavior may indicate that there is a bug in the tools.

@litghost
Copy link
Contributor

litghost commented Oct 29, 2020

This bug is a result of Vivado not handling explicit BUFHCE's which is equivilant from a bitstream standpoint from using the BUFHCE site route-through psuedo pip. The solution to this bug is to change how fasm2bels handles this. In the case where a BUFHCE site is configured as a route through (e.g. BUFHCE(.CE(1'b1), ...)), then fasm2bels should enable the pseudo pip rather than emitting a BUFHCE cell.

There are examples of how this is done for the ILOGIC and OLOGIC sites here:

https://github.com/SymbiFlow/symbiflow-xc-fasm2bels/blob/8fa587570df242de48cbf67f214bbb5d45af07ef/fasm2bels/models/ioi_models.py#L740-L742

GitHub
Library to convert a FASM file into BELs importable into Vivado. - SymbiFlow/symbiflow-xc-fasm2bels

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