2 FPGA实现SPI接口--SPI接口芯片的实际使用( 七 )

<= 1'b0;//初始复位#20//20个时钟周期后sys_rst_n <= 1'b1;//拉高复位,系统进入工作状态 end//重定义初始化数值defparam memory.mem_access.initfile = "initM25P16_test.txt"; //其中的数据是从0累加 //------------<设置时钟>----------------------------------------------always #10 sys_clk = ~sys_clk;//系统时钟周期20nsendmodule
仿真结果如下:
命令窗口打印内容如下(单位:ps):约5us处开始进行扇区擦除操作,1s后扇区擦除操作完成 。与预期结果一致 。
2.3.4、上板验证
首先使用扇区擦除模块24‘,实际上就是擦除扇区0,和后面的页地址和字节地址没有关系 。在2.2节做页写操作的验证时,我们给地址扇区0的页0的地址0x00~0x0a分别写入了数据0x00、0x02、···、0x12,我们只要再使用读数据模块对这10个地址读取一遍,根据读出的内容就可以判断扇区擦除操作是否成功 。
使用 tap对读数据操作抓取的波形如下:可以看到连续读取的数据均为0XFF,说明扇区擦除操作成功 。
2.4、全擦除(Bulk Erase) 2.4.1、时序
全擦除(Bulk Erase)操作,简称 BE,操作指令为 8’(C7h),全擦除指令是将 Flash 芯片中的所有存储单元设 置为全 1,在 Flash 芯片写入全擦出指令之前,需要先写入写使能(WREN)指令;随后要拉低片选信号,写入全擦除指令,在指令写入过程中,片选信号始终保持低电平,待指令被芯片锁存后,将片选信号拉高;全擦除指令被锁存并执行后,需要等待一个完整的全擦除周期(tBE),才能完成 Flash 芯片的全擦除操作 。时序图如下:
2.4.2、代码
代码分为3个模块:SPI驱动模块、SPI全擦除控制模块和全擦除顶层模块 。
SPI全擦除控制模块代码如下:
//全擦除指令控制模块module spi_bulk_erase_ctrl(inputsys_clk,// 全局时钟50MHzinputsys_rst_n ,// 复位信号,低电平有效inputsend_done ,// 主机发送一个字节完毕标志位outputregspi_start ,// 发送传输开始信号,一个高电平outputregspi_end,// 发送传输结束信号,一个高电平outputreg[7:0]data_send// 要发送的数据);//指令定义parameterWR_EN= 8'b0000_0110,//写使能指令BULK_ERASE= 8'b1100_0111,//全擦除指令READ= 8'h0000_0011;//读数据指令//reg define reg [7:0] flow_cnt;//状态跳转计数器reg [31:0] cnt_wait;//等待计数器always@(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)begindata_send <= 8'd0;spi_start <= 1'b0; flow_cnt <= 1'd0;cnt_wait <= 'd0;endelse beginspi_start <= 1'b0;//便于生成脉冲信号spi_end <= 1'b0;//便于生成脉冲信号case(flow_cnt)'d0:beginif(cnt_wait == 100)begin//上电后等待稳定cnt_wait <= 8'd0;flow_cnt <= flow_cnt + 1'd1;endelse begincnt_wait <= cnt_wait + 1'd1;flow_cnt <= flow_cnt;endend'd1:begindata_send <= WR_EN;//数据为写使能指令spi_start <= 1'b1;//拉高spi开始通讯信号flow_cnt <= flow_cnt + 1'd1;end 'd2:beginif(send_done)begin//主机一个字节数据被发送完成flow_cnt <= flow_cnt + 1'd1;spi_end <= 1'b1;//结束第1次SPI通信endelseflow_cnt <= flow_cnt;end 'd3:beginif(cnt_wait == 10)begin//等待200ns,两次命令的间隔时间cnt_wait <= 8'd0;//等待计数器清零flow_cnt <= flow_cnt + 1'd1;endelse begincnt_wait <= cnt_wait + 1'd1;flow_cnt <= flow_cnt;endend'd4:begindata_send <= BULK_ERASE;//全擦除指令spi_start <= 1'b1;//拉高spi开始通讯信号flow_cnt <= flow_cnt + 1'd1;end 'd5:beginif(send_done)begin//主机一个字节数据被发送完成flow_cnt <= flow_cnt + 1'd1;spi_end <= 1'b1;//结束第2次SPI通信endelseflow_cnt <= flow_cnt;end'd6:begin//停留在这个状态flow_cnt <= flow_cnt;enddefault:;endcaseendendendmodule
SPI全擦除顶层模块代码如下:
//全擦除指令模块module spi_bulk_erase(// 系统接口input sys_clk,//全局时钟50MHzinput sys_rst_n ,//复位信号,低电平有效// SPI物理接口input spi_miso ,//SPI串行输入,用来接收从机的数据output spi_sclk ,//SPI时钟output spi_cs,//SPI片选信号,低电平有效output spi_mosi//SPI输出,用来给从机发送数据);wirespi_start ; //发送传输开始信号,一个高电平wirespi_end;//发送传输结束信号,一个高电平wire [7:0]data_send;//要发送的数据wiresend_done ;//主机发送一个字节完毕标志//------------