基于线性序列机实现的FPGA 通过SPI协议读写winbond公司flash芯片25Q16-FPGA常见问题论坛-FPGA CPLD-ChipDebug

基于线性序列机实现的FPGA 通过SPI协议读写winbond公司flash芯片25Q16

 

基于线性序列机思想设计读写该芯片的SPI协议,线性序列机简单来说就是用一个计数器对时钟计数,对于每一个计数值,按照时序要求对信号做出相应操作。简单写了一下 Read Manufacturer / Device ID (90h) 指令,需要先发送0x90(一字节),接着发送地址0x000000(三字节),再接收Manufacturer ID 和Device ID 两字节,接收正确的话分别是0xEF和0x14。芯片手册的指令说明及时序图如下。

图片[1]-基于线性序列机实现的FPGA 通过SPI协议读写winbond公司flash芯片25Q16-FPGA常见问题论坛-FPGA CPLD-ChipDebug
图片[2]-基于线性序列机实现的FPGA 通过SPI协议读写winbond公司flash芯片25Q16-FPGA常见问题论坛-FPGA CPLD-ChipDebug

按照时序图一步一步写即可,程序如下,已经验证。

module spi_dri(
    input wire sys_clk,
    input wire rst_n,
    
    input wire start,
    input wire [7:0] instruct,
    input wire [23:0] addr,
    
    output reg spi_clk,
    output reg spi_cs_n,
    output reg spi_mosi,
    input wire spi_miso,
    output reg work_done,
    output reg [7:0] manu_id,
    output reg [7:0] device_id
);
 
reg [7:0] r_manu_id;
reg [7:0] r_device_id;
 
reg work_ing;
reg [9:0] cnt_sysclk;
 
 
 
always@(posedge sys_clk or negedge rst_n)
    if(!rst_n)
        work_ing <= 1'b0;
    else if(start)
        work_ing <= 1'b1;
    else if(work_done)
        work_ing <= 1'b0;
    else
        work_ing <= work_ing;
 
 
