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 Diff line number Diff line
@@ -44,6 +44,9 @@ module oob_dev #(
    output  reg     txcomwake,
    output  reg     txelecidle,

    output  wire    txpcsreset_req,
    input   wire    recal_tx_done,

    // output data stream to gtx
    output  wire    [DATA_BYTE_WIDTH*8 - 1:0] txdata_out,
    output  wire    [DATA_BYTE_WIDTH - 1:0]   txcharisk_out,
@@ -60,6 +63,7 @@ localparam STATE_AWAITCOMWAKE = 2;
localparam  STATE_AWAITNOCOMWAKE    = 3;
localparam  STATE_CALIBRATE         = 4;
localparam  STATE_COMWAKE           = 5;
localparam  STATE_RECAL             = 55;
localparam  STATE_SENDALIGN         = 6;
localparam  STATE_READY             = 7;
localparam  STATE_PARTIAL           = 8;
@@ -115,27 +119,34 @@ begin
    rxcharisk    <= rxcharisk_in;
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  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)
    if (rst | ~gtx_ready)
    if (rst | (~gtx_ready & ~(state == STATE_RECAL)))
    begin
        state       <= STATE_RESET;
        txelecidle  <= 1'b1;
        txcominit   <= 1'b0;
        txcomwake   <= 1'b0;
        txelecidle_cnt <= 10'h0;
    end
    else
        case (state)
        STATE_RESET:
        begin
            if (rxcominitdet_in)
            if (rxcominitdet) begin
                txelecidle_cnt <= 10'h0;
                state       <= STATE_COMINIT;
                txelecidle  <= 1'b1;
                txcominit   <= 1'b0;
                txcomwake   <= 1'b0;
            end
        end
        STATE_COMINIT:
        begin
            state       <= STATE_AWAITCOMWAKE;
@@ -144,7 +155,7 @@ always @ (posedge clk)
        STATE_AWAITCOMWAKE:
        begin
            txcominit   <= 1'b0;
            if (rxcomwakedet_in)
            if (rxcomwakedet)
                state   <= STATE_AWAITNOCOMWAKE;
            else 
            if (retry_interval_elapsed)
@@ -166,12 +177,27 @@ always @ (posedge clk)
        STATE_COMWAKE:
        begin
            txcomwake   <= 1'b1;
            state       <= STATE_SENDALIGN;
            state       <= STATE_RECAL;
            txelecidle_cnt <= 10'h0;
        end
        STATE_SENDALIGN:
        STATE_RECAL:
        begin
            data    <= align;
            isk     <= 4'h1;
            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;
            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;
            isk     <= 4'h1;
            if (aligndet)
@@ -184,6 +210,7 @@ always @ (posedge clk)
        end
        STATE_READY:
        begin
            txelecidle <= 1'b0;
            data    <= sync;
            isk     <= 4'h1;
            if (rxelecidle_in)
@@ -191,6 +218,7 @@ always @ (posedge clk)
        end
        STATE_ERROR:
        begin
            txelecidle <= 1'b0;
            state   <= STATE_RESET;
        end
        endcase
+23 −3
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ module sata_phy_dev(

parameter  CHIPSCOPE            = "FALSE";

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

wire            gtx_ready;

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

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

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

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
// !!!ATTENTION!!!
// async rst block
@@ -174,6 +192,8 @@ assign rst = rst_r;
always @ (posedge clk or posedge extrst)
    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
 * It's recommended to use MMCM instead of PLL, whatever
@@ -329,7 +349,7 @@ GTXE2_CHANNEL #(
    .ES_QUAL_MASK                           (80'h00000000000000000000),
    .ES_SDATA_MASK                          (80'h00000000000000000000),
    .ES_VERT_OFFSET                         (9'b000000000),
    .RX_DATA_WIDTH                          (20),
    .RX_DATA_WIDTH                          (40),
    .OUTREFCLK_SEL_INV                      (2'b11),
    .PMA_RSV                                (32'h00018480),
    .PMA_RSV2                               (16'h2050),
@@ -680,10 +700,10 @@ gtx(
    .TXHEADER                       (3'd0),
    .TXSEQUENCE                     (7'd0),
    .TXSTARTSEQ                     (1'b0),
    .TXPCSRESET                     (1'b0),
    .TXPCSRESET                     (txpcsreset),
    .TXPMARESET                     (1'b0),
    .TXRESETDONE                    (txresetdone),
    .TXCOMFINISH                    (),
    .TXCOMFINISH                    (txcomfinish),
    .TXCOMINIT                      (txcominit),
    .TXCOMSAS                       (1'b0),
    .TXCOMWAKE                      (txcomwake),
+1 −1
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ module dma_adapter(
    // additinal wire to indicate if membridge recieved a packet
    input   wire                                rdata_done // = membridge.is_last_in_page & membridge.afi_rready;
);
reg     [2:0]   membr_state;
// cmd handling
// if not busy and got cmd with val => cmd recieved, assert busy, start a respective algorithm
wire            wr_start;
@@ -299,7 +300,6 @@ reg [32:0] membr_data;
reg     [15:0]  membr_addr;
reg             membr_start;
reg             membr_done;
reg     [2:0]   membr_state;
reg             membr_setup; // indicates the first tick of the state
wire            membr_inprocess;

+34 −34
Original line number Diff line number Diff line
@@ -109,40 +109,6 @@ wire adp_val_sclk;
reg     [31:7]  current_addr;
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
wire    state_idle;
@@ -216,6 +182,40 @@ pulse_cross_clock adp_busy_clr_pulse(
    .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
+2 −2
Original line number 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_rst_i   (.O(axi_rst),.I(axi_rst_pre));
axi_hp_clk #(
    .CLKIN_PERIOD(20),
    .CLKFBOUT_MULT_AXIHP(18),
    .CLKIN_PERIOD(6.666),
    .CLKFBOUT_MULT_AXIHP(6),
    .CLKFBOUT_DIV_AXIHP(6)
) axi_hp_clk_i (
    .rst          (axi_rst), // input
Loading