原创 那一年在学SRAM之Verilog HDL

2012-12-30 01:55 3422 23 25 分类: FPGA/CPLD 文集: Verilog

/* ************************************************************************************************
// Engineer   :  xymbmcu@163.com
// Target Device :  Altera Cyclone EP2C8Q208C8
// Clock     :  50Mhz
// Create Date  :    2012-12-29 20:47
// Amend Date   :   
// Module Name  :  sram_test
// Project Name :    sram_test
// Tool versions :    Quartus II 12.1
// Description  :    实现SRAM的读写操作
// Revision   :    NO
// Additional Comments: 好好学学,这是FPGA学习的跳板,这或许是你真正走进FPGA大门的金钥匙,只是或许是为建模的注释 ^o^
************************************************************************************************ */
module sram_test(
      Clk_50m,
      Rst_n,
      SramWrEn_n,
      SramRdEn_n,
      SramCsEn_n,
      SramLbEn_n,
      SramUbEn_n,
      SramAddr,
      SramData,
      LedOut
      );
/* ************************************************************************* */
input Clk_50m;
input Rst_n;

output SramWrEn_n;
output SramRdEn_n;
output SramCsEn_n;
output SramLbEn_n;
output SramUbEn_n;
output [17:0] SramAddr;
inout  [15:0] SramData;

output LedOut;
/* ************************************************************************* */
//延时计时器(1S)
reg [25:0] i_DelayCount;

always @ (posedge Clk_50m or negedge Rst_n)
 if(!Rst_n)
  i_DelayCount <= 26'd0;
 else
  i_DelayCount <= i_DelayCount + 1'b1;
/* ***************************************************** */
//产生读写请求信号
wire SramRdReq_w;
wire SramWrReq_w;

