专注收集记录技术开发学习笔记、技术难点、解决方案
网站信息搜索 >> 请输入关键词:
您当前的位置: 首页 > Verilog

Verilog HDL SPI通讯——写

发布时间:2011-06-30 07:19:24 文章来源:www.iduyao.cn 采编人员:星星草
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

 

友情提示:
信息收集于互联网,如果您发现错误或造成侵权,请及时通知本站更正或删除,具体联系方式见页面底部联系我们,谢谢。

其他相似内容:

热门推荐: