Verilog HDL SPI通信——写

module spi_write(

    input clk,            //system clock:50M

    input rst,        

    output reg cs,        //chip select

    output sck,            //chip clock:50K

    input din,            //DO

    output reg dout,    //DI

    input wflag,        //write enable

    input[7:0] data

);



//general chip clock:50K

/*reg temp;

reg[9:0] count;

always@(posedge clk or posedge rst)

    if(rst) begin count <= 10'd0; temp <= 1'b0; end

    else

        begin

            count <= count+1'b1;

            if(count == 10'd999) begin temp <= 1'b1; count <= 10'd0; end

            else if(count == 10'd499) temp <= 1'b0;

        end

assign sck = temp;



`define    high (count == 10'd999)            // 时钟上升沿

`define    low (count == 10'd499)*/        // 时钟下降沿

reg temp;

reg[9:0] count;

always@(posedge clk or posedge rst)

    if(rst) 

        begin

            count <= 10'd0;

            temp <= 1'b0;

        end

    else if(count >= 10'd500)

        begin

            count <= 10'd0;

            temp <= ~temp;

        end

    else count <= count+1'b1;



assign sck = temp;

    

//capture posedge and negedge of sck

reg sck_m;

wire high;        // 时钟上升沿

wire low;        // 时钟下降沿

always@(posedge clk or posedge rst)

    if(rst) sck_m <= 1'b0;

    else sck_m <= sck;

assign high = ~sck_m & sck;

assign low = sck_m & ~sck;





//load

reg[7:0] data_medium;

reg[5:0] wstate;

always@(negedge clk or posedge rst)

    begin

        if(rst) 

            begin

                wstate <= 6'b0;

                cs <= 1'b0;

                dout <= 1'b0;

            end

        else 

            begin

                case(wstate)

                    6'd0: begin

                            if(wflag)

                                begin

                                    data_medium <= data;

                                    wstate <= 6'd1;

                                    cs <= 1'b1;

                                    dout <= 1'b0;

                                end

                            else

                                begin

                                    wstate <= 6'd0;

                                    cs <= 1'b0;

                                    dout <= 1'b0;

                                end

                          end

                    6'd1: begin

                            

                            if(low) begin wstate <= 6'd2; dout <=1'b1; cs <= 1'b1; end        // 先执行写使能命令,高位在前,低位在后

                            else    begin wstate <= 6'd1; end                                //SB=1

                          end

                          

                    6'd2: begin

                            if(low) begin wstate <= 6'd3; dout <=1'b0; cs <= 1'b1; end        //OP1=0

                            else    begin wstate <= 6'd2; end

                          end

                          

                    6'd3: begin

                            if(low) begin wstate <= 6'd4; dout <=1'b0; cs <= 1'b1; end        //OP0=0

                            else    begin wstate <= 6'd3; end

                          end

                          

                    6'd4: begin

                            if(low) begin wstate <= 6'd5; dout <=1'b1; cs <= 1'b1; end        //A6=1

                            else    begin wstate <= 6'd4; end

                          end

                          

                    6'd5: begin

                            if(low) begin wstate <= 6'd6; dout <=1'b1; cs <= 1'b1; end        //A5=1

                            else    begin wstate <= 6'd5; end

                          end

                          

                    6'd6: begin

                            if(low) begin wstate <= 6'd7; dout <=1'b1; cs <= 1'b1; end        //A4=1

                            else    begin wstate <= 6'd6; end

                          end

                          

                    6'd7: begin

                            if(low) begin wstate <= 6'd8; dout <=1'b1; cs <= 1'b1; end        //A3=1

                            else    begin wstate <= 6'd7; end

                          end

                          

                    6'd8: begin

                            if(low) begin wstate <= 6'd9; dout <=1'b1; cs <= 1'b1; end        //A2=1

                            else    begin wstate <= 6'd8; end

                          end

                          

                    6'd9: begin

                            if(low) begin wstate <= 6'd10; dout <=1'b1; cs <= 1'b1; end        //A1=1

                            else    begin wstate <= 6'd9; end

                          end

                          

                    6'd10: begin

                            if(low) begin wstate <= 6'd11; dout <=1'b1; cs <= 1'b1; end        //A0=1

                            else    begin wstate <= 6'd10; end

                          end

                          

                    6'd11: begin

                            if(low) begin wstate <= 6'd12; dout <= 1'b0;cs <= 1'b0; end        // 先停一个周期,将CS 拉低,再进行写操作(Address)

                            else    begin wstate <= 6'd11; end                                

                          end

                          

                    6'd12: begin

                            if(low) begin wstate <= 6'd13; dout <=1'b1; cs <= 1'b1; end        //SB=1

                            else    begin wstate <= 6'd12; end

                          end

                          

                    6'd13: begin

                            if(low) begin wstate <= 6'd14; dout <=1'b0; cs <= 1'b1; end        //OP1=0

                            else    begin wstate <= 6'd13; end

                          end

                          

                    6'd14: begin

                            if(low) begin wstate <= 6'd15; dout <=1'b1; cs <= 1'b1; end        //OP0=1

                            else    begin wstate <= 6'd14; end

                          end

                          

                    6'd15: begin

                            if(low) begin wstate <= 6'd16; dout <=1'b0; cs <= 1'b1; end        //A6=0

                            else    begin wstate <= 6'd15; end

                          end      

                          

                    6'd16: begin

                            if(low) begin wstate <= 6'd17; dout <=1'b0; cs <= 1'b1; end        //A5=0

                            else    begin wstate <= 6'd16; end

                          end

                          

                    6'd17: begin

                            if(low) begin wstate <= 6'd18; dout <=1'b0; cs <= 1'b1; end        //A4=0

                            else    begin wstate <= 6'd17; end

                          end

                          

                    6'd18: begin

                            if(low) begin wstate <= 6'd19; dout <=1'b0; cs <= 1'b1; end        //A3=0

                            else    begin wstate <= 6'd18; end

                          end

                          

                    6'd19: begin

                            if(low) begin wstate <= 6'd20; dout <=1'b1; cs <= 1'b1; end        //A2=1

                            else    begin wstate <= 6'd19; end

                          end

                          

                    6'd20: begin

                            if(low) begin wstate <= 6'd21; dout <=1'b0; cs <= 1'b1; end        //A1=0

                            else    begin wstate <= 6'd20; end

                          end

                          

                    6'd21: begin

                            if(low) begin wstate <= 6'd22; dout <=1'b1; cs <= 1'b1; end        //A0=1

                            else    begin wstate <= 6'd21; end

                          end

                          

                    6'd22: begin

                            if(low) begin wstate <= 6'd23; dout <=data[7]; cs <= 1'b1; end  // 开始写入数据:器件数据在上升沿更新,FPGA要在下降沿写出

                            else    begin wstate <= 6'd22; end                            // D7

                          end

                          

                    6'd23: begin

                            if(low) begin wstate <= 6'd24; dout <=data[6]; cs <= 1'b1; end    //D6

                            else    begin wstate <= 6'd23; end

                          end

                          

                    6'd24: begin

                            if(low) begin wstate <= 6'd25; dout <=data[5]; cs <= 1'b1; end    //D5

                            else    begin wstate <= 6'd24; end

                          end

                          

                    6'd25: begin

                            if(low) begin wstate <= 6'd26; dout <=data[4]; cs <= 1'b1; end    //D4

                            else    begin wstate <= 6'd25; end

                          end

                          

                    6'd26: begin

                            if(low) begin wstate <= 6'd27; dout <=data[3]; cs <= 1'b1; end    //D3

                            else    begin wstate <= 6'd26; end

                          end

                          

                    6'd27: begin

                            if(low) begin wstate <= 6'd28; dout <=data[2]; cs <= 1'b1; end    //D2

                            else    begin wstate <= 6'd27; end

                          end

                          

                    6'd28: begin

                            if(low) begin wstate <= 6'd29; dout <=data[1]; cs <= 1'b1; end    //D1

                            else    begin wstate <= 6'd28; end

                          end

                          

                    6'd29: begin

                            if(low) begin wstate <= 6'd30; dout <=data[0]; cs <= 1'b1; end    //D0

                            else    begin wstate <= 6'd29; end

                          end

                          

                    6'd30: begin                                                                                

                            if(low)    begin wstate <= 6'd31; dout <= 1'b0;cs <= 1'b0; end            // 数据写完,停止一个周期,拉低CS

                            else    begin wstate <= 6'd30; end    

                           end

                           

                    6'd31: begin

                            if(low) begin wstate <= 6'd32; cs <= 1'b1; end    //拉高CS,读DO状态,看其是否忙

                            else    begin wstate <= 6'd31; end

                          end

                          

                    6'd32: begin

                            if(din == 1'b1) begin wstate <= 6'd33; cs <= 1'b0; end    //若忙,停在此状态继续检测    

                            else            begin wstate <= 6'd32; cs <= 1'b1; end

                          end

                          

                    6'd33: begin

                            if(low) begin wstate <= 6'd34; cs <= 1'b0; end    //数据写完,停止一个周期

                            else    begin wstate <= 6'd33; end

                          end

                          

                    6'd34: begin

                            if(low) begin wstate <= 6'd35; dout <= 1'b1; cs <= 1'b1; end    //当写操作完成后,为了保护数据,对器件进行擦/写禁止指令

                            else    begin wstate <= 6'd34; end

                          end

                          

                    6'd34: begin

                            if(low) begin wstate <= 6'd35; dout <= 1'b0; cs <= 1'b1; end    //OP=1

                            else    begin wstate <= 6'd34; end

                          end

                          

                    6'd35: begin

                            if(low) begin wstate <= 6'd36; dout <= 1'b0; cs <= 1'b1; end    //OP=2

                            else    begin wstate <= 6'd35; end

                          end

                          

                    6'd36: begin

                            if(low) begin wstate <= 6'd37; dout <= 1'b0; cs <= 1'b1; end    //A6

                            else    begin wstate <= 6'd36; end

                          end    

                          

                    6'd37: begin

                            if(low) begin wstate <= 6'd38; dout <= 1'b0; cs <= 1'b1; end    //A5

                            else    begin wstate <= 6'd37; end

                          end

                          

                    6'd38: begin

                            if(low) begin wstate <= 6'd39; dout <= 1'b1; cs <= 1'b1; end    //A4

                            else    begin wstate <= 6'd38; end

                          end

                          

                    6'd39: begin

                            if(low) begin wstate <= 6'd40; dout <= 1'b1; cs <= 1'b1; end    //A3

                            else    begin wstate <= 6'd39; end

                          end    

                          

                    6'd40: begin

                            if(low) begin wstate <= 6'd41; dout <= 1'b1; cs <= 1'b1; end    //A2

                            else    begin wstate <= 6'd40; end

                          end    

                          

                    6'd41: begin

                            if(low) begin wstate <= 6'd42; dout <= 1'b1; cs <= 1'b1; end    //A1

                            else    begin wstate <= 6'd41; end

                          end        

                          

                    6'd42: begin

                            if(low) begin wstate <= 6'd43; dout <= 1'b1; cs <= 1'b1; end    //A0

                            else    begin wstate <= 6'd42; end

                          end

                          

                    6'd43: begin

                            if(low) begin wstate <= 6'd44; dout <= 1'b0; end    //over

                            else    begin wstate <= 6'd43; end

                          end

                          

                    6'd44: begin

                            if(low) begin wstate <= 6'd0; cs <= 1'b0; end    //cs  down

                            else    begin wstate <= 6'd44; end

                          end

                

                endcase

                    

            end

    end

    

endmodule

 

你可能感兴趣的:(Verilog)