verilog的复位问题

50s以后复位,复位宽度为10ms怎么做到啊

用一个比较笨但是非常好理解的办法,首先找到一个固定的时钟信号,比如说现在有一个时钟信号是1kHz的(可以通过对全局时钟进行计数分频得到),那么这个时钟周期就是1ms。
用一个always模块以这个1k的时钟作为敏感信号去做一个计数器,计数器能够覆盖到50s个数,那么50s就是计数到50s/1ms=50000个数,这个数据可以用一个16位的数表示,那么确定了计数器的宽度。然后判定从第50s时刻之后的10ms是复位信号,即判定计数器的值在50000~50010之间是输出复位信号高或低即可,有如下代码

reg [15:0] cnter; //计数器
always @(posedge clk_1k or posedge sys_rst)
begin
 if(sys_rst)
   cnter<=16'd0;
 else if(cnter<16'd65535)
  cnter<=cnter+16'd1;   //从0开始计数,直到65535(其实只要大于50000就可以)
 else
  cnter<=cnter; //计到最大之后停止
end

wire rst_10ms; //复位信号
assign rst_10ms=((cnter>16'd50000)&&(cnter<=16'd50010))?1'b0:1'b1;

模块端口声明省略未写
后续如果要优化资源占用可以降低敏感信号频率,这样计数器宽度可以缩小。

`timescale 1 ns/ 1 ns
module Top_tb();

defparam UUT.LCD12864.DIV = 'd10; //
reg clock ;
reg resetn;
////////////////////////////////////////////////////////
reg io_sdat_in;
wire io_adc_clk;
wire io_cs_n ;

////////////////////uart////////////////////////////////////
reg io_uart_rx;
wire io_uart_tx;

////////////////////lcd12864////////////////////////////////////
wire io_lcd_rs; //0是c,1是d寄存器
wire io_lcd_rw; //0读、1写操作选择输出信号
wire io_lcd_e ; //1到0写
wire io_lcd_psb ;
wire io_lcd_rstn;
wire [7:0]io_lcd_data;

Top UUT(
clock ,
resetn,
////////////////////TLC549////////////////////////////////////
io_sdat_in,
io_adc_clk,
io_cs_n ,

////////////////////uart////////////////////////////////////
io_uart_rx,
io_uart_tx,

////////////////////lcd12864////////////////////////////////////
io_lcd_rs, //0是c,1是d寄存器
io_lcd_rw, //0读、1写操作选择输出信号
io_lcd_e , //1到0写
io_lcd_psb ,
io_lcd_rstn,
io_lcd_data
);

localparam cp = 10; //t=20 ns
always #(cp/2) clock = ~clock;

initial
begin
//+++++++初始化+++++++++++++
clock = 0;
resetn = 0;
io_sdat_in= 0;
io_uart_rx = 0;
#(2cp);
resetn = 1;
repeat(31
6)//
@(posedge clock);
io_sdat_in = 1;
repeat(316)//
@(posedge clock);
io_sdat_in= 0;
//--------------------------
repeat(31
100)//
@(posedge clock);
$stop;
end
endmodule
这是激励代码