verilog入门3——计数器

这个程序的仿真是废了好大的劲
主要原因就是用always #()产生时钟时序总是报错,或者在ism中没有clk的波形。
解决方法就是用forever #10 clk=~clk;
那么还有一个就是赋初始值的时候,可以用多个initial begin-end 比如可以在一个initial结构中做clk,另一个时序做rst_n。
介绍程序的作用:
有时钟50M,周期20ns。led是输出,每500ms变化一次,那么500ms/20ns=25000000个周期。

下面给出代码

module counter(clk50M,rst_n,led
    );
  input clk50M,rst_n;
  output reg led;//always中一定要用reg
  reg [24:0] cnt;  //是根据计数25000000的二进制决定的
  always@(posedge clk50M or negedge rst_n)
  begin
  if (rst_n == 1'b0)
   cnt <= 25'd0;
   else if (cnt == 25'd9)
    cnt <= 25'd0;
  else
   cnt <= cnt + 1'b1;
  end 
  always@(posedge clk50M or negedge rst_n)
  begin
  if (rst_n == 1'b0)
   led <= 1'b1;
  else if (cnt == 25'd9)//由于仿真时间问题就把24999999改成9
   led<=~led;
  else
   led<=led;
  end
endmodule

下面是仿真:

`timescale 1ns / 1ps
module counter_tb;
 // Inputs
 reg clk50M; //加载激励源
 reg rst_n;
 // Outputs
 wire led;
 // Instantiate the Unit Under Test (UUT)
 counter uut (
  .clk50M(clk50M),  //端口的连接
  .rst_n(rst_n), 
  .led(led)
 );
 //用于生成50M时钟
 initial begin
  clk50M = 0;
  rst_n = 0;
 forever  #10 
  clk50M = ~clk50M;
 end  
 initial begin
  #100;  //延时产生复位信号
  rst_n= 1;
 end  
endmodule

看一下波形:
verilog入门3——计数器_第1张图片
起初,复位有效,led为高,之后复位无效,9个clk50M产生一个cnt=9,从而led翻转,之后cnt归零。
下面看一下原理图:
verilog入门3——计数器_第2张图片

verilog入门3——计数器_第3张图片
同样的,这个也可以用vhdl写
但是仿真不对,我再想想.

你可能感兴趣的:(verilog)