Commit 2371769e authored by Alexey Grebenkin's avatar Alexey Grebenkin
Browse files

Fixes after simulation with xilinx's GTX

parent a4102b78
Loading
Loading
Loading
Loading
+34 −6
Original line number Original line Diff line number Diff line
@@ -44,6 +44,9 @@ module oob_dev #(
    output  reg     txcomwake,
    output  reg     txcomwake,
    output  reg     txelecidle,
    output  reg     txelecidle,


    output  wire    txpcsreset_req,
    input   wire    recal_tx_done,

    // output data stream to gtx
    // output data stream to gtx
    output  wire    [DATA_BYTE_WIDTH*8 - 1:0] txdata_out,
    output  wire    [DATA_BYTE_WIDTH*8 - 1:0] txdata_out,
    output  wire    [DATA_BYTE_WIDTH - 1:0]   txcharisk_out,
    output  wire    [DATA_BYTE_WIDTH - 1:0]   txcharisk_out,
@@ -60,6 +63,7 @@ localparam STATE_AWAITCOMWAKE = 2;
localparam  STATE_AWAITNOCOMWAKE    = 3;
localparam  STATE_AWAITNOCOMWAKE    = 3;
localparam  STATE_CALIBRATE         = 4;
localparam  STATE_CALIBRATE         = 4;
localparam  STATE_COMWAKE           = 5;
localparam  STATE_COMWAKE           = 5;
localparam  STATE_RECAL             = 55;
localparam  STATE_SENDALIGN         = 6;
localparam  STATE_SENDALIGN         = 6;
localparam  STATE_READY             = 7;
localparam  STATE_READY             = 7;
localparam  STATE_PARTIAL           = 8;
localparam  STATE_PARTIAL           = 8;
@@ -115,27 +119,34 @@ begin
    rxcharisk    <= rxcharisk_in;
    rxcharisk    <= rxcharisk_in;
end
end


reg [9:0] txelecidle_cnt;

assign  aligndet = ~|(rxdata ^ {8'b01111011, 8'b01001010, 8'b01001010, 8'b10111100}) & ~|(rxcharisk ^ 4'h1); // {D27.3, D10.2, D10.2, K28.5}
assign  aligndet = ~|(rxdata ^ {8'b01111011, 8'b01001010, 8'b01001010, 8'b10111100}) & ~|(rxcharisk ^ 4'h1); // {D27.3, D10.2, D10.2, K28.5}
assign  syncdet  = ~|(rxdata ^ {8'b10110101, 8'b10110101, 8'b10010101, 8'b01111100}) & ~|(rxcharisk ^ 4'h1); // {D21.5, D21.5, D21.4, K28.3}
assign  syncdet  = ~|(rxdata ^ {8'b10110101, 8'b10110101, 8'b10010101, 8'b01111100}) & ~|(rxcharisk ^ 4'h1); // {D21.5, D21.5, D21.4, K28.3}


assign  txpcsreset_req = state == STATE_RECAL & (txelecidle_cnt == 10'd160);

always @ (posedge clk)
always @ (posedge clk)
    if (rst | ~gtx_ready)
    if (rst | (~gtx_ready & ~(state == STATE_RECAL)))
    begin
    begin
        state       <= STATE_RESET;
        state       <= STATE_RESET;
        txelecidle  <= 1'b1;
        txelecidle  <= 1'b1;
        txcominit   <= 1'b0;
        txcominit   <= 1'b0;
        txcomwake   <= 1'b0;
        txcomwake   <= 1'b0;
        txelecidle_cnt <= 10'h0;
    end
    end
    else
    else
        case (state)
        case (state)
        STATE_RESET:
        STATE_RESET:
        begin
        begin
            if (rxcominitdet_in)
            if (rxcominitdet) begin
                txelecidle_cnt <= 10'h0;
                state       <= STATE_COMINIT;
                state       <= STATE_COMINIT;
                txelecidle  <= 1'b1;
                txelecidle  <= 1'b1;
                txcominit   <= 1'b0;
                txcominit   <= 1'b0;
                txcomwake   <= 1'b0;
                txcomwake   <= 1'b0;
            end
            end
        end
        STATE_COMINIT:
        STATE_COMINIT:
        begin
        begin
            state       <= STATE_AWAITCOMWAKE;
            state       <= STATE_AWAITCOMWAKE;
@@ -144,7 +155,7 @@ always @ (posedge clk)
        STATE_AWAITCOMWAKE:
        STATE_AWAITCOMWAKE:
        begin
        begin
            txcominit   <= 1'b0;
            txcominit   <= 1'b0;
            if (rxcomwakedet_in)
            if (rxcomwakedet)
                state   <= STATE_AWAITNOCOMWAKE;
                state   <= STATE_AWAITNOCOMWAKE;
            else 
            else 
            if (retry_interval_elapsed)
            if (retry_interval_elapsed)
@@ -166,12 +177,27 @@ always @ (posedge clk)
        STATE_COMWAKE:
        STATE_COMWAKE:
        begin
        begin
            txcomwake   <= 1'b1;
            txcomwake   <= 1'b1;
            state       <= STATE_SENDALIGN;
            state       <= STATE_RECAL;
            txelecidle_cnt <= 10'h0;
        end
        end
        STATE_SENDALIGN:
        STATE_RECAL:
        begin
        begin
            data    <= align;
            isk     <= 4'h1;
            txcomwake   <= 1'b0;
            txcomwake   <= 1'b0;
            // txcomwake period = 213.333 ns times let's say 10 pulses => 2133.333 ns = 160 cycles of 75Mhz
            if (txelecidle_cnt == 10'd160) begin
                txelecidle  <= 1'b0;
                txelecidle  <= 1'b0;
            end
            else begin
                txelecidle_cnt <= txelecidle_cnt + 1'b1;
            end
            if (recal_tx_done) begin
                state   <= STATE_SENDALIGN;
            end
        end
        STATE_SENDALIGN:
        begin
            data    <= align;
            data    <= align;
            isk     <= 4'h1;
            isk     <= 4'h1;
            if (aligndet)
            if (aligndet)
@@ -184,6 +210,7 @@ always @ (posedge clk)
        end
        end
        STATE_READY:
        STATE_READY:
        begin
        begin
            txelecidle <= 1'b0;
            data    <= sync;
            data    <= sync;
            isk     <= 4'h1;
            isk     <= 4'h1;
            if (rxelecidle_in)
            if (rxelecidle_in)
@@ -191,6 +218,7 @@ always @ (posedge clk)
        end
        end
        STATE_ERROR:
        STATE_ERROR:
        begin
        begin
            txelecidle <= 1'b0;
            state   <= STATE_RESET;
            state   <= STATE_RESET;
        end
        end
        endcase
        endcase
+23 −3
Original line number Original line Diff line number Diff line
@@ -51,6 +51,7 @@ module sata_phy_dev(


parameter  CHIPSCOPE            = "FALSE";
parameter  CHIPSCOPE            = "FALSE";


wire            txcomfinish;
wire    [31:0]  txdata;
wire    [31:0]  txdata;
wire    [31:0]  txdata_oob;
wire    [31:0]  txdata_oob;
wire    [3:0]   txcharisk;
wire    [3:0]   txcharisk;
@@ -71,6 +72,8 @@ wire rxreset;
wire            rxelecidle;
wire            rxelecidle;
wire            txelecidle;
wire            txelecidle;
wire            rxbyteisaligned;
wire            rxbyteisaligned;
wire            txpcsreset_req;
wire            recal_tx_done;


wire            gtx_ready;
wire            gtx_ready;


@@ -97,6 +100,9 @@ oob_dev oob_dev(
    .txcomwake          (txcomwake),
    .txcomwake          (txcomwake),
    .txelecidle         (txelecidle),
    .txelecidle         (txelecidle),


    .txpcsreset_req     (txpcsreset_req),
    .recal_tx_done      (recal_tx_done),

    // output data stream to gtx
    // output data stream to gtx
    .txdata_out         (txdata_oob),
    .txdata_out         (txdata_oob),
    .txcharisk_out      (txcharisk_oob),
    .txcharisk_out      (txcharisk_oob),
@@ -114,6 +120,7 @@ wire cpllreset;
wire    gtrefclk;
wire    gtrefclk;
wire    rxresetdone;
wire    rxresetdone;
wire    txresetdone;
wire    txresetdone;
wire    txpcsreset;
wire    txreset;
wire    txreset;
wire    txuserrdy;
wire    txuserrdy;
wire    rxuserrdy;
wire    rxuserrdy;
@@ -161,6 +168,17 @@ assign txuserrdy = usrpll_locked & cplllock & ~cpllreset & ~txreset & txpmarese


assign  gtx_ready = rxuserrdy & txuserrdy & rxresetdone & txresetdone;
assign  gtx_ready = rxuserrdy & txuserrdy & rxresetdone & txresetdone;


// issue partial tx reset to restore functionality after oob sequence. Let it lasts 8 clock lycles
reg [3:0]   txpcsreset_cnt;
wire        txpcsreset_stop;

assign  txpcsreset_stop = txpcsreset_cnt[3];
assign  txpcsreset = txpcsreset_req & ~txpcsreset_stop;
assign  recal_tx_done = txpcsreset_stop & gtx_ready;

always @ (posedge clk or posedge extrst)
    txpcsreset_cnt <= extrst | rst | ~txpcsreset_req ? 4'h0 : txpcsreset_stop ? txpcsreset_cnt : txpcsreset_cnt + 1'b1;

// generate internal reset after a clock is established
// generate internal reset after a clock is established
// !!!ATTENTION!!!
// !!!ATTENTION!!!
// async rst block
// async rst block
@@ -174,6 +192,8 @@ assign rst = rst_r;
always @ (posedge clk or posedge extrst)
always @ (posedge clk or posedge extrst)
    rst_r <= extrst | ~|rst_timer ? 1'b0 : rst_timer[3] ? 1'b0 : 1'b1;
    rst_r <= extrst | ~|rst_timer ? 1'b0 : rst_timer[3] ? 1'b0 : 1'b1;




/*
/*
 * USRCLKs generation. USRCLK @ 150MHz, same as TXOUTCLK; USRCLK2 @ 75Mhz -> sata_clk === sclk
 * USRCLKs generation. USRCLK @ 150MHz, same as TXOUTCLK; USRCLK2 @ 75Mhz -> sata_clk === sclk
 * It's recommended to use MMCM instead of PLL, whatever
 * It's recommended to use MMCM instead of PLL, whatever
@@ -329,7 +349,7 @@ GTXE2_CHANNEL #(
    .ES_QUAL_MASK                           (80'h00000000000000000000),
    .ES_QUAL_MASK                           (80'h00000000000000000000),
    .ES_SDATA_MASK                          (80'h00000000000000000000),
    .ES_SDATA_MASK                          (80'h00000000000000000000),
    .ES_VERT_OFFSET                         (9'b000000000),
    .ES_VERT_OFFSET                         (9'b000000000),
    .RX_DATA_WIDTH                          (20),
    .RX_DATA_WIDTH                          (40),
    .OUTREFCLK_SEL_INV                      (2'b11),
    .OUTREFCLK_SEL_INV                      (2'b11),
    .PMA_RSV                                (32'h00018480),
    .PMA_RSV                                (32'h00018480),
    .PMA_RSV2                               (16'h2050),
    .PMA_RSV2                               (16'h2050),
@@ -680,10 +700,10 @@ gtx(
    .TXHEADER                       (3'd0),
    .TXHEADER                       (3'd0),
    .TXSEQUENCE                     (7'd0),
    .TXSEQUENCE                     (7'd0),
    .TXSTARTSEQ                     (1'b0),
    .TXSTARTSEQ                     (1'b0),
    .TXPCSRESET                     (1'b0),
    .TXPCSRESET                     (txpcsreset),
    .TXPMARESET                     (1'b0),
    .TXPMARESET                     (1'b0),
    .TXRESETDONE                    (txresetdone),
    .TXRESETDONE                    (txresetdone),
    .TXCOMFINISH                    (),
    .TXCOMFINISH                    (txcomfinish),
    .TXCOMINIT                      (txcominit),
    .TXCOMINIT                      (txcominit),
    .TXCOMSAS                       (1'b0),
    .TXCOMSAS                       (1'b0),
    .TXCOMWAKE                      (txcomwake),
    .TXCOMWAKE                      (txcomwake),
+1 −1
Original line number Original line Diff line number Diff line
@@ -71,6 +71,7 @@ module dma_adapter(
    // additinal wire to indicate if membridge recieved a packet
    // additinal wire to indicate if membridge recieved a packet
    input   wire                                rdata_done // = membridge.is_last_in_page & membridge.afi_rready;
    input   wire                                rdata_done // = membridge.is_last_in_page & membridge.afi_rready;
);
);
reg     [2:0]   membr_state;
// cmd handling
// cmd handling
// if not busy and got cmd with val => cmd recieved, assert busy, start a respective algorithm
// if not busy and got cmd with val => cmd recieved, assert busy, start a respective algorithm
wire            wr_start;
wire            wr_start;
@@ -299,7 +300,6 @@ reg [32:0] membr_data;
reg     [15:0]  membr_addr;
reg     [15:0]  membr_addr;
reg             membr_start;
reg             membr_start;
reg             membr_done;
reg             membr_done;
reg     [2:0]   membr_state;
reg             membr_setup; // indicates the first tick of the state
reg             membr_setup; // indicates the first tick of the state
wire            membr_inprocess;
wire            membr_inprocess;


+34 −34
Original line number Original line Diff line number Diff line
@@ -109,40 +109,6 @@ wire adp_val_sclk;
reg     [31:7]  current_addr;
reg     [31:7]  current_addr;
reg             current_type;
reg             current_type;


// synchronize with host fsm
reg     adp_done;
wire    adp_done_clr;
wire    adp_done_set;

assign  dma_done_adp = adp_done;

assign  adp_done_set = state_wait_done & clr_wait_done & ~set_wait_busy; // = state_wait_done & set_idle;
assign  adp_done_clr = dma_done;
always @ (posedge sclk)
    adp_done <= (adp_done | adp_done_set) & ~adp_done_clr & ~rst;


// calculate sent sector count
// 1 sector = 512 bytes for now => 1 quarter_sector = 128 bytes
always @ (posedge sclk)
    quarter_sector_cnt <= ~set_wait_busy ? quarter_sector_cnt :
                              state_idle ? 34'h0 :                    // new dma request
                                           quarter_sector_cnt + 1'b1; // same dma request, next 128 bytes

// flags if we're currently sending the last data piece of dma transaction
assign  last_data = (sector_cnt == quarter_sector_cnt[33:2] + 1'b1) & (&quarter_sector_cnt[1:0]);

// calculate outgoing address
// increment every transaction to adapter
always @ (posedge sclk)
    current_addr <= ~set_wait_busy ? current_addr :
                        state_idle ? mem_address :           // new dma request
                                     current_addr + 1'b1; // same dma request, next 128 bytes

always @ (posedge sclk)
    current_type <= ~set_wait_busy ? current_type :
                        state_idle ? dma_type :           // new dma request
                                     current_type;        // same dma request, next 128 bytes


// fsm itself
// fsm itself
wire    state_idle;
wire    state_idle;
@@ -216,6 +182,40 @@ pulse_cross_clock adp_busy_clr_pulse(
    .busy       ()
    .busy       ()
);
);


// synchronize with host fsm
reg     adp_done;
wire    adp_done_clr;
wire    adp_done_set;

assign  dma_done_adp = adp_done;

assign  adp_done_set = state_wait_done & clr_wait_done & ~set_wait_busy; // = state_wait_done & set_idle;
assign  adp_done_clr = dma_done;
always @ (posedge sclk)
    adp_done <= (adp_done | adp_done_set) & ~adp_done_clr & ~rst;


// calculate sent sector count
// 1 sector = 512 bytes for now => 1 quarter_sector = 128 bytes
always @ (posedge sclk)
    quarter_sector_cnt <= ~set_wait_busy ? quarter_sector_cnt :
                              state_idle ? 34'h0 :                    // new dma request
                                           quarter_sector_cnt + 1'b1; // same dma request, next 128 bytes

// flags if we're currently sending the last data piece of dma transaction
assign  last_data = (sector_cnt == quarter_sector_cnt[33:2] + 1'b1) & (&quarter_sector_cnt[1:0]);

// calculate outgoing address
// increment every transaction to adapter
always @ (posedge sclk)
    current_addr <= ~set_wait_busy ? current_addr :
                        state_idle ? mem_address :           // new dma request
                                     current_addr + 1'b1; // same dma request, next 128 bytes

always @ (posedge sclk)
    current_type <= ~set_wait_busy ? current_type :
                        state_idle ? dma_type :           // new dma request
                                     current_type;        // same dma request, next 128 bytes


//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//// DATA
//// DATA
+2 −2
Original line number Original line Diff line number Diff line
@@ -167,8 +167,8 @@ BUFG bufg_axi_aclk_i (.O(axi_aclk),.I(/*fclk[0]*/ sclk));
BUFG bufg_axi_aclk0_i  (.O(axi_aclk0),.I(fclk[0]));
BUFG bufg_axi_aclk0_i  (.O(axi_aclk0),.I(fclk[0]));
BUFG bufg_axi_rst_i   (.O(axi_rst),.I(axi_rst_pre));
BUFG bufg_axi_rst_i   (.O(axi_rst),.I(axi_rst_pre));
axi_hp_clk #(
axi_hp_clk #(
    .CLKIN_PERIOD(20),
    .CLKIN_PERIOD(6.666),
    .CLKFBOUT_MULT_AXIHP(18),
    .CLKFBOUT_MULT_AXIHP(6),
    .CLKFBOUT_DIV_AXIHP(6)
    .CLKFBOUT_DIV_AXIHP(6)
) axi_hp_clk_i (
) axi_hp_clk_i (
    .rst          (axi_rst), // input
    .rst          (axi_rst), // input
Loading