当前位置: 首页 > news >正文

FPGA project : flash_continue_write

本实验学习了通过spi通信协议,驱动flash;完成连续写操作。

连续写:

本质上还是页编程指令,两种连续写的方式:

1,每次只写1byte的数据。

2,每次写满1页数据,计算剩余数据够不够写满1页,并计算地址。

本实验采取方案一。

模块框图:

状态机: 

 时序图:

代码:

只放spi模块。 

module spi (input       wire            sys_clk     ,input       wire            sys_rst_n   ,input       wire            key_flag    ,input       wire            miso        ,output      reg             cs_n        ,output      reg             sck         ,output      reg             mosi        ,output      reg             po_flag     ,output      wire    [7:0]   po_data     
);// localparam define 一般状态机的状态定义用局部参数就可以。localparam  IDLE     = 4'b0001 ,INSTRUCT = 4'b0010 ,READ     = 4'b0100 ,SEND     = 4'b1000 ;// parameter define  指令,计数器最大值,用全局参数定义。parameter   COMD_REA = 8'h03 , // comd_readADDR_SEC = 8'h00 , // address_secter 扇区地址ADDR_PAG = 8'h00 , // address_page   页地址(行地址)ADDR_BYT = 8'hc8 , // assress_byte   字节地址NUM_COMD = 4'd4  ; // 用来记录在指令状态传递指令和地址byte数量parameter   CNT_MAX_BYTE = 11'd260   , // 4 + 要读出的数据。例如: 4 + 256CNT_MAX_SEND = 20'd53000 ;// reg signal define reg     [3:0]       state_c   ;reg     [3:0]       state_n   ;reg                 cnt_20_ns ;reg     [2:0]       cnt_bit   ;reg     [10:0]      cnt_byte  ;reg                 flag_b    ; // flag_bytereg                 flagBreg  ;reg                 flag_R_S  ; // flag_bytereg                 flag_RSr  ;reg     [7:0]       datInFifo ; // data_in_fiforeg                 flag_data ; // flag_data 采样标志信号reg                 flaInFifo ; // flag_in_fiforeg     [19:0]      cnt_send  ; // uart_tx模块发送1byte数据的等待时间。reg                 flaSenEnd ; // 计数器cnt_send计数到CNT_MAX_SEND - 2 拉高一个时钟周期,reg                 flag_out_fifo_reg ;// wire signal definewire                empty     ;wire                full      ;wire                flaOutFif ; // flag_out_fifo  wire    [9:0]       usedw     ; // fifo中存储的数据量   wire                IDLEtoINSTRUCT  ;wire                INSTRUCTto_READ ;wire                READtoSEND      ;wire                SENDtoIDLE      ; 
/**********************************************************************/// // reg signal describe /*******状态机采用三段式描述*******/// reg     [3:0]       state_c   ;// reg     [3:0]       state_n   ;always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) state_c <= IDLE ;else state_c <= state_n ;endalways @(*) begincase (state_c)IDLE     :  if(IDLEtoINSTRUCT)state_n <= INSTRUCT ;else state_n <= IDLE ;INSTRUCT :  if(INSTRUCTto_READ)state_n <= READ ;else state_n <= INSTRUCT ;READ     :  if(READtoSEND)state_n <= SEND ;else state_n <= READ ;SEND     :  if(SENDtoIDLE)state_n <= IDLE ;else state_n <= SEND ;default:        state_n <= IDLE ;endcaseendassign   IDLEtoINSTRUCT  = (state_c == IDLE    ) && (key_flag) ;assign   INSTRUCTto_READ = (state_c == INSTRUCT) && (flagBreg) ; // 指令的的最后1byte发送完毕assign   READtoSEND      = (state_c == READ    ) && (flag_RSr) ; // 读完想要的最后1byteassign   SENDtoIDLE      = (state_c == SEND    ) && (flaSenEnd && empty) ;// reg                 cnt_20_ns ;always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n)cnt_20_ns <= 1'b0 ;else if(state_c == INSTRUCT || state_c == READ)cnt_20_ns <= cnt_20_ns + 1'b1 ;else if(state_c != INSTRUCT || state_c != READ)cnt_20_ns <= 1'b0 ;else cnt_20_ns <= 1'b0 ;end// reg     [2:0]       cnt_bit   ;always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n)cnt_bit <=3'd0 ;elsecase (state_c)IDLE    :   cnt_bit <=3'd0 ;INSTRUCT:   if(!cnt_20_ns && sck && cnt_bit == 7)  cnt_bit <= 3'd0 ;else if(!cnt_20_ns && sck)cnt_bit <= cnt_bit + 1'b1 ;READ    :   if(!cnt_20_ns && sck && cnt_bit == 7)  cnt_bit <= 3'd0 ;else if(!cnt_20_ns && sck)cnt_bit <= cnt_bit + 1'b1 ;SEND    :   cnt_bit <=3'd0 ;default :   cnt_bit <=3'd0 ; endcaseend// reg     [10:0]       cnt_byte  ;always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n)cnt_byte <= 4'd0 ;else if(cnt_bit == 7 && cnt_byte == CNT_MAX_BYTE - 1 && !cnt_20_ns && sck)cnt_byte <= 4'd0 ;else if(cnt_bit == 7 && !cnt_20_ns && sck)cnt_byte <= cnt_byte + 1'b1 ;else cnt_byte <= cnt_byte ;end// reg                 flag_R_S  ;// reg                 flag_b    ;always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) beginflag_b   <= 1'b0 ;flag_R_S <= 1'b0 ;endelsecase (state_c)IDLE    :   beginflag_b <= 1'b0 ;flag_R_S <= 1'b0 ;end         INSTRUCT:   begin if((cnt_byte == NUM_COMD - 1) && (cnt_bit == 7) && !cnt_20_ns && sck)flag_b <= 1'b1 ;else flag_b <= flag_b ;flag_R_S <= 1'b0 ;endREAD    :   beginif(cnt_byte == NUM_COMD)flag_R_S <= 1'b0 ;else if((cnt_byte == CNT_MAX_BYTE - 1) && (cnt_bit == 7) && !cnt_20_ns && sck)flag_R_S <= 1'b1 ;flag_b <= 1'b0 ;endSEND    :   beginflag_b <= 1'b0 ;flag_R_S <= 1'b0 ;end default :   beginflag_b <= 1'b0 ;flag_R_S <= 1'b0 ;end endcase end// reg                 flagBreg  ;// reg                 flag_RSr  ;always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n)flagBreg <= 1'b0 ;else flagBreg <= flag_b ;endalways @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n)flag_RSr <= 1'b0 ;else flag_RSr <= flag_R_S ;end// reg     [7:0]       datInFifo ; // data_in_fifoalways @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) datInFifo <= 1'b0 ;else if(flag_data)datInFifo <= {datInFifo[6:0],miso}; // 读flash中数据,先传的低位{miso,datInFifo[7:1]}。else datInFifo <= datInFifo ;end// reg                 flag_data ; // flag_data 采样标志信号always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n)flag_data <= 1'b0 ;else if(state_c == READ) beginif(cnt_20_ns && !sck)flag_data <= 1'b1 ;else flag_data <= 1'b0 ;end else beginflag_data <= 1'b0 ;endend// reg                 flaInFifo ; // flag_in_fifoalways @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n)flaInFifo <= 1'b0 ;else if(state_c == READ && cnt_bit == 7 && flag_data)flaInFifo <= 1'b1 ;else flaInFifo <= 1'b0 ;end// reg     [19:0]      cnt_send  ; // uart_tx模块发送1byte数据的等待时间。always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) cnt_send <= 20'd0 ;else if(state_c == SEND) beginif(cnt_send == CNT_MAX_SEND - 1) cnt_send <= 20'd0 ;else cnt_send <= cnt_send + 1'b1 ;endelse cnt_send <= 20'd0 ;end//     reg                 flag_out_fifo_reg ;always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n)flag_out_fifo_reg <= 1'b0 ;else if(flaSenEnd && !empty)flag_out_fifo_reg <= 1'b1 ;else flag_out_fifo_reg <= 1'b0 ;end//     reg                 flaSenEnd ;always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) flaSenEnd <= 1'b0 ;else if(cnt_send == CNT_MAX_SEND - 2)flaSenEnd <= 1'b1 ;else flaSenEnd <= 1'b0 ;end// output signal describe// cs_n        ,always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n)cs_n <= 1'b1 ;else case (state_c)IDLE    :   if(key_flag)cs_n <= 1'b0 ;else cs_n <= cs_n ;INSTRUCT:   cs_n <= cs_n ;READ    :   cs_n <= cs_n ;SEND    :   cs_n <= 1'b1 ;default :   cs_n <= 1'b1 ;endcaseend// sck         ,always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) sck <= 1'b0 ;else case (state_c)IDLE    :   sck <= 1'b0 ; INSTRUCT:   if(cnt_20_ns)sck <= ~sck ;else sck <= sck  ;READ    :   if(cnt_20_ns)sck <= ~sck ;else sck <=  sck ;SEND    :   sck <= 1'b0 ; default :   sck <= 1'b0 ; endcaseend// mosi        ,always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) beginmosi <= 1'b0 ;end else begincase (state_c)IDLE    :   mosi <= 1'b0 ;INSTRUCT:   case (cnt_byte)0   :   if(cnt_bit == 0)mosi <= COMD_REA[7] ;else if(cnt_20_ns && sck)mosi <= COMD_REA[7 - cnt_bit] ;else mosi <= mosi ;1   :   if(cnt_bit == 0)mosi <= ADDR_SEC[7] ;else if(cnt_20_ns && sck)mosi <= ADDR_SEC[7 - cnt_bit] ;else mosi <= mosi ;2   :   if(cnt_bit == 0)mosi <= ADDR_PAG[7] ;else if(cnt_20_ns && sck)mosi <= ADDR_PAG[7 - cnt_bit] ;else mosi <= mosi ;3   :   if(cnt_bit == 0)mosi <= ADDR_BYT[7] ;else if(cnt_20_ns && sck)mosi <= ADDR_BYT[7 - cnt_bit] ;else mosi <= mosi ;default :   mosi <= 1'b0 ;endcaseREAD    :   mosi <= 1'b0 ;SEND    :   mosi <= 1'b0 ;default :   mosi <= 1'b0 ;endcaseendend// po_flag     ,always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n)po_flag <= 1'b0 ;else po_flag <= flag_out_fifo_reg ;end// wire     [7:0]    po_data ;// 直接连接到fifo的输出端口。     // */
/***********************例化FIFO***************************************/assign flaOutFif = flag_out_fifo_reg ;
fifo_1024x8 fifo_1024x8_inst(.clock              ( sys_clk   ) ,.data               ( datInFifo ) ,.rdreq              ( flaOutFif ) ,.wrreq              ( flaInFifo ) ,.empty              ( empty     ) ,.full               ( full      ) ,.q                  ( po_data   ) ,.usedw              ( usedw     )
);endmodule

