| |
W25Q128全擦除实验,
TRIG我映射到了开发板的按键,只打了拍子,没有进行消抖。
verilog;toolbar:false">module SPI_FLASH ( SCK, CSB, MOSI, CLK, RSTB, TRIG ); output reg SCK; output reg CSB; output reg MOSI; input wire CLK; input wire RSTB; input wire TRIG; parameter IDLE = 3'b000; parameter WREN = 3'b001; parameter WAIT = 3'b010; parameter BE = 3'b011; parameter DONE = 3'b100; reg [7:0] DATA; reg [2:0] DIV_CNT; reg [2:0] CNT_100NS; reg [3:0] CNT_BIT; reg [1:0] CNT_BYTE; reg [2:0] NST,PST; reg START; reg TRIG_1P,TRIG_2P,TRIG_3P; always@(posedge CLK or negedge RSTB)begin if(!RSTB)begin {TRIG_1P,TRIG_2P,TRIG_3P} <= 3'b0; end else begin {TRIG_1P,TRIG_2P,TRIG_3P} <= {TRIG,TRIG_1P,TRIG_2P}; end end wire TRIG_RISE = TRIG_2P & !TRIG_3P; always@(posedge CLK or negedge RSTB)begin if(!RSTB)begin START <= 1'b0; end else if(NST == DONE) begin START <= 1'b0; end else if(TRIG_RISE) begin START <= 1'b1; end end wire DIV_CNT_FULL = (DIV_CNT >= 3'h3); wire DIV_CNT_HALF = (DIV_CNT == 3'h1); always@(posedge CLK or negedge RSTB)begin if(!RSTB) DIV_CNT <= 3'b0; else if(NST == WAIT) DIV_CNT <= 3'h0; else if(DIV_CNT_FULL) DIV_CNT <= 3'h0; else if(NST == WREN || NST == BE) DIV_CNT <= DIV_CNT + 1'b1; end wire CNT_BIT_FULL = (CNT_BIT >= 4'h7); always@(posedge CLK or negedge RSTB)begin if(!RSTB) CNT_BIT <= 4'h0; else if(DIV_CNT_FULL&&CNT_BIT_FULL) CNT_BIT <= 4'h0; else if((NST == WREN || NST == BE ) && DIV_CNT_FULL) CNT_BIT <= CNT_BIT + 1'b1; end wire CNT_BYTE_FULL = (CNT_BYTE >= 2'h1); always@(posedge CLK or negedge RSTB)begin if(!RSTB) CNT_BYTE <= 4'h0; else if(DIV_CNT_FULL&&CNT_BIT_FULL&&CNT_BYTE_FULL) CNT_BYTE <= 4'h0; else if((NST == WREN || NST == BE ) && CNT_BIT_FULL) CNT_BYTE <= CNT_BYTE + 1'b1; end wire CNT_100NS_FULL = (CNT_100NS > 3'h5); always@(posedge CLK or negedge RSTB)begin if(!RSTB) CNT_100NS <= 4'h0; else if(CNT_100NS_FULL) CNT_100NS <= 4'h0; else if(PST == WAIT) CNT_100NS <= CNT_100NS + 1'b1; end always@(posedge CLK or negedge RSTB)begin if(!RSTB) DATA <= 8'h00; else if(NST == WREN) DATA <= 8'b0000_0110; else if(NST == BE ) DATA <= 8'b1100_0111; end always@(posedge CLK or negedge RSTB)begin if(!RSTB) SCK <= 1'b0; else if(DIV_CNT_HALF) SCK <= 1'b1; else if(DIV_CNT_FULL) SCK <= 1'b0; else if (NST == DONE) SCK <= 1'b0; end always@(posedge CLK or negedge RSTB)begin if(!RSTB) CSB <= 1'b1; else if((NST == WREN)||((NST == BE)&&CNT_100NS_FULL)) CSB <= 1'b0; else if(PST == WAIT | PST == DONE) CSB <= 1'b1; end always@(posedge CLK or negedge RSTB)begin if(!RSTB) PST <= 3'b000; else PST <= NST; end always@(posedge CLK or negedge RSTB)begin if(!RSTB) MOSI <= 1'b0; else if(DIV_CNT == 3'h1) MOSI <= DATA[7-CNT_BIT]; else if(NST == IDLE) MOSI <= 1'b0; end always@(*)begin NST = PST; case(PST) IDLE : begin if(START) NST = WREN; else NST = IDLE; end WREN : begin if(DIV_CNT_FULL&&CNT_BIT_FULL&&CNT_BYTE_FULL) NST = WAIT; else NST = WREN; end WAIT : begin if(CNT_100NS_FULL) NST = BE; else NST = WAIT; end BE : begin if(DIV_CNT_FULL&&CNT_BIT_FULL&&CNT_BYTE_FULL) NST = DONE; else NST = BE; end DONE:begin NST = IDLE; end default : NST = IDLE; endcase end endmodule