Verilog 在单口RAM下的配置。

今天终于又有点小收获。真不错。

关于这个配置呢。通过 深入浅出玩转FPGA 系列视频教程的第28讲可以清楚知道怎么配置。现在我把例化文件和测试文件贴上.

 

先看QuartusII生成的波形图。

 

先贴上没有带clr信号的吧。简单些.

//`include "RAM4.V"//这句话可以不要
module RAM(CLK,RST,RAM_WR,RAM_ADDR,DATA_IN,DATA_OUT);

input CLK,RST,RAM_WR;
input [7:0]RAM_ADDR;
input [7:0]DATA_IN;
output [7:0]DATA_OUT;

//
RAM4 u1(
.address(RAM_ADDR),
.clock(CLK),
.data(DATA_IN),
.wren(RAM_WR),
.q(DATA_OUT)
);  endmodule

 

再上那啥,带有clr信号的吧。

//`include "RAM4.V"
module RAM(CLK,RST,RAM_WR,RAM_ADDR,DATA_IN,DATA_OUT);

input CLK,RST,RAM_WR;
input [7:0]RAM_ADDR;
input [7:0]DATA_IN;
output [7:0]DATA_OUT;

//
RAM4 u1(
.aclr(CLR),
.address(RAM_ADDR),
.clock(CLK),
.data(DATA_IN),
.wren(RAM_WR),
.q(DATA_OUT)
);

endmodule 


 

测试文件如下:

`timescale 1ns/100ps

module a_ram_tb;

reg clk,rst,ram_write;
reg [7:0]ram_addr;
reg [7:0]data_in;

wire[7:0]data_out;


RAM ram4k(
.CLK(clk),
.RST(rst),
.RAM_WR(ram_write),
.RAM_ADDR(ram_addr),
.DATA_IN(data_in),
.DATA_OUT(data_out)
);

initial 
	begin
		clk=0;
		forever #5 clk=~clk;//200M 5ns
	end
		
initial 	
	forever @(posedge rst)
		begin
			ram_write=0;
			ram_addr=8'hzz;
			data_in=8'hzz;
		end
		
		
initial 
	begin
		rst=1;
		ram_write=0;
		ram_addr=8'hzz;
		data_in=8'hzz;
		#500;
		
		rst=0;
		ram_write=0;
		ram_addr=8'hzz;
		data_in=8'hzz;
		
		#1000;
		
		task_ram_write(8'd0,8'd1);//0地址写数据1
		task_ram_write(8'd1,8'd3);//1地址写数据3
		task_ram_write(8'd2,8'd5);//2地址写数据5
		task_ram_write(8'd3,8'd7);//3地址写数据7
		
		#50;
		@(posedge clk);
			ram_addr=8'd0;//读地址0数据
		@(posedge clk);
			ram_addr=8'd1;//读地址1数据
		@(posedge clk);
			ram_addr=8'd2;//读地址2数据
		@(posedge clk);
			ram_addr=8'd3;//读地址3数据
		
		#100;
		$stop;
	end
		

task task_ram_write; // 顺序控制内部两个并行块
	input[7:0] addr;
	input[7:0] data;
	begin//顺序执行的两条语句。先写入,再读出
		@(posedge clk);
		fork//并行执行
			ram_write<=1;
			data_in<=data;
			ram_addr<=addr;		
		join
		
		@(posedge clk);//读出数据操作
		fork//并行执行
			ram_write<=0;
			data_in<=8'hzz;//配置地址和时钟线为高阻
			//ram_addr<=8'hzz;//这条语句注释掉很重要		
		join
	end
endtask

endmodule 

这看看屏蔽了这条语句(上)和没屏蔽这条语句(下)究竟差在哪。

 

 

 

知道答案了。//ram_addr<=8'hzz;就是这条语句。 因为没有屏蔽掉这句话,浪费了足足半天功夫。(也怪我基础不扎实啊。)。呵呵,该睡觉了。微笑

由于单口RAM和双口RAMVerilog代码实现有所不同,所以我将为您提供这两种RAM的代码。 单口RAMmodule single_port_RAM ( input clk, // 时钟信号 input write_en, // 写使能信号 input [7:0] addr, // 地址信号 input [7:0] data_in,// 输入数据信号 output [7:0] data_out// 输出数据信号 ); reg [7:0] mem [0:255]; // 256个8位字节的内存 always @(posedge clk) begin if (write_en) begin // 写使能信号为高时,将数据写入内存中 mem[addr] <= data_in; end end assign data_out = mem[addr]; // 输出数据信号为对应地址上的数据 endmodule 爽口RAMmodule dual_port_RAM ( input clk, // 时钟信号 input [7:0] addr_A, // A端地址信号 input [7:0] addr_B, // B端地址信号 input [7:0] data_in_A,// A端输入数据信号 input [7:0] data_in_B,// B端输入数据信号 input write_en_A, // A端写使能信号 input write_en_B, // B端写使能信号 output reg [7:0] data_out_A, // A端输出数据信号 output reg [7:0] data_out_B // B端输出数据信号 ); reg [7:0] mem [0:255]; // 256个8位字节的内存 always @(posedge clk) begin if (write_en_A) begin // A端写使能信号为高时,将数据写入内存中 mem[addr_A] <= data_in_A; end if (write_en_B) begin // B端写使能信号为高时,将数据写入内存中 mem[addr_B] <= data_in_B; end end always @(addr_A or addr_B) begin data_out_A <= mem[addr_A]; // A端输出数据信号为对应地址上的数据 data_out_B <= mem[addr_B]; // B端输出数据信号为对应地址上的数据 end endmodule
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值