Mario875
Newbie level 4
Hi all,
I have created some verilog code to lock onto the output signal of a device and make a new signal with a greater pulse width. Now when I have the device powered on and I program the FPGA it locks on 100% of the time, no issues.
However, if I reset the device, but do not re-program the FPGA, I lose the lock (as expected), so I created a 'watchdog' reset that will essentially reset the IP and allow it to re-lock again. If I attach the 'reset_db' signal to an external push button, it works perfectly in that resetting the device loses the lock, but when I press the push button, the IP resets and re-locks as expected.
I thought, that's great, now let me try and automate the reset with a watchdog timer, code (with comments) below, and the strange thing is that when I simulate it, the code works as expected, but when I implement it, it just doesn't, almost as if some of the counters or states are not being properly reset.
Essentially the watchdog is clocked by the FPGA 100MHz clock and if the device is enabled, one of the signals resets the watchdog every 100us, but when the device is reset the signal will go low for 500ms and the watchdog timer is set to only 10ms, so when that happens the FPGA should hold the reset value high, then when the device comes back on and reset is held high, all states and counters will be reset, once that happens (hbstate==boot) then the reset signal is asserted low and the watchdog counter reset for it to repeat.
It just doesn't work and the output signals end up totally out of sync, but when I use a push button to manually reset instead of the watchdog counter, it works as expected??
I have even tried the modified code as below, adding a 750ms delay after hbstate changes to 'boot' but still the exact same issue. Again, when I comment out the code in the 1st always block and use a push button to enable reset_db, it works fine?! What is going on??
I have created some verilog code to lock onto the output signal of a device and make a new signal with a greater pulse width. Now when I have the device powered on and I program the FPGA it locks on 100% of the time, no issues.
However, if I reset the device, but do not re-program the FPGA, I lose the lock (as expected), so I created a 'watchdog' reset that will essentially reset the IP and allow it to re-lock again. If I attach the 'reset_db' signal to an external push button, it works perfectly in that resetting the device loses the lock, but when I press the push button, the IP resets and re-locks as expected.
I thought, that's great, now let me try and automate the reset with a watchdog timer, code (with comments) below, and the strange thing is that when I simulate it, the code works as expected, but when I implement it, it just doesn't, almost as if some of the counters or states are not being properly reset.
Essentially the watchdog is clocked by the FPGA 100MHz clock and if the device is enabled, one of the signals resets the watchdog every 100us, but when the device is reset the signal will go low for 500ms and the watchdog timer is set to only 10ms, so when that happens the FPGA should hold the reset value high, then when the device comes back on and reset is held high, all states and counters will be reset, once that happens (hbstate==boot) then the reset signal is asserted low and the watchdog counter reset for it to repeat.
It just doesn't work and the output signals end up totally out of sync, but when I use a push button to manually reset instead of the watchdog counter, it works as expected??
Code:
.
.
.
reg [1:0] hbstate=2'b00, vbstate=2'b00; //initialise states to 0
reg reset_db=0; //initialise reset to 0
integer hbcnt=0, hbbootcnt=0, vbcnt=0, vbbootcnt=0, watchdog=1000000; //counters, values initialised as required, 1000000 for watchdog = 10ms
always @ (posedge clock) //FPGA clock
begin
watchdog<=watchdog-1;
if(ps2_hblank==1 && watchdog>=1) watchdog<=1000000; //if signal from device is present (square wave with 100us period) and watchdog is present, reset watchdog timer
else if(ps2_hblank==0 && watchdog<=0) //if signal is lost (drops for 500ms during a reset), and watchdog counter is less than or equal to 0 (10ms has elapsed), begin the reset
begin
reset_db<=1; //turn on reset
if(hbstate==boot) //if 1 of the states has reset (indicating the device has powered back on, as it is reliant on the devices own clock)
begin
watchdog<=1000000; //set watchdog timer to 10ms again
reset_db<=0; //turn off reset
end
end
end
always @ (posedge ps2_vclk) //device clock
begin
if(reset_db==1) //if reset is equal to 1, reset all counters and status' as below
begin
hbstate<=boot;
hbcnt<=0;
hbbootcnt<=0;
vbstate<=boot;
vbcnt<=0;
vbbootcnt<=0;
end
.
.
.
I have even tried the modified code as below, adding a 750ms delay after hbstate changes to 'boot' but still the exact same issue. Again, when I comment out the code in the 1st always block and use a push button to enable reset_db, it works fine?! What is going on??
Code:
.
.
.
reg [1:0] hbstate=2'b00, vbstate=2'b00, wdstate=2'b00;
reg reset_db=0;
integer hbcnt=0, hbbootcnt=0, vbcnt=0, vbbootcnt=0, watchdog=0, wdcnt=0;
always @ (posedge clock)
begin
watchdog<=watchdog+1;
case(wdstate)
boot : begin
if (ps2_hblank==1 && watchdog<=1000000) watchdog<=0;
else if(watchdog>=1000001) wdstate<=start;
end
start : begin
reset_db<=1;
if(hbstate==boot)
begin
wdcnt<=wdcnt+1;
if(wdcnt>=75000000)
begin
watchdog<=0;
wdcnt<=0;
reset_db<=0;
wdstate<=boot;
end
end
end
endcase
end
always @ (posedge ps2_vclk)
begin
if(reset_db==1)
begin
hbstate<=boot;
hbcnt<=0;
hbbootcnt<=0;
vbstate<=boot;
vbcnt<=0;
vbbootcnt<=0;
end
case(hbstate)
.
.
.