文章目录
1.呼吸灯设计
- 要求:完成呼吸灯设计,要求从亮到灭时间为2s,从灭到亮时间也为2s,完成一个完整的呼吸需要4s。
- 分析:需要产生一个逐渐改变占空比的方波,即PWM(脉冲宽度调制)。具体方案为:将2s平均分成1000份(即每份时长为2ms),第一份占空比为1000/1000,第二份占空比为999/1000,以此类推。能实现从亮到灭的过程,而从灭到亮则是其反过程。
1.1波形设计:
1.2代码设计与tb
1.2.1 代码
module breath_led(
input wire clk,
input wire rst,
output reg led
);
reg[9:0]pwm_cyc_cnt,cnt50m_1000;
reg[6:0]cnt50m;
reg flag;
parameter cnt50m_end=99;
parameter cnt50m_1000_end=999;
parameter pwm_cyc_cnt_end=999;
//cnt50m
always @(posedge clk) begin
if(rst==1'b1) begin
cnt50m<='d0;
end
else if (cnt50m==cnt50m_end) begin
cnt50m<='d0;
end
else
cnt50m<=cnt50m+1'b1;
end
//cnt50m_1000
always @(posedge clk) begin
if(rst==1'b1) begin
cnt50m_1000 <='d0;
end
else if (cnt50m==cnt50m_end&&cnt50m_1000==cnt50m_1000_end) begin
cnt50m_1000<='d0;
end
else if (cnt50m==cnt50m_end) begin
cnt50m_1000<=cnt50m_1000+1'b1;
end
end
// pwm_cyc_cnt
always @(posedge clk) begin
if(rst==1'b1) begin
pwm_cyc_cnt <= 'd0;
end
else if (cnt50m==cnt50m_end && cnt50m_1000==cnt50m_1000_end && pwm_cyc_cnt==pwm_cyc_cnt_end) begin
pwm_cyc_cnt <= 'd0;
end
else if (cnt50m==cnt50m_end&&cnt50m_1000==cnt50m_1000_end) begin
pwm_cyc_cnt <= pwm_cyc_cnt+1'b1;
end
end
//led_flag
always @(posedge clk) begin
if(rst==1'b1) begin
flag <= 'd0;
end
else if (cnt50m==cnt50m_end && cnt50m_1000==cnt50m_1000_end && pwm_cyc_cnt==pwm_cyc_cnt_end) begin
flag=~flag;
end
end
always @(posedge clk) begin
if(rst==1'b1) begin
led <='d0;
end
else if (flag==1'b0) begin
if (cnt50m_1000<pwm_cyc_cnt) begin
led<='d0;
end
else
led<='d1;
end
else if (flag==1'b1) begin
if (cnt50m_1000<pwm_cyc_cnt) begin
led<='d1;
end
else
led<='d0;
end
end
endmodule
1.2.2 tb
module tb_breath_led();
reg clk;
reg rst;
wire led;
initial begin
clk=0;
rst=1;
#100
rst=0;
end
always #10 clk=~clk;
breath_led inst_breath_led (
.clk (clk),
.rst (rst),
.led (led)
);
endmodule
1.3仿真
2.计数器实现奇数分频
- 要求:假设原时钟sclk周期为10ns,现要在sclk的基础上实现五分频时钟clk5
- 分析:clk5的周期为50ns,默认占空比为50%,则高电平持续25ns,低电平持续25ns。
2.1 波形设计:
这里主要注意一下关键部分:分别用时钟的上升沿和下降沿去采样,这样就能得到奇数倍的分频,代码部分比较简单,这里省略。
3.完成一个top_down设计
- 要求:实现pi_a、pi_b在4个clk周期内相与一次。
- 分析:这里涉及两个功能:分频和相与,因此可以将其划分成两个功能模块去实现。
模块框图:
3.1 波形设计:
3.2 代码与tb:
分频设计:
module div_clk (
input wire clk,
input wire rst,
output reg po_flag
);
reg[1:0] cnt;
always @(posedge clk) begin
if(rst==1'b1) begin
cnt <= 'd0;
end
else
cnt<=cnt+1'b1;
end
always @(posedge clk) begin
if(rst==1'b1) begin
po_flag<='d0;
end
else if (cnt=='d2) begin
po_flag<='d1;
end
else if (cnt=='d3) begin
po_flag<='d0;
end
end
endmodule
相与:
module a_and_b (
input wire clk, // Clock
input wire rst,
input wire pi_flag,
input wire pi_a,
input wire pi_b,
output reg po_c
);
always @(posedge clk) begin
if(rst==1'b1) begin
po_c <='d0;
end
else if (pi_flag==1'b1) begin
po_c<=pi_a & pi_b;
end
else
po_c<='d0;
end
endmodule
顶层设计
module top(
input wire clk, // Clock
input wire rst,
input wire pi_a,
input wire pi_b,
output wire po_c
);
wire po_flag;
div_clk inst_div_clk
(.clk(clk),
.rst(rst),
.po_flag(po_flag));
a_and_b inst_a_and_b
(.clk(clk),
.rst(rst),
.pi_flag(po_flag),
.pi_a(pi_a),
.pi_b(pi_b),
.po_c(po_c));
endmodule
tb
module tb_top();
reg clk;
reg rst;
reg pi_a;
reg pi_b;
wire po_c;
initial begin
clk=0;
rst=1;
#100
rst=0;
end
always #5 clk=~clk;
always #10 pi_a={$random};
always #10 pi_b={$random};
top inst_top
(.clk(clk),
.rst(rst),
.pi_a(pi_a),
.pi_b(pi_b),
.po_c(po_c));
endmodule
3.3 仿真
4.完成一个top_down设计(在3的基础上实现)
4.1 波形设计
4.2 代码与tb(这里主要是在四分频的基础上又进行了一次四分频,代码变动不大,故省略)
5.自动售货机(简易版)
- 要求:假设可乐3元一瓶,每次投币只能投入1元。完成设计和仿真
- 分析:涉及状态转换类的,一般需要有限状态机设计,需要画出状态转换图。
5.1 状态转换图
模块信号示意图:
5.2代码设计与tb
5.2.1 代码
module fsm(
input wire clk,
input wire rst,
input wire pi_money,
output reg po_cola
);
parameter IDLE=3'b001;
parameter ONE=3'b010;
parameter TWO=3'b100;
reg [2:0] state;
always @(posedge clk) begin
if(rst==1'b1) begin
state<=IDLE;
end
else case (state)
IDLE:begin
if (pi_money==1'b1) begin
state<=ONE;
end
else
state<=IDLE;
end
ONE:begin
if (pi_money==1'b1) begin
state<=TWO;
end
else
state<=ONE;
end
TWO:begin
if (pi_money==1'b1) begin
state<=IDLE;
end
else
state<=TWO;
end
default : state<=IDLE;
endcase
end
always @(posedge clk) begin
if(rst==1'b1) begin
po_cola <= 'd0;
end
else if (state==TWO && pi_money==1'b1) begin
po_cola<=1'b1;
end
else
po_cola<='d0;
end
endmodule
5.2.2 tb
module tb_sim();
reg clk;
reg rst;
reg pi_money;
wire po_cola;
initial begin
clk=0;
rst=1;
#30
rst=0;
end
always #5 clk=~clk;
always #10 pi_money={$random};
fsm inst_fsm (
.clk (clk),
.rst (rst),
.pi_money (pi_money),
.po_cola (po_cola)
);
endmodule
5.3仿真
6.自动售货机(复杂版)
6.1状态转换图
模块信号示意图
6.2代码设计与tb
6.2.1代码
module fsm (
input wire clk, // Clock
input wire rst,
input wire pi_money, // high:1元 , low:0.5元
output reg po_cola,
output reg po_money
);
parameter IDLE=5'b00001;
parameter HALF=5'b00010;
parameter ONE=5'b00100;
parameter ONE_HALF=5'b01000;
parameter TWO=5'b10000;
reg [4:0] state;
always @(posedge clk) begin
if(rst==1'b1) begin
state <= IDLE;
end
else case (state)
IDLE:begin
if(pi_money==1'b1)
state<=ONE;
else
state<=HALF;
end
HALF:begin
if (pi_money==1'b1) begin
state<=ONE_HALF;
end
else
state<=ONE;
end
ONE:begin
if (pi_money==1'b1) begin
state<=TWO;
end
else
state<=ONE_HALF;
end
ONE_HALF:begin
if (pi_money==1'b1) begin
state<=IDLE;
end
else
state<=TWO;
end
TWO:begin
state<=IDLE;
end
default : state<=IDLE;
endcase
end
always @(posedge clk) begin
if(rst==1'b1) begin
po_cola <= 'd0;
end
else if (state==ONE_HALF && pi_money==1'b1) begin
po_cola<=1'b1;
end
else if (state==TWO) begin
po_cola<=1'b1;
end
else
po_cola<='d0;
end
always @(posedge clk) begin
if(rst==1'b1) begin
po_money <='d0;
end
else if (state==TWO && pi_money==1'b1) begin
po_money<='d1;
end
else
po_money<='d0;
end
endmodule
6.2.2tb
module tb_sim();
reg clk;
reg rst;
reg pi_money;
wire po_cola;
wire po_money;
initial begin
clk=0;
rst=1;
#30
rst=0;
end
always #5 clk=~clk;
always #10 pi_money={$random};
fsm inst_fsm (
.clk (clk),
.rst (rst),
.pi_money (pi_money),
.po_cola (po_cola),
.po_money (po_money)
);
endmodule
6.3 仿真
7.按键消抖设计
按键模型:
理想按键波形:
实际按键波形:
按键消抖设计思想:
由于clk是ns级别,而按键一般是ms级别,因此clk会采集到非常多次key,如果不进行按键消抖,则会被认为按下了很多次按键。从实际按键波形图可以看到,按下一次按键key后会经历:前抖动→较长时间的低电平→后抖动,因此我们可以给出这样的设计方式:
当key低电平持续时间为5~10ms的时候,可以给出一个标志,此标志意味着一次按键按下。
7.1 按键消抖波形设计
7.2代码与tb
7.2.1代码
module key_debounce(
input wire clk,
input wire rst,
input wire key,
output reg po_key_flag
);
reg [17:0]cnt;
reg cnt_flag;
parameter cnt_mux=250000-1;
always @(posedge clk) begin
if(rst==1'b1) begin
cnt <= 'd0;
end
else if (key==1'b0) begin
cnt<=cnt+1'b1;
end
else
cnt<='d0;
end
always @(posedge clk) begin
if(rst==1'b1) begin
cnt_flag <= 'd0;
end
else if (cnt==cnt_mux) begin
cnt_flag<='d1;
end
else if (cnt_flag==1'b1 && key==1'b1) begin
cnt_flag<='d0;
end
end
always @(posedge clk) begin
if(rst==1'b1) begin
po_key_flag <= 'd0;
end
else if (cnt==cnt_mux && cnt_flag==1'b0) begin
po_key_flag<='d1;
end
else
po_key_flag<='d0;
end
endmodule
7.2.2 tb
module tb_key_debounce();
parameter CLK_PERIOD=20;
reg clk;
reg rst;
reg key;
wire po_key_flag;
key_debounce inst_key_debounce
(.clk(clk),
.rst(rst),
.key(key),
.po_key_flag(po_key_flag)
);
initial begin
clk=0;
rst=1;
#30
rst=0;
end
always #((CLK_PERIOD/2)) clk=~clk;
initial begin
//前抖
key = 0;
#200;
key = 1;
#200;
key = 0;
#500;
key = 1;
#200;
key = 0;
#1000; //1ms
key = 1;
//按键持续
#200;
key = 0;
#13000; //13ms
key = 1;
//后抖
#200
key=0;
#200
key=1;
#200
key=0;
end
endmodule
7.3仿真
8 按键控制自动售货机设置
要求:
分析,这里共涉及这几个模块:
1.fsm模块负责实现自动售货机的状态跳转。
2.两个流水灯模块:led_water_sigle 和led_water_double。
3.按键消抖模块
4.顶层top模块
8.1 系统构架框图
8.2状态转换图
8.3 波形图
8.3.1 状态机模块波形:
8.3.2 Led_water_sigle波形:
8.3.3 Led_water_double波形:
8.4 代码部分
8.4.1 fsm
module fsm (
input wire clk, // Clock
input wire rst,
input wire key_1, //5毛
input wire key_2, //1元
input wire [3:0]led1,
input wire [3:0]led2,
output reg [3:0]led
);
parameter IDLE=7'b0000001;
parameter HALF=7'b0000010;
parameter ONE=7'b0000100;
parameter ONE_HALF=7'b0001000;
parameter TWO=7'b0010000;
parameter LED1=7'b0100000;
parameter LED2=7'b1000000;
parameter END_10S = 500000000-1;
reg[6:0]state;
reg[28:0] cnt_10;
always @(posedge clk) begin
if(rst==1'b1) begin
state <= IDLE;
end
else case (state)
IDLE:begin
if (key_1==1'b1) begin
state<=HALF;
end
else if (key_2==1'b1) begin
state<=ONE;
end
end
HALF:begin
if (key_1==1'b1) begin
state<=ONE;
end
else if (key_2==1'b1) begin
state<=ONE_HALF;
end
end
ONE:begin
if (key_1==1'b1) begin
state<=ONE_HALF;
end
else if (key_2==1'b1) begin
state<=TWO;
end
end
ONE_HALF:begin
if (key_1==1'b1) begin
state<=TWO;
end
else if (key_2==1'b1) begin
state<=LED1;
end
end
TWO:begin
if (key_1==1'b1) begin
state<=LED1;
end
else if (key_2==1'b1) begin
state<=LED2;
end
end
LED1:begin
if (cnt_10==END_10S) begin
state<=IDLE;
end
end
LED2:begin
if (cnt_10==END_10S) begin
state<=IDLE;
end
end
default : state<=IDLE;
endcase
end
//cnt_10
always @(posedge clk) begin
if(rst==1'b1) begin
cnt_10 <= 'd0;
end
else if (cnt_10==END_10S) begin
cnt_10<='d0;
end
else if (state==LED1 || state==LED2) begin
cnt_10<=cnt_10+1'b1;
end
end
// led
always @(posedge clk) begin
if(rst==1'b1) begin
led<= 4'b0000;
end
else case (state)
IDLE:led<=4'b0000;
HALF:led<=4'b0001;
ONE:led<=4'b0010;
ONE_HALF:led<=4'b0100;
TWO:led<=4'b1000;
LED1:led<=led1;
LED2:led<=led2;
default :led<=4'b0000;
endcase
end
endmodule
8.4.2 led_water_sigle
module led_water_sigle(
input wire clk,
input wire rst,
output reg [3:0] led
);
parameter CNT_END=12500000-1;
reg[23:0]cnt;
reg shift_flag;
//cnt
always @(posedge clk) begin
if(rst==1'b1) begin
cnt <= 'd0;
end
else if (cnt==CNT_END) begin
cnt<='d0;
end
else
cnt<=cnt+1'b1;
end
// shift_flag
always @(posedge clk) begin
if(rst==1'b1) begin
shift_flag <= 'd0;
end
else if (cnt==CNT_END) begin
shift_flag<='d1;
end
else
shift_flag<='d0;
end
//led
always @(posedge clk) begin
if(rst==1'b1) begin
led<= 4'b0001;
end
else if (shift_flag==1'b1) begin
led<={led[2:0],led[3]};
end
end
endmodule
8.4.3 led_water_double
module led_water_double(
input wire clk,
input wire rst,
output reg [3:0] led
);
parameter CNT_END=12500000-1;
reg[23:0]cnt;
reg shift_flag;
reg L_shift_flag;
//cnt
always @(posedge clk) begin
if(rst==1'b1) begin
cnt <= 'd0;
end
else if (cnt==CNT_END) begin
cnt<='d0;
end
else
cnt<=cnt+1'b1;
end
// shift_flag
always @(posedge clk) begin
if(rst==1'b1) begin
shift_flag <= 'd0;
end
else if (cnt==CNT_END) begin
shift_flag<='d1;
end
else
shift_flag<='d0;
end
// L_shift_flag
always @(posedge clk) begin
if(rst==1'b1) begin
L_shift_flag <='d0;
end
else if (led==4'b0001) begin
L_shift_flag<='d1;
end
else if (led==4'b1000) begin
L_shift_flag<='d0;
end
end
//led
always @(posedge clk) begin
if(rst=='d1) begin
led<= 4'b0001;
end
else if (L_shift_flag==1'b1 && shift_flag==1'b1) begin
led<={led[2:0],led[3]};
end
else if (L_shift_flag==1'b0 && shift_flag==1'b1) begin
led<={led[0],led[3:1]};
end
end
endmodule
8.4.4 key_debounce
module key_debounce(
input wire clk,
input wire rst,
input wire key,
output reg po_key_flag
);
reg [17:0]cnt;
reg cnt_flag;
parameter cnt_mux=250000-1;
always @(posedge clk) begin
if(rst==1'b1) begin
cnt <= 'd0;
end
else if (key==1'b0) begin
cnt<=cnt+1'b1;
end
else
cnt<='d0;
end
always @(posedge clk) begin
if(rst==1'b1) begin
cnt_flag <= 'd0;
end
else if (cnt==cnt_mux) begin
cnt_flag<='d1;
end
else if (cnt_flag==1'b1 && key==1'b1) begin
cnt_flag<='d0;
end
end
always @(posedge clk) begin
if(rst==1'b1) begin
po_key_flag <= 'd0;
end
else if (cnt==cnt_mux && cnt_flag==1'b0) begin
po_key_flag<='d1;
end
else
po_key_flag<='d0;
end
endmodule
8.4.5 top_key_ctrl_fsm
module top_key_ctrl_fsm(
input wire clk,
input wire rst,
input wire key1,
input wire key2,
output wire[3:0] led
);
wire key_flag1;
wire key_flag2;
wire [3:0]led1;
wire [3:0]led2;
fsm inst_fsm (
.clk (clk),
.rst (rst),
.key_1 (key_1),
.key_2 (key_2),
.led1 (led1),
.led2 (led2),
.led (led)
);
led_water_sigle inst_led_water_sigle (
.clk(clk),
.rst(rst),
.led(led1));
led_water_double inst_led_water_double (
.clk(clk),
.rst(rst),
.led(led2));
key_debounce inst_key1_debounce
(.clk(clk),
.rst(rst),
.key(key1),
.po_key_flag(key_flag1));
key_debounce inst_key2_debounce
(.clk(clk),
.rst(rst),
.key(key2),
.po_key_flag(key_flag2));
endmodule
9.对ram进行基础的读写操作
- 要求:写出对 ram 控制的 Verilog HDL 代码,要求对该 ram 进行整体的读写交替进行(乒乓操作),要求实现的波形效果如下。
- 分析:可以看到rd_data和rd_addr之间存在一拍延时,因此在ip核参数选择时需要注意。
- ip参数设置如下:
9.1代码与tb
9.1.1 ctrl_ram
module ctrl_ram(
input wire clk,
input wire rst,
input wire [7:0] wr_data,
output wire [7:0] rd_data
);
reg wr_en;
reg [7:0] wr_addr;
reg [7:0] rd_addr;
// wr_en
always @(posedge clk) begin
if(rst==1'b1) begin
wr_en <= 'd1;
end
else if (wr_addr=='d255) begin
wr_en<='d0;
end
else if (rd_addr=='d255) begin
wr_en<='d1;
end
end
//wr_addr
always @(posedge clk) begin
if(rst==1'b1) begin
wr_addr <= 'd0;
end
else if (wr_en==1'b1) begin
wr_addr<=wr_addr+1'b1;
end
else
wr_addr<='d0;
end
//rd_addr
always @(posedge clk) begin
if(rst==1'b1) begin
rd_addr<= 'd0;
end
else if (wr_en=='d0) begin
rd_addr<=rd_addr+1'b1;
end
else
rd_addr<='d0;
end
ram_r8x256_w8x256 ram_r8x256_w8x256_inst (
.clka(clk), // input wire clka
.wea(wr_en), // input wire [0 : 0] wea
.addra(wr_addr), // input wire [7 : 0] addra
.dina(wr_data), // input wire [7 : 0] dina
.clkb(clk), // input wire clkb
.addrb(rd_addr), // input wire [7 : 0] addrb
.doutb(rd_data) // output wire [7 : 0] doutb
);
endmodule
9.1.2 tb
module tb_ctrl_ram();
reg clk;
reg rst;
reg [7:0] wr_data;
wire [7:0] rd_data;
initial begin
clk=0;
rst=1;
wr_data='d0;
#30
rst=0;
end
always #5 clk=~clk;
always #20 wr_data={$random}%255;
ctrl_ram inst_ctrl_ram (
.clk(clk),
.rst(rst),
.wr_data(wr_data),
.rd_data(rd_data));
endmodule
9.2 仿真效果
10. ram的乒乓操作
- 要求:调用两个异步双口 RAM,读写时钟都设置 100Mhz,两个 RAM 为 RAMA 和RAMB,深度为 1024 ,位宽为8bit,写入数据为 8bit@100Mhz 持续数据流,当 RAMA被写入 1024 字节数据后切换到写 RAMB,RAMB 被写入 1024 字节后切换 RAMA以此循环类推。
当 RAMA 被写入 1024 字节时,给读时序提供一个启动信号读取 RAMA 的数据,读取完 RAMA 的 1024 字节数据时,切换读 RAMB 以此类推。写入 RAMA和B的数据是 0~255 递增的数据。
两个 RAM 的交替读写操作我们称之为乒乓操作
10.1 波形设计
ram ip核的参数情况:
10.2代码与tb
10.2.1 ctrl_ram
module ctrl_ram(
input wire clk,
input wire rst,
input wire [7:0] pi_data,
output wire [7:0] po_data
);
reg wr_en_A,wr_en_B;
reg [9:0] wr_addr_A,wr_addr_B;
reg [9:0] rd_addr_A,rd_addr_B;
wire [7:0] po_data_A;
wire [7:0] po_data_B;
assign po_data=(wr_en_A==1'b1)?po_data_B:po_data_A;
//wr_en_A
always @(posedge clk) begin
if(rst==1'b1) begin
wr_en_A <= 'd1;
end
else if (wr_addr_A=='d1023) begin
wr_en_A<='d0;
end
else if (wr_addr_B=='d1023) begin
wr_en_A<='d1;
end
end
//wr_en_B
always @(posedge clk) begin
if(rst==1'b1) begin
wr_en_B <= 'd0;
end
else if (wr_addr_A=='d1023) begin
wr_en_B<='d1;
end
else if (wr_addr_B=='d1023) begin
wr_en_B<='d0;
end
end
// wr_addr_A
always @(posedge clk) begin
if(rst==1'b1) begin
wr_addr_A<= 'd0;
end
else if (wr_en_A==1'b1) begin
wr_addr_A<=wr_addr_A+1'b1;
end
else
wr_addr_A<='d0;
end
// wr_addr_B
always @(posedge clk) begin
if(rst==1'b1) begin
wr_addr_B <= 'd0;
end
else if (wr_en_B=='b1) begin
wr_addr_B<=wr_addr_B+1'b1;
end
else
wr_addr_B<='d0;
end
// rd_addr_A
always @(posedge clk) begin
if(rst==1'b1) begin
rd_addr_A <= 'd0;
end
else if (wr_en_A==1'b0) begin
rd_addr_A<=rd_addr_A+1'b1;
end
else
rd_addr_A<='d0;
end
// rd_addr_B
always @(posedge clk) begin
if(rst==1'b1) begin
rd_addr_B<= 'd0;
end
else if (wr_en_B==1'b0) begin
rd_addr_B<=rd_addr_B+1'b1;
end
else
rd_addr_B<='d0;
end
ram_w8x1024_r8x1024 ram_w8x1024_r8x1024_A (
.clka(clk), // // input wire clka
.wea(wr_en_A), // input wire [0 : 0] wea
.addra(wr_addr_A), // input wire [9 : 0] addra
.dina(pi_data), // input wire [7 : 0] dina
.clkb(clk), // // input wire clkb
.addrb(rd_addr_A), // input wire [9 : 0] addrb
.doutb(po_data_A) // output wire [7 : 0] doutb
);
ram_w8x1024_r8x1024 ram_w8x1024_r8x1024_B (
.clka(clk), // // input wire clka
.wea(wr_en_B), // input wire [0 : 0] wea
.addra(wr_addr_B), // input wire [9 : 0] addra
.dina(pi_data), // input wire [7 : 0] dina
.clkb(clk), // // input wire clkb
.addrb(rd_addr_B), // input wire [9 : 0] addrb
.doutb(po_data_B) // output wire [7 : 0] doutb
);
endmodule
10.2.2 tb
module tb_ctrl_ram();
reg clk;
reg rst;
reg [7:0] pi_data;
wire [7:0] po_data;
initial begin
clk=0;
rst=1;
pi_data='d0;
#100
rst=0;
end
always #5 clk=~clk;
initial begin
#100
gen_data();
end
task gen_data;
integer i;
begin
for ( i = 1; i < 7000; i=i+1) begin
@(posedge clk);
pi_data=i[7:0];
end
end
endtask
ctrl_ram inst_ctrl_ram (
.clk(clk),
.rst(rst),
.pi_data(pi_data),
.po_data(po_data));
endmodule
10.3 仿真
RAM的交替读写情况:
ram写细节:
ram读细节: