+ Post New Thread
Results 1 to 5 of 5
  1. #1
    Member level 4
    Points: 976, Level: 7

    Join Date
    Jul 2015
    Posts
    69
    Helped
    0 / 0
    Points
    976
    Level
    7

    Spartan 6 - OSERDES2 to ODDR - Unroutable signals

    Hello all,

    I'm working on a simple DVI driver in a Spartan 6 and I'm running into a routing problem. To transmit the TMDS signals I'm trying to create a 10:1 serializer. I'm using two sets of OSERDES primitives each generating a 5:1 serializer then I'm using a ODDR primitive to do the final 2:1 serialization(for a total of 10:1).

    The problem I'm having is ISE is saying that it can't route the signal between the OSERDES2 output to the ODDR input. The error I'm getting is:
    Code:
    ParHelpers:360 - Design is not completely routed.
    
       blueSer/evenData
       blueSer/oddData
       greenSer/evenData
       greenSer/oddData
       redSer/evenData
       redSer/oddData
       serStrobeSR_2
    The code for the serializer is below:
    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    
    `timescale 1ns / 1ps
    //////////////////////////////////////////////////////////////////////////////////
    // Company: 
    // Engineer: 
    // 
    // Create Date:    06:11:45 01/09/2019 
    // Design Name: 
    // Module Name:    Ser_10_1 
    // Project Name: 
    // Target Devices: 
    // Tool versions: 
    // Description: 
    //
    // Dependencies: 
    //
    // Revision: 
    // Revision 0.01 - File Created
    // Additional Comments: 
    //
    //////////////////////////////////////////////////////////////////////////////////
    module Ser_10_1(
       input wire parClk,
       input wire serClk,
       input wire dataStrobe,
       input wire serCE,
       input wire reset,
       input wire[9:0] parData,
       
       output serData
       );
       
       parameter integer dataWidth = 5;
       
       wire cascade_do1, cascade_do2, cascade_to1, cascade_to2;
       wire cascade_di1, cascade_di2, cascade_ti1, cascade_ti2;
       wire evenData, oddData;
       
     
          // Output serializer 
       OSERDES2 #(
                  .DATA_RATE_OQ("SDR"),
                  .DATA_RATE_OT("SDR"),
                  .DATA_WIDTH(dataWidth),
                  .OUTPUT_MODE("SINGLE_ENDED"),
                  .SERDES_MODE("MASTER"),
                  .TRAIN_PATTERN(4'hA)
                  ) serdesMaster1 (
                  .CLK0(serClk),
                  .CLK1(),
                  .CLKDIV(parClk),
                  .IOCE(dataStrobe),
                  .D1(parData[8]),
                  .D2(1'b0),
                  .D3(1'b0),
                  .D4(1'b0),
                  .OCE(serCE),
                  .RST(~reset),
                  .T1(1'b0),
                  .T2(1'b0),
                  .T3(1'b0),
                  .T4(1'b0),
                  .TCE(1'b1),
                  .SHIFTIN1(1'b1),
                  .SHIFTIN2(1'b1),
                  .SHIFTIN3(cascade_do1),
                  .SHIFTIN4(cascade_to1),
                  .TRAIN(1'b0),
                  .OQ(evenData),
                  .TQ(),
                  .SHIFTOUT1(cascade_di1),
                  .SHIFTOUT2(cascade_ti1),
                  .SHIFTOUT3(),
                  .SHIFTOUT4()
                  );
     
       OSERDES2 #(
                  .DATA_RATE_OQ("SDR"),
                  .DATA_RATE_OT("SDR"),
                  .DATA_WIDTH(dataWidth),
                  .OUTPUT_MODE("SINGLE_ENDED"),
                  .SERDES_MODE("SLAVE"),
                  .TRAIN_PATTERN(4'hA)
                  ) serdesSlave1 (
                  .CLK0(serClk),
                  .CLK1(),
                  .CLKDIV(parClk),
                  .IOCE(dataStrobe),
                  .D1(parData[0]),
                  .D2(parData[2]),
                  .D3(parData[4]),
                  .D4(parData[6]),
                  .OCE(serCE),
                  .RST(~reset),
                  .T1(1'b0),
                  .T2(1'b0),
                  .T3(1'b0),
                  .T4(1'b0),
                  .TCE(1'b1),
                  .SHIFTIN1(cascade_di1),
                  .SHIFTIN2(cascade_ti1),
                  .SHIFTIN3(1'b1),
                  .SHIFTIN4(1'b1),
                  .TRAIN(1'b0),
                  .OQ(),
                  .TQ(),
                  .SHIFTOUT1(),
                  .SHIFTOUT2(),
                  .SHIFTOUT3(cascade_do1),
                  .SHIFTOUT4(cascade_to1)
                  );
     
       OSERDES2 #(
                  .DATA_RATE_OQ("SDR"),
                  .DATA_RATE_OT("SDR"),
                  .DATA_WIDTH(dataWidth),
                  .OUTPUT_MODE("SINGLE_ENDED"),
                  .SERDES_MODE("MASTER"),
                  .TRAIN_PATTERN(4'hA)
                  ) serdesMaster2 (
                  .CLK0(serClk),
                  .CLK1(),
                  .CLKDIV(parClk),
                  .IOCE(dataStrobe),
                  .D1(parData[9]),
                  .D2(1'b0),
                  .D3(1'b0),
                  .D4(1'b0),
                  .OCE(serCE),
                  .RST(~reset),
                  .T1(1'b0),
                  .T2(1'b0),
                  .T3(1'b0),
                  .T4(1'b0),
                  .TCE(1'b1),
                  .SHIFTIN1(1'b1),
                  .SHIFTIN2(1'b1),
                  .SHIFTIN3(cascade_do2),
                  .SHIFTIN4(cascade_to2),
                  .TRAIN(1'b0),
                  .OQ(oddData),
                  .TQ(),
                  .SHIFTOUT1(cascade_di2),
                  .SHIFTOUT2(cascade_ti2),
                  .SHIFTOUT3(),
                  .SHIFTOUT4()
                  );
     
       OSERDES2 #(
                  .DATA_RATE_OQ("SDR"),
                  .DATA_RATE_OT("SDR"),
                  .DATA_WIDTH(dataWidth),
                  .OUTPUT_MODE("SINGLE_ENDED"),
                  .SERDES_MODE("SLAVE"),
                  .TRAIN_PATTERN(4'hA)
                  ) serdesSlave2 (
                  .CLK0(serClk),
                  .CLK1(),
                  .CLKDIV(parClk),
                  .IOCE(dataStrobe),
                  .D1(parData[1]),
                  .D2(parData[3]),
                  .D3(parData[5]),
                  .D4(parData[7]),
                  .OCE(serCE),
                  .RST(~reset),
                  .T1(1'b0),
                  .T2(1'b0),
                  .T3(1'b0),
                  .T4(1'b0),
                  .TCE(1'b1),
                  .SHIFTIN1(cascade_di2),
                  .SHIFTIN2(cascade_ti2),
                  .SHIFTIN3(1'b1),
                  .SHIFTIN4(1'b1),
                  .TRAIN(1'b0),
                  .OQ(),
                  .TQ(),
                  .SHIFTOUT1(),
                  .SHIFTOUT2(),
                  .SHIFTOUT3(cascade_do2),
                  .SHIFTOUT4(cascade_to2)
                  );                             
      
             
       // Output DDR 
       ODDR2 #(
                .DDR_ALIGNMENT("C0"),
                .INIT(1'b0),
                .SRTYPE("ASYNC")
                ) DDROutRed (
                .D0(evenData),
                .D1(oddData),
                .C0(serClk),
                .C1(~serClk),
                .CE(serCE),
                .R(~reset),
                .S(1'b0),
                .Q(serData)
                );
     
    endmodule

    I can't seem to figure out what the problem here is. I've looked on the Xilinx forums but the problems other people had don't seem to be my problems. Both the clocks used in this module are given to a BUFG.

    The signal serStrobeSR_2 is a bit in a shift register in the following code:
    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    
    `timescale 1ns / 1ps
    //////////////////////////////////////////////////////////////////////////////////
    // Company: 
    // Engineer: 
    // 
    // Create Date:    05:37:47 12/18/2018 
    // Design Name: 
    // Module Name:    DVI_Driver 
    // Project Name: 
    // Target Devices: 
    // Tool versions: 
    // Description: 
    //
    // Dependencies: 
    //
    // Revision: 
    // Revision 0.01 - File Created
    // Additional Comments: 
    //
    //////////////////////////////////////////////////////////////////////////////////
    module DVI_Driver(
        input wire clk50Buffer,
        input wire reset_brd,
       
       output wire redDataSer_p,
       output wire redDataSer_n,
       output wire greenDataSer_p,
       output wire greenDataSer_n,
       output wire blueDataSer_p,
       output wire blueDataSer_n,
       output wire VSYNCOut
       );
       
       // Define screen size
       parameter HPixelWidth = 1024;
       parameter VPixelWidth = 768;
       parameter blankPixelWidth = 148;  // This gives a pixel clock very close to 54MHz.
       
       // TMDS encoders singals
       wire redEnable, greenEnable, blueEnable;
       reg allEnable;
       wire redDone, greenDone, blueDone;
       reg DE, HSYNC, VSYNC;
       reg[7:0] redData, greenData, blueData;
       wire[9:0] redDataEncoded, greenDataEncoded, blueDataEncoded;
     
       assign redEnable = allEnable;
       assign greenEnable = allEnable;
       assign blueEnable = allEnable;
     
       // Serializer signals
       wire redDataSer, greenDataSer, blueDataSer;
       
       // Timing control signals
       reg[11:0] HPixelCount, VPixelCount, blankCount;
       
       // Clocking signals
       wire clk54, clk270;
       wire locked54, locked270;
       wire reset;
       
       assign reset = locked54 & locked270;
       
       // Serializer and DDR singals
       reg[4:0] serStrobeSR;
       reg serStrobe, serCE;
       
     
       // Top level outputs
       assign clk54Out = 1'b0;//clk54;
       assign clk270Out = 1'b0; //clk270;
       assign VSYNCOut = VSYNC;
       
       // Define IBUFG directly because clk50 goes to two DCMs which try to make their own BUFG.
       IBUFG clkBuffer50 ( .I(clk50Buffer), .O(clk50) );
       
       // Define output differential signals
       OBUFDS redDataDS ( .I(redDataSer), .O(redDataSer_p), .OB(redDataSer_n) );
       OBUFDS greenDataDS ( .I(greenDataSer), .O(greenDataSer_p), .OB(greenDataSer_n) );
       OBUFDS blueDataDS ( .I(blueDataSer), .O(blueDataSer_p), .OB(blueDataSer_n) );
       
       // Generate 270MHz clock
       Clock_Generator_270 gen270(
                                  .CLK_IN1(clk50),
                                  .CLK_OUT1(clk270),
                                  .RESET(~reset_brd),
                                  .LOCKED(locked270)                             
                                  );
       
      
       // Generate 54MHz clk
       //    I use two separte DCMs to keep precision.  Using one to generate both clocks caused the clocks to not be exact multiples.
       Clock_Generator_54 gen54(
                                .CLK_IN1(clk50),
                                .CLK_OUT1(clk54),
                                .RESET(~reset_brd),
                                .LOCKED(locked54)
                                );
       
       
       // Red data
       TMDS_Encoder redEncoder(
                               .clk(clk54),
                               .reset(reset),
                               .enable(redEnable),
                               .DE(DE),
                               .C0(HSYNC),
                               .C1(VSYNC),
                               .rawData(redData),
                               .encodedData(redDataEncoded),
                               .done(redDone)                           
                               );
       
       // Green data
       TMDS_Encoder greenEncoder(
                               .clk(clk54),
                               .reset(reset),
                               .enable(greenEnable),
                               .DE(DE),
                               .C0(1'b0),
                               .C1(1'b0),
                               .rawData(greenData),
                               .encodedData(greenDataEncoded),
                               .done(greenDone)                           
                               );
                               
       // Blue data
       TMDS_Encoder blueEncoder(
                               .clk(clk54),
                               .reset(reset),
                               .enable(blueEnable),
                               .DE(DE),
                               .C0(1'b0),
                               .C1(1'b0),
                               .rawData(blueData),
                               .encodedData(blueDataEncoded),
                               .done(blueDone)                           
                               );
       
       
       // Red Serializer
       Ser_10_1 redSer(
                      .parClk     (clk54),
                      .serClk     (clk270),
                      .dataStrobe (serStrobe),
                      .serCE      (serCE),
                      .reset      (reset),
                      .parData    (redDataEncoded),
                      .serData    (redDataSer)
                      );
     
       // Green Serializer
       Ser_10_1 greenSer(
                      .parClk     (clk54),
                      .serClk     (clk270),
                      .dataStrobe (serStrobe),
                      .serCE      (serCE),
                      .reset      (reset),
                      .parData    (greenDataEncoded),
                      .serData    (greenDataSer)
                      );
     
       // Blue Serializer
       Ser_10_1 blueSer(
                      .parClk     (clk54),
                      .serClk     (clk270),
                      .dataStrobe (serStrobe),
                      .serCE      (serCE),
                      .reset      (reset),
                      .parData    (blueDataEncoded),
                      .serData    (blueDataSer)
                      );   
       
       // Generate serializer strobe
       always @(posedge clk270 or negedge reset) begin
          if(!reset) begin
             serStrobeSR <= 5'b00001;
             serStrobe <= 1'b0;
             serCE <= 1'b0;
          end else begin
             serCE <= 1'b1;
             serStrobeSR <= {serStrobeSR[3:0], serStrobeSR[4]};
             serStrobe <= serStrobeSR[1];
          end
       end 
       
       
       // Manage output data
       always @(posedge clk54 or negedge reset) begin
          if(!reset) begin
             allEnable = 1'b0;
             DE = 1'b0;
             HSYNC = 1'b0;
             VSYNC = 1'b0;
             redData = 8'd0;
             greenData = 8'd1;
             blueData = 8'd2;
             
             HPixelCount = 12'b0;
             VPixelCount = 12'b0;
             blankCount = 12'b0;
          end else begin
             allEnable = 1'b1;
             redData = redData + 1;
             greenData = greenData + 1;
             blueData = blueData + 1;
             
             if(HPixelCount < HPixelWidth) begin
                DE = 1'b0;
                HSYNC = 1'b0;
                VSYNC = 1'b0;
                
                HPixelCount = HPixelCount + 1'b1;
             end else begin
                DE = 1'b1;
                HSYNC = 1'b1;
     
                if(VPixelCount == VPixelWidth) begin
                   VSYNC = 1'b1;
                end else begin
                   VSYNC = 1'b0;
                   VPixelCount = VPixelCount + 1'b1;
                end
                
                if(blankCount == blankPixelWidth) begin
                   HPixelCount = 12'b0;
                   VPixelCount = 12'b0;
                   blankCount = 12'b0;
                end else begin
                   blankCount = blankCount + 1'b1;
                end
             end
          end
       end
    endmodule

    Does anyone know why this might be happening? Or what I can do to try to track this down a little better?

    Thank you!

    •   AltAdvertisment

        
       

  2. #2
    Advanced Member level 5
    Points: 22,400, Level: 36
    barry's Avatar
    Join Date
    Mar 2005
    Location
    California, USA
    Posts
    4,284
    Helped
    949 / 949
    Points
    22,400
    Level
    36

    Re: Spartan 6 - OSERDES2 to ODDR - Unroutable signals

    I'm not sure this is allowed, as the SERDES are in the I/O module, i.e., the output of the SERDES goes to an output port, not back into the fabric. You might need to roll-your-own parallel-to-serial converter.



    •   AltAdvertisment

        
       

  3. #3
    Full Member level 1
    Points: 681, Level: 5
    Achievements:
    Created Blog entry

    Join Date
    Apr 2018
    Location
    Gdańsk, Poland
    Posts
    96
    Helped
    22 / 22
    Points
    681
    Level
    5
    Blog Entries
    3

    Re: Spartan 6 - OSERDES2 to ODDR - Unroutable signals

    Have you checked ug381?
    There is a following drawing which might give you a hint:
    Click image for larger version. 

Name:	OSERDES_DDR.png 
Views:	7 
Size:	25.9 KB 
ID:	150741

    The ODDR is after 3rd OSERDES(counting 4th -> 3rd -> ODDR).
    Make sure you didn't instantiated the 2nd OSERDES.
    To encourage me to help more, click on "Helpful Post" if you feel that I've helped you.



    •   AltAdvertisment

        
       

  4. #4
    Member level 4
    Points: 976, Level: 7

    Join Date
    Jul 2015
    Posts
    69
    Helped
    0 / 0
    Points
    976
    Level
    7

    Re: Spartan 6 - OSERDES2 to ODDR - Unroutable signals

    @barry Yep, that does seem to be my problem. I used two OSERDES2 primitives in parallel each driving one pin of the ODDR but with the image niciki posted that doesn't seem to be possible. The only reason I did this was because I need a 10 to 1 serializer but the OSERDES2 only allows a max of 8 bits. I'll just have to create another clock and load the 5:1 serializer twice as often.

    @niciki Thank you for finding that for me. I only looked at the ODDR and OSERDES2 sections so I missed that. I don't believe I'm creating the third OSERDES2. But I am doing some stuff that violates that diagram. Although that diagram is a little confusing. I don't even understand how you can have 3 OSERDES2 primitives in series. The maximum data width of the OSERDES2 is 8 with each individual OSERDES2 having 4 bits. I tried simulating numbers higher than 8 but it threw a bunch of errors. Secondly, it shows the OSERDES2 output going to the ODDR input but OSERDES2 is a one bit output but ODDR is a two bit input. It's not clear to me how exactly this is resolved. I'm not really asking these questions directly. It's more just my thought process.

    I think I know what I need to do now. Thanks again for the help!



  5. #5
    Super Moderator
    Points: 250,751, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    43,660
    Helped
    13280 / 13280
    Points
    250,751
    Level
    100

    Re: Spartan 6 - OSERDES2 to ODDR - Unroutable signals

    The DDR output register is fed with half the final output data rate. This should allow to use general core registers for the 5:1 serializers. In other words make your own 10:1 OSERDES block.

    If you can't achieve timing closure, you are probably beyond the capabilities of the used device family.



--[[ ]]--