配置单端口
输出寄存&异步清零
查看.v文件发现端口发生一些变化,其他基本一致
硬件语言描述
顶层:
module test_ip (
input rst_n,
input clk,
input [4:0] rdaddress,
input [4:0] wraddress,
input [7:0] data,
input wren,
input rden,
output [7:0] q
);
//在调用ram时,此时pll中的时钟信号就变为了中间信号
wire c0 ;//25M
wire c1 ;//100M,90°相移
wire c2 ;//100M
wire c3 ;//25M,25%占空比
wire c4 ;//70M
wire locked ;
wire inclk ;//添加时钟中间信号,便于更改时钟
assign inclk = c2 & locked;//locked观察时钟是否锁定,
//能看到输出稳定的时钟信号,如果不&。c2输出时钟就为不定态
pll pll_inst (
.areset ( ~rst_n ),//根据手册,pll复位高电平有效,而设计的rst_n为低电平有效
.inclk0 ( clk ),
.c0 ( c0 ),
.c1 ( c1 ),
.c2 ( c2 ),
.c3 ( c3 ),
.c4 ( c4 ),
.locked ( locked )
);
//ram_1port ram_1port_inst (
//.aclr ( ~rst_n ),//复位信号低电平有效,手册ram高电平有效
//.address ( address ),
//.clock ( inclk ),//选用100M时钟
//.data ( data ),
//.rden ( rden ),
//.wren ( wren ),
//.q ( q )
//);
ram_2port ram_2port_inst (
.data ( data ),
.rd_aclr ( ~rst_n ),
.rdaddress ( rdaddress ),
.rdclock ( c0),
.rden ( rden ),
.wraddress ( wraddress ),
.wrclock ( clk ),
.wren ( wren ),
.q ( q )
);
endmodule
测试文件:
`timescale 1ns/1ps
module test_tb();
reg rst_n ;
reg clk ;
reg [4:0] rdaddress ;
reg [4:0] wraddress ;
reg [7:0] data ;
reg wren ;
reg rden ;
wire[7:0] q ;
parameter CYCLE = 20;
test_ip u_test_ip (
.rst_n ( rst_n ),
.clk ( clk ),
.rdaddress ( rdaddress ),
.wraddress ( wraddress ),
.data ( data ),
.wren ( wren ),
.rden ( rden ),
.q ( q )
);
integer i ;//加入i个存储单位(字节),ram中设置的64个字节
initial begin
clk = 1'b1;
rst_n = 1'b1;
#(2*CYCLE);
rst_n = 1'b0;
//时钟复位后给所有信号一个初值
rdaddress = 0;
wraddress = 0;
data = 0 ;
wren = 0 ;
rden = 0 ;
//延迟5个周期释放
#(5*CYCLE);
rst_n = 1'b1;
#(CYCLE*10);//延迟10个时钟是为了打开时钟锁得到稳定的时钟信号
//写数据
for(i=0;i<32;i=i+1) begin
wren = 1'b1 ;
data = i + 1 ;//data给1到64
wraddress = i ;//地址给0到63刚好与data错开
#(CYCLE) ;//保证一个时钟周期写写完一个数据
end
wren = 1'b0 ;//写完数据拉低
#(5*CYCLE) ;
//读数据
for (i=0;i<32;i=i+1) begin
rden = 1'b1 ;
rdaddress = i ;//写数据读地址
#(CYCLE*2) ;//保证一个是时钟周期读完一个数据
end
rden = 1'b0 ;//读完数据拉低
#(20*CYCLE) ;
$stop;
end
always #(CYCLE/2) clk = ~clk ;//50M
endmodule
仿真
修改test.do文件内仿真:
补充
双端口也一样,根据具体引脚设置即可