一 、如何做
把时间当成横向坐标轴,在想要标记的时间节点打一个标记,并在这个时刻作出相应的动作。我在0.25s,0.5s,0.75s…直到2s为止,打了节点标记;我想让led在0.25s时刻亮,0.5s时刻亮,0.75s时刻灭,1s时刻亮…随便我怎么设置对应的动作,这里我想要led作出这样的样式:0100_1011。右边的低位是我想要在0.25s作出的动作…等等以此类推到最高位。
二 、代码
1. 设计代码
module Q3(
input rst_n,
input sys_clk,
input [7:0] ctrl,
output reg led
);
parameter time0_25=12_500_000;
reg [26:0] cnt;
reg [3:0] cnt2;
//第1个时钟
always@(posedge sys_clk)
if(!rst_n)
cnt<=0;
else if(cnt==time0_25-1)
cnt<=0;
else
cnt<=cnt+1;
//第2个时钟
always@(posedge sys_clk)
if(!rst_n)
cnt2<=0;
else if(cnt==time0_25-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
2. 仿真代码
`timescale 1ns / 1ps
module tb();
reg rst_n;
reg sys_clk;
reg [7:0] ctrl;
wire led;
wire cnt;
wire cnt2;
defparam q3.time0_25=125;
Q3 q3(
.rst_n (rst_n ) ,
.sys_clk(sys_clk) ,
.ctrl (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'b0100_1011;
end
endmodule
3. 仿真图

这里的图片可以看到,我的led是随着ctrl数组来改变的。在第一个单位时段,led为1…以此类推,完成了样式。
三 、我的高阻态 和 想尝试的参数化设计
我们都知道如果一块板子上的晶振是50M,那么就意味着,系统时钟1s最多可以震动50M次,那么我可以算出0.25s,晶振震动的频率。
定义的计数器 cnt,就是最基本的计数器。在记到0.25s的时候,会自动清零,并且触发到我的 2级 计数器cnt2,后果就是cnt2 此时会+1;这样就可以实现用cnt2来打标记,cnt2不同的数值会对应不同的 led 赋值语句。
仿真的时候,我觉得0.25s对应的12_500_000次太多,仿真跑得慢,因此我改小了 参数的值,变成125,但是因此我仿真之后,cnt 和 cnt2 都跑出了高阻态。
有懂这个问题的 想交流的可以留言 ,谢谢大家
我一开始12500_000,没有高阻态,现在我改小了,相当于从0.25s变成了2.5us。2.5us改变一次LED的状态,从 ctrl[0] 变到 ctrl[1]。
1万+

被折叠的 条评论
为什么被折叠?



