这是本文档旧的修订版!
银杏科技有限公司旗下技术文档发布平台 | |||
技术支持电话 | 0379-69926675-801 | ||
技术支持邮件 | Gingko@vip.163.com | ||
技术论坛 | http://www.eeschool.org | ||
版本 | 日期 | 作者 | 修改内容 |
---|---|---|---|
V1.0 | 2020-03-06 | gingko | 初次建立 |
指令名称 | 字节1 | 字节2 | 字节3 | 字节4 |
---|---|---|---|---|
器件ID | 01h | |||
写数据长度 | 02h | A15~A8 | A7~A0 | |
写数据 | 04h | A15~A8 | A7~A0 | 数据(直至写完所有数据) |
读数据长度 | 05h | A15~A8 | A7~A0 | |
读数据 | 07h | A15~A8 | A7~A0 | 数据(直至读完所有数据) |
读错误信息 | 08h |
<code verilog>
//Parameter Value //注意:地址和长度之和不能大于1024 write_address = 0; write_length = 1024; read_address = 0; read_length = 1024; * 2、实现ARM与FPGA通信,对FPGA而言,其关键就在于SPI时序的模拟,实现SPI数据的接收与发送,实现数据与传输信号之间的串并转换。FPGA首先接收ARM指令,然后解析指令,存储相应的信息与数据,并根据指令需求将相应的指令数据放到SIMO总线上,等待ARM读取,从而实现两者之间的数据交互。SPI时序的硬件语言描述如下:
<code verilog> ———————————————— 按字节接收SPI发送过来的数据 /接收模块/ reg [3:0]receive_state; reg [7:0]data_in; reg [7:0]receive_byte_r; reg spi_rx_en_r; always@(posedge spi_clk or negedge rst_n or posedge cs_delay) begin if1) begin receive_state ⇐ 4'd0; receive_byte_r ⇐ 8'd0; data_in ⇐ 8'd0; spi_rx_en_r ⇐ 1'd0; end else 低时钟时可以利用提取沿的方式
begin case(receive_state) //从高位开始接收数据,每8个spi_clk时钟接收一个Byte 4'd0:begin receive_state <= receive_state + 1'd1; data_in <= {data_in[6:0],spi_mosi}; spi_rx_en_r <= 1'd0; end 4'd1,4'd2:begin receive_state <= receive_state + 1'd1; data_in <= {data_in[6:0],spi_mosi}; end 4'd3:begin receive_state <= receive_state + 1'd1; data_in <= {data_in[6:0],spi_mosi}; spi_rx_en_r <= 1'd1; end 4'd4,4'd5:begin receive_state <= receive_state + 1'd1; data_in <= {data_in[6:0],spi_mosi}; spi_rx_en_r <= 1'd0; end 4'd6:begin receive_state <= receive_state + 1'd1; data_in <= {data_in[6:0],spi_mosi}; end 4'd7:begin receive_state <= 4'd0; data_in <= {data_in[6:0],spi_mosi}; receive_byte_r <= {data_in[6:0],spi_mosi}; end endcase end end
———————————————— /发送模块/ reg [3:0]send_state; reg spi_miso_r; reg spi_tx_en_r; reg [7:0]data_out;
always@(negedge spi_clk or negedge rst_n or posedge cs_delay)
if((!rst_n) || (cs_delay)) begin send_state <= 4'd0; spi_tx_en_r <= 1'd0; data_out <= 8'd0; end else begin case(send_state) 4'd0:begin spi_miso_r <= data_out[7]; send_state <= send_state + 1'd1; end 4'd1:begin spi_miso_r <= data_out[6]; send_state <= send_state + 1'd1; end 4'd2:begin spi_miso_r <= data_out[5]; send_state <= send_state + 1'd1; end 4'd3:begin spi_miso_r <= data_out[4]; send_state <= send_state + 1'd1; end 4'd4:begin spi_miso_r <= data_out[3]; send_state <= send_state + 1'd1; spi_tx_en_r <= 1'd0; end 4'd5:begin spi_miso_r <= data_out[2]; send_state <= send_state+ 1'd1; spi_tx_en_r <= 1'd1; end 4'd6:begin spi_miso_r <= data_out[1]; send_state <= send_state + 1'd1; spi_tx_en_r <= 1'd0; end 4'd7:begin data_out <= send_byte; spi_miso_r <= data_out[0]; send_state <= 4'd0; spi_tx_en_r <= 1'd0; end endcase end
<code verilog>
1、通过Signaltap观察SPI通信的时序是否和参考时序一致。 2、实现错误信息读取指令功能。