一、看波形图
二、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。