仿真波形: 

上版验证成功。

相关文章:

FPGA project : flash_continue_write

本实验学习了通过spi通信协议&#xff0c;驱动flash&#xff1b;完成连续写操作。 连续写&#xff1a; 本质上还是页编程指令&#xff0c;两种连续写的方式&#xff1a; 1&#xff0c;每次只写1byte的数据。 2&#xff0c;每次写满1页数据&#xff0c;计算剩余数据够不够写…...

论文阅读:Rethinking Range View Representation for LiDAR Segmentation

来源ICCV2023 0、摘要 LiDAR分割对于自动驾驶感知至关重要。最近的趋势有利于基于点或体素的方法&#xff0c;因为它们通常产生比传统的距离视图表示更好的性能。在这项工作中&#xff0c;我们揭示了建立强大的距离视图模型的几个关键因素。我们观察到&#xff0c;“多对一”…...

本地配置免费的https咋做?

大家好这里是tony4geek。 今天和公司的小伙伴对接项目&#xff0c;因为涉及到https的权限调用。所以在服务器本地localhost 要配置https用来测试 。现在把过程中遇到的问题记录下来。 • 因为是测试用所以生成https的证书用免费的就可以了。 openssl req -x509 -nodes -days …...

微信小程序框架---详细教程

&#x1f3ac; 艳艳耶✌️&#xff1a;个人主页 &#x1f525; 个人专栏 &#xff1a;《Spring与Mybatis集成整合》《Vue.js使用》 ⛺️ 越努力 &#xff0c;越幸运。 目录 1.框架 1.1响应的数据绑定 1.2.页面管理 1.3.基础组件 1.4.丰富的 API 2.视图层 View 2.1.介绍 …...

