0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

FPGA学习系列:内存128M的flash芯片设计

FPGA学习交流 2018-09-14 11:49 次阅读

设计背景:

FLASH闪存闪存的英文名称是"Flash Memory",一般简称为"Flash",它属于内存器件的一种,是一种不挥发性( Non-Volatile )内存。闪存的物理特性与常见的内存有根本性的差异:目前各类 DDRSDRAM 或者 RDRAM 都属于挥发性内存,只要停止电流供应内存中的数据便无法保持,因此每次电脑开机都需要把数据重新载入内存;闪存在没有电流供应的条件下也能够长久地保持数据,其存储特性相当于硬盘,这项特性正是闪存得以成为各类便携型数字设备的存储介质的基础。

设计原理:

我们的设计用的是W25Q128FV 内存128M的flash芯片,大家可以自行在网上下载器件手册具体看所应用的具体命令和自己项目具体的应用和想发来设计。

这款flash芯片的的存储是一个扇区4KB,一个扇区可以存256个字,一个字是8位,一个块是64KB,一共有256个块组成一个存储flash内存。

我在下面的讲解中,将主要讲实现一下字节的读写,我用的协议是SPI协议,这个芯片支持QSPI,双端口SPI等。flash有三个状态寄存器,每一个状态寄存器的每一位都有各自的功能。大家可以具体的看器件手册,我给大家简单的讲一下第一个状态寄存器。

这个状态寄存器第一位是可读忙和不忙的标志位,大家可以在我们的设计中判断芯片是否忙和不忙来是否进行下一步的操作。第二位是一个写标志的信号,当写使能打开的时候它位1,只有它为1的时候我们才可以进行写,值得一说的不管是页操作,还是擦除等命令后都会使这个标志位变成0。然后前面的命令算的上的是保护命令,具体有使用的逻辑功能。

在flash中我们写数据前先要擦除数据你想擦除的地方,然后进行写,如果没有用过的flash芯片的话那么可以不用擦除。毕竟我们的flash可是掉电不丢失数据的。

我的设计思路是这样的我们先读出我们的器件厂商,和芯片ID,然后记性写命令,写使能打开,页操作写入数据(值得说明的是我们FLASH是新的所以没进行擦除命令,建议擦除---关闭写使能 -- 打开写使能),然后读第一个寄存器判断芯片的第一位是否忙,不忙然后进行读操作之后再数码管上显示出我们写入的数据。

部分操作命令如下

我们的发送格式为在时钟的上升沿写入命令,在时钟的下降沿读出命令,我们用的是标准的SPI协议,端口IO0,和IO1,都是单向的。

写使能时序:

读使能时序:

之后别的时序我们将不展示,大家可以参考器件手册。

设计架构图:

我们的设计是用一个FSM控制器来控制发送什么命令,flash模块判断FSM发送过来的state信号来选择应该执行什么操作,当命令写入或者读出后,会发送一个flag_done命令,这个命令让我们判断上个指令是否完成,如果完成后FAM将发送下一个命令。

设计代码:

设计模块

0modulefsm(clk,rst_n,flag_done,command,addr,state,data);

1

2 inputclk,rst_n;

3 inputflag_done;//输入标志位

4 outputreg[7:0]command;//输出命令

5 outputreg[23:0]addr;//输出地址

6 outputreg[2:0]state; //输出状态模式

7 outputreg[7:0]data;//输出写入数据

8

9 reg[2:0]state_s;

10 reg[20:0]count;

11 always@(posedgeclk)

12 if(!rst_n)

13 begin

14 state_s <=0;

15 data <=8'd0;

16 addr <=24'd0;

17 command <=8'd0;

18 state <=0;

19 count <=0;

20 end

21 else

22 case(state_s)

23 0 : begin

24 if(count <200)//延迟一段时间

25 count <=count +1;

26 else

27 begin//发送读厂商ID的命令

28 command <=8'h90;

29 addr <=24'd0;

30 state <=1;

31 count <=1;

32 end

33 if(flag_done)//检查是否完成

34 state_s <=1;

35 end

36

37 1 : begin

38 if(count <200)//延迟一段时间

39 count <=count +1;

40 else

41 begin//写使能

42 command <=8'h06;

43 state <=3;

