// *************************************************************************** // *************************************************************************** // Copyright 2011(c) Analog Devices, Inc. // // All rights reserved. // // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: // - Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // - Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in // the documentation and/or other materials provided with the // distribution. // - Neither the name of Analog Devices, Inc. nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // - The use of this software may or may not infringe the patent rights // of one or more patent holders. This license does not release you // from the requirement that you obtain separate licenses from these // patent holders to use this software. // - Use of the software either in source or binary form, must be run // on or directly connected to an Analog Devices Inc. component. // // THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, // INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE ARE DISCLAIMED. // // IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY // RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR // BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // *************************************************************************** // *************************************************************************** `timescale 1ns/100ps module ad_gt_es ( // drp interface drp_rst, drp_clk, es_sel, es_wr, es_addr, es_wdata, es_rdata, es_ready, // axi4 interface axi_rstn, axi_clk, axi_awvalid, axi_awaddr, axi_awprot, axi_awready, axi_wvalid, axi_wdata, axi_wstrb, axi_wready, axi_bvalid, axi_bresp, axi_bready, axi_arvalid, axi_araddr, axi_arprot, axi_arready, axi_rvalid, axi_rresp, axi_rdata, axi_rready, // processor interface es_start, es_stop, es_init, es_lpm_dfe_n, es_sdata0, es_sdata1, es_sdata2, es_sdata3, es_sdata4, es_qdata0, es_qdata1, es_qdata2, es_qdata3, es_qdata4, es_prescale, es_hoffset_min, es_hoffset_max, es_hoffset_step, es_voffset_min, es_voffset_max, es_voffset_step, es_voffset_range, es_start_addr, es_dmaerr, es_status, // debug interface es_dbg_trigger, es_dbg_data); // parameters parameter GTH_GTX_N = 0; // gt address localparam ES_DRP_CTRL_ADDR = (GTH_GTX_N == 1) ? 12'h03c : 12'h03d; // GTH-7 12'h03d localparam ES_DRP_SDATA0_ADDR = (GTH_GTX_N == 1) ? 12'h049 : 12'h036; // GTH-7 12'h036 localparam ES_DRP_SDATA1_ADDR = (GTH_GTX_N == 1) ? 12'h04a : 12'h037; // GTH-7 12'h037 localparam ES_DRP_SDATA2_ADDR = (GTH_GTX_N == 1) ? 12'h04b : 12'h038; // GTH-7 12'h038 localparam ES_DRP_SDATA3_ADDR = (GTH_GTX_N == 1) ? 12'h04c : 12'h039; // GTH-7 12'h039 localparam ES_DRP_SDATA4_ADDR = (GTH_GTX_N == 1) ? 12'h04d : 12'h03a; // GTH-7 12'h03a localparam ES_DRP_QDATA0_ADDR = (GTH_GTX_N == 1) ? 12'h044 : 12'h031; // GTH-7 12'h031 localparam ES_DRP_QDATA1_ADDR = (GTH_GTX_N == 1) ? 12'h045 : 12'h032; // GTH-7 12'h032 localparam ES_DRP_QDATA2_ADDR = (GTH_GTX_N == 1) ? 12'h046 : 12'h033; // GTH-7 12'h033 localparam ES_DRP_QDATA3_ADDR = (GTH_GTX_N == 1) ? 12'h047 : 12'h034; // GTH-7 12'h034 localparam ES_DRP_QDATA4_ADDR = (GTH_GTX_N == 1) ? 12'h048 : 12'h035; // GTH-7 12'h035 localparam ES_DRP_HOFFSET_ADDR = (GTH_GTX_N == 1) ? 12'h04f : 12'h03c; // GTH-7 12'h03c localparam ES_DRP_VOFFSET_ADDR = (GTH_GTX_N == 1) ? 12'h097 : 12'h03b; // GTH-7 12'h03b localparam ES_DRP_STATUS_ADDR = (GTH_GTX_N == 1) ? 12'h153 : 12'h151; // GTH-7 12'h153 localparam ES_DRP_SCNT_ADDR = (GTH_GTX_N == 1) ? 12'h152 : 12'h150; // GTH-7 12'h152 localparam ES_DRP_ECNT_ADDR = (GTH_GTX_N == 1) ? 12'h151 : 12'h14f; // GTH-7 12'h151 // state machine localparam ES_FSM_IDLE = 6'h00; localparam ES_FSM_STATUS = 6'h01; localparam ES_FSM_INIT = 6'h02; localparam ES_FSM_CTRLINIT_READ = 6'h03; localparam ES_FSM_CTRLINIT_RRDY = 6'h04; localparam ES_FSM_CTRLINIT_WRITE = 6'h05; localparam ES_FSM_CTRLINIT_WRDY = 6'h06; localparam ES_FSM_SDATA0_WRITE = 6'h07; localparam ES_FSM_SDATA0_WRDY = 6'h08; localparam ES_FSM_SDATA1_WRITE = 6'h09; localparam ES_FSM_SDATA1_WRDY = 6'h0a; localparam ES_FSM_SDATA2_WRITE = 6'h0b; localparam ES_FSM_SDATA2_WRDY = 6'h0c; localparam ES_FSM_SDATA3_WRITE = 6'h0d; localparam ES_FSM_SDATA3_WRDY = 6'h0e; localparam ES_FSM_SDATA4_WRITE = 6'h0f; localparam ES_FSM_SDATA4_WRDY = 6'h10; localparam ES_FSM_QDATA0_WRITE = 6'h11; localparam ES_FSM_QDATA0_WRDY = 6'h12; localparam ES_FSM_QDATA1_WRITE = 6'h13; localparam ES_FSM_QDATA1_WRDY = 6'h14; localparam ES_FSM_QDATA2_WRITE = 6'h15; localparam ES_FSM_QDATA2_WRDY = 6'h16; localparam ES_FSM_QDATA3_WRITE = 6'h17; localparam ES_FSM_QDATA3_WRDY = 6'h18; localparam ES_FSM_QDATA4_WRITE = 6'h19; localparam ES_FSM_QDATA4_WRDY = 6'h1a; localparam ES_FSM_HOFFSET_READ = 6'h1b; localparam ES_FSM_HOFFSET_RRDY = 6'h1c; localparam ES_FSM_HOFFSET_WRITE = 6'h1d; localparam ES_FSM_HOFFSET_WRDY = 6'h1e; localparam ES_FSM_VOFFSET_READ = 6'h1f; localparam ES_FSM_VOFFSET_RRDY = 6'h20; localparam ES_FSM_VOFFSET_WRITE = 6'h21; localparam ES_FSM_VOFFSET_WRDY = 6'h22; localparam ES_FSM_CTRLSTART_READ = 6'h23; localparam ES_FSM_CTRLSTART_RRDY = 6'h24; localparam ES_FSM_CTRLSTART_WRITE = 6'h25; localparam ES_FSM_CTRLSTART_WRDY = 6'h26; localparam ES_FSM_STATUS_READ = 6'h27; localparam ES_FSM_STATUS_RRDY = 6'h28; localparam ES_FSM_CTRLSTOP_READ = 6'h29; localparam ES_FSM_CTRLSTOP_RRDY = 6'h2a; localparam ES_FSM_CTRLSTOP_WRITE = 6'h2b; localparam ES_FSM_CTRLSTOP_WRDY = 6'h2c; localparam ES_FSM_SCNT_READ = 6'h2d; localparam ES_FSM_SCNT_RRDY = 6'h2e; localparam ES_FSM_ECNT_READ = 6'h2f; localparam ES_FSM_ECNT_RRDY = 6'h30; localparam ES_FSM_DMA_WRITE = 6'h31; localparam ES_FSM_DMA_READY = 6'h32; localparam ES_FSM_UPDATE = 6'h33; // drp interface input drp_rst; input drp_clk; output es_sel; output es_wr; output [11:0] es_addr; output [15:0] es_wdata; input [15:0] es_rdata; input es_ready; // axi4 interface input axi_rstn; input axi_clk; output axi_awvalid; output [31:0] axi_awaddr; output [ 2:0] axi_awprot; input axi_awready; output axi_wvalid; output [31:0] axi_wdata; output [ 3:0] axi_wstrb; input axi_wready; input axi_bvalid; input [ 1:0] axi_bresp; output axi_bready; output axi_arvalid; output [31:0] axi_araddr; output [ 2:0] axi_arprot; input axi_arready; input axi_rvalid; input [31:0] axi_rdata; input [ 1:0] axi_rresp; output axi_rready; // processor interface input es_start; input es_stop; input es_init; input es_lpm_dfe_n; input [15:0] es_sdata0; input [15:0] es_sdata1; input [15:0] es_sdata2; input [15:0] es_sdata3; input [15:0] es_sdata4; input [15:0] es_qdata0; input [15:0] es_qdata1; input [15:0] es_qdata2; input [15:0] es_qdata3; input [15:0] es_qdata4; input [ 4:0] es_prescale; input [11:0] es_hoffset_min; input [11:0] es_hoffset_max; input [11:0] es_hoffset_step; input [ 7:0] es_voffset_min; input [ 7:0] es_voffset_max; input [ 7:0] es_voffset_step; input [ 1:0] es_voffset_range; input [31:0] es_start_addr; output es_dmaerr; output es_status; // debug interface output [275:0] es_dbg_data; output [ 7:0] es_dbg_trigger; // internal registers reg axi_req_toggle_m1 = 'd0; reg axi_req_toggle_m2 = 'd0; reg axi_req_toggle_m3 = 'd0; reg axi_awvalid = 'd0; reg [31:0] axi_awaddr = 'd0; reg axi_wvalid = 'd0; reg [31:0] axi_wdata = 'd0; reg axi_ack_toggle = 'd0; reg axi_err = 'd0; reg es_dma_ack_toggle_m1 = 'd0; reg es_dma_ack_toggle_m2 = 'd0; reg es_dma_ack_toggle_m3 = 'd0; reg es_dmaerr_m1 = 'd0; reg es_dmaerr = 'd0; reg es_dma_req_toggle = 'd0; reg [31:0] es_dma_addr = 'd0; reg [31:0] es_dma_data = 'd0; reg es_status = 'd0; reg es_ut = 'd0; reg [31:0] es_dma_addr_int = 'd0; reg [11:0] es_hoffset = 'd0; reg [ 7:0] es_voffset = 'd0; reg [15:0] es_hoffset_rdata = 'd0; reg [15:0] es_voffset_rdata = 'd0; reg [15:0] es_ctrl_rdata = 'd0; reg [15:0] es_scnt_rdata = 'd0; reg [15:0] es_ecnt_rdata = 'd0; reg [ 5:0] es_fsm = 'd0; reg es_sel = 'd0; reg es_wr = 'd0; reg [11:0] es_addr = 'd0; reg [15:0] es_wdata = 'd0; // internal signals wire axi_req_s; wire es_dma_ack_s; wire es_heos_s; wire es_eos_s; wire es_ut_s; wire [ 7:0] es_voffset_2_s; wire [ 7:0] es_voffset_n_s; wire [ 7:0] es_voffset_s; // debug interface assign es_dbg_trigger = {es_start, es_eos_s, es_fsm}; assign es_dbg_data[ 0: 0] = es_sel; assign es_dbg_data[ 1: 1] = es_wr; assign es_dbg_data[ 13: 2] = es_addr; assign es_dbg_data[ 29: 14] = es_wdata; assign es_dbg_data[ 45: 30] = es_rdata; assign es_dbg_data[ 46: 46] = es_ready; assign es_dbg_data[ 47: 47] = axi_awvalid; assign es_dbg_data[ 79: 48] = axi_awaddr; assign es_dbg_data[ 80: 80] = axi_awready; assign es_dbg_data[ 81: 81] = axi_wvalid; assign es_dbg_data[113: 82] = axi_wdata; assign es_dbg_data[117:114] = axi_wstrb; assign es_dbg_data[118:118] = axi_wready; assign es_dbg_data[119:119] = axi_bvalid; assign es_dbg_data[121:120] = axi_bresp; assign es_dbg_data[122:122] = axi_bready; assign es_dbg_data[123:123] = es_dmaerr; assign es_dbg_data[124:124] = es_start; assign es_dbg_data[125:125] = es_init; assign es_dbg_data[126:126] = es_status; assign es_dbg_data[127:127] = es_ut; assign es_dbg_data[159:128] = es_dma_addr_int; assign es_dbg_data[171:160] = es_hoffset; assign es_dbg_data[179:172] = es_voffset; assign es_dbg_data[195:180] = es_hoffset_rdata; assign es_dbg_data[211:196] = es_voffset_rdata; assign es_dbg_data[227:212] = es_ctrl_rdata; assign es_dbg_data[243:228] = es_scnt_rdata; assign es_dbg_data[259:244] = es_ecnt_rdata; assign es_dbg_data[265:260] = es_fsm; assign es_dbg_data[266:266] = es_heos_s; assign es_dbg_data[267:267] = es_eos_s; assign es_dbg_data[275:268] = es_voffset_s; // axi write interface assign axi_awprot = 3'd0; assign axi_wstrb = 4'hf; assign axi_bready = 1'd1; assign axi_arvalid = 1'd0; assign axi_araddr = 32'd0; assign axi_arprot = 3'd0; assign axi_rready = 1'd1; assign axi_req_s = axi_req_toggle_m3 ^ axi_req_toggle_m2; always @(negedge axi_rstn or posedge axi_clk) begin if (axi_rstn == 0) begin axi_req_toggle_m1 <= 'd0; axi_req_toggle_m2 <= 'd0; axi_req_toggle_m3 <= 'd0; axi_awvalid <= 'b0; axi_awaddr <= 'd0; axi_wvalid <= 'b0; axi_wdata <= 'd0; axi_ack_toggle <= 'd0; axi_err <= 'd0; end else begin axi_req_toggle_m1 <= es_dma_req_toggle; axi_req_toggle_m2 <= axi_req_toggle_m1; axi_req_toggle_m3 <= axi_req_toggle_m2; if ((axi_awvalid == 1'b1) && (axi_awready == 1'b1)) begin axi_awvalid <= 1'b0; axi_awaddr <= 32'd0; end else if (axi_req_s == 1'b1) begin axi_awvalid <= 1'b1; axi_awaddr <= es_dma_addr; end if ((axi_wvalid == 1'b1) && (axi_wready == 1'b1)) begin axi_wvalid <= 1'b0; axi_wdata <= 32'd0; end else if (axi_req_s == 1'b1) begin axi_wvalid <= 1'b1; axi_wdata <= es_dma_data; end if (axi_bvalid == 1'b1) begin axi_ack_toggle <= ~axi_ack_toggle; axi_err <= axi_bresp[1] | axi_bresp[0]; end end end assign es_dma_ack_s = es_dma_ack_toggle_m3 ^ es_dma_ack_toggle_m2; always @(posedge drp_clk) begin if (drp_rst == 1'b1) begin es_dma_ack_toggle_m1 <= 'd0; es_dma_ack_toggle_m2 <= 'd0; es_dma_ack_toggle_m3 <= 'd0; es_dmaerr_m1 <= 'd0; es_dmaerr <= 'd0; es_dma_req_toggle <= 'd0; es_dma_addr <= 'd0; es_dma_data <= 'd0; end else begin es_dma_ack_toggle_m1 <= axi_ack_toggle; es_dma_ack_toggle_m2 <= es_dma_ack_toggle_m1; es_dma_ack_toggle_m3 <= es_dma_ack_toggle_m2; es_dmaerr_m1 <= axi_err; es_dmaerr <= es_dmaerr_m1; if (es_fsm == ES_FSM_DMA_WRITE) begin es_dma_req_toggle <= ~es_dma_req_toggle; es_dma_addr <= es_dma_addr_int; es_dma_data <= {es_scnt_rdata, es_ecnt_rdata}; end end end // prescale, horizontal and vertical offsets assign es_heos_s = (es_hoffset == es_hoffset_max) ? es_ut : 1'b0; assign es_eos_s = (es_voffset == es_voffset_max) ? es_heos_s : 1'b0; assign es_ut_s = es_ut & ~es_lpm_dfe_n; assign es_voffset_2_s = ~es_voffset + 1'b1; assign es_voffset_n_s = {1'b1, es_voffset_2_s[6:0]}; assign es_voffset_s = (es_voffset[7] == 1'b1) ? es_voffset_n_s : es_voffset; always @(posedge drp_clk) begin if (es_fsm == ES_FSM_IDLE) begin es_status <= 1'b0; end else begin es_status <= 1'b1; end if (es_fsm == ES_FSM_IDLE) begin es_ut <= es_lpm_dfe_n; es_dma_addr_int <= es_start_addr; es_hoffset <= es_hoffset_min; es_voffset <= es_voffset_min; end else if (es_fsm == ES_FSM_UPDATE) begin es_ut <= ~es_ut | es_lpm_dfe_n; es_dma_addr_int <= es_dma_addr_int + 3'd4; if (es_heos_s == 1'b1) begin es_hoffset <= es_hoffset_min; end else if (es_ut == 1'b1) begin es_hoffset <= es_hoffset + es_hoffset_step; end if (es_heos_s == 1'b1) begin es_voffset <= es_voffset + es_voffset_step; end end end // read-modify-write parameters (gt's are full of mixed up controls) always @(posedge drp_clk) begin if ((es_fsm == ES_FSM_HOFFSET_RRDY) && (es_ready == 1'b1)) begin es_hoffset_rdata <= es_rdata; end if ((es_fsm == ES_FSM_VOFFSET_RRDY) && (es_ready == 1'b1)) begin es_voffset_rdata <= es_rdata; end if (((es_fsm == ES_FSM_CTRLINIT_RRDY) || (es_fsm == ES_FSM_CTRLSTART_RRDY) || (es_fsm == ES_FSM_CTRLSTOP_RRDY)) && (es_ready == 1'b1)) begin es_ctrl_rdata <= es_rdata; end if ((es_fsm == ES_FSM_SCNT_RRDY) && (es_ready == 1'b1)) begin es_scnt_rdata <= es_rdata; end if ((es_fsm == ES_FSM_ECNT_RRDY) && (es_ready == 1'b1)) begin es_ecnt_rdata <= es_rdata; end end // eye scan state machine- write vertical and horizontal offsets // and read back sample and error counters always @(posedge drp_clk) begin if ((drp_rst == 1'b1) || (es_stop == 1'b1)) begin es_fsm <= ES_FSM_IDLE; end else begin case (es_fsm) ES_FSM_IDLE: begin // idle if (es_start == 1'b1) begin es_fsm <= ES_FSM_STATUS; end else begin es_fsm <= ES_FSM_IDLE; end end ES_FSM_STATUS: begin // set status es_fsm <= ES_FSM_INIT; end ES_FSM_INIT: begin // initialize if (es_init == 1'b1) begin es_fsm <= ES_FSM_CTRLINIT_READ; end else begin es_fsm <= ES_FSM_HOFFSET_READ; end end ES_FSM_CTRLINIT_READ: begin // control read es_fsm <= ES_FSM_CTRLINIT_RRDY; end ES_FSM_CTRLINIT_RRDY: begin // control ready if (es_ready == 1'b1) begin es_fsm <= ES_FSM_CTRLINIT_WRITE; end else begin es_fsm <= ES_FSM_CTRLINIT_RRDY; end end ES_FSM_CTRLINIT_WRITE: begin // control write es_fsm <= ES_FSM_CTRLINIT_WRDY; end ES_FSM_CTRLINIT_WRDY: begin // control ready if (es_ready == 1'b1) begin es_fsm <= ES_FSM_SDATA0_WRITE; end else begin es_fsm <= ES_FSM_CTRLINIT_WRDY; end end ES_FSM_SDATA0_WRITE: begin // sdata write es_fsm <= ES_FSM_SDATA0_WRDY; end ES_FSM_SDATA0_WRDY: begin // sdata ready if (es_ready == 1'b1) begin es_fsm <= ES_FSM_SDATA1_WRITE; end else begin es_fsm <= ES_FSM_SDATA0_WRDY; end end ES_FSM_SDATA1_WRITE: begin // sdata write es_fsm <= ES_FSM_SDATA1_WRDY; end ES_FSM_SDATA1_WRDY: begin // sdata ready if (es_ready == 1'b1) begin es_fsm <= ES_FSM_SDATA2_WRITE; end else begin es_fsm <= ES_FSM_SDATA1_WRDY; end end ES_FSM_SDATA2_WRITE: begin // sdata write es_fsm <= ES_FSM_SDATA2_WRDY; end ES_FSM_SDATA2_WRDY: begin // sdata ready if (es_ready == 1'b1) begin es_fsm <= ES_FSM_SDATA3_WRITE; end else begin es_fsm <= ES_FSM_SDATA2_WRDY; end end ES_FSM_SDATA3_WRITE: begin // sdata write es_fsm <= ES_FSM_SDATA3_WRDY; end ES_FSM_SDATA3_WRDY: begin // sdata ready if (es_ready == 1'b1) begin es_fsm <= ES_FSM_SDATA4_WRITE; end else begin es_fsm <= ES_FSM_SDATA3_WRDY; end end ES_FSM_SDATA4_WRITE: begin // sdata write es_fsm <= ES_FSM_SDATA4_WRDY; end ES_FSM_SDATA4_WRDY: begin // sdata ready if (es_ready == 1'b1) begin es_fsm <= ES_FSM_QDATA0_WRITE; end else begin es_fsm <= ES_FSM_SDATA4_WRDY; end end ES_FSM_QDATA0_WRITE: begin // qdata write es_fsm <= ES_FSM_QDATA0_WRDY; end ES_FSM_QDATA0_WRDY: begin // qdata ready if (es_ready == 1'b1) begin es_fsm <= ES_FSM_QDATA1_WRITE; end else begin es_fsm <= ES_FSM_QDATA0_WRDY; end end ES_FSM_QDATA1_WRITE: begin // qdata write es_fsm <= ES_FSM_QDATA1_WRDY; end ES_FSM_QDATA1_WRDY: begin // qdata ready if (es_ready == 1'b1) begin es_fsm <= ES_FSM_QDATA2_WRITE; end else begin es_fsm <= ES_FSM_QDATA1_WRDY; end end ES_FSM_QDATA2_WRITE: begin // qdata write es_fsm <= ES_FSM_QDATA2_WRDY; end ES_FSM_QDATA2_WRDY: begin // qdata ready if (es_ready == 1'b1) begin es_fsm <= ES_FSM_QDATA3_WRITE; end else begin es_fsm <= ES_FSM_QDATA2_WRDY; end end ES_FSM_QDATA3_WRITE: begin // qdata write es_fsm <= ES_FSM_QDATA3_WRDY; end ES_FSM_QDATA3_WRDY: begin // qdata ready if (es_ready == 1'b1) begin es_fsm <= ES_FSM_QDATA4_WRITE; end else begin es_fsm <= ES_FSM_QDATA3_WRDY; end end ES_FSM_QDATA4_WRITE: begin // qdata write es_fsm <= ES_FSM_QDATA4_WRDY; end ES_FSM_QDATA4_WRDY: begin // qdata ready if (es_ready == 1'b1) begin es_fsm <= ES_FSM_HOFFSET_READ; end else begin es_fsm <= ES_FSM_QDATA4_WRDY; end end ES_FSM_HOFFSET_READ: begin // horizontal offset read es_fsm <= ES_FSM_HOFFSET_RRDY; end ES_FSM_HOFFSET_RRDY: begin // horizontal offset ready if (es_ready == 1'b1) begin es_fsm <= ES_FSM_HOFFSET_WRITE; end else begin es_fsm <= ES_FSM_HOFFSET_RRDY; end end ES_FSM_HOFFSET_WRITE: begin // horizontal offset write es_fsm <= ES_FSM_HOFFSET_WRDY; end ES_FSM_HOFFSET_WRDY: begin // horizontal offset ready if (es_ready == 1'b1) begin es_fsm <= ES_FSM_VOFFSET_READ; end else begin es_fsm <= ES_FSM_HOFFSET_WRDY; end end ES_FSM_VOFFSET_READ: begin // vertical offset read es_fsm <= ES_FSM_VOFFSET_RRDY; end ES_FSM_VOFFSET_RRDY: begin // vertical offset ready if (es_ready == 1'b1) begin es_fsm <= ES_FSM_VOFFSET_WRITE; end else begin es_fsm <= ES_FSM_VOFFSET_RRDY; end end ES_FSM_VOFFSET_WRITE: begin // vertical offset write es_fsm <= ES_FSM_VOFFSET_WRDY; end ES_FSM_VOFFSET_WRDY: begin // vertical offset ready if (es_ready == 1'b1) begin es_fsm <= ES_FSM_CTRLSTART_READ; end else begin es_fsm <= ES_FSM_VOFFSET_WRDY; end end ES_FSM_CTRLSTART_READ: begin // control read es_fsm <= ES_FSM_CTRLSTART_RRDY; end ES_FSM_CTRLSTART_RRDY: begin // control ready if (es_ready == 1'b1) begin es_fsm <= ES_FSM_CTRLSTART_WRITE; end else begin es_fsm <= ES_FSM_CTRLSTART_RRDY; end end ES_FSM_CTRLSTART_WRITE: begin // control write es_fsm <= ES_FSM_CTRLSTART_WRDY; end ES_FSM_CTRLSTART_WRDY: begin // control ready if (es_ready == 1'b1) begin es_fsm <= ES_FSM_STATUS_READ; end else begin es_fsm <= ES_FSM_CTRLSTART_WRDY; end end ES_FSM_STATUS_READ: begin // status read es_fsm <= ES_FSM_STATUS_RRDY; end ES_FSM_STATUS_RRDY: begin // status ready if (es_ready == 1'b0) begin es_fsm <= ES_FSM_STATUS_RRDY; end else if (es_rdata[3:0] == 4'b0101) begin es_fsm <= ES_FSM_CTRLSTOP_READ; end else begin es_fsm <= ES_FSM_STATUS_READ; end end ES_FSM_CTRLSTOP_READ: begin // control read es_fsm <= ES_FSM_CTRLSTOP_RRDY; end ES_FSM_CTRLSTOP_RRDY: begin // control ready if (es_ready == 1'b1) begin es_fsm <= ES_FSM_CTRLSTOP_WRITE; end else begin es_fsm <= ES_FSM_CTRLSTOP_RRDY; end end ES_FSM_CTRLSTOP_WRITE: begin // control write es_fsm <= ES_FSM_CTRLSTOP_WRDY; end ES_FSM_CTRLSTOP_WRDY: begin // control ready if (es_ready == 1'b1) begin es_fsm <= ES_FSM_SCNT_READ; end else begin es_fsm <= ES_FSM_CTRLSTOP_WRDY; end end ES_FSM_SCNT_READ: begin // read sample count es_fsm <= ES_FSM_SCNT_RRDY; end ES_FSM_SCNT_RRDY: begin // sample count ready if (es_ready == 1'b1) begin es_fsm <= ES_FSM_ECNT_READ; end else begin es_fsm <= ES_FSM_SCNT_RRDY; end end ES_FSM_ECNT_READ: begin // read error count es_fsm <= ES_FSM_ECNT_RRDY; end ES_FSM_ECNT_RRDY: begin // error count ready if (es_ready == 1'b1) begin es_fsm <= ES_FSM_DMA_WRITE; end else begin es_fsm <= ES_FSM_ECNT_RRDY; end end ES_FSM_DMA_WRITE: begin // dma write es_fsm <= ES_FSM_DMA_READY; end ES_FSM_DMA_READY: begin // dma ack if (es_dma_ack_s == 1'b1) begin es_fsm <= ES_FSM_UPDATE; end else begin es_fsm <= ES_FSM_DMA_READY; end end ES_FSM_UPDATE: begin // update if (es_eos_s == 1'b1) begin es_fsm <= ES_FSM_IDLE; end else if (es_ut == 1'b1) begin es_fsm <= ES_FSM_HOFFSET_READ; end else begin es_fsm <= ES_FSM_VOFFSET_READ; end end default: begin es_fsm <= ES_FSM_IDLE; end endcase end end // drp signals controlled by the fsm always @(posedge drp_clk) begin case (es_fsm) ES_FSM_CTRLINIT_READ: begin es_sel <= 1'b1; es_wr <= 1'b0; es_addr <= ES_DRP_CTRL_ADDR; es_wdata <= 16'h0000; end ES_FSM_CTRLINIT_WRITE: begin es_sel <= 1'b1; es_wr <= 1'b1; es_addr <= ES_DRP_CTRL_ADDR; if (GTH_GTX_N == 1) begin es_wdata <= {es_ctrl_rdata[15:10], 2'b11, es_ctrl_rdata[7:5], es_prescale}; end else begin es_wdata <= {es_ctrl_rdata[15:10], 2'b11, es_ctrl_rdata[7:0]}; end end ES_FSM_SDATA0_WRITE: begin es_sel <= 1'b1; es_wr <= 1'b1; es_addr <= ES_DRP_SDATA0_ADDR; es_wdata <= es_sdata0; end ES_FSM_SDATA1_WRITE: begin es_sel <= 1'b1; es_wr <= 1'b1; es_addr <= ES_DRP_SDATA1_ADDR; es_wdata <= es_sdata1; end ES_FSM_SDATA2_WRITE: begin es_sel <= 1'b1; es_wr <= 1'b1; es_addr <= ES_DRP_SDATA2_ADDR; es_wdata <= es_sdata2; end ES_FSM_SDATA3_WRITE: begin es_sel <= 1'b1; es_wr <= 1'b1; es_addr <= ES_DRP_SDATA3_ADDR; es_wdata <= es_sdata3; end ES_FSM_SDATA4_WRITE: begin es_sel <= 1'b1; es_wr <= 1'b1; es_addr <= ES_DRP_SDATA4_ADDR; es_wdata <= es_sdata4; end ES_FSM_QDATA0_WRITE: begin es_sel <= 1'b1; es_wr <= 1'b1; es_addr <= ES_DRP_QDATA0_ADDR; es_wdata <= es_qdata0; end ES_FSM_QDATA1_WRITE: begin es_sel <= 1'b1; es_wr <= 1'b1; es_addr <= ES_DRP_QDATA1_ADDR; es_wdata <= es_qdata1; end ES_FSM_QDATA2_WRITE: begin es_sel <= 1'b1; es_wr <= 1'b1; es_addr <= ES_DRP_QDATA2_ADDR; es_wdata <= es_qdata2; end ES_FSM_QDATA3_WRITE: begin es_sel <= 1'b1; es_wr <= 1'b1; es_addr <= ES_DRP_QDATA3_ADDR; es_wdata <= es_qdata3; end ES_FSM_QDATA4_WRITE: begin es_sel <= 1'b1; es_wr <= 1'b1; es_addr <= ES_DRP_QDATA4_ADDR; es_wdata <= es_qdata4; end ES_FSM_HOFFSET_READ: begin es_sel <= 1'b1; es_wr <= 1'b0; es_addr <= ES_DRP_HOFFSET_ADDR; es_wdata <= 16'h0000; end ES_FSM_HOFFSET_WRITE: begin es_sel <= 1'b1; es_wr <= 1'b1; es_addr <= ES_DRP_HOFFSET_ADDR; if (GTH_GTX_N == 1) begin es_wdata <= {es_hoffset, es_hoffset_rdata[3:0]}; end else begin es_wdata <= {es_hoffset_rdata[15:12], es_hoffset}; end end ES_FSM_VOFFSET_READ: begin es_sel <= 1'b1; es_wr <= 1'b0; es_addr <= ES_DRP_VOFFSET_ADDR; es_wdata <= 16'h0000; end ES_FSM_VOFFSET_WRITE: begin es_sel <= 1'b1; es_wr <= 1'b1; es_addr <= ES_DRP_VOFFSET_ADDR; if (GTH_GTX_N == 1) begin es_wdata <= {es_voffset_rdata[15:11], es_voffset_s[7], es_ut_s, es_voffset_s[6:0], es_voffset_range}; end else begin es_wdata <= {es_prescale, es_voffset_rdata[10:9], es_ut_s, es_voffset_s}; end end ES_FSM_CTRLSTART_READ: begin es_sel <= 1'b1; es_wr <= 1'b0; es_addr <= ES_DRP_CTRL_ADDR; es_wdata <= 16'h0000; end ES_FSM_CTRLSTART_WRITE: begin es_sel <= 1'b1; es_wr <= 1'b1; es_addr <= ES_DRP_CTRL_ADDR; if (GTH_GTX_N == 1) begin es_wdata <= {6'd1, es_ctrl_rdata[9:0]}; end else begin es_wdata <= {es_ctrl_rdata[15:6], 6'd1}; end end ES_FSM_STATUS_READ: begin es_sel <= 1'b1; es_wr <= 1'b0; es_addr <= ES_DRP_STATUS_ADDR; es_wdata <= 16'h0000; end ES_FSM_CTRLSTOP_READ: begin es_sel <= 1'b1; es_wr <= 1'b0; es_addr <= ES_DRP_CTRL_ADDR; es_wdata <= 16'h0000; end ES_FSM_CTRLSTOP_WRITE: begin es_sel <= 1'b1; es_wr <= 1'b1; es_addr <= ES_DRP_CTRL_ADDR; if (GTH_GTX_N == 1) begin es_wdata <= {6'd0, es_ctrl_rdata[9:0]}; end else begin es_wdata <= {es_ctrl_rdata[15:6], 6'd0}; end end ES_FSM_SCNT_READ: begin es_sel <= 1'b1; es_wr <= 1'b0; es_addr <= ES_DRP_SCNT_ADDR; es_wdata <= 16'h0000; end ES_FSM_ECNT_READ: begin es_sel <= 1'b1; es_wr <= 1'b0; es_addr <= ES_DRP_ECNT_ADDR; es_wdata <= 16'h0000; end default: begin es_sel <= 1'b0; es_wr <= 1'b0; es_addr <= 9'h000; es_wdata <= 16'h0000; end endcase end endmodule // *************************************************************************** // ***************************************************************************