【LeetCode刷题(数组and排序)】:存在重复元素

给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 &#xff0c;返回 true &#xff1b;如果数组中每个元素互不相同&#xff0c;返回 false 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3,1] 输出&#xff1a;true 示例 2&#xff1a; 输入&#xff1a;nums [1,2…...

半导体产业链解析:晶圆厂、无晶圆厂与代工厂的比较与作用

半导体产业一直是全球科技发展的关键驱动力&#xff0c;在半导体产业中&#xff0c;晶圆厂、无晶圆厂公司和代工厂是三个重要的参与者。它们在产业环节、生产方式、经营模式和市场竞争等方面存在一些显著差异。本文将探讨半导体晶圆厂、无晶圆厂公司和代工厂之间的区别&#xf…...

Apipost一键压测已支持导入CSV文件

最近更新中Apipost对UI页面进行了一些调整&#xff0c;另外一键压测功能支持参数化&#xff01;本篇文章将详细介绍这些改动&#xff01; API调试页面的细节改动 在请求区填入请求参数或脚本时会有相应的标识 如在Query中填入多个参数时上方会展示数量 在预、后执行脚本中写…...

RabbitMQ的5种模式——再探RabbitMQ的模式,简单、工作,发布订阅(广播),路由、主题 页面分析

前言 RabbitMQ作为一款常用的消息中间件&#xff0c;在微服务项目中得到大量应用&#xff0c;其本身是微服务中的重点和难点&#xff0c;有不少概念我自己的也是一知半解&#xff0c;本系列博客尝试结合实际应用场景阐述RabbitMQ的应用&#xff0c;分析其为什么使用&#xff0…...

