一、 看门狗简介
看门狗:也称看门狗定时器,是常见于系统的一种外设;看门狗似乎就是一条看门的狗,如果系统一切正常则看门狗不叫,如果程序不正常,则看门狗则会将程序咬死(即程序强制复位)。
看门狗的作用:当一段程序跑飞,卡死或不受控制时,能使得系统强制重启;
喂狗:当看门狗被初始化后,需要在程序中每进行一段时间就重置看门狗模块的定时器计数值,防止程序被咬死;
程序咬死:当程序出现问题时(跑飞或锁死),导致看门狗定时器的计数值没能及时重置,当计数值达到设置的阈值后,看门狗定时器则输出复位信号,使得CPU强制复位;
二、看门狗分类
硬件看门狗:看门狗实际上就是一个计数器,硬件看门狗就是以硬件实现的一种计数器,其可以集成在单片机,SOC等系统中,使用硬件看门狗不用消耗额外的软件资源;
软件看门狗:利用软件实现软件计数器,利用该计数器判断是否计数达到阈值,达到阈值则调用软件复位程序,常与定时器中断一起使用;
窗口看门狗:独立看门狗在0-重载值之间都可以进行喂狗操作,这样如果程序跑飞反复在喂狗,则程序无法复位;窗口看门狗则对喂狗的时间设置了阈值(上下限),喂狗操作只能在阈值间进行喂狗,其他时间喂狗都无效;
三、实现
`timescale 1ns / 1psmodule wtd #(parameter COUNTER_WIDTH = 16) (input ref_clk, //system reference clockinput nrst, //system reset signal, Valid: 1'b0input en, //system enable signal, Valid: 1'b1input [COUNTER_WIDTH - 1:0] up_threshold, //system upside thresholdoutput [COUNTER_WIDTH - 1:0] count, //system clock counteroutput wtd_rst
);/**************************wtd inner signal design**************************/reg [COUNTER_WIDTH - 1:0] count_r;wire rst_req;/**************************wtd inner signal connect**************************/assign rst_req = (count == up_threshold) ? 1'b1 : 1'b0;// 计数器assign count = count_r;always @(posedge ref_clk) beginif (~nrst) begincount_r <= 'b0;end else beginif (en) beginif (count_r < up_threshold) count_r <= count_r + 1'b1;else count_r <= count_r;end else begincount_r <= count_r;endendend//边沿检测reg din_dff;assign wtd_rst = (rst_req) & (~din_dff);always @(posedge ref_clk) beginif (~nrst) begindin_dff <= 0;end else begindin_dff <= rst_req;endendendmodule
tb代码
`timescale 1ns / 1psmodule wtd_tb; // wtd Parameters
parameter PERIOD = 10;
parameter COUNTER_WIDTH = 16;// wtd Inputs
reg clk = 0 ;
reg rst_n = 0 ;
reg en = 0 ;
reg [COUNTER_WIDTH - 1:0] up_threshold = 0 ;// wtd Outputs
wire [COUNTER_WIDTH - 1:0] count ;
wire wtd_rst ;initial
beginforever #(PERIOD/2) clk=~clk;
endinitial
beginup_threshold = 20;rst_n = 0;#(PERIOD*2) rst_n = 1;en = 1;endwtd #(.COUNTER_WIDTH ( COUNTER_WIDTH ))u_wtd (.ref_clk ( clk ),.nrst ( rst_n ),.en ( en ),.up_threshold ( up_threshold [COUNTER_WIDTH - 1:0] ),.count ( count [COUNTER_WIDTH - 1:0] ),.wtd_rst ( wtd_rst )
);initial
begin#10000 $finish;
endendmodule
另外为了方便看门狗产生的复位信号能够被采样会考虑增加脉冲扩展
代码写的比较简单,作为了解