-  本实验基于ARM+FPGA构架,通过ARM首先发送查询ID指令,然后依次通过指令设置写数据的长度、写数据地址、读数据的长度、读数据的地址,然后对比写入数据和读出数据是否一致判断数据是否写入成功,从而基于SPI总线实现ARM与FPGA之间的通信。 
-  实现ARM与FPGA通信,对FPGA而言,其关键就在于SPI时序的模拟,实现SPI数据的接收与发送,实现数据与传输信号之间的串并转换。FPGA首先接收ARM指令,然后解析指令,存储相应的信息与数据,并根据指令需求将相应的指令数据放到SIMO总线上,等待ARM读取,从而实现两者之间的数据交互。SPI时序的硬件语言描述如下: 
////////////////按字节接收SPI发送过来的数据//////////////
///////接收模块///////			 		 
reg[3:0]i;
reg[7:0]data_in;
reg [39:0]temp_data,data;
 
always@(posedge spi_clk or negedge rst_n)
	if(!rst_n)
	    begin
		i <= 4'd0;
		temp_data <= 40'd0;
		data <= 40'd0;
		data_in <= 8'd0;
	    end
	else case(i)   //从高位开始接收数据,每8个spi_clk时钟接收一个Byte
		4'd0:
		    begin
			i <= i + 1'd1;
			data_in <= {data_in[6:0],spi_mosi};
			temp_data <= {temp_data[31:0],data_in};
			if(data_in == 8'd13)
			    begin
			        data <= temp_data;
			    end
			else 
			    begin
				data <= data;
			    end
			end
		4'd1,4'd2,4'd3,4'd4,4'd5,4'd6:
			begin
			    i <= i + 1'd1;
			    data_in <= {data_in[6:0],spi_mosi};
			end
		4'd7:begin
			    i <= 4'd0;
			    data_in <= {data_in[6:0],spi_mosi};
			end
		default: i <= 4'd0;
	endcase
 
/*对比接收数据*/
reg [2:0]led;	
 
always@(posedge clk_25m or negedge rst_n)
	if(!rst_n)
	    begin
		led <= 3'b101;
	    end
	else if (data == ledr)
		led <= 3'b011;                  //红灯亮
	else if (data == ledg)
		led <= 3'b101;			//绿灯亮
	else if (data == ledb)
		led <= 3'b110;			//蓝灯亮
 
assign {led_red,led_green,led_blue} = led;
 
//--------------------------delay----------------------------//
	reg spi_clk_r;
	always@(posedge clk_25m or negedge rst_n)
		if(!rst_n)
		    begin
			spi_clk_r <= 1'd1;
		    end
		else 
			spi_clk_r <= spi_clk; 
 
//--------------------------spi_miso----------------------------//
/*发送模块*/
reg [39:0]data_out;
reg [5:0]j;
reg spi_out;
always@(negedge spi_clk_r or negedge rst_n)
	if(!rst_n)
		begin
		    data_out <= hello;
		    spi_out <= 1'd0;
		    j <= 6'd0;
		end
	else case(j)  //连续40个spi_clk_r时钟发送“hello”字符串
		6'd0:
		    begin
			{spi_out,data_out[39:1]} <= data_out;
			j <= j + 1'd1;
		    end
		6'd39:
		    begin
			{spi_out,data_out[39:1]} <= data_out;
			data_out <= hello;
			j <= 6'd0;
		    end
		default:
		    begin
			{spi_out,data_out[39:1]} <= data_out;
			j <= j + 1'd1;
		    end
	endcase