Loading device/oob_dev.v +34 −6 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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; Loading Loading @@ -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; Loading @@ -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) Loading @@ -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) Loading @@ -184,6 +210,7 @@ always @ (posedge clk) end STATE_READY: begin txelecidle <= 1'b0; data <= sync; isk <= 4'h1; if (rxelecidle_in) Loading @@ -191,6 +218,7 @@ always @ (posedge clk) end STATE_ERROR: begin txelecidle <= 1'b0; state <= STATE_RESET; end endcase Loading device/sata_phy_dev.v +23 −3 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -71,6 +72,8 @@ wire rxreset; wire rxelecidle; wire txelecidle; wire rxbyteisaligned; wire txpcsreset_req; wire recal_tx_done; wire gtx_ready; Loading @@ -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), Loading @@ -114,6 +120,7 @@ wire cpllreset; wire gtrefclk; wire rxresetdone; wire txresetdone; wire txpcsreset; wire txreset; wire txuserrdy; wire rxuserrdy; Loading Loading @@ -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 Loading @@ -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 Loading Loading @@ -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), Loading Loading @@ -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), Loading dma/dma_adapter.v +1 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading dma/dma_control.v +34 −34 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading dma/top.v +2 −2 Original line number Diff line number Diff line Loading @@ -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 Loading
device/oob_dev.v +34 −6 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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; Loading Loading @@ -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; Loading @@ -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) Loading @@ -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) Loading @@ -184,6 +210,7 @@ always @ (posedge clk) end STATE_READY: begin txelecidle <= 1'b0; data <= sync; isk <= 4'h1; if (rxelecidle_in) Loading @@ -191,6 +218,7 @@ always @ (posedge clk) end STATE_ERROR: begin txelecidle <= 1'b0; state <= STATE_RESET; end endcase Loading
device/sata_phy_dev.v +23 −3 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -71,6 +72,8 @@ wire rxreset; wire rxelecidle; wire txelecidle; wire rxbyteisaligned; wire txpcsreset_req; wire recal_tx_done; wire gtx_ready; Loading @@ -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), Loading @@ -114,6 +120,7 @@ wire cpllreset; wire gtrefclk; wire rxresetdone; wire txresetdone; wire txpcsreset; wire txreset; wire txuserrdy; wire rxuserrdy; Loading Loading @@ -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 Loading @@ -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 Loading Loading @@ -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), Loading Loading @@ -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), Loading
dma/dma_adapter.v +1 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading
dma/dma_control.v +34 −34 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading
dma/top.v +2 −2 Original line number Diff line number Diff line Loading @@ -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