vivado初学之--RAM真双端口

一、看波形图

 二、ram具体思路

A端口:
1.指定地址进行交接,包含区别读写及写了多少数据信息
2.进行写,计数
3.回指定地址,将数据改成已写
B端口:
1.指定地址进行交接,取出写了多少数据信息
2.进行读,计数,直到读完
3.回到指定地址,将数据改成已读

三、代码

`timescale 1ns / 1ps
module double_true_rammem(
input sysclk,
input rst_n
    );
	

reg wea	;   //写使能
reg [6:0]buer_fly; //A端口写地址
reg buer_id;//A端口最高位
wire [7:0]addra;//A端地址
wire [7:0]douta; //输出数据
reg [3:0]st;//A状态机
reg [6:0]cnt;//A端口
reg [7:0]data=8'h00;//输入数据
assign addra = {buer_id,buer_fly};


===================A端口================/
always@(posedge sysclk or negedge rst_n)
if(!rst_n)//初始化
	begin
	cnt<=0;//写数计时
	wea<=0;//写使能信号初始化
	buer_fly<=0;
	buer_id<=0;
	st<=0;//A状态机初始化
	end
else
	case(st)//状态机
	0:	begin
			wea<=0;//写使能信号归零
			cnt<=0;//写计数信号归零
			buer_fly<=7'h7f;
			buer_id<=0;
			st<=1;//状态切换到1
		end
	1:	begin
			st<=2;
		end
	2:	begin	//判断控制地址信号第七位是否为0,为0则开始写
				wea<=0;
			if(douta[7]==0)begin//控制地址信号是否为0
					st<=3;//状态切换到2
					end
		end
	3:	begin
			wea<=1;//写使能信号拉高,ram开始写入工作
			buer_fly<=buer_fly+1;//地址自加
			data<=data+1;//数据自加
			cnt<=cnt+1;//计数自加
			if(cnt==127)//计数器到达127时,可接数据结束信号
				begin
					wea<=1;//写使能信号拉高,写控制地址数据信息
					buer_fly<=7'h7f;
					data<={1'b1,cnt[6:0]};//向控制地址写入1000+4个位宽的数据信息
					st<=4;//状态切换到0
				end
 
		end
	4:	begin
				wea<=0;
				buer_fly<=7'h7f;
				buer_id<=buer_id+1;
			st<=1;
		end
		default:;
	endcase
==================B端口=================///
reg web	;   //读使能
reg [6:0]buer_fly_B; //B端口写地址
reg buer_id_B;//B端口最高位
wire [7:0]addrb; 	//读地址
wire [7:0]doutb;//B端口输出
reg [3:0]st1;// B状态机
reg [7:0]cnt1;//B端口
reg [7:0]dinb ;  //输入
assign addrb={buer_id_B,buer_fly_B};

========================//
always@(posedge sysclk )
if(!rst_n)//初始化
	begin
			buer_fly_B<=0; //B端口写地址
			buer_id_B<=0;//B端口最高位
			cnt1	<=0;//计数器初始化
			web		<=0;//写使能初始化
			st1		<=0;//状态初始化
	end
else
	case(st1)//状态机
	0:	begin
			buer_fly_B<=7'h7f;
			cnt1	<=0;
			web		<=0;
			st1		<=1;
		end
	1:	begin
		st1		<=2;
		end
	2:	begin//状态为1则开始读,否则归零
			if(doutb[7]==1'b1)//判断控制地址信号第七位是否为1,为1则开始读,否则归零
				st1<=3;//状态切换到2
		end
	3:	begin//读出控制地址数据
			cnt1<=doutb[6:0];//取出计数器
			buer_fly_B<=buer_fly_B+1;//地址自加
			st1<=4;//状态切换到3
		end
	4:	begin
			cnt1<=cnt1-1;//计数器减少
			st1<=5;//状态切换到4
		end
	5:	begin
		if(cnt1==0)begin
				web<=1;//写使能拉高
				dinb<=0;//数据写入0
				buer_fly_B<=7'h7f;//指向控制地址			
				st1<=6;//状态切换到0
			end
		else begin//计数器不为0的情况下继续读取
				web<=0;	//写使能拉高
				buer_fly_B<=buer_fly_B+1;//地址自加
				st1<=4;//状态切换到3
			end
		end
	6:	begin
				web<=0;
				buer_fly_B<=7'h7f;
				buer_id_B<=buer_id_B+1;
				st1<=0;
		end
	default:;
	endcase 
blk_double_mem_test double_true_test (
  .clka (sysclk),    // input wire clka
  .wea  (wea),      // input wire [0 : 0] wea
  .addra(addra),  // input wire [3 : 0] addra
  .dina (data),    // input wire [7 : 0] dina
  .douta(douta),  // output wire [7 : 0] douta
  .clkb (sysclk),    // input wire clkb
  .web  (web),      // input wire [0 : 0] web
  .addrb(addrb),  // input wire [3 : 0] addrb
  .dinb (dinb),    // input wire [7 : 0] dinb
  .doutb(doutb)  // output wire [7 : 0] doutb
);
endmodule

 备注:以上内容创意来自成电少年学的李老师,代码是自己写的,非copy。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值