计时(微秒、毫秒、秒)脉冲的产生verilog

计时(微秒、毫秒、秒)脉冲的产生

在SoC设计中,有时需要产生微秒、毫秒或者秒脉冲。设计一个定时器电路可以供其他电路使用,以降低逻辑资源消耗。
整体思路是,假如输入时钟为100M,则每个时钟周期为10ns,则1us的脉冲可以计数100次。1ms的脉冲可以利用1us的脉冲计数1000次,1s的脉冲可以利用1ms的脉冲计数1000次。
语言:verilog
环境:modelsim10.4
模块代码如下所示:

module timetick_gen(clk_100,reset,us_tick,ms_tick,sec_tick);
input clk_100,reset;
output us_tick,ms_tick,sec_tick;

reg [7:0] us_counter;
wire [7:0] us_counter_nxt;
reg us_tick;
wire us_tick_nxt;

reg [9:0] ms_counter,ms_counter_nxt;
reg ms_tick;
wire ms_tick_nxt;

reg [9:0] sec_counter;
wire[9:0] sec_counter_nxt;
reg sec_tick;
wire sec_tick_nxt;

assign us_counter_nxt = (us_counter == 'd99)?'d0:(us_counter + 1'b1);
assign us_tick_nxt = (us_counter == 'd99);
always@(*)begin
 ms_counter_nxt = ms_counter;
 if(us_tick)begin
  if(ms_counter == 'd999) ms_counter_nxt = 'd0;
  else ms_counter_nxt = ms_counter_nxt + 1;
 end
end

assign ms_tick_nxt = (ms_counter == 'd999);
assign sec_counter_nxt = ms_tick?((sec_counter == 'd999)?'d0:(sec_counter + 1)):sec_counter;
assign sec_tick_nxt = (sec_counter == 'd999);

always@(posedge clk_100 or negedge reset)begin
 if(!reset)begin
  us_counter <= 'd0;
  ms_counter <= 'd0;
  sec_counter <= 'd0;
  us_tick <= 'd0;
  ms_tick <= 'd0;
  sec_tick <= 'd0;
 end
 else begin
  us_counter <= us_counter_nxt;
  ms_counter <= ms_counter_nxt;
  sec_counter <= sec_counter_nxt;
  us_tick <= us_tick_nxt;
  ms_tick <= ms_tick_nxt;
  sec_tick <= sec_tick_nxt;
 end
end

endmodule

测试代码如下:

`timescale 1ns/1ns
module testbench;
reg clk_100_tb;
reg reset_tb;
wire us_tick_tb,ms_tick_tb,sec_tick_tb;

parameter CLK_HALF_PERIOD = 5;

initial begin
 clk_100_tb = 0;
 forever #CLK_HALF_PERIOD clk_100_tb = ~clk_100_tb;
end

initial begin
 reset_tb = 0;
 #100 reset_tb = 1'b1;
end

timetick_gen    timetick_gen_test
  (.clk_100(clk_100_tb),
  .reset(reset_tb),
  .us_tick(us_tick_tb),
  .ms_tick(ms_tick_tb),
  .sec_tick(sec_tick_tb));
  
endmodule

仿真结果如下:
计时(微秒、毫秒、秒)脉冲的产生verilog_第1张图片

你可能感兴趣的:(计时(微秒、毫秒、秒)脉冲的产生verilog)