**axi_quad_spi IP核四线转三线SPI读写ADI ADC FPGA实现(附源码)**

xilinx vivado axi_quad_spi IP核四线转三线SPI读写ADI ADC FPGA实现(附源码)

近期项目中,用到了xilinx axi_quad_spi模块,想通过该模块读写ADI公司的ADC,vivado中对应的IP核的配置参数如下

axi_quad_spi参数配置
对应的FPGA读写配置代码如下:

//
// Company:  SYCP
// Engineer: 西电老顽童
// 
// Create Date: 2024/10/10 14:38:02
// Design Name: 
// Module Name: axi_quad_spi_test
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
//     This interface is used to connect Xilinx axi_quad_spi IP and ADI 3 wire-spi devices,the SPI transfer payload is  [ W/R   Addr    DATA]
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//

module adi_axi_spi_interface#(
    parameter CLK_DIV    = 8'd4,  // ext_spi_clk/AXI_SPI_sck_o, correspond value is 2, 4, 8,....
    parameter ADDR_WIDTH = 8'd15,
    parameter DATA_WIDTH = 8'd8
)(

input   ext_spi_clk,   // connect to axi_quad_spi ext_spi_clk(at leset 2 times faster than AXI_SPI_sck_o)

input   AXI_SPI_sck_o, // connect to axi_quad_spi AXI_SPI_sck_o
inout   ad_sdio,       // connect to ADC spi sdio
output  ad_cs,         // connect to ADC spi cs
output  ad_spi_clk,

output  AXI_SPI_io0_i, // connect to axi_quad_spi AXI_SPI_io0_i
input   AXI_SPI_io0_o, // connect to axi_quad_spi AXI_SPI_io0_o(MOSI output)
input   AXI_SPI_io0_t, // connect to axi_quad_spi AXI_SPI_io0_t(low active)

output  AXI_SPI_io1_i, // connect to axi_quad_spi AXI_SPI_io1_i(MOSI input)
input   AXI_SPI_io1_o, // connect to axi_quad_spi AXI_SPI_io1_o
input   AXI_SPI_io1_t  // connect to axi_quad_spi AXI_SPI_io1_t
);


reg [2:0] AXI_SPI_sck_o_dly;
always @(posedge ext_spi_clk) begin
    AXI_SPI_sck_o_dly <= {AXI_SPI_sck_o_dly, AXI_SPI_sck_o};
end


reg [7:0] cnt, delay_cnt;
reg wr_flag;
localparam  IDLE     = 2'b00,
            TransCMD   = 2'b01,
            TransDATA  = 2'b10;
reg [1:0] STATE;
always @(posedge ext_spi_clk) begin
    if(AXI_SPI_io0_t)begin
	    cnt <= 0;
	    delay_cnt <= 0;
		wr_flag <= 0; 
		STATE <= IDLE;
	end else begin
	     case(STATE)
            IDLE:begin
                if({AXI_SPI_sck_o_dly[0], AXI_SPI_sck_o} == 2'd1)begin
				    cnt <= cnt + 1'd1;
				    if(AXI_SPI_io0_o == 1'd0)begin // 1:write    0:read
					    wr_flag <= 1;                    
					end 
					STATE <= TransCMD; 
                end
                else begin
				    cnt <= 0;
				    delay_cnt <= 0;
					wr_flag <= 0; 
                    STATE <= IDLE;
                end
            end
            
			TransCMD:begin
			    if({AXI_SPI_sck_o_dly[0], AXI_SPI_sck_o} == 2'd1)begin // rising edge
				    cnt <= cnt + 1'd1;
					if(cnt <= ADDR_WIDTH - 1)begin
					    STATE <= TransCMD; 
					end else begin
					    delay_cnt <= delay_cnt + 1'd1;
					    STATE <= TransDATA; 
					end
				end
			end
			
			TransDATA:begin
			    delay_cnt <= 0;
			    if({AXI_SPI_sck_o_dly[0], AXI_SPI_sck_o} == 2'd1)begin // rising edge
			        cnt <= cnt + 1'd1;
			        if(cnt <= ADDR_WIDTH -1 + DATA_WIDTH)begin
					    STATE <= TransDATA; 
					end else begin
					    STATE <= IDLE;
					end
			    end
			end
            
            default:STATE <= IDLE;
        endcase
		
    end
end



assign ad_sdio    =  (cnt <= ADDR_WIDTH) ? AXI_SPI_io0_o
                                         : wr_flag ? AXI_SPI_io0_o
                                                   : 1'dz;
assign ad_cs      = AXI_SPI_io0_t;
assign ad_spi_clk = AXI_SPI_sck_o;
assign AXI_SPI_io1_i = ad_sdio;

endmodule

上面代码已经在项目中使用两个月了,运行可靠。
需要注意的一点就是,axi时钟要分频后(一般4倍或以上)来配置IP核
另外,spi总线payload我们使用的是24bit模式。如果想用其它模式payload,自行修改吧。
祝好运!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值