#FPGA(IP_RAM 调用 )

本文介绍了如何在QuartusIIIDE中使用CycloneIIEP2C8Q208C8N器件进行单端口RAM的读写操作,包括添加初始化文件、解决仿真时的配置问题,以及展示了一个带有计数器功能的ram_ctrl模块和tb_ram_ctrl测试模块的代码实现。
摘要由CSDN通过智能技术生成

1.IDE:Quartus II


2.设备:Cyclone II  EP2C8Q208C8N  


3.实验:调用单端口RAM仿真读取写入


4.时序图:


5.步骤:

(1)添加一个初始化文件做对比,255递减到0(HEX文件)

(2)仿真时出现报错,为配置的ram的.v文件没有添加,按如下方式解决。

 


6.代码:

ram_ctrl.v

/*
 *因为工程名失误,应该是ram_ctrl
 */
module ram_ip(
input    wire         sys_clk    ,
input    wire         sys_rst_n  ,
input    wire         wr_flag    ,
input    wire         rd_flag    ,

output   reg          wr_en      ,
output   reg  [7:0]   addr       ,
output   wire [7:0]   wr_data    ,
output   reg          rd_en      

);

parameter     CNT_MAX   =24'd1000_0000;   //计数值200ms     20ns per clk
reg     [23:0]     cnt_200ms;

/*
 *计时器(用于数码管显示,数码管需要留存时间)
 */
always @ (posedge sys_clk or negedge sys_rst_n) begin
     if(sys_rst_n == 1'b0)
	       cnt_200ms <= 24'd0;
     else  if((cnt_200ms == CNT_MAX) || (wr_flag == 1'b1) || (rd_flag == 1'b1))       //有读、写直接清零,计满时间也清零    
	       cnt_200ms <= 24'd0;
	  else  if(rd_en == 1'b1)
	       cnt_200ms <= cnt_200ms + 1'b1;         //读ram期间计数(读出来数码管显示需要时间)
	  else
	       cnt_200ms <= cnt_200ms;
end

/*
 *写使能控制
 */
always @ (posedge sys_clk or negedge sys_rst_n) begin
     if(sys_rst_n == 1'b0)
          wr_en <= 1'b0;
	  else  if(addr == 8'd255)                   //地址到达最大禁止写入
          wr_en <= 1'b0;
	  else  if(wr_flag == 1'b1)                  //写标志位拉高,使能写
          wr_en <= 1'b1;	 
	  else
	       wr_en <= wr_en; 
end

/*
 *地址控制
 */
always @ (posedge sys_clk or negedge sys_rst_n) begin
     if(sys_rst_n == 1'b0)
	       addr <= 8'd0;
	  else  if((addr == 8'd255 && wr_en == 1'b1) || (addr == 8'd255 && cnt_200ms == CNT_MAX) || (wr_flag == 1'b1) || (rd_flag == 1'b1))
	       addr <= addr + 1'b1;
	  else
	       addr <= addr;	 
end

/*
 *写入的数据赋值
 */
assign  wr_data = (wr_en == 1'b1) ? addr : 8'd0;   //写使能期间将地址作为数据

/*
 *读使能控制
 */
always @ (posedge sys_clk or negedge sys_rst_n) begin
     if(sys_rst_n == 1'b0)
          rd_en <= 1'b0;
	  else if(wr_flag == 1'b1)    //写信号到来,直接失能读操作
	       rd_en <= 1'b0;
	  else if(rd_flag == 1'b1 && wr_en == 1'b0)  //读信号到来且写信号失能才会将读信号使能
	       rd_en <= 1'b1;
	  else
	       rd_en <= rd_en;     
end

endmodule

tb_ram_ctrl.v

/*
 *ram_ip仿真代码
 */
`timescale 1ns/1ns
module tb_ram_ctrl();

reg        sys_clk       ;
reg        sys_rst_n     ;
reg        wr_flag       ;
reg        rd_flag       ;

wire       wr_en         ;
wire [7:0] addr          ;     
wire [7:0] wr_data       ;
wire       rd_en         ;
wire [7:0] data_out      ;

/*
 *读,写,再读
 */
initial
      begin
		     sys_clk    =   1'b1;
			  sys_rst_n  <=  1'b0;
			  wr_flag    <=  1'b0;
			  rd_flag    <=  1'b0;
			  #20
			  sys_rst_n  <=  1'b1;
			  #1000
//rd_flag
           rd_flag    <=  1'b1;    //读信号拉高一个时钟周期
           #20
           rd_flag    <=  1'b0;
           #60_000     //    > CNT_MAX * 20ns * 255 =10 * 20 * 256 = 51200  
//wr_flag
           wr_flag    <=  1'b1;    //写信号拉高一个时钟周期
           #20   
           wr_flag    <=  1'b0;
           #60_000
//rd_flag			
           rd_flag    <=  1'b1;    //写完之后再读看写入是否正确
			  #20
			  rd_flag    <=  1'b0;
		end
		
always #10 sys_clk = ~ sys_clk;    //模拟时钟
defparam   ram_ip_inst.CNT_MAX = 10 ;   //用于仿真(10 * 20ns = 200ns per data)

/*
 *实例化ram_ctrl
 */
ram_ip ram_ip_inst(
.sys_clk    (sys_clk )  ,
.sys_rst_n  (sys_rst_n)  ,
.wr_flag    (wr_flag )  ,
.rd_flag    (rd_flag )  ,
               
.wr_en      (wr_en   )  ,
.addr       (addr    )  ,
.wr_data    (wr_data )  ,
.rd_en      (rd_en   )
);

/*
 *实例化IP核,CYCLONE II 没有读使能控制信号?
 */
ram_8x256_one	ram_8x256_one_inst (
	.aclr       (~sys_rst_n),            //异步清零信号(高电平有信号)
	.address    (addr),
	.clock      (sys_clk),
	.data       (wr_data),
	.wren       (wr_en),
	.q          (data_out)
	);


endmodule

 


  • 18
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值