FPGA-spi问题

2019-03-25 07:16发布

问大家一个SPI问题,ARM采用am335X作为主机,FPGA作为从机,模式是3模式,即CPOL=1,CPHA=1,我在FPGA检测SCK的上升沿和CS_n为低电平时,进行把MOSI数据放入缓存器中,当然现在传输数据是没问题,最大的问题是,ARM连续发数据时,假如连续发1和2,sck设定5MHZ时钟,FPGA的时钟要达到600MHZ才能检测出来1和2,FPGA时钟慢了,只能收到一个数据2,大家可以帮分析下,是什么原因吗?
此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
2条回答
a416485164
2019-03-25 17:46
hh_kings 发表于 2018-4-20 15:43
你的检测方式有问题的,理论上只要大于2倍SPI时钟速率就可以的

你好,对呀,这个理论上是这样,但是却差得远,现在是ARM在SCK下降沿开始发送数据,FPGA在上升沿进行数据采样,不应该有问题呀,正好把数据采集过来,你看下代码,希望能给出建议
//同步寄存器,消除亚稳态
always@(posedge clk or negedge rst_n)
        if(!rst_n)begin
                s0 <= 1'b0;
                s1 <= 1'b0;       
        end
        else begin
                s0 <= SCK;
                s1 <= s0;       
        end
//数据寄存器
always@(posedge clk or negedge rst_n)
        if(!rst_n)begin
                t0 <= 1'b0;
                t1 <= 1'b0;       
        end
        else begin
                t0 <= s1;
                t1 <= t0;       
        end
always@(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        begin
            sck_r0 <= 1'b0;   //sck of the idle state is high
            sck_r1 <= 1'b0;
        end
    else
        begin
            sck_r0 <= t1;
            sck_r1 <= sck_r0;
        end
end

assign sck_n = (!sck_r0 & sck_r1);   //capture the sck negedge
assign sck_p = (sck_r0 & !sck_r1);   //capture the sck posedge

//-----------------------spi_slaver read data-------------------------------
always@(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        begin
            rxd_data <= 1'b0;
            rxd_flag_r <= 1'b0;
            rxd_state <= 1'b0;
        end
    else if(sck_p && !CS_N)   
        begin
            case(rxd_state)
                4'd0:begin
                        rxd_data[7] <= MOSI;
                        rxd_flag_r <= 1'b0;   //reset rxd_flag
                        rxd_state <= 4'd1;
                      end
                4'd1:begin
                        rxd_data[6] <= MOSI;
                        rxd_state <= 4'd2;
                      end
                4'd2:begin
                        rxd_data[5] <= MOSI;
                        rxd_state <= 4'd3;
                      end
                4'd3:begin
                        rxd_data[4] <= MOSI;
                        rxd_state <= 4'd4;
                      end
                4'd4:begin
                        rxd_data[3] <= MOSI;
                        rxd_state <= 4'd5;
                      end
                4'd5:begin
                        rxd_data[2] <= MOSI;
                        rxd_state <= 4'd6;
                      end
                4'd6:begin
                        rxd_data[1] <= MOSI;
                        rxd_state <= 4'd7;
                      end
                4'd7:begin
                        rxd_data[0] <= MOSI;
                        rxd_flag_r <= 1'b1;   //reset rxd_flag
                        rxd_state <= 4'd0;
                      end                                       
                default: ;
            endcase
        end
end

一周热门 更多>