初识华为云数据库GaussDB for openGauss

01 前言 GaussDB是华为自主创新研发的分布式关系型数据库。该产品具备企业级复杂事务混合负载能力&#xff0c;同时支持分布式事务&#xff0c;同城跨AZ部署&#xff0c;数据0丢失&#xff0c;支持1000的扩展能力&#xff0c;PB级海量存储。同时拥有云上高可用&#xff0c;高可…...

深圳寄包裹到德国

深圳&#xff0c;作为全球最发达的城市之一&#xff0c;以其高效的物流服务在全球范围内享有盛名。如果你正在寻找一种方式将包裹从深圳寄送到德国&#xff0c;那么本文将为你提供详细的步骤和建议。 第一步&#xff1a;了解国际邮寄的基本信息 首先&#xff0c;你需要了解包裹…...

系统架构师备考倒计时22天(每日知识点)Redis篇

Redis篇 1.Redis与Memcache能力对比 工作MemCacheRedis数据类型简单 key/value 结构丰富的数据结构持久性不支持支持分布式存储客户端哈希分片/一致性哈希多种方式&#xff0c;主从、Sentinel、Cluster 等多线程支持支持支持(Redis5.0及以前版本不支持)内存管理私有内存池/内…...

现有库存(on-hand inventory),库存水平(inventory level),库存位置(inventory position)

库存管理中&#xff0c;这几个名词特别容易混&#xff0c;干脆写一篇博客总结下。 现有库存(on-hand inventory)&#xff0c;是指持有的真实库存量 库存水平(inventory level)&#xff0c;现有库存减去延迟交付的订单 inventory level on-hand inventory − backorder quant…...

智慧空开让用电更安全、管理更智能——电脑APP远程控制开合闸

安科瑞 崔丽洁 01 什么是低压断路器&#xff1f;低压断路器的定义是&#xff1a;能够接通、承载及分断正常电路条件下的电流&#xff0c;也能在规定的非正常电路条件&#xff08;过载、短路、特别是短路&#xff09;下接通、承载一定时间和分断电流的开关电器。 断路器的分类&…...

PyTorch 中张量运算广播

TLDR 右对齐&#xff0c;空补一&#xff0c;从左往右依维运算 [m] [x, y] [m x, m y] 正文 以如下 a b 两个 tensor 计算为例 a torch.tensor([[1],[2],[3], ]) b torch.tensor([[[1, 2, 3],],[[4, 5, 6],],[[7, 8, 9],], ]) # a.shape (3, 1) # b.shape (3, 1, 3)首先…...

Blender:使用立方体制作动漫头像

好久没水文章 排名都掉到1w外了 ~_~ 学习一下blender&#xff0c;看能不能学习一点曲面变形的思路 一些快捷键 ctrl 空格&#xff1a;区域最大化&#xff0c;就是全屏 ctrl alt 空格&#xff1a;也是区域最大化 shift b&#xff1a;框选区域然后最大化显示该范围 shift 空…...

【ppt技巧】ppt里的图片如何提取出来?

之前分享过如何将PPT文件导出成图片&#xff0c;今天继续分享PPT技巧&#xff0c;如何提取出PPT文件里面的图片。 首先&#xff0c;我们将PPT文件的后缀名&#xff0c;修改为rar&#xff0c;将文件改为压缩包文件 然后我们将压缩包文件进行解压 最好是以文件夹的形式解压出来…...

Python学习基础笔记七十三——调试程序

为什么要调试&#xff1f; 我们发现程序运行的结果和我们预期的不符。 程序运行的错误&#xff0c;我们通常叫做bug。 有两种类型的bug&#xff1a;语句错误和逻辑错误。 所谓语句错误&#xff0c;就是执行代码的时候&#xff0c;解释器就可以直接发现的代码错误&#xff0c…...

BOSHIDA DC电源模块关于电容器的电解液位置

BOSHIDA DC电源模块关于电容器的电解液位置 DC电源模块中的电容器扮演着一个非常重要的角色&#xff0c;它们能够对电路提供稳定的电源电压&#xff0c;同时也可以作为电路中的滤波器&#xff0c;去除电路中的噪声和纹波。在DC电源模块中使用的电容器通常是电解型电容器&#…...

如何实现 Es 全文检索、高亮文本略缩处理(封装工具接口极致解耦)

如何实现 Es 全文检索、高亮文本略缩处理 前言技术选型JAVA 常用语法说明全文检索开发高亮开发Es Map 转对象使用核心代码 Trans 接口&#xff08;支持父类属性的复杂映射&#xff09;Trans 接口可优化的点高亮全局配置类如下真实项目落地效果为什么不用 numOfFragments、fragm…...

C++多线程编程(第四章 案例1,C++11和C++17 多核并行计算样例)

目录 4.1手动实现多核base16编码4.1.1 实现base16编码4.1.2无多线程代码4.1.3 C 11多线程代码4.1.4 C 17多线程并发4.1.5 所有测试代码汇总 4.1手动实现多核base16编码 4.1.1 实现base16编码 二进制转换为字符串 一个字节8位&#xff0c;拆分为两个4位字节&#xff08;最大值…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

代码随想录刷题day30

1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额&#xff0c;返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...