一 、怎么做
让一个灯刚开始以0.1s的频率亮灭;再以0.2s的频率亮灭。亮灭的模式是1001,还是1100,全都由自己指定。之前项目里面都是有一开始指定的参数决定亮灭之间的间隔,现在把间隔时间作为一个输入端口,来增加自由度,之后调试可以改变灯的亮灭频率。
二 、
1.设计代码
module Q4(
input rst_n,
input sys_clk,
input [7:0] ctrl,
input [31:0] time_ctrl,//控制时间长短的端口
output reg led
);
reg [31:0] cnt;
reg [3:0] cnt2;
//第1个时钟
always@(posedge sys_clk)
if(!rst_n)
cnt<=0;
else if(cnt==time_ctrl-1)
cnt<=0;
else
cnt<=cnt+1;
//第2个时钟
always@(posedge sys_clk)
if(!rst_n)
cnt2<=0;
else if(cnt==time_ctrl-1)
cnt2<=cnt2+1;
else if(cnt2==8)
cnt2<=0;
else
cnt2<=cnt2;
///条件语句
always@(posedge sys_clk)
if(!rst_n)
led<=0;
else
case(cnt2)
0:led<=ctrl[0];
1:led<=ctrl[1];
2:led<=ctrl[2];
3:led<=ctrl[3];
4:led<=ctrl[4];
5:led<=ctrl[5];
6:led<=ctrl[6];
7:led<=ctrl[7];
default:led<=0;
endcase
endmodule
设计代码对应设计思想,加上了调节时间对应的端口 time_ctrl , 测试的时候可以给时间端口赋值,相当于从其他设备传过来的时间。
2.仿真代码
`timescale 1ns / 1ps
module tb();
reg rst_n;
reg sys_clk;
reg [7:0] ctrl;
reg [31:0] time_ctrl;
wire led;
wire cnt;
wire cnt2;
Q4 q4(
.rst_n (rst_n ) ,
.sys_clk(sys_clk) ,
.ctrl (ctrl ) ,
.time_ctrl(time_ctrl) ,
.led (led )
);
//时钟///
initial begin
sys_clk=0;
forever #10 sys_clk=~sys_clk;
end
//复位
initial begin
rst_n=0;
#40 rst_n=1;
end
//ctrl///
initial begin
ctrl=8'd0;
# 100 ctrl=8'b1100_0101;
end
//time_ctrl//
initial begin
time_ctrl=32'd0;
#150 time_ctrl=32'd50_000;
#10_000_000 time_ctrl=32'd100_000;
end
endmodule
仿真的 time_ctrl 开始为0;延时150ns后为50_000, 也就是1ms变一次led的 0 1 值;再延时 10 ms 后,将时间间隔改成 100_000 ,2ms改变一次led 的 0 1 值。
3.仿真图
4.仿真分析
由图可以看出,第一个marker和第二个marker之间相隔一毫秒。第一个marker到第三个marker是完整的一个信号传输周期。
从第三个marker到第四个marker之间仍是在 以一毫秒为变化频率 的信号传输周期内。
从第四个marker之后,就切换成了以两毫秒为频率切换。
在两毫秒的频率传输信号的周期里,第三个到第四个marker之间传输的为1 0 。第四个marker到第五个marker传输的是 1 。
从这里可以看出,这个高电平已经比之前的高电平多了一倍的时间。后面接着传输00_0011。到最后一个marker以2ms为频率传输的一个完整周期已经完成。