From 29f0ce36bbf53a58066a6bada1851a05442cfa35 Mon Sep 17 00:00:00 2001 From: Istvan Csomortani Date: Fri, 28 Oct 2016 10:32:30 +0300 Subject: [PATCH] axi_ad5766: Initial commit This core can be used in conjunction with the SPI_ENGINE, will work as an offload module, forwarding a data stream to the SPI excecution, received from a DMA. --- library/axi_ad5766/axi_ad5766.v | 422 +++++++++++++++++++++++ library/axi_ad5766/axi_ad5766_ip.tcl | 67 ++++ library/axi_ad5766/up_ad5766_sequencer.v | 260 ++++++++++++++ 3 files changed, 749 insertions(+) create mode 100644 library/axi_ad5766/axi_ad5766.v create mode 100644 library/axi_ad5766/axi_ad5766_ip.tcl create mode 100644 library/axi_ad5766/up_ad5766_sequencer.v diff --git a/library/axi_ad5766/axi_ad5766.v b/library/axi_ad5766/axi_ad5766.v new file mode 100644 index 000000000..aca3f47a0 --- /dev/null +++ b/library/axi_ad5766/axi_ad5766.v @@ -0,0 +1,422 @@ +// *************************************************************************** +// *************************************************************************** +// 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 axi_ad5766 #( + + parameter DATA_WIDTH = 8, + parameter NUM_OF_SDI = 1, + parameter ASYNC_SPI_CLK = 0, + parameter CMD_MEM_ADDRESS_WIDTH = 4, + parameter SDO_MEM_ADDRESS_WIDTH = 4)( + + // Slave AXI interface + + input s_axi_aclk, + input s_axi_aresetn, + input s_axi_awvalid, + input [31:0] s_axi_awaddr, + output s_axi_awready, + input [ 2:0] s_axi_awprot, + input s_axi_wvalid, + input [31:0] s_axi_wdata, + input [ 3:0] s_axi_wstrb, + output s_axi_wready, + output s_axi_bvalid, + output [ 1:0] s_axi_bresp, + input s_axi_bready, + input s_axi_arvalid, + input [31:0] s_axi_araddr, + output s_axi_arready, + input [ 2:0] s_axi_arprot, + output s_axi_rvalid, + input s_axi_rready, + output [ 1:0] s_axi_rresp, + output [31:0] s_axi_rdata, + + // FIFO transmit + + output dma_clk, + output reg dma_valid, + input dma_enable, + input [15:0] dma_data, + input dma_xfer_req, + input dma_underflow, + + // SPI engine control interface (to the SPI engine interconnect) + + input spi_clk, // should be connected to up_clk + input spi_resetn, + + input cmd_ready, + output cmd_valid, + output [15:0] cmd_data, + + input sdo_data_ready, + output sdo_data_valid, + output [(DATA_WIDTH-1):0] sdo_data, + + output sdi_data_ready, + input sdi_data_valid, + input [(NUM_OF_SDI * DATA_WIDTH-1):0] sdi_data, + + output sync_ready, + input sync_valid, + input [ 7:0] sync_data, + + // SPI engine offload interface (to the AXI SPI engine) + + input ctrl_clk, + input ctrl_cmd_wr_en, + input [15:0] ctrl_cmd_wr_data, + + input ctrl_enable, + output ctrl_enabled, + input ctrl_mem_reset); + + // internal wires + + wire up_wreq_s; + wire [13:0] up_waddr_s; + wire [31:0] up_wdata_s; + wire up_rreq_s; + wire [13:0] up_raddr_s; + wire [31:0] up_rdata_s[0:1]; + wire up_rack_s[0:1]; + wire up_wack_s[0:1]; + wire trigger_s; + wire [31:0] pulse_period_s; + wire [ 7:0] dac_datarate_s; + wire spi_reset; + wire spi_enable_s; + wire [ 3:0] sequencer[15:0]; + wire [ 3:0] cmd_bits; + wire [ 3:0] end_of_sequence; + wire spi_mem_reset_s; + wire sequence_valid_s; + wire [ 7:0] sequence_data_s; + wire dac_rst_s; + wire dac_rstn_s; + wire [CMD_MEM_ADDRESS_WIDTH-1:0] spi_cmd_rd_addr_next; + + // registers + + reg [31:0] up_rdata = 32'b0; + reg up_rack = 0; + reg up_wack = 1'b0; + reg [15:0] cmd_mem[0:2**CMD_MEM_ADDRESS_WIDTH-1]; + reg [(DATA_WIDTH-1):0] sdo_mem[0:2**SDO_MEM_ADDRESS_WIDTH-1]; + reg [CMD_MEM_ADDRESS_WIDTH-1:0] ctrl_cmd_wr_addr = 'b0; + reg [CMD_MEM_ADDRESS_WIDTH-1:0] spi_cmd_rd_addr = 'b0; + reg [SDO_MEM_ADDRESS_WIDTH-1:0] ctrl_sdo_wr_addr = 'b0; + reg [SDO_MEM_ADDRESS_WIDTH-1:0] spi_sdo_rd_addr = 'b0; + reg spi_active = 1'b0; + + assign up_rstn = s_axi_aresetn; + + // the dma interface runs on SPI_CLK + + assign dma_clk = spi_clk; + + // command and SDO data offload + + assign cmd_valid = spi_active; + assign cmd_data = cmd_mem[spi_cmd_rd_addr]; + assign sdo_data_valid = spi_active; + assign sdo_data = sdo_mem[spi_sdo_rd_addr]; + assign sync_ready = 1'b1; + + assign sdi_data_ready = 1'b0; + + generate if (ASYNC_SPI_CLK) begin + + /* + * The synchronization circuit takes care that there are no glitches on the + * ctrl_enabled signal. ctrl_do_enable is asserted whenever ctrl_enable is + * asserted, but only deasserted once the signal has been synchronized back from + * the SPI domain. This makes sure that we can't end up in a state where the + * enable signal in the SPI domain is asserted, but neither enable nor enabled + * is asserted in the control domain. + */ + + reg ctrl_do_enable = 1'b0; + wire ctrl_is_enabled; + reg spi_enabled = 1'b0; + + always @(posedge ctrl_clk) begin + if (ctrl_enable == 1'b1) begin + ctrl_do_enable <= 1'b1; + end else if (ctrl_is_enabled == 1'b1) begin + ctrl_do_enable <= 1'b0; + end + end + + assign ctrl_enabled = ctrl_is_enabled | ctrl_do_enable; + + always @(posedge spi_clk) begin + spi_enabled <= spi_enable_s | spi_active; + end + + sync_bits # ( + .NUM_OF_BITS(1), + .ASYNC_CLK(1) + ) i_sync_enable ( + .in(ctrl_do_enable), + .out_clk(spi_clk), + .out_resetn(1'b1), + .out(spi_enable_s) + ); + + sync_bits # ( + .NUM_OF_BITS(1), + .ASYNC_CLK(1) + ) i_sync_enabled ( + .in(spi_enabled), + .out_clk(ctrl_clk), + .out_resetn(1'b1), + .out(ctrl_is_enabled) + ); + + sync_bits # ( + .NUM_OF_BITS(1), + .ASYNC_CLK(1) + ) i_sync_mem_reset ( + .in(ctrl_mem_reset), + .out_clk(spi_clk), + .out_resetn(1'b1), + .out(spi_mem_reset_s) + ); + + end else begin + assign spi_enable_s = ctrl_enable; + assign ctrl_enabled = spi_enable_s | spi_active; + assign spi_mem_reset_s = ctrl_mem_reset; + end endgenerate + + assign spi_cmd_rd_addr_next = spi_cmd_rd_addr + 1; + + always @(posedge spi_clk) begin + if (spi_resetn == 1'b0) begin + spi_active <= 1'b0; + end else begin + if (spi_active == 1'b0) begin + if ((trigger_s == 1'b1 && spi_enable_s == 1'b1)) begin + spi_active <= 1'b1; + end + end else if (cmd_ready == 1'b1 && spi_cmd_rd_addr_next == ctrl_cmd_wr_addr) begin + spi_active <= 1'b0; + end + end + end + + always @(posedge spi_clk) begin + if (cmd_valid == 1'b0) begin + spi_cmd_rd_addr <= 'h00; + end else if (cmd_ready == 1'b1) begin + spi_cmd_rd_addr <= spi_cmd_rd_addr_next; + end + end + + always @(posedge spi_clk) begin + if (spi_active == 1'b0) begin + spi_sdo_rd_addr <= 'h00; + end else if (sdo_data_ready == 1'b1) begin + spi_sdo_rd_addr <= spi_sdo_rd_addr + 1'b1; + end + end + + always @(posedge ctrl_clk) begin + if (ctrl_cmd_wr_en) begin + cmd_mem[ctrl_cmd_wr_addr] <= ctrl_cmd_wr_data; + end + end + + always @(posedge ctrl_clk) begin + if (ctrl_mem_reset) begin + ctrl_cmd_wr_addr <= 0; + end else if (ctrl_cmd_wr_en) begin + ctrl_cmd_wr_addr <= ctrl_cmd_wr_addr + 1; + end + end + + // request data from the DMA at the desired rate + + always @(posedge dma_clk) begin + if (!dma_xfer_req) begin + dma_valid <= 1'b0; + end else begin + if (trigger_s) begin + dma_valid <= 1'b1; + end + if (dma_valid) begin + dma_valid <= 1'b0; + end + end + if (dma_valid) begin + sdo_mem[1] <= dma_data[15:8]; + sdo_mem[2] <= dma_data[ 7:0]; + end + if (sequence_valid_s) begin + sdo_mem[0] <= sequence_data_s; + end + end + + // rate controller + + assign dac_rstn_s = ~dac_rst_s; + util_pulse_gen #(.PULSE_WIDTH(1)) i_trigger_gen ( + .clk (spi_clk), + .rstn (dac_rstn_s), + .pulse_period (pulse_period_s), + .pulse_period_en (1'b1), + .pulse (trigger_s) + + ); + + // offset of the sequencer registers are 8'h40 + + always @(negedge up_rstn or posedge spi_clk) begin + if (up_rstn == 0) begin + up_rdata <= 'd0; + up_rack <= 'd0; + up_wack <= 'd0; + end else begin + up_rdata <= up_rdata_s[0] | up_rdata_s[1]; + up_rack <= up_rack_s[0] | up_rack_s[1]; + up_wack <= up_wack_s[0] | up_wack_s[1]; + end + end + + // DAC common registermap + + assign pulse_period_s = {24'h0, dac_datarate_s}; + + up_ad5766_sequencer #( + .SEQ_ID(4)) + i_sequencer ( + .sequence_clk (spi_clk), + .sequence_rst (spi_mem_reset_s), + .sequence_req (dma_valid), + .sequence_valid (sequence_valid_s), + .sequence_data (sequence_data_s), + .up_rstn (up_rstn), + .up_clk (spi_clk), + .up_wreq (up_wreq_s), + .up_waddr (up_waddr_s), + .up_wdata (up_wdata_s), + .up_wack (up_wack_s[1]), + .up_rreq (up_rreq_s), + .up_raddr (up_raddr_s), + .up_rdata (up_rdata_s[1]), + .up_rack (up_rack_s[1])); + + up_dac_common #( + .DAC_COMMON_ID (0) + ) i_dac_common ( + .mmcm_rst (), + .dac_clk (spi_clk), + .dac_rst (dac_rst_s), + .dac_sync (), + .dac_frame (), + .dac_clksel (), + .dac_par_type (), + .dac_par_enb (), + .dac_r1_mode (), + .dac_datafmt (dac_datafmt), + .dac_datarate (dac_datarate_s), + .dac_status (), + .dac_status_ovf (), + .dac_status_unf (dma_underflow), + .dac_clk_ratio (32'b0), + .up_drp_sel (), + .up_drp_wr (), + .up_drp_addr (), + .up_drp_wdata (), + .up_drp_rdata (16'b0), + .up_drp_ready (1'b0), + .up_drp_locked (1'b0), + .up_usr_chanmax (), + .dac_usr_chanmax (8'b0), + .up_dac_gpio_in (32'b0), + .up_dac_gpio_out (), + .up_rstn (up_rstn), + .up_clk (spi_clk), + .up_wreq (up_wreq_s), + .up_waddr (up_waddr_s), + .up_wdata (up_wdata_s), + .up_wack (up_wack_s[0]), + .up_rreq (up_rreq_s), + .up_raddr (up_raddr_s), + .up_rdata (up_rdata_s[0]), + .up_rack (up_rack_s[0])); + + + // AXI wrapper + + up_axi #( + .ADDRESS_WIDTH (14) + ) i_up_axi ( + .up_rstn (up_rstn), + .up_clk (spi_clk), + .up_axi_awvalid (s_axi_awvalid), + .up_axi_awaddr (s_axi_awaddr), + .up_axi_awready (s_axi_awready), + .up_axi_wvalid (s_axi_wvalid), + .up_axi_wdata (s_axi_wdata), + .up_axi_wstrb (s_axi_wstrb), + .up_axi_wready (s_axi_wready), + .up_axi_bvalid (s_axi_bvalid), + .up_axi_bresp (s_axi_bresp), + .up_axi_bready (s_axi_bready), + .up_axi_arvalid (s_axi_arvalid), + .up_axi_araddr (s_axi_araddr), + .up_axi_arready (s_axi_arready), + .up_axi_rvalid (s_axi_rvalid), + .up_axi_rresp (s_axi_rresp), + .up_axi_rdata (s_axi_rdata), + .up_axi_rready (s_axi_rready), + .up_wreq (up_wreq_s), + .up_waddr (up_waddr_s), + .up_wdata (up_wdata_s), + .up_wack (up_wack), + .up_rreq (up_rreq_s), + .up_raddr (up_raddr_s), + .up_rdata (up_rdata), + .up_rack (up_rack)); + +endmodule diff --git a/library/axi_ad5766/axi_ad5766_ip.tcl b/library/axi_ad5766/axi_ad5766_ip.tcl new file mode 100644 index 000000000..0c295bf23 --- /dev/null +++ b/library/axi_ad5766/axi_ad5766_ip.tcl @@ -0,0 +1,67 @@ +# ip + +source ../scripts/adi_env.tcl +source $ad_hdl_dir/library/scripts/adi_ip.tcl + +adi_ip_create axi_ad5766 +adi_ip_files axi_ad5766 [list \ + "$ad_hdl_dir/library/common/up_xfer_cntrl.v" \ + "$ad_hdl_dir/library/common/up_xfer_status.v" \ + "$ad_hdl_dir/library/common/sync_bits.v" \ + "$ad_hdl_dir/library/common/ad_rst.v" \ + "$ad_hdl_dir/library/common/up_dac_common.v" \ + "$ad_hdl_dir/library/common/up_clock_mon.v" \ + "$ad_hdl_dir/library/common/up_axi.v" \ + "$ad_hdl_dir/library/common/util_pulse_gen.v" \ + "up_ad5766_sequencer.v" \ + "axi_ad5766.v" ] + +adi_ip_properties axi_ad5766 + +adi_add_bus "spi_engine_ctrl" "master" \ + "analog.com:interface:spi_engine_ctrl_rtl:1.0" \ + "analog.com:interface:spi_engine_ctrl:1.0" \ + { + {"cmd_ready" "CMD_READY"} \ + {"cmd_valid" "CMD_VALID"} \ + {"cmd_data" "CMD_DATA"} \ + {"sdo_data_ready" "SDO_READY"} \ + {"sdo_data_valid" "SDO_VALID"} \ + {"sdo_data" "SDO_DATA"} \ + {"sdi_data_ready" "SDI_READY"} \ + {"sdi_data_valid" "SDI_VALID"} \ + {"sdi_data" "SDI_DATA"} \ + {"sync_ready" "SYNC_READY"} \ + {"sync_valid" "SYNC_VALID"} \ + {"sync_data" "SYNC_DATA"} \ + } + +adi_add_bus "spi_engine_offload_ctrl" "slave" \ + "analog.com:interface:spi_engine_offload_ctrl_rtl:1.0" \ + "analog.com:interface:spi_engine_offload_ctrl:1.0" \ + { \ + { "ctrl_cmd_wr_en" "CMD_WR_EN"} \ + { "ctrl_cmd_wr_data" "CMD_WR_DATA"} \ + { "ctrl_enable" "ENABLE"} \ + { "ctrl_enabled" "ENABLED"} \ + { "ctrl_mem_reset" "MEM_RESET"} \ + } + +adi_add_bus "dma_fifo_tx" "master" \ + "analog.com:interface:fifo_rd_rtl:1.1" \ + "analog.com:interface:fifo_rd:1.1" \ + { \ + { "dma_data" "DATA"} \ + { "dma_valid" "ENABLE"} \ + { "dma_enable" "VALID"} \ + { "dma_underflow" "UNDERFLOW"} \ + { "dma_xfer_req" "XFER_REQ"} \ + } + + +adi_add_bus_clock "ctrl_clk" "spi_engine_offload_ctrl" +adi_add_bus_clock "spi_clk" "spi_engine_ctrl" "spi_resetn" +adi_add_bus_clock "dma_clk" "dma_fifo_tx" + +ipx::save_core [ipx::current_core] + diff --git a/library/axi_ad5766/up_ad5766_sequencer.v b/library/axi_ad5766/up_ad5766_sequencer.v new file mode 100644 index 000000000..9cdd30756 --- /dev/null +++ b/library/axi_ad5766/up_ad5766_sequencer.v @@ -0,0 +1,260 @@ +// *************************************************************************** +// *************************************************************************** +// 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 up_ad5766_sequencer #( + + parameter SEQ_ID = 0)( + + input sequence_clk, + input sequence_rst, + input sequence_req, + output reg sequence_valid, + output reg [ 7:0] sequence_data, + + input up_rstn, + input up_clk, + input up_wreq, + input [13:0] up_waddr, + input [31:0] up_wdata, + output reg up_wack, + input up_rreq, + input [13:0] up_raddr, + output reg [31:0] up_rdata, + output reg up_rack); + + + // registers + + reg [ 7:0] up_sequencer[15:0]; + reg [ 3:0] up_endof_seq = 4'b0; + reg up_xfer_req = 1'b0; + reg [ 3:0] sequence_counter = 0; + + // internal signals + + wire up_wreq_s; + wire up_rreq_s; + wire [ 7:0] sequencer[15:0]; + wire [ 3:0] end_of_sequence; + + integer i; + + // sequence counter + + always @(posedge sequence_clk) begin + if (sequence_rst) begin + sequence_counter <= 4'b0; + end else if (sequence_req) begin + sequence_counter <= (sequence_counter == end_of_sequence) ? 0 : sequence_counter + 1; + end + end + + // sequence output mux + + always @(posedge sequence_clk) begin + if (sequence_rst) begin + sequence_data <= 16'b0; + end + else if (sequence_req) begin + sequence_data <= sequencer[sequence_counter]; + end + sequence_valid <= sequence_req; + end + + // decode block select + + assign up_wreq_s = (up_waddr[13:8] == SEQ_ID) ? up_wreq : 1'b0; + assign up_rreq_s = (up_raddr[13:8] == SEQ_ID) ? up_rreq : 1'b0; + + // processor write interface + + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + for (i=0; i<16; i=i+1) begin + up_sequencer[i] <= 8'b0; + end + up_endof_seq <= 4'b0; + up_wack <= 1'b0; + end else begin + up_wack <= up_wreq_s; + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h40)) begin + up_sequencer[0] <= up_wdata[7:0]; + up_endof_seq <= (up_wdata[16]) ? up_waddr[3:0] : 4'b0; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h41)) begin + up_sequencer[1] <= up_wdata[7:0]; + up_endof_seq <= (up_wdata[16]) ? up_waddr[3:0] : 4'b0; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h42)) begin + up_sequencer[2] <= up_wdata[7:0]; + up_endof_seq <= (up_wdata[16]) ? up_waddr[3:0] : 4'b0; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h43)) begin + up_sequencer[3] <= up_wdata[7:0]; + up_endof_seq <= (up_wdata[16]) ? up_waddr[3:0] : 4'b0; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h44)) begin + up_sequencer[4] <= up_wdata[7:0]; + up_endof_seq <= (up_wdata[16]) ? up_waddr[3:0] : 4'b0; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h45)) begin + up_sequencer[5] <= up_wdata[7:0]; + up_endof_seq <= (up_wdata[16]) ? up_waddr[3:0] : 4'b0; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h46)) begin + up_sequencer[6] <= up_wdata[7:0]; + up_endof_seq <= (up_wdata[16]) ? up_waddr[3:0] : 4'b0; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h47)) begin + up_sequencer[7] <= up_wdata[7:0]; + up_endof_seq <= (up_wdata[16]) ? up_waddr[3:0] : 4'b0; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h48)) begin + up_sequencer[8] <= up_wdata[7:0]; + up_endof_seq <= (up_wdata[16]) ? up_waddr[3:0] : 4'b0; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h49)) begin + up_sequencer[9] <= up_wdata[7:0]; + up_endof_seq <= (up_wdata[16]) ? up_waddr[3:0] : 4'b0; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h4a)) begin + up_sequencer[10] <= up_wdata[7:0]; + up_endof_seq <= (up_wdata[16]) ? up_waddr[3:0] : 4'b0; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h4b)) begin + up_sequencer[11] <= up_wdata[7:0]; + up_endof_seq <= (up_wdata[16]) ? up_waddr[3:0] : 4'b0; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h4c)) begin + up_sequencer[12] <= up_wdata[7:0]; + up_endof_seq <= (up_wdata[16]) ? up_waddr[3:0] : 4'b0; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h4d)) begin + up_sequencer[13] <= up_wdata[7:0]; + up_endof_seq <= (up_wdata[16]) ? up_waddr[3:0] : 4'b0; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h4e)) begin + up_sequencer[14] <= up_wdata[7:0]; + up_endof_seq <= (up_wdata[16]) ? up_waddr[3:0] : 4'b0; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h4f)) begin + up_sequencer[15] <= up_wdata[7:0]; + up_endof_seq <= (up_wdata[16]) ? up_waddr[3:0] : 4'b0; + end + end + end + + // processor read interface + + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_rack <= 'd0; + up_rdata <= 'd0; + end else begin + up_rack <= up_rreq_s; + if (up_rreq_s == 1'b1) begin + case (up_raddr[7:0]) + 8'h40 : up_rdata <= {24'b0, up_sequencer[0]}; + 8'h41 : up_rdata <= {24'b0, up_sequencer[1]}; + 8'h42 : up_rdata <= {24'b0, up_sequencer[2]}; + 8'h43 : up_rdata <= {24'b0, up_sequencer[3]}; + 8'h44 : up_rdata <= {24'b0, up_sequencer[4]}; + 8'h45 : up_rdata <= {24'b0, up_sequencer[5]}; + 8'h46 : up_rdata <= {24'b0, up_sequencer[6]}; + 8'h47 : up_rdata <= {24'b0, up_sequencer[7]}; + 8'h48 : up_rdata <= {24'b0, up_sequencer[8]}; + 8'h49 : up_rdata <= {24'b0, up_sequencer[9]}; + 8'h4a : up_rdata <= {24'b0, up_sequencer[10]}; + 8'h4b : up_rdata <= {24'b0, up_sequencer[11]}; + 8'h4c : up_rdata <= {24'b0, up_sequencer[12]}; + 8'h4d : up_rdata <= {24'b0, up_sequencer[13]}; + 8'h4e : up_rdata <= {24'b0, up_sequencer[14]}; + 8'h4f : up_rdata <= {24'b0, up_sequencer[15]}; + 8'h60 : up_rdata <= {27'b0, up_xfer_req, up_endof_seq}; + endcase + end else begin + up_rdata <= 32'b0; + end + end + end + + // CDC + + up_xfer_cntrl #(.DATA_WIDTH(132)) i_xfer_cntrl ( + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_data_cntrl ({up_endof_seq, + up_sequencer[0], + up_sequencer[1], + up_sequencer[2], + up_sequencer[3], + up_sequencer[4], + up_sequencer[5], + up_sequencer[6], + up_sequencer[7], + up_sequencer[8], + up_sequencer[9], + up_sequencer[10], + up_sequencer[11], + up_sequencer[12], + up_sequencer[13], + up_sequencer[14], + up_sequencer[15]}), + .up_xfer_done (up_cntrl_xfer_done), + .d_rst (sequence_rst), + .d_clk (sequence_clk), + .d_data_cntrl ({end_of_sequence, + sequencer[0], + sequencer[1], + sequencer[2], + sequencer[3], + sequencer[4], + sequencer[5], + sequencer[6], + sequencer[7], + sequencer[8], + sequencer[9], + sequencer[10], + sequencer[11], + sequencer[12], + sequencer[13], + sequencer[14], + sequencer[15]})); + +endmodule