I want to sample an external, possibly very short interrupt signal in my FPGA softcore. I did some research in some digital logic design books, and found this solution, where A is the input signal. The problem here is that it is way too short to be sampled by the synchronous flipflop shown, so a latch is used:
I am now wondering how this can be implemented in Verilog for use in a FPGA, I do not know how to tell the synthesis tool to place a latch there. How can this be done? Also, the design doesn't show how to reset Q - in the plot, it stays high for the rest of the example. How do I reset the whole design to be ready for the next interrupt signal?
Additionally: Do I need to put this signal through a few chained flip-flops to combat metastability, or is this design safe as-is?
-
\$\begingroup\$ You could instantiate the gates directly. \$\endgroup\$Cristobol Polychronopolis– Cristobol Polychronopolis2020年03月13日 19:36:53 +00:00Commented Mar 13, 2020 at 19:36
-
\$\begingroup\$ Do not fail to run any asynchronous external signal through a chain of at least two flip-flops/registers before using it with anything that runs off the FPGA clock. \$\endgroup\$DKNguyen– DKNguyen2020年03月13日 19:51:30 +00:00Commented Mar 13, 2020 at 19:51
-
\$\begingroup\$ That's true for signals that are longer than your clock period. But OP's problem is a bit (no pun intended) different. \$\endgroup\$SteveSh– SteveSh2020年03月13日 20:09:53 +00:00Commented Mar 13, 2020 at 20:09
-
\$\begingroup\$ @SteveSh Yes, I was just looking at it again just now thinking it might be okay. \$\endgroup\$DKNguyen– DKNguyen2020年03月13日 20:11:02 +00:00Commented Mar 13, 2020 at 20:11
2 Answers 2
Just connect your signal to the clock input and use an async reset:
module see_shorty (
input short_signal,
input short_signal_clear,
output reg short_signal_seen
);
// You can make this negedge short_signal to detect a falling edge
// In the same way you can invert the reset signal
always @(posedge short_signal or posedge short_signal_clear)
if (short_signal_clear)
short_signal_seen <= 1'b0;
else
short_signal_seen <= 1'b1;
endmodule // see_shorty
Synchronize short_signal_seen
to your clock and use the result to make a short_signal_clear
pulse which clears the FF again. (I leave those details to you)
Make a reset pulse:
// Make a reset pulse if short signal (synced to system clock) is high
// but previously it was low
reg delayed_sig; // Need previous state of signal
wire short_signal_clear;
always @(posedge clk)
delayed_sig <= short_signal_seen_synced;
assign short_signal_clear = short_signal_seen_synced & ~delayed_sig;
-
\$\begingroup\$ Thank you, that looks good! I would personally use a chain of two FF to synchronize the signal to my clock domain, is that sufficient? :) \$\endgroup\$Katharina– Katharina2020年03月13日 20:25:58 +00:00Commented Mar 13, 2020 at 20:25
-
1\$\begingroup\$ Yes. That is the norm. Then a third FF with an exor to make the reset pulse. \$\endgroup\$Oldfart– Oldfart2020年03月14日 07:44:14 +00:00Commented Mar 14, 2020 at 7:44
-
\$\begingroup\$ Thanks. What do you mean by "exor"? I would have generated the pulse in Verilog by asserting the reset signal, and with the next clock edge, deasserting it, like a small state machine. Is there a simpler way? :) \$\endgroup\$Katharina– Katharina2020年03月14日 22:35:51 +00:00Commented Mar 14, 2020 at 22:35
-
1\$\begingroup\$ Sorry, probably not an exor gate. I'll update the code \$\endgroup\$Oldfart– Oldfart2020年03月14日 22:44:00 +00:00Commented Mar 14, 2020 at 22:44
How bout something like this? The clock is your local clock, common to all the flip flops. R is the reset (usually power on) for the FFs.
The glitch filter is optional.
Answer to OP's Question
S is just the SET input of the flip flop.
-
\$\begingroup\$ What is the "S" input from the first flip flop? Will this catch signals that are shorter than the clock period and do no coincide with the clock edges? \$\endgroup\$Katharina– Katharina2020年03月13日 19:33:48 +00:00Commented Mar 13, 2020 at 19:33
Explore related questions
See similar questions with these tags.