44 count <=0;

45 end

46 if(flag_done)//检查是否完成

47 state_s <=2;

48 end

49

50 2 : begin

51 if(count <200)//延迟一段时间

52 count <=count +1;

53 else

54 begin//页操作

55 command <=8'h02;

56 addr <=24'd0;

57 state <=4;

58 data <=8'haa;

59 count <=0;

60 end

61 if(flag_done)//检查是否完成

62 state_s <=3;

63 end

64

65 3 : begin

66 if(count <200)//延迟一段时间

67 count <=count +1;

68 else

69 begin//读寄存器

70 command <=8'h05;

71 count <=0;

72 state <=5;

73 end

74 if(flag_done)//检查是否完成

75 state_s <=4;

76 end

77

78 4 : begin

79 if(count <200)//延迟一段时间

80 count <=count +1;

81 else

82 begin//读数据

83 command <=8'h03;

84 addr <=24'd0;

85 state <=2;

86 count <=0;

87 end

88 end

89

90 default:state_s <=0;

91 endcase

92

93endmodule

0moduleflash (clk ,rst_n,q0,q1,sclk,cs,command,addr,state, data,show_data,flag_done);

1

2 inputclk,rst_n;

3 inputq0;

4 outputregq1;

5 outputregsclk;

6 outputregcs;

7 input[7:0]command; //输入命令

8 input[23:0]addr; //地址

9 input[2:0]state; //状态

10 input[7:0]data; //数据

11 outputreg[23:0]show_data; //显示

12 outputregflag_done; //命令完成标志

13

14 reg[5:0]count;

15 reg[5:0]cnt;

16 reg[31:0]temp;

17 reg[15:0]d;

18 reg[5:0]count_s;

19 reg[7:0]dou;

20 reg[39:0]xie;

21 reg[7:0]r_reg;

22

23 always@(posedgeclk)

24 if(!rst_n)

25 begin

26 sclk <=1;

27 count_s <=0;

28 end

29 elseif(cs)

30 begin

31 count_s <=0;

32 sclk <=1;

33 end

34 else

35 begin

36 if(count_s ==25-1) //产生1M的时钟

37 begin

38 count_s <=0;

39 sclk <=~sclk;

40 end

41 else

42 count_s <=count_s +1;

43 end

44

45 reg[1:0]signle_s;

46

47 //边沿检测电路

48 always@(posedgeclk ornegedgerst_n)

49 if(!rst_n)

50 begin

51 signle_s <=2'b11;

52 end

53 else

54 begin

55 signle_s[0]<=sclk;

56 signle_s[1]<=signle_s[0];

57 end

58

59 assignpose_dge =signle_s[0]&&~signle_s[1];//上升沿脉冲

60 assignnege_dge =~signle_s[0]&&signle_s[1];//下降沿脉冲

61

62 reg[1:0]s;

63 reg[1:0]s1,s2,s3,s4;

64 always@(posedgeclk ornegedgerst_n)

65 if(!rst_n)

66 begin

67 q1 <=0;

68 count <=0;

69 cs <=1;

70 temp <=0;

71 d <=0;

72 cnt <=0;

73 s <=0;

74 s1 <=0;

75 s2 <=0;

76 s3 <=0;

77 flag_done <=0;

78 s4 <=0;

79 end

80 else

81 begin

82 if(state ==1)//state == 1进入读芯片的厂商和ID

83 case(s)

84 0:begincs <=0;temp <={command,addr};s <=1; end

85

86 1 :begin

87 if(nege_dge) //下降沿发送数据

88 begin

89 if(count <32)

90 begin

91 q1 <=temp[31];

92 count <=count +1;

93 temp <= {temp[30:0],temp[31]};

94 end

95 else

96 begin

97 count <=0;

98 s <=2;

99 end

100 end

101 else

102 q1 <=q1;

103 end

104

105 2 : begin

106 if(pose_dge) //上升沿采集数据

107 begin

108 if(count <16)

109 begin

110 count <=count +1;

111 d <={d[14:0],q0};

112 end

113 else

114 begin

115 s <=3;

116 cs <=1;

117 count <=0;

118 flag_done <=1;

119 show_data <=d;

120 end

121 end

122 else

123 begin

124 s <=2;

125 end

126 end

