From 8ae9de8fbaf464eb7745cb01ddf97bcf333d74b6 Mon Sep 17 00:00:00 2001 From: Istvan Csomortani Date: Mon, 14 Dec 2015 16:00:56 +0200 Subject: [PATCH] axi_ad7616: Update core + Both the data width and number of SDI lines are configurable + SER1W line is hardware configurable, it was removed from the IP + Add 'Hardware mode' support for the controller --- library/axi_ad7616/axi_ad7616.v | 233 +++++++++++++----------- library/axi_ad7616/axi_ad7616_control.v | 124 +++++++++---- 2 files changed, 218 insertions(+), 139 deletions(-) diff --git a/library/axi_ad7616/axi_ad7616.v b/library/axi_ad7616/axi_ad7616.v index 83f4abfde..d09eabc5f 100644 --- a/library/axi_ad7616/axi_ad7616.v +++ b/library/axi_ad7616/axi_ad7616.v @@ -63,7 +63,6 @@ module axi_ad7616 ( hw_rngsel, chsel, crcen, - ser1w_n, burst, os, @@ -106,10 +105,12 @@ module axi_ad7616 ( // local parameters - localparam SDI_DATA_WIDTH = 16; + localparam DATA_WIDTH = 16; + localparam NUM_OF_SDI = 2; localparam SERIAL = 0; localparam PARALLEL = 1; localparam NEG_EDGE = 1; + localparam UP_ADDRESS_WIDTH = 14; // IO definitions @@ -131,7 +132,6 @@ module axi_ad7616 ( output [ 1:0] hw_rngsel; output [ 2:0] chsel; output crcen; - output ser1w_n; output burst; output [ 2:0] os; @@ -163,20 +163,31 @@ module axi_ad7616 ( // internal registers - // internal signals - wire up_clk; - wire up_rstn; - wire up_rst; - wire up_rreq_s; - wire [13:0] up_raddr_s; - wire [31:0] up_rdata_s[0:2]; - wire up_rack_s[0:2]; - wire up_wack_s[0:2]; - wire up_wreq_s; - wire [13:0] up_waddr_s; - wire [31:0] up_wdata_s; + wire up_clk; + wire up_rstn; + wire up_rst; + wire up_rreq_s; + wire [(UP_ADDRESS_WIDTH-1):0] up_raddr_s; + wire up_wreq_s; + wire [(UP_ADDRESS_WIDTH-1):0] up_waddr_s; + wire [31:0] up_wdata_s; + + wire up_wack_if_s; + wire up_rack_if_s; + wire [31:0] up_rdata_if_s; + wire up_wack_cntrl_s; + wire up_rack_cntrl_s; + wire [31:0] up_rdata_cntrl_s; + + wire trigger_s; + + // internal registers + + reg up_wack = 1'b0; + reg up_rack = 1'b0; + reg [31:0] up_rdata = 32'b0; // defaults @@ -184,6 +195,20 @@ module axi_ad7616 ( assign up_rstn = s_axi_aresetn; assign up_rst = ~s_axi_aresetn; + // processor read interface + + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_wack <= 'd0; + up_rack <= 'd0; + up_rdata <= 'd0; + end else begin + up_wack <= up_wack_if_s | up_wack_cntrl_s; + up_rack <= up_rack_if_s | up_rack_cntrl_s; + up_rdata <= up_rdata_if_s | up_rdata_cntrl_s; + end + end + generate if (IF_TYPE == SERIAL) begin // ground all parallel interface signals @@ -192,77 +217,70 @@ module axi_ad7616 ( assign rd_n = 1'b0; assign wr_n = 1'b0; - // all the SPI Framework instances and logic + // SPI Framework instances and logic - wire spi_resetn_s; - wire s0_cmd_ready_s; - wire s0_cmd_valid_s; - wire [15:0] s0_cmd_data_s; - wire s0_sdo_data_ready_s; - wire s0_sdo_data_valid_s; - wire [ 7:0] s0_sdo_data_s; - wire s0_sdi_data_ready_s; - wire s0_sdi_data_valid_s; - wire [(SDI_DATA_WIDTH-1):0] s0_sdi_data_s; - wire s0_sync_ready_s; - wire s0_sync_valid_s; - wire [ 7:0] s0_sync_data_s; - wire s1_cmd_ready_s; - wire s1_cmd_valid_s; - wire [15:0] s1_cmd_data_s; - wire s1_sdo_data_ready_s; - wire s1_sdo_data_valid_s; - wire [ 7:0] s1_sdo_data_s; - wire s1_sdi_data_ready_s; - wire s1_sdi_data_valid_s; - wire [(SDI_DATA_WIDTH-1):0] s1_sdi_data_s; - wire s1_sync_ready_s; - wire s1_sync_valid_s; - wire [ 7:0] s1_sync_data_s; - wire m_cmd_ready_s; - wire m_cmd_valid_s; - wire [15:0] m_cmd_data_s; - wire m_sdo_data_ready_s; - wire m_sdo_data_valid_s; - wire [ 7:0] m_sdo_data_s; - wire m_sdi_data_ready_s; - wire m_sdi_data_valid_s; - wire [(SDI_DATA_WIDTH-1):0] m_sdi_data_s; - wire m_sync_ready_s; - wire m_sync_valid_s; - wire [ 7:0] m_sync_data_s; - wire offload0_cmd_wr_en_s; - wire offload0_cmd_wr_data_s; - wire offload0_sdo_wr_en_s; - wire offload0_sdo_wr_data_s; - wire offload0_mem_reset_s; - wire offload0_enable_s; - wire offload0_enabled_s; - wire trigger_s; + wire spi_resetn_s; + wire s0_cmd_ready_s; + wire s0_cmd_valid_s; + wire [15:0] s0_cmd_data_s; + wire s0_sdo_data_ready_s; + wire s0_sdo_data_valid_s; + wire [(DATA_WIDTH-1):0] s0_sdo_data_s; + wire s0_sdi_data_ready_s; + wire s0_sdi_data_valid_s; + wire [(NUM_OF_SDI * DATA_WIDTH-1):0] s0_sdi_data_s; + wire s0_sync_ready_s; + wire s0_sync_valid_s; + wire [ 7:0] s0_sync_s; + wire s1_cmd_ready_s; + wire s1_cmd_valid_s; + wire [15:0] s1_cmd_data_s; + wire s1_sdo_data_ready_s; + wire s1_sdo_data_valid_s; + wire [(DATA_WIDTH-1):0] s1_sdo_data_s; + wire s1_sdi_data_ready_s; + wire s1_sdi_data_valid_s; + wire [(NUM_OF_SDI * DATA_WIDTH-1):0] s1_sdi_data_s; + wire s1_sync_ready_s; + wire s1_sync_valid_s; + wire [ 7:0] s1_sync_s; + wire m_cmd_ready_s; + wire m_cmd_valid_s; + wire [15:0] m_cmd_data_s; + wire m_sdo_data_ready_s; + wire m_sdo_data_valid_s; + wire [(DATA_WIDTH-1):0] m_sdo_data_s; + wire m_sdi_data_ready_s; + wire m_sdi_data_valid_s; + wire [(NUM_OF_SDI * DATA_WIDTH-1):0] m_sdi_data_s; + wire m_sync_ready_s; + wire m_sync_valid_s; + wire [ 7:0] m_sync_s; + wire offload0_cmd_wr_en_s; + wire [15:0] offload0_cmd_wr_data_s; + wire offload0_sdo_wr_en_s; + wire [(DATA_WIDTH-1):0] offload0_sdo_wr_data_s; + wire offload0_mem_reset_s; + wire offload0_enable_s; + wire offload0_enabled_s; axi_spi_engine #( - .SDI_DATA_WIDTH (SDI_DATA_WIDTH), - .NUM_OFFLOAD(1) + .DATA_WIDTH (DATA_WIDTH), + .NUM_OF_SDI (NUM_OF_SDI), + .NUM_OFFLOAD(1), + .MM_IF_TYPE(1), + .UP_ADDRESS_WIDTH (UP_ADDRESS_WIDTH) ) i_axi_spi_engine( - .s_axi_aclk (up_clk), - .s_axi_aresetn (up_rstn), - .s_axi_awvalid (s_axi_awvalid), - .s_axi_awaddr (s_axi_awaddr), - .s_axi_awready (s_axi_awready), - .s_axi_wvalid (s_axi_wvalid), - .s_axi_wdata (s_axi_wdata), - .s_axi_wstrb (s_axi_wstrb), - .s_axi_wready (s_axi_wready), - .s_axi_bvalid (s_axi_bvalid), - .s_axi_bresp (s_axi_bresp), - .s_axi_bready (s_axi_bready), - .s_axi_arvalid (s_axi_arvalid), - .s_axi_araddr (s_axi_araddr), - .s_axi_arready (s_axi_arready), - .s_axi_rvalid (s_axi_rvalid), - .s_axi_rready (s_axi_rready), - .s_axi_rresp (s_axi_rresp), - .s_axi_rdata (s_axi_rdata), + .up_clk (up_clk), + .up_rstn (up_rstn), + .up_wreq (up_wreq_s), + .up_waddr (up_waddr_s), + .up_wdata (up_wdata_s), + .up_wack (up_wack_if_s), + .up_rreq (up_rreq_s), + .up_raddr (up_raddr_s), + .up_rdata (up_rdata_if_s), + .up_rack (up_rack_if_s), .irq (irq), .spi_clk (up_clk), .spi_resetn (spi_resetn_s), @@ -277,7 +295,7 @@ module axi_ad7616 ( .sdi_data (s0_sdi_data_s), .sync_ready (s0_sync_ready_s), .sync_valid (s0_sync_valid_s), - .sync_data (s0_sync_data_s), + .sync_data (s0_sync_s), .offload0_cmd_wr_en (offload0_cmd_wr_en_s), .offload0_cmd_wr_data (offload0_cmd_wr_data_s), .offload0_sdo_wr_en (offload0_sdo_wr_en_s), @@ -287,7 +305,8 @@ module axi_ad7616 ( .offload0_enabled(offload0_enabled_s)); spi_engine_offload #( - .SDI_DATA_WIDTH (SDI_DATA_WIDTH) + .DATA_WIDTH (DATA_WIDTH), + .NUM_OF_SDI (NUM_OF_SDI) ) i_spi_engine_offload( .ctrl_clk (up_clk), .ctrl_cmd_wr_en (offload0_cmd_wr_en_s), @@ -311,24 +330,25 @@ module axi_ad7616 ( .sdi_data (s1_sdi_data_s), .sync_valid (s1_sync_valid_s), .sync_ready (s1_sync_ready_s), - .sync_data (s1_sync_data_s), + .sync_data (s1_sync_s), .offload_sdi_valid (m_axis_tvalid), .offload_sdi_ready (m_axis_tready), .offload_sdi_data (m_axis_tdata)); spi_engine_interconnect #( - .SDI_DATA_WIDTH (SDI_DATA_WIDTH) + .DATA_WIDTH (DATA_WIDTH), + .NUM_OF_SDI (NUM_OF_SDI) ) i_spi_engine_interconnect ( .clk (up_clk), .resetn (spi_resetn_s), .m_cmd_valid (m_cmd_valid_s), .m_cmd_ready (m_cmd_ready_s), .m_cmd_data (m_cmd_data_s), - .m_sdo_valid (m_sdo_valid_s), - .m_sdo_ready (m_sdo_ready_s), + .m_sdo_valid (m_sdo_data_valid_s), + .m_sdo_ready (m_sdo_data_ready_s), .m_sdo_data (m_sdo_data_s), - .m_sdi_valid (m_sdi_valid_s), - .m_sdi_ready (m_sdi_ready_s), + .m_sdi_valid (m_sdi_data_valid_s), + .m_sdi_ready (m_sdi_data_ready_s), .m_sdi_data (m_sdi_data_s), .m_sync_valid (m_sync_valid_s), .m_sync_ready (m_sync_ready_s), @@ -337,29 +357,30 @@ module axi_ad7616 ( .s0_cmd_ready (s0_cmd_ready_s), .s0_cmd_data (s0_cmd_data_s), .s0_sdo_valid (s0_sdo_data_valid_s), - .s0_sdo_ready (s0_sdi_data_ready_s), + .s0_sdo_ready (s0_sdo_data_ready_s), .s0_sdo_data (s0_sdo_data_s), .s0_sdi_valid (s0_sdi_data_valid_s), .s0_sdi_ready (s0_sdi_data_ready_s), .s0_sdi_data (s0_sdi_data_s), .s0_sync_valid (s0_sync_valid_s), .s0_sync_ready (s0_sync_ready_s), - .s0_sync (s0_sync_data_s), + .s0_sync (s0_sync_s), .s1_cmd_valid (s1_cmd_valid_s), .s1_cmd_ready (s1_cmd_ready_s), .s1_cmd_data (s1_cmd_data_s), - .s1_sdo_valid (s1_sdo_valid_s), - .s1_sdo_ready (s1_sdo_ready_s), + .s1_sdo_valid (s1_sdo_data_valid_s), + .s1_sdo_ready (s1_sdo_data_ready_s), .s1_sdo_data (s1_sdo_data_s), - .s1_sdi_valid (s1_sdi_valid_s), - .s1_sdi_ready (s1_sdi_ready_s), + .s1_sdi_valid (s1_sdi_data_valid_s), + .s1_sdi_ready (s1_sdi_data_ready_s), .s1_sdi_data (s1_sdi_data_s), .s1_sync_valid (s1_sync_valid_s), .s1_sync_ready (s1_sync_ready_s), .s1_sync (s1_sync_s)); spi_engine_execution #( - .SDI_DATA_WIDTH (SDI_DATA_WIDTH) + .DATA_WIDTH (DATA_WIDTH), + .NUM_OF_SDI (NUM_OF_SDI) ) i_spi_engine_execution ( .clk (up_clk), .resetn (spi_resetn_s), @@ -375,7 +396,7 @@ module axi_ad7616 ( .sdi_data (m_sdi_data_s), .sync_ready (m_sync_ready_s), .sync_valid (m_sync_valid_s), - .sync (m_sync_data_s), + .sync (m_sync_s), .sclk (sclk), .sdo (sdo), .sdo_t (), @@ -387,9 +408,10 @@ module axi_ad7616 ( .three_wire ()); end + endgenerate generate if (IF_TYPE == PARALLEL) begin - + //assign trigger_s = 1'b0; end endgenerate @@ -404,7 +426,6 @@ module axi_ad7616 ( .hw_rngsel (hw_rngsel), .chsel (chsel), .crcen (crcen), - .ser1w_n (ser1w_n), .burst (burst), .os (os), .end_of_conv (trigger_s), @@ -412,16 +433,18 @@ module axi_ad7616 ( .up_clk (up_clk), .up_wreq (up_wreq_s), .up_waddr (up_waddr_s), - .up_wdata (up_wdata), - .up_wack (up_wack_s), + .up_wdata (up_wdata_s), + .up_wack (up_wack_cntrl_s), .up_rreq (up_rreq_s), .up_raddr (up_raddr_s), - .up_rdata (up_rdata_s), - .up_rack (up_rack_s)); + .up_rdata (up_rdata_cntrl_s), + .up_rack (up_rack_cntrl_s)); // up bus interface - up_axi i_up_axi ( + up_axi #( + .ADDRESS_WIDTH (UP_ADDRESS_WIDTH) + ) i_up_axi ( .up_rstn (up_rstn), .up_clk (up_clk), .up_axi_awvalid (s_axi_awvalid), diff --git a/library/axi_ad7616/axi_ad7616_control.v b/library/axi_ad7616/axi_ad7616_control.v index 4d396ebb8..36d91de84 100644 --- a/library/axi_ad7616/axi_ad7616_control.v +++ b/library/axi_ad7616/axi_ad7616_control.v @@ -50,7 +50,6 @@ module axi_ad7616_control ( hw_rngsel, chsel, crcen, - ser1w_n, burst, os, @@ -77,9 +76,8 @@ module axi_ad7616_control ( localparam PCORE_VERSION = 'h0001001; localparam SW = 0; localparam HW = 1; - - input clk; - input rst; + localparam POS_EDGE = 0; + localparam NEG_EDGE = 1; output reset_n; output cnvst; @@ -88,7 +86,6 @@ module axi_ad7616_control ( output [ 1:0] hw_rngsel; output [ 2:0] chsel; output crcen; - output ser1w_n; output burst; output [ 2:0] os; @@ -109,18 +106,39 @@ module axi_ad7616_control ( // internal signals - reg [31:0] up_scratch = 'b0; - reg up_resetn = 'b0; - reg up_cnvst_en = 'b0; - reg up_ser1w = 'b0; - reg [ 7:0] up_cnvst_high = 'b0; - reg [31:0] up_conv_rate = 'b0; + reg [31:0] up_scratch = 32'b0; + reg up_resetn = 1'b0; + reg up_cnvst_en = 1'b0; + reg up_wack = 1'b0; + reg up_rack = 1'b0; + reg [31:0] up_rdata = 32'b0; + reg [31:0] up_conv_rate = 32'b0; + reg [31:0] cnvst_counter = 32'b0; - reg [ 7:0] pulse_counter = 8'b0; + reg [ 3:0] pulse_counter = 8'b0; reg cnvst_buf = 1'b0; + reg cnvst_pulse = 1'b0; + reg [ 2:0] chsel_ff = 3'b0; + + reg [ 1:0] up_hw_rngsel = 2'b0; + reg [ 2:0] up_chsel = 3'b0; + reg up_crcen = 1'b0; + reg up_burst = 1'b0; + reg [ 2:0] up_os = 3'b0; + reg up_seq_en = 1'b0; + + + wire up_rst; + wire up_rreq_s; + wire up_wreq_s; + wire end_of_conv_s; // decode block select + assign up_wreq_s = (up_waddr[13:8] == 6'h01) ? up_wreq : 1'b0; + assign up_rreq_s = (up_raddr[13:8] == 6'h01) ? up_rreq : 1'b0; + + assign end_of_conv = end_of_conv_s; // processor write interface @@ -130,9 +148,13 @@ module axi_ad7616_control ( up_scratch <= 32'b0; up_resetn <= 1'b0; up_cnvst_en <= 1'b0; - up_ser1w <= 1'b0; - up_cnvst_high <= 8'b0; up_conv_rate <= 32'b0; + up_hw_rngsel <= 2'b0; + up_chsel <= 3'b0; + up_crcen <= 1'b0; + up_burst <= 1'b0; + up_os <= 3'b0; + up_seq_en <= 1'b0; end else begin up_wack <= up_wreq_s; if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h02)) begin @@ -141,13 +163,21 @@ module axi_ad7616_control ( if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h10)) begin up_resetn <= up_wdata[0]; up_cnvst_en <= up_wdata[1]; - up_ser1w <= up_wdata[2]; end if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h11)) begin - up_cnvst_high <= up_wdata[7:0]; + up_conv_rate <= up_wdata; end if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h12)) begin - up_conv_rate <= up_wdata; + up_hw_rngsel <= up_wdata[1:0]; + up_os <= up_wdata[4:2]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h13)) begin + up_seq_en <= up_wdata[0]; + up_burst <= up_wdata[1]; + up_chsel <= up_wdata[4:2]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h14)) begin + up_crcen <= up_wdata[0]; end end end @@ -165,9 +195,11 @@ module axi_ad7616_control ( 8'h00 : up_rdata = PCORE_VERSION; 8'h01 : up_rdata = ID; 8'h02 : up_rdata = up_scratch; - 8'h10 : up_rdata = {28'b0, up_ser1w, up_cnvst_en, up_resetn}; - 8'h11 : up_rdata = {24'b0, up_cnvst_high}; - 8'h12 : up_rdata = up_conv_rate; + 8'h10 : up_rdata = {29'b0, up_cnvst_en, up_resetn}; + 8'h11 : up_rdata = up_conv_rate; + 8'h12 : up_rdata = {27'b0, up_os, up_hw_rngsel}; + 8'h13 : up_rdata = {27'b0, up_chsel, up_burst, up_seq_en}; + 8'h14 : up_rdata = {30'b0, up_crcen}; endcase end end @@ -175,52 +207,54 @@ module axi_ad7616_control ( // instantiations + assign up_rst = ~up_rstn; + ad_edge_detect #( .EDGE(NEG_EDGE) ) i_ad_edge_detect ( .clk (up_clk), - .rstn (up_rstn), + .rst (up_rst), .in (busy), - .out (end_of_conv) + .out (end_of_conv_s) ); // convertion start generator - // NOTE: The minimum convertion cycle is 1 us and the - // minimum CNVST high pulse width is 20 ns. - // See the AD7616 datasheet for more information. + // NOTE: + The minimum convertion cycle is 1 us + // + The rate of the cnvst must be defined in a way, + // to not lose any data. cnvst_rate >= t_conversion + t_aquisition + // See the AD7616 datasheet for more information. - always @(posedge clk) begin - if(up_resetn == 0) begin + always @(posedge up_clk) begin + if(up_resetn == 1'b0) begin cnvst_counter <= 32'b0; end else begin cnvst_counter <= (cnvst_counter < up_conv_rate) ? cnvst_counter + 1 : 32'b0; end end - always @(cnvst_counter) begin + always @(cnvst_counter, up_conv_rate) begin cnvst_pulse <= (cnvst_counter == up_conv_rate) ? 1'b1 : 1'b0; end - always @(posedge clk) begin + always @(posedge up_clk) begin if(up_resetn == 1'b0) begin - pulse_counter <= 8'b0; + pulse_counter <= 3'b0; cnvst_buf <= 1'b0; end else begin - pulse_counter <= (cnvst == 1'b1) ? pulse_counter + 1 : 8'b0; + pulse_counter <= (cnvst == 1'b1) ? pulse_counter + 1 : 3'b0; if(cnvst_pulse == 1'b1) begin cnvst_buf <= 1'b1; - end else if (pulse_counter == up_cnvst_high) begin + end else if (pulse_counter[2] == 1'b1) begin cnvst_buf <= 1'b0; end end end - assign cnvst <= (up_cnvst_en == 1'b1) ? cnvst_buf : 1'b0; + assign cnvst = (up_cnvst_en == 1'b1) ? cnvst_buf : 1'b0; // output logic assign reset_n = up_resetn; // device's reset - assign ser1w_n = ~up_ser1w; // serial output operates over SDOA and SDOB OR just SDOA generate if (OP_MODE == SW) begin @@ -236,5 +270,27 @@ module axi_ad7616_control ( end endgenerate + generate if (OP_MODE == HW) begin + + assign hw_rngsel = up_hw_rngsel; + assign crcen = up_crcen; + assign burst = up_burst; + assign os = up_os; + assign seq_en = up_seq_en; + assign chsel = chsel_ff; + + // CHSEL is updated after BUSY deasserts + + always @(posedge up_clk) begin + if (up_rstn == 1'b0) begin + chsel_ff <= 3'b0; + end else begin + chsel_ff <= (end_of_conv_s == 1'b1) ? up_chsel : chsel_ff; + end + end + + end + endgenerate + endmodule