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
main
Istvan Csomortani 2015-12-14 16:00:56 +02:00
parent 4e57170384
commit 8ae9de8fba
2 changed files with 218 additions and 139 deletions

View File

@ -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,27 +163,52 @@ 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_ADDRESS_WIDTH-1):0] up_raddr_s;
wire up_wreq_s;
wire [13:0] up_waddr_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
assign up_clk = s_axi_aclk;
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,7 +217,7 @@ 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;
@ -200,69 +225,62 @@ module axi_ad7616 (
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 [(DATA_WIDTH-1):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 [(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_data_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 [ 7:0] s1_sdo_data_s;
wire [(DATA_WIDTH-1):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 [(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_data_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 [ 7:0] m_sdo_data_s;
wire [(DATA_WIDTH-1):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 [(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_data_s;
wire [ 7:0] m_sync_s;
wire offload0_cmd_wr_en_s;
wire offload0_cmd_wr_data_s;
wire [15:0] offload0_cmd_wr_data_s;
wire offload0_sdo_wr_en_s;
wire offload0_sdo_wr_data_s;
wire [(DATA_WIDTH-1):0] offload0_sdo_wr_data_s;
wire offload0_mem_reset_s;
wire offload0_enable_s;
wire offload0_enabled_s;
wire trigger_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),

View File

@ -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.
// 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