assign SramWrReq_w = (i_DelayCount == 26'd9999);
assign SramRdReq_w = (i_DelayCount == 26'd19999);
/* ***************************************************** */
//采用简单的时序进行读写,只需控制SramWrEn_n!!
reg SramCsEn_nr;
reg SramRdEn_nr;
reg SramLbEn_nr;
reg SramUbEn_nr;

always @ (posedge Clk_50m or negedge Rst_n)
 if(!Rst_n) begin
  SramCsEn_nr <= 1'b1;
  SramRdEn_nr <= 1'b1;
  SramLbEn_nr <= 1'b1;
  SramUbEn_nr <= 1'b1;
 end
 else begin
  SramCsEn_nr <= 1'b0;
  SramRdEn_nr <= 1'b0;
  SramLbEn_nr <= 1'b0;
  SramUbEn_nr <= 1'b0; 
 end
/* ***************************************************** */
assign SramCsEn_n = SramCsEn_nr;
assign SramRdEn_n = SramRdEn_nr;
assign SramLbEn_n = SramLbEn_nr;
assign SramUbEn_n = SramUbEn_nr;
/* ***************************************************** */
reg [15:0] SramWrData_r;
reg [15:0] SramRdData_r;
reg [17:0] SramAddr_r;

reg LedOut_r;
//遍历数据
always @ (posedge Clk_50m or negedge Rst_n)
 if(!Rst_n)
  SramWrData_r <= 16'b0;
 else if(i_DelayCount == 26'd29999)
  SramWrData_r <= SramWrData_r + 1'b1;
//遍历地址  
always @ (posedge Clk_50m or negedge Rst_n)
 if(!Rst_n)
  SramAddr_r <= 16'b0;
 else if(i_DelayCount == 26'd29999)
  SramAddr_r <= SramAddr_r + 1'b1;
//用LED的显示来指示SRAM的读写是否正常
always @ (posedge Clk_50m or negedge Rst_n)
 if(!Rst_n)
  LedOut_r <= 1'b0;
 else if(i_DelayCount == 26'd29999) begin
  if(SramRdData_r == SramWrData_r)
   LedOut_r <= 1'b1;
  else
   LedOut_r <= 1'b0;
 end //end of else if
/* ***************************************************** */
assign LedOut = LedOut_r;
/* ***************************************************** */
reg [2:0] j_DelayCount;
`define Delay80ns  (j_DelayCount == 3'd7)

always @ (posedge Clk_50m or negedge Rst_n)
 if(!Rst_n)
  j_DelayCount <= 3'd0;
 else if(CurrentState_r == IDLE)
  j_DelayCount <= 3'd0;
 else j_DelayCount <= j_DelayCount + 1'b1;
/* ***************************************************** */
parameter  IDLE    = 4'd0,
    WrData0 = 4'd1,
    WrData1 = 4'd2,
    RdData0 = 4'd3,
    RdData1 = 4'd4;
reg [3:0] CurrentState_r,NextState_r;
//第一段状态机
always @ (posedge Clk_50m or negedge Rst_n)
 if(!Rst_n)
  CurrentState_r <= IDLE;
 else
  CurrentState_r <= NextState_r;
//第二段状态机
always @ (CurrentState_r or SramWrReq_w or SramRdReq_w or j_DelayCount) begin
 case (CurrentState_r)
  IDLE : if(SramRdReq_w) NextState_r <= WrData0;
     else if(SramRdReq_w) NextState_r <= RdData0;
     else NextState_r <= IDLE;
  WrData0: if(`Delay80ns) NextState_r <= WrData1;
     else NextState_r <= WrData0;
  WrData1: NextState_r <= IDLE;
  RdData0: if(`Delay80ns) NextState_r <= RdData1;
     else NextState_r <= RdData0;
  RdData1: NextState_r <= IDLE;
  default: NextState_r <= IDLE;
 endcase
end
/* ************************************************************************* */
assign SramAddr = SramAddr_r;
/* ************************************************************************* */
always @ (posedge Clk_50m or negedge Rst_n)
 if(!Rst_n)
  SramRdData_r <= 16'b0;
 else
  SramRdData_r <= SramData;
/* ************************************************************************* */ 
reg SramLink_r;

always @ (posedge Clk_50m or negedge Rst_n)
 if(!Rst_n)
  SramLink_r <= 1'b0;
 else case (CurrentState_r)
  IDLE:
    if(SramWrReq_w) SramLink_r <= 1'b1;
    else if(SramRdReq_w) SramLink_r <= 1'b0;
    else SramLink_r <= 1'b0;
  WrData0: SramLink_r <= 1'b1;
  default: SramLink_r <= 1'b0;
 endcase
/* ************************************************************************* */
assign SramData = SramLink_r ? SramWrData_r : 16'bx;
assign SramWrEn_n = ~SramLink_r; 
/* ************************************************************************* */
endmodule

这次代码的编写过程自己特别列了一个Verilog HDL的代码书写规范,无规矩不成方圆吗??说明,在复制过程中可能格式有变,在QUARTUS II 12.1中看起来真的很漂亮,再加上其软件的只能功能,编写起来舒服、漂亮,享受其中的快乐吧,O(∩_∩)O~,时间不早了,灯亮了,自己该睡了…

文章评论2条评论)

登录后参与讨论

用户1852423 2016-6-13 09:44

SRAM读写地址发生器是怎么回事?刚接触FPGA编程,望多指点。

用户1851850 2016-4-10 20:50

不错 总结的很好啊

用户1758489 2014-11-7 12:01

延时计时器有什么作用?我刚开始接触,看不懂

liang890319_284707880 2013-9-9 17:10

好的 下次试试 谢谢

用户403664 2013-9-9 14:59

不是的,图片占很大字节!你可以使用高级编辑器一键排版功能!!
相关推荐阅读
残弈悟恩 2018-11-29 18:36
【博客大赛】国产SWM32单片机学习连载(一)
让更多人知道“中国芯”第1章 SWM320控制器简介单片微型计算机简称单片机,是典型的嵌入式微控制器(Microcontroller Unit),常用缩写MCU表示。单片机由运算器、控制...
残弈悟恩 2018-11-22 21:47
签到
2年没来了,既然来了,就签个到...
残弈悟恩 2016-03-25 18:38
评论:@以芯筑未来 博客中提到的“[转]29岁了,继续做个精致的电子工程师”
今天没时间看,先转了,等有时间了,好好拜读一下。...
残弈悟恩 2016-01-11 14:55
【博客大赛】各位网友,你想对EDN网站说点什么?
自荣获2015年EDN最佳博主奖以后,可能太过于自满,就再也没怎么写过博客自己!! 说心里话,肯定不是自满,实在是太忙了,所以只是常来看看,看大家写了什么,有什么最新的科技动态,反正是不想写。...
残弈悟恩 2015-10-23 14:28
评论:@wshr_king's Blog 博客中提到的“CODE RW RO ZI”
积累一下,谢谢楼主。...
我要评论
2
23
关闭 站长推荐上一条 /2 下一条