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

Cannot use OSERDESE2 in MASTER-SLAVE configuration to support 10-to-1 bit serialization #46

Open
jhladik opened this issue Nov 8, 2022 · 1 comment

Comments

@jhladik
Copy link

jhladik commented Nov 8, 2022

if (ci->type == ctx->id("OSERDESE2")) {
NetInfo *q = get_net_or_empty(ci, ctx->id("OQ"));
if (q == nullptr || q->users.empty())
log_error("%s '%s' has disconnected OQ output\n", ci->type.c_str(ctx), ctx->nameOf(ci));
BelId io_bel;
CellInfo *ob = find_p_outbuf(q);
if (ob != nullptr)
io_bel = ctx->getBelByName(ctx->id(ob->attrs.at(ctx->id("BEL")).as_string()));
else
log_error("%s '%s' has illegal fanout on OQ output\n", ci->type.c_str(ctx), ctx->nameOf(ci));
std::string ol_site = get_ologic_site(ctx->getBelName(io_bel).str(ctx));
ci->attrs[ctx->id("BEL")] = ol_site + "/OSERDESE2";

There should be some switch to skip the IO check if the OSERDES2 primitive has parameter SERDES_MODE set to "SLAVE" to to support 10-to-1 bit serialization as shown in Xilinx UG471 p. 167 Figure 3-15.

module serializer (
    input  logic       clk_i,
    input  logic       clk_div_i,
    input  logic       rst_i,
    input  logic [9:0] data_i,
    output logic       ser_o
);

    //
    // https://docs.xilinx.com/r/en-US/ug953-vivado-7series-libraries/OSERDESE2
    // https://docs.xilinx.com/v/u/en-US/ug471_7Series_SelectIO
    //

    logic shiftout1, shiftout2;

    OSERDESE2 #(
        .DATA_RATE_OQ   ("DDR"),    // DDR, SDR
        .DATA_RATE_TQ   ("SDR"),    // DDR, BUF, SDR
        .DATA_WIDTH     (10),       // Parallel data width (2-8,10,14)
        .INIT_OQ        (1'b0),     // Initial value of OQ output (1'b0,1'b1)
        .INIT_TQ        (1'b0),     // Initial value of TQ output (1'b0,1'b1)
        .SERDES_MODE    ("MASTER"), // MASTER, SLAVE
        .SRVAL_OQ       (1'b0),     // OQ output value when SR is used (1'b0,1'b1)
        .SRVAL_TQ       (1'b0),     // TQ output value when SR is used (1'b0,1'b1)
        .TBYTE_CTL      ("FALSE"),  // Enable tristate byte operation (FALSE, TRUE)
        .TBYTE_SRC      ("FALSE"),  // Tristate byte source (FALSE, TRUE)
        .TRISTATE_WIDTH (1)         // 3-state converter width (1,4)
    )
    inst_oserdese2_master (
        .OFB       ( ),         // 1-bit output: Feedback path for data
        .OQ        (ser_o),     // 1-bit output: Data path output
        // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
        .SHIFTOUT1 ( ),
        .SHIFTOUT2 ( ), 
        .TBYTEOUT  ( ),         // 1-bit output: Byte group tristate
        .TFB       ( ),         // 1-bit output: 3-state control
        .TQ        ( ),         // 1-bit output: 3-state control
        .CLK       (clk_i),     // 1-bit input: High speed clock
        .CLKDIV    (clk_div_i), // 1-bit input: Divided clock
        // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
        .D1        (data_i[0]),
        .D2        (data_i[1]),
        .D3        (data_i[2]),
        .D4        (data_i[3]),
        .D5        (data_i[4]),
        .D6        (data_i[5]),
        .D7        (data_i[6]),
        .D8        (data_i[7]),
        .OCE       (1'b1),      // 1-bit input: Output data clock enable
        .RST       (rst_i),     // 1-bit input: Reset
        // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
        .SHIFTIN1  (shiftout1),
        .SHIFTIN2  (shiftout2),
        // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
        .T1        (1'b0),
        .T2        (1'b0),
        .T3        (1'b0),
        .T4        (1'b0),
        .TBYTEIN   (1'b0),      // 1-bit input: Byte group tristate
        .TCE       (1'b0)       // 1-bit input: 3-state clock enable
    );

    OSERDESE2 #(
        .DATA_RATE_OQ   ("DDR"),    // DDR, SDR
        .DATA_RATE_TQ   ("SDR"),    // DDR, BUF, SDR
        .DATA_WIDTH     (10),       // Parallel data width (2-8,10,14)
        .INIT_OQ        (1'b0),     // Initial value of OQ output (1'b0,1'b1)
        .INIT_TQ        (1'b0),     // Initial value of TQ output (1'b0,1'b1)
        .SERDES_MODE    ("SLAVE"),  // MASTER, SLAVE
        .SRVAL_OQ       (1'b0),     // OQ output value when SR is used (1'b0,1'b1)
        .SRVAL_TQ       (1'b0),     // TQ output value when SR is used (1'b0,1'b1)
        .TBYTE_CTL      ("FALSE"),  // Enable tristate byte operation (FALSE, TRUE)
        .TBYTE_SRC      ("FALSE"),  // Tristate byte source (FALSE, TRUE)
        .TRISTATE_WIDTH (1)         // 3-state converter width (1,4)
    )
    inst_oserdese2_slave (
        .OFB       ( ),         // 1-bit output: Feedback path for data
        .OQ        ( ),         // 1-bit output: Data path output
        // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
        .SHIFTOUT1 (shiftout1), 
        .SHIFTOUT2 (shiftout2), 
        .TBYTEOUT  ( ),         // 1-bit output: Byte group tristate
        .TFB       ( ),         // 1-bit output: 3-state control
        .TQ        ( ),         // 1-bit output: 3-state control
        .CLK       (clk_i),     // 1-bit input: High speed clock
        .CLKDIV    (clk_div_i), // 1-bit input: Divided clock
        // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
        .D1        (1'b0),
        .D2        (1'b0),
        .D3        (data_i[8]),
        .D4        (data_i[9]),
        .D5        (1'b0),
        .D6        (1'b0),
        .D7        (1'b0),
        .D8        (1'b0),
        .OCE       (1'b1),      // 1-bit input: Output data clock enable
        .RST       (rst_i),     // 1-bit input: Reset
        // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
        .SHIFTIN1  (1'b0),
        .SHIFTIN2  (1'b0),
        // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
        .T1        (1'b0),
        .T2        (1'b0),
        .T3        (1'b0),
        .T4        (1'b0),
        .TBYTEIN   (1'b0),      // 1-bit input: Byte group tristate
        .TCE       (1'b0)       // 1-bit input: 3-state clock enable
    );
    
endmodule
@jhladik jhladik changed the title Cannot use OSERDES2 in MASTER-SLAVE configuration to support 10-to-1 bit serialization Cannot use OSERDESE2 in MASTER-SLAVE configuration to support 10-to-1 bit serialization Nov 8, 2022
@jhladik
Copy link
Author

jhladik commented Nov 9, 2022

I believe this would work, however, I do not know if that is all that is needed to add to support the master-slave configuration of OSERDESE2.

       if (ci->type == ctx->id("OSERDESE2")) {
            std::string serdes_mode = str_or_default(ci->params, ctx->id("SERDES_MODE"), "MASTER");
            if (serdes_mode == "MASTER") {
                NetInfo *q = get_net_or_empty(ci, ctx->id("OQ"));
                if (q == nullptr || q->users.empty())
                    log_error("%s '%s' has disconnected OQ output\n", ci->type.c_str(ctx), ctx->nameOf(ci));
                BelId io_bel;
                CellInfo *ob = find_p_outbuf(q);
                if (ob != nullptr)
                    io_bel = ctx->getBelByName(ctx->id(ob->attrs.at(ctx->id("BEL")).as_string()));
                else
                    log_error("%s '%s' has illegal fanout on OQ output\n", ci->type.c_str(ctx), ctx->nameOf(ci));
                std::string ol_site = get_ologic_site(ctx->getBelName(io_bel).str(ctx));
                ci->attrs[ctx->id("BEL")] = ol_site + "/OSERDESE2";
            }
         ... 

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

No branches or pull requests

1 participant