127

128 3 : begin

129 flag_done <=0;

130 end

131

132 endcase

133

134 elseif(state ==2) //state == 2进入读模式

135 case(s1)

136 0:begincs <=0;temp <={command,addr};s1 <=1; end

137

138 1 :begin

139 if(nege_dge)

140 begin

141 if(count <32)

142 begin

143 q1 <=temp[31];

144 count <=count +1;

145 temp <={temp[30:0],temp[31]};

146 end

147 else

148 begin

149 count <=0;

150 s1 <=2;

151 end

152 end

153 else

154 q1 <=q1;

155 end

156

157 2 : begin

158 if(pose_dge)

159 begin

160 if(count <8)

161 begin

162 count <=count +1;

163 dou <={dou[6:0],q0};

164 s1 <=2;

165 end

166 else

167 begin

168 s1 <=3;

169 cs <=1;

170 count <=0;

171 flag_done <=1;

172 show_data <=dou;

173 end

174 end

175 else

176 begin

177 s1 <=2;

178 end

179 end

180

181 3 : begin

182 flag_done <=0;

183 end

184 endcase

185

186 elseif(state ==3) //state == 3 进入写使能模式

187 case(s2)

188 0:begincs <=0;temp <={command,addr};s2 <=1; end

189

190 1 :begin

191 if(nege_dge)

192 begin

193 if(count <8)

194 begin

195 q1 <=temp[31];

196 count <=count +1;

197 temp <={temp[30:0],temp[31]};

198 end

199 else

200 begin

201 count <=0;

202 s2 <=2;

203 cs <=1;

204 flag_done <=1;

205 end

206 end

207 else

208 q1 <=q1;

209 end

210

211 2 :flag_done <=0;

212 endcase

213

214 elseif(state ==4) //state == 4 进入页写操作

215 case(s3)

216 0:begincs <=0;xie <={command,addr,data};s3 <= 1;end

217

218 1 :begin

219 if(nege_dge)

220 begin

221 if(count <40)

222 begin

223 q1 <=xie[39];

224 count <=count +1;

225 xie <={xie[38:0],xie[39]};

226 end

227 else

228 begin

229 count <=0;

230 s3 <=2;

231 cs <=1;

232 flag_done <=1;

233 end

234 end

235 else

236 q1 <=q1;

237 end

238

239 2 :flag_done <=0;

240

241 endcase

242

243 elseif(state ==5) //state == 5 进入读第一个状态寄存器 操作

244 case(s4)

245 0:begincs <=0;r_reg <=command;s4 <=1;end

246

247 1 :begin

248 if(nege_dge)

249 begin

250 if(count <8)

251 begin

252 q1 <=r_reg[7];

253 count <=count +1;

254 r_reg <={r_reg[6:0],r_reg[7]};

255 end

256 else

257 begin

258 count <=0;

259 s4 <=2;

260 end

261 end

262 else

263 q1 <=q1;

264 end

265

266 2 : begin

267 if(pose_dge)

268 begin

269 if(count <8)

270 begin

271 count <=count +1;

272 d <={d[14:0],q0};

273 end

274 else

275 begin

276 cs <=1;

277 count <=0;

278 if(!d[8])//判断BUSY位忙不忙, 不忙进入下个状态

279 begin

280 flag_done <=1;

281 s4 <=3;

282 end

283 else//忙继续读第一个寄存器

284 s4 <=0;

285 end

286 end

287 else

288 begin

289 s4 <=2;

290 end

291 end

292

293 3 :flag_done <=0;

294

295 endcase

296

297 end

298

299endmodule

SignalTap 采集图

图中显示的和我们的设计一样,发送的各个命令也是一样的,我们写入的是AA然后下班接收的也是AA。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1625

    文章

    21620

    浏览量

    601179
