The data sent and received are often misaligned or stuck, causing instability

STM32F103VE SPI speed 9M

EPM240T100C5N clock 50M

Should I have a problem with the CPLD SPI interface program?


/************************************************* **********************

   ****************** name: SPI_Slaver_Driver **************

   ********** author: made by zzuxzt **********

   ****************** time: 2014.4.29 **********************

************************************************** *********************/

//use SPI 3 mode, CHOL = 1, CHAL = 1

module spi( input clk,

                        input rst_n,

                        input CS_N,

                        input SCK,

                        input MOSI,

                        output reg MISO,

                        input [7:0] txd_data,

                        output reg [7:0] rxd_data,

                        output rxd_flag); /*recieve done,please transmit data*/


//-------------------------capture the sck-------------------- ---------

reg sck_r0,sck_r1;

wire sck_n,sck_p;

always@(posedge clk or negedge rst_n)

begin

    if(!rst_n)

        begin

            sck_r0 <= 1'b1; //sck of the idle state is high

            sck_r1 <= 1'b1;

        end

    else

        begin

            sck_r0 <= SCK;

            sck_r1 <= sck_r0;

        end

end

assign sck_n = (~sck_r0 & sck_r1)? 1'b1:1'b0;   //capture the sck negedge

assign sck_p = (~sck_r1 & sck_r0)? 1'b1:1'b0;   //capture the sck posedge


//-----------------------spi_slaver read data-------------------------------

reg rxd_flag_r;

reg [2:0] rxd_state;

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)

                3'd0:begin

                        rxd_data[7] <= MOSI;

                        rxd_flag_r <= 1'b0;   //reset rxd_flag

                        rxd_state <= 3'd1;

                      end

                3'd1:begin

                        rxd_data[6] <= MOSI;

                        rxd_state <= 3'd2;

                      end

                3'd2:begin

                        rxd_data[5] <= MOSI;

                        rxd_state <= 3'd3;

                      end

                3'd3:begin

                        rxd_data[4] <= MOSI;

                        rxd_state <= 3'd4;

                      end

                3'd4:begin

                        rxd_data[3] <= MOSI;

                        rxd_state <= 3'd5;

                      end

                3'd5:begin

                        rxd_data[2] <= MOSI;

                        rxd_state <= 3'd6;

                      end

3'd6:begin

                        rxd_data[1] <= MOSI;

                        rxd_state <= 3'd7;

                      end

                3'd7:begin

                        rxd_data[0] <= MOSI;

                        rxd_flag_r <= 1'b1;  //set rxd_flag

                        rxd_state <= 3'd0;

                      end

                default: ;

            endcase

        end

end



//--------------------capture spi_flag posedge--------------------------------

reg rxd_flag_r0,rxd_flag_r1;

always@(posedge clk or negedge rst_n)

begin

    if(!rst_n)

        begin

            rxd_flag_r0 <= 1'b0;

            rxd_flag_r1 <= 1'b0;

        end

    else

        begin

            rxd_flag_r0 <= rxd_flag_r;

            rxd_flag_r1 <= rxd_flag_r0;

        end

end


assign rxd_flag = (~rxd_flag_r1 & rxd_flag_r0)? 1'b1:1'b0;   


//---------------------spi_slaver send data---------------------------

reg [2:0] txd_state;

always@(posedge clk or negedge rst_n)

begin

    if(!rst_n)

        begin

            txd_state <= 1'b0;

        end

    else if(sck_n && !CS_N)

        begin

            case(txd_state)

                3'd0:begin

                        MISO <= txd_data[7];

                        txd_state <= 3'd1;

                      end

3'd1:begin

                        MISO <= txd_data[6];

                        txd_state <= 3'd2;

                      end

                3'd2:begin

                        MISO <= txd_data[5];

                        txd_state <= 3'd3;

                      end

                3'd3:begin

                        MISO <= txd_data[4];

                        txd_state <= 3'd4;

                      end

                3'd4:begin

                        MISO <= txd_data[3];

                        txd_state <= 3'd5;

                      end

                3'd5:begin

                        MISO <= txd_data[2];

                        txd_state <= 3'd6;

                      end

                3'd6:begin

                        MISO <= txd_data[1];

                        txd_state <= 3'd7;

                      end

                3'd7:begin

                        MISO <= txd_data[0];

                        txd_state <= 3'd0;

                      end

                default: ;

            endcase

        end

end


endmodule


Reply