1计数器
//计数器
module counter(clk,cnt);
input clk;
//写位宽是为了使得传输正常。以下为个人理解:
//信号传输无非就三种情况:
//一是:信号与所连接的线网或传输的寄存器变量的位宽一致
//这样是可以保证信号传输正常的。
//二是:信号比所连接的线网或传输的寄存器变量的位宽大
//这样信号的高位数据将会被裁掉。
//三是:信号比所连接的线网或传输的寄存器变量的位宽小
//这样后者的高位就会扩展为全0或全1.
//总结:在赋值过程中等号右端大则截位,位宽少则补0或1(0无符号时,1有符号时)
//如果不写位宽导致在进行spyglass语法检查和编译器编译时报warning甚至可能为error
//所以在对输入输出信号以及信号类型描述时是有必要需要添加位宽的.
output reg [3:0] cnt = 0;//[3:0]位宽指计数2^4=16,即计数0-15
always@(posedge clk)
begin
if(cnt < 10)
cnt <= cnt + 1;
else
cnt <= cnt;
end
endmodule
复位信号:只要复位信号来,所有信号回复到初始值
标题计数器的应用
1.计时间
采用50mhz的时钟进行0.5s的时间计数
T=1/50MHZ=20ns cnt=0.5s/20ns=25000000
参数设置
定义参数parameter t= 25000000
locapramt=25000000
`define t 25000000
前面两个是局部参数 后面``define是全局都可以用
错误分析
输入端口“cnt”不能用类型“<变量数据类型,例如reg>”声明
没有定义led_n的类型 端口设置得定义
2.分频
2.1偶数分频
把50mhz时钟变成5mhz(频率缩小十倍,周期T扩大十倍)
设计架构:
代码
module div_freq(clk,rst_n,clk_out);
input clk;
input rst_n;
output reg clk_out;
parameter t = 50_000_000/5_000_000/2-1;//计数周期
reg [2:0] cnt;//2^3=8>4,所以输出cnt位宽选[2:0]
//计数器模块编写
always@(posedge clk,negedge rst_n)
begin
if(!rst_n)
cnt <= 0;//如果复位,计数器为0
clk_out <= 0
else
if(cnt < t)
cnt <= cnt + 1;//小于t时 计数器循环一次加1
else
cnt <= 0;//大于t时,停止计数
end
//功能模块编写
always@(posedge clk,negedge rst_n)
begin
if(!rst_n)
clk_out <= 0; else
if(cnt < t)
clk_out <= clk_out ;
else
clk_out <= ~clk_out;
end
endmodule
仿真窗口多开了,关掉一个即可
modesim仿真报错:出现在12行代码
实际上是未将测试文件设置为testbench
找到上/下降沿,在仿真里面
先鼠标点击所选端口,再用下面来找clk的上升沿
鼠标点击锁定确定红色线
点击绿色加号产生新的线