完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
2个回答
|
|
至简设计代码实现(附录部分代码)
下面是使用至简设计法实现的SDRAM控制器,该控制器使用了四段式状态机,其他信号根据状态机对齐而设计,结构相当清晰,无论是设计还是调试,都非常容易,相信有一定基础的工程师,能感觉到这样设计的精简、奇妙之处,欢迎借鉴、学习。 网络上亦有相当多的SDRAM实现代码,欢迎您拿来与明德扬对比,我们对自身的代码设计就是有这样的自信。 1 //四段式状态机 2 3 //第一段:同步时序always模块,格式化描述次态寄存器迁移到现态寄存器 4 always@(posedge clk or negedge rst_n)begin 5 if(!rst_n)begin 6 state_c <= IDL; 7 end 8 else begin 9 state_c <= state_n; 10 end 11 end 12 13 //第二段:组合逻辑always模块,描述状态转移条件判断 14 //只需要思考转移到哪里去 15 always@(*)begin 16 case(state_c) 17 NOP:begin 18 if(nop2pre_start)begin 19 state_n = PRE; 20 end 21 else begin 22 state_n = state_c; 23 end 24 end 25 PRE:begin 26 if(pre2aut_start)begin 27 state_n = AUT; 28 end 29 else if(pre2idl_start)begin 30 state_n = IDL; 31 end 32 33 else begin 34 state_n = state_c; 35 end 36 end 37 AUT:begin 38 if(aut2aut_start)begin 39 state_n = AUT; 40 end 41 else if(aut2lmd_start)begin 42 state_n = LMD; 43 end 44 else if(aut2idl_start)begin 45 state_n = IDL; 46 end 47 end 48 LMD:begin 49 if(lmd2idl_start)begin 50 state_n = IDL; 51 end 52 else begin 53 state_n = state_c; 54 end 55 end 56 IDL:begin 57 if(idl2act_start)begin 58 state_n = ACT; 59 end 60 else if(idl2aut_start)begin 61 state_n = AUT; 62 end 63 64 else begin 65 state_n = state_c; 66 end 67 end 68 ACT:begin 69 if(act2red_start)begin 70 state_n = RED; 71 end 72 else if(act2wrt_start)begin 73 state_n = WRT; 74 end 75 76 else begin 77 state_n = state_c; 78 end 79 end 80 RED:begin 81 if(red2pre_start)begin 82 state_n = PRE; 83 end 84 else begin 85 state_n = state_c; 86 end 87 end 88 WRT:begin 89 if(wrt2pre_start)begin 90 state_n = PRE; 91 end 92 else begin 93 state_n = state_c; 94 end 95 end 96 default:begin 97 state_n = IDL; 98 end 99 endcase 100 end 101 //第三段:设计转移条件 102 //相同现态的要放在一起,条件互斥,方便比较 103 assign nop2pre_start = state_c==NOP && end_cnt; 104 105 assign pre2aut_start = state_c==PRE && init_flag==1 && end_cnt; 106 assign pre2idl_start = state_c==PRE && init_flag==0 && end_cnt; 107 108 assign aut2aut_start = state_c==AUT && init_flag==1 && init_auto_flag==1 && end_cnt; 109 assign aut2lmd_start = state_c==AUT && init_flag==1 && init_auto_flag==0 && end_cnt; 110 111 assign aut2idl_start = state_c==AUT && init_flag==0 && end_cnt; 112 113 assign lmd2idl_start = state_c==LMD && end_cnt; 114 115 assign idl2act_start = state_c==IDL && ref_req==0&& (wr_req||rd_req); 116 assign idl2aut_start = state_c==IDL && ref_req ==1 ; 117 118 assign act2red_start = state_c==ACT && rd_flag==1 && end_cnt; 119 assign act2wrt_start = state_c==ACT && rd_flag==0 && end_cnt; 120 121 assign red2pre_start = state_c==RED && end_cnt; 122 assign wrt2pre_start = state_c==WRT && end_cnt; 123 124 always @(posedge clk or negedge rst_n)begin 125 if(rst_n==1'b0)begin 126 init_flag <= 1; 127 end 128 else if(lmd2idl_start)begin 129 init_flag <= 0; 130 end 131 end 132 133 always @(posedge clk or negedge rst_n)begin 134 if(rst_n==1'b0)begin 135 init_auto_flag <= 1; 136 end 137 else if(aut2aut_start)begin 138 init_auto_flag <= 0; 139 end 140 end 141 142 //刷新请求 143 always @(posedge clk or negedge rst_n)begin 144 if(rst_n==1'b0)begin 145 ref_req <= 0; 146 end 147 else if(end_cnt_self)begin 148 ref_req <= 1; 149 end 150 else if(idl2aut_start)begin 151 ref_req <= 0; 152 end 153 end 154 155 //写响应 156 assign wr_ack = idl2act_start==1&& (wr_req==1&&((rd_flag==1)||(rd_flag==0&&rd_req==0))); 157 //读响应 158 assign rd_ack = idl2act_start==1&& (rd_req==1&&((rd_flag==0)||(rd_flag==1&&wr_req==0))); 159 160 always @(posedge clk or negedge rst_n)begin 161 if(rst_n==1'b0)begin 162 rd_flag <= 0; 163 end 164 else if(rd_flag==0&&rd_ack==1)begin 165 rd_flag <= 1; 166 end 167 else if(rd_flag==1&&wr_ack==1)begin 168 rd_flag <= 0; 169 end 170 end 171 172 173 //刷新时间计算 174 always @(posedge clk or negedge rst_n)begin 175 if(!rst_n)begin 176 cnt_self <= 0; 177 end 178 else if(add_cnt_self)begin 179 if(end_cnt_self) 180 cnt_self <= 0; 181 else 182 cnt_self <= cnt_self + 1; 183 end 184 end 185 186 assign add_cnt_self = init_flag==0; 187 assign end_cnt_self = add_cnt_self && cnt_self==1562-1 ; 188 189 //命令时间计数,此处使用了变量法,并且复用了一个计数器 190 always @(posedge clk or negedge rst_n)begin 191 if(!rst_n)begin 192 cnt <= 0; 193 end 194 else if(add_cnt)begin 195 if(end_cnt) 196 cnt <= 0; 197 else 198 cnt <= cnt + 1; 199 end 200 end 201 202 assign add_cnt = state_c!=IDL; 203 assign end_cnt = add_cnt && cnt==x-1 ; 204 205 //各个命令所需要的时间,在下面列出来就好了 206 always @(*)begin 207 if(state_c==NOP)begin 208 x = INITIATE; 209 end 210 else if(state_c==PRE)begin 211 x = TRP; 212 end 213 else if(state_c==AUT)begin 214 x = TRC; 215 end 216 else if(state_c==LMD)begin 217 x = TMRD; 218 end 219 else if(state_c==ACT)begin 220 x = TRCD ; 221 end 222 else begin 223 x = 256 ; 224 end 225 end 226 227 always @(posedge clk or negedge rst_n)begin 228 if(rst_n==1'b0)begin 229 cke <= 1; 230 end 231 else begin 232 cke <= 1; 233 end 234 end 235 236 assign command = {cs,ras,cas,we}; 237 238 //下面是产生命令的代码,由于状态机结构简单,要产生COMMAND是非常方便的 239 //仅从名字下就可以看出代码是否正确 240 always @(posedge clk or negedge rst_n)begin 241 if(rst_n==1'b0)begin 242 command <= 0; 243 end 244 else if(nop2pre_start||wrt2pre_start||red2pre_start)begin 245 command <= precharge; 246 end 247 else if(pre2aut_start||aut2aut_start||idl2aut_start)begin 248 command <= autorefresh; 249 end 250 else if(aut2lmd_start)begin 251 command <= loadmode; 252 end 253 else if(idl2act_start)begin 254 command <= active; 255 end 256 else if(act2red_start)begin 257 command <= read; 258 end 259 else if(act2wrt_start)begin 260 command <= write; 261 end 262 else begin 263 command <= nop; 264 end 265 266 end 267 268 always @(posedge clk or negedge rst_n)begin 269 if(rst_n==1'b0)begin 270 dqm <= 0; 271 end 272 else if(init_flag==1)begin 273 dqm <= 2'b11; 274 end 275 else begin 276 dqm <= 0; 277 end 278 end 279 280 always @(posedge clk or negedge rst_n)begin 281 if(rst_n==1'b0)begin 282 dq_out <= 0; 283 end 284 else begin 285 dq_out <= wdata; 286 end 287 end 288 289 always @(posedge clk or negedge rst_n)begin 290 if(rst_n==1'b0)begin 291 dq_out_en <= 0; 292 end 293 else if(act2wrt_start)begin 294 dq_out_en <= 1; 295 end 296 else if(wrt2pre_start)begin 297 dq_out_en <= 0; 298 end 299 end 300 301 302 always @(posedge clk or negedge rst_n)begin //256拍 303 if(rst_n==1'b0)begin 304 rdata_flag <= 0; 305 end 306 else if(act2red_start)begin 307 rdata_flag <= 1; 308 end 309 else if(red2pre_start)begin 310 rdata_flag <= 0; 311 end 312 end 313 314 always @(posedge clk or negedge rst_n)begin 315 if(rst_n==1'b0)begin 316 rdata_flag_ff0 <= 0; 317 rdata_flag_ff1 <= 0; 318 rdata_flag_ff2 <= 0; 319 end 320 else begin 321 rdata_flag_ff0 <= rdata_flag; 322 rdata_flag_ff1 <= rdata_flag_ff0; 323 rdata_flag_ff2 <= rdata_flag_ff1; 324 325 end 326 end 327 328 329 always @(posedge clk or negedge rst_n)begin 330 if(rst_n==1'b0)begin 331 rdata <= 0; 332 end 333 else begin 334 rdata <= dq_in; 335 end 336 337 end 338 339 always @(posedge clk or negedge rst_n)begin 340 if(rst_n==1'b0)begin 341 rdata_vld <= 0; 342 end 343 else begin 344 rdata_vld <= rd_flag_ff2; 345 end 346 end 347 348 always @(posedge clk or negedge rst_n)begin //锁存地址waddr; 349 if(rst_n==1'b0)begin 350 waddr_ff0 <= 0; 351 end 352 else if(idl2act_start)begin 353 waddr_ff0 <= waddr; 354 end 355 end 356 357 always @(posedge clk or negedge rst_n)begin 358 if(rst_n==1'b0)begin 359 addr <= 0; 360 end 361 else if(nop2pre_start)begin 362 addr <=12'b0100_0000_0000; 363 end 364 else if(aut2lmd_start)begin 365 addr <= 12'b00_1_00_010_0_111;//latency Mode 为010 的情况 366 end 367 else if(idl2act_start)begin 368 addr[7:0] <= waddr[19:8]; //行地址 369 end 370 else if(act2wrt_start||act2red_start)begin 371 addr[7:0] <= waddr_ff0[7:0]; //列地址 372 end 373 end 374 375 always @(posedge clk or negedge rst_n)begin 376 if(rst_n==1'b0)begin 377 bank <=0; 378 end 379 else if(nop2pre_start)begin 380 bank <= 2'b11; 381 end 382 else if(idl2act_start)begin 383 bank <= waddr[21:20]; 384 end 385 else if(act2red_start||act2wrt_start)begin 386 bank < waddr_ff0[21:20]; 387 end 388 else begin 389 bank <= 0; 390 end 391 end |
|
|
|
只有小组成员才能发言,加入小组>>
895 浏览 0 评论
1202 浏览 1 评论
2579 浏览 5 评论
2914 浏览 9 评论
移植了freeRTOS到STMf103之后显示没有定义的原因?
2776 浏览 6 评论
keil5中manage run-time environment怎么是灰色,不可以操作吗?
1254浏览 3评论
229浏览 2评论
503浏览 2评论
410浏览 2评论
M0518 PWM的电压输出只有2V左右,没有3.3V是怎么回事?
489浏览 1评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-2-4 04:34 , Processed in 1.153229 second(s), Total 79, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号