always@(posedge sys_clk or negedge rst_n)
    if(!rst_n)
        cnt_sysclk <= 10'b0;
    else if(work_ing)
        cnt_sysclk <= cnt_sysclk + 1'b1;
    else if(cnt_sysclk == 10'd97)
        cnt_sysclk <= 10'b0;
    else
        cnt_sysclk <= cnt_sysclk;
 
always@(posedge sys_clk or negedge rst_n)
    if(!rst_n)begin
        spi_cs_n <= 1'b1;
        spi_clk <= 1'b0;
        spi_mosi <= 1'b1;
        r_device_id <= 8'd0;
        r_manu_id <= 8'd0;
        device_id <= 8'd0;
        manu_id <= 8'd0;
        work_done <= 1'b0;
    end
    else begin
        case(cnt_sysclk)
            0:begin spi_cs_n <= 1'b0; spi_clk <= 1'b0; spi_mosi <= instruct[7]; end
            1:begin spi_clk <= 1'b1; end
            2:begin spi_clk <= 1'b0; spi_mosi <= instruct[6]; end
            3:begin spi_clk <= 1'b1; end
            4:begin spi_clk <= 1'b0; spi_mosi <= instruct[5]; end
            5:begin spi_clk <= 1'b1; end
            6:begin spi_clk <= 1'b0; spi_mosi <= instruct[4];end
            7:begin spi_clk <= 1'b1; end
            8:begin spi_clk <= 1'b0; spi_mosi <= instruct[3];end
            9:begin spi_clk <= 1'b1; end
            10:begin spi_clk <= 1'b0; spi_mosi <= instruct[2];end
            11:begin spi_clk <= 1'b1; end
            12:begin spi_clk <= 1'b0; spi_mosi <= instruct[1];end
            13:begin spi_clk <= 1'b1; end
            14:begin spi_clk <= 1'b0; spi_mosi <= instruct[0];end
            
            15:begin spi_clk <= 1'b1; end
            16:begin spi_clk <= 1'b0; spi_mosi <= addr[23]; end
            17:begin spi_clk <= 1'b1; end
            18:begin spi_clk <= 1'b0; spi_mosi <= addr[22]; end
            19:begin spi_clk <= 1'b1; end
            20:begin spi_clk <= 1'b0; spi_mosi <= addr[21]; end
            21:begin spi_clk <= 1'b1; end
            22:begin spi_clk <= 1'b0; spi_mosi <= addr[20];end
            23:begin spi_clk <= 1'b1; end
            24:begin spi_clk <= 1'b0; spi_mosi <= addr[19];end
            25:begin spi_clk <= 1'b1; end
            26:begin spi_clk <= 1'b0; spi_mosi <= addr[18];end
            27:begin spi_clk <= 1'b1; end
            28:begin spi_clk <= 1'b0; spi_mosi <= addr[17];end
            29:begin spi_clk <= 1'b1; end
            30:begin spi_clk <= 1'b0; spi_mosi <= addr[16]; end
            31:begin spi_clk <= 1'b1; end
            32:begin spi_clk <= 1'b0; spi_mosi <= addr[15]; end
            33:begin spi_clk <= 1'b1; end
            34:begin spi_clk <= 1'b0; spi_mosi <= addr[14]; end
            35:begin spi_clk <= 1'b1; end
            36:begin spi_clk <= 1'b0; spi_mosi <= addr[13];end
            37:begin spi_clk <= 1'b1; end
            38:begin spi_clk <= 1'b0; spi_mosi <= addr[12];end
            39:begin spi_clk <= 1'b1; end
            40:begin spi_clk <= 1'b0; spi_mosi <= addr[11];end
            41:begin spi_clk <= 1'b1; end
            42:begin spi_clk <= 1'b0; spi_mosi <= addr[10];end
            43:begin spi_clk <= 1'b1; end
            44:begin spi_clk <= 1'b0; spi_mosi <= addr[9]; end
            45:begin spi_clk <= 1'b1; end
            46:begin spi_clk <= 1'b0; spi_mosi <= addr[8]; end
            47:begin spi_clk <= 1'b1; end
            48:begin spi_clk <= 1'b0; spi_mosi <= addr[7]; end
            49:begin spi_clk <= 1'b1; end
            50:begin spi_clk <= 1'b0; spi_mosi <= addr[6];end
            51:begin spi_clk <= 1'b1; end
            52:begin spi_clk <= 1'b0; spi_mosi <= addr[5];end
            53:begin spi_clk <= 1'b1; end
            54:begin spi_clk <= 1'b0; spi_mosi <= addr[4];end
            55:begin spi_clk <= 1'b1; end
            56:begin spi_clk <= 1'b0; spi_mosi <= addr[3];end
            57:begin spi_clk <= 1'b1; end
            58:begin spi_clk <= 1'b0; spi_mosi <= addr[2]; end
            59:begin spi_clk <= 1'b1; end
            60:begin spi_clk <= 1'b0; spi_mosi <= addr[1]; end
            61:begin spi_clk <= 1'b1; end
            62:begin spi_clk <= 1'b0; spi_mosi <= addr[0]; end
            63:begin spi_clk <= 1'b1; end
            64:begin spi_clk <= 1'b0; end
            65:begin spi_clk <= 1'b1; r_manu_id[7] <= spi_miso; end
            66:begin spi_clk <= 1'b0; end
            67:begin spi_clk <= 1'b1; r_manu_id[6] <= spi_miso; end
            68:begin spi_clk <= 1'b0; end
            69:begin spi_clk <= 1'b1; r_manu_id[5] <= spi_miso; end
            70:begin spi_clk <= 1'b0; end
            71:begin spi_clk <= 1'b1; r_manu_id[4] <= spi_miso; end
            72:begin spi_clk <= 1'b0; end
            73:begin spi_clk <= 1'b1; r_manu_id[3] <= spi_miso; end
            74:begin spi_clk <= 1'b0; end
            75:begin spi_clk <= 1'b1; r_manu_id[2] <= spi_miso; end
            76:begin spi_clk <= 1'b0; end
            77:begin spi_clk <= 1'b1; r_manu_id[1] <= spi_miso; end
            78:begin spi_clk <= 1'b0; end
            79:begin spi_clk <= 1'b1; r_manu_id[0] <= spi_miso; manu_id <= r_manu_id; end
            
            
            80:begin spi_clk <= 1'b0; end
            81:begin spi_clk <= 1'b1; r_device_id[7] <= spi_miso;end
            82:begin spi_clk <= 1'b0;  end
            83:begin spi_clk <= 1'b1; r_device_id[6] <= spi_miso;end
            84:begin spi_clk <= 1'b0; end
            85:begin spi_clk <= 1'b1; r_device_id[5] <= spi_miso; end
            86:begin spi_clk <= 1'b0; end
            87:begin spi_clk <= 1'b1; r_device_id[4] <= spi_miso; end
            88:begin spi_clk <= 1'b0; end
            89:begin spi_clk <= 1'b1; r_device_id[3] <= spi_miso; end
            90:begin spi_clk <= 1'b0;end
            91:begin spi_clk <= 1'b1; r_device_id[2] <= spi_miso;  end
            92:begin spi_clk <= 1'b0;  end
            93:begin spi_clk <= 1'b1;r_device_id[1] <= spi_miso; end
            94:begin spi_clk <= 1'b0;   end
            95:begin spi_clk <= 1'b1; r_device_id[0] <= spi_miso;device_id <= r_device_id;end
            96:begin spi_cs_n <= 1'b1; work_done <= 1'b1; end
            default:;
        endcase
    end
 
 
endmodule

 

请登录后发表评论

    没有回复内容