收藏 人收藏

    评论

    相关推荐

    基于FPGA内存128M flash芯片控制器设计方案

    这款flash芯片的的存储是一个扇区4KB,一个扇区可以存256个字,一个字是8位,一个块是64KB,一共有256个块组成一个存储flash内存
    发表于 04-19 09:52 1071次阅读
    基于<b class='flag-5'>FPGA</b>的<b class='flag-5'>内存</b><b class='flag-5'>128M</b> <b class='flag-5'>flash</b><b class='flag-5'>芯片</b>控制器设计方案

    基于FPGA内存128M flash芯片控制器设计

    今天给大侠带来基于FPGA内存128M flash芯片控制器设计,话不多说,上货。 设计原理及思路
    发表于 05-23 16:07

    内存故障维修与经验

    128M DDR内存,但是开机显示内存显示128M,偶尔显示256M。   故障分析:打开机箱检查,发现两条
    发表于 01-05 16:46

    想用DM6446做图像处理,板子DDR是128M,请问我应该怎么修改 才能符合我自己的应用?

    本帖最后由 一只耳朵怪 于 2018-6-22 10:36 编辑 我想用DM6446做图像处理, 我目前的板子是合众达的,DDR是128M,而TI的默认文档都是256M内存的配置,请问我应该怎么修改 才能符合我自己的应用?
    发表于 06-22 05:53

    Kintex超级设备的BPI Flash编程的选择列表是哪个?

    嗨,我的BPI Flash制造商部件号是内存大小为2G(128M x16)的PC28F00BP33EF,在生成MCS文件并尝试Flash theBPI后,它显示了附件中附带的设备列表
    发表于 04-24 08:20

    请问在NuMirco™系列芯片Flash内存中包括哪些?

    在NuMirco™系列芯片Flash内存中包括哪些?
    发表于 12-11 07:17

    外部FLASH芯片内存

    提要:外部FLASH芯片据说通常用来放置字库,图形库,反正它的大内存让我可以避免在写程序时因为其中的数据过大而无法编译成功。 软件:KEIL C51、stc-isp-15xx-v6.87C 硬件:STC8A8K64S4A12、
    发表于 12-13 06:00

    通过EIM总线连接的imx6和fpga, 这个128MB EIM内存的物理位置在哪里?

    你好。 我们正在使用通过 EIM 总线连接的 imx6 和 fpga。 当cpu发生中断时,从EIM Memory中读取CS0的数据。 我们基本上把CS0分配为一个128M的区域。 我有个
    发表于 05-19 08:50

    纽曼s999固件升级 (含内存4G和128M)

    纽曼s999固件升级:S999TV4.0支持N制CA卡固件(机身内存128M)和S999TV4.0增加股票信息(机身内存4G)。
    发表于 04-25 18:47 186次下载

    Winbond -DRAM 64M 128M 256M SD

    Winbond -DRAM 64M 128M 256M SDRAM 产品规格 ‧64M 128M 256
    发表于 01-08 16:59 1544次阅读

    K9F1G08_datasheet

    sunsumg 128m flash(128M x 8 Bit / 64M x 16 Bit NAND Flash Memory)
    发表于 12-21 11:12 5次下载

    SPI—外部FLASH-W25Q128

    -ST固件库版本:1.5.1 【 !】功能简介: 读写板载的SPI FLASH芯片学习目的:学习STM32的SPI驱动。 【 !!】注意事项: 板子的
    发表于 12-13 15:13 98次下载

    新唐科技N55S128简介

    N55S128是一个128M位(16M字节)的SPI串行式Mask ROM。 规格数据
    的头像 发表于 02-12 11:23 1858次阅读
    新唐科技N55S<b class='flag-5'>128</b>简介

    FLASH芯片(W25Q128

    简介W25Q128FV (128M-bit)串行闪存为有限的空间、引脚和电源系统提供了存储解决方案。25Q系列提供的灵活性和性能远远超过普通的串行Flash设备。执行代码直接从双/四
    发表于 11-26 18:51 72次下载
    <b class='flag-5'>FLASH</b><b class='flag-5'>芯片</b>(W25Q<b class='flag-5'>128</b>)

    FPGA实现的SPI协议(二)----基于SPI接口的FLASH芯片M25P16的使用

    进行通信验证,未免测试不够周全。本文通过对FLASH芯片M25P16的仿真模型进行一系列测试,从而验证SPI驱动的代码的正确性,同时对M25
    发表于 12-22 19:25 19次下载
    <b class='flag-5'>FPGA</b>实现的SPI协议(二)----基于SPI接口的<b class='flag-5'>FLASH</b><b class='flag-5'>芯片</b><b class='flag-5'>M</b>25P16的使用