Day 73: Peripheral: GPIO with interrupt lines
Peripheral: GPIO with interrupt lines
GPIO (general-purpose I/O) gives software direct pins: a direction register (input/output per pin), an output register, and an input register. The interesting part is interrupts: pins configured to raise an interrupt on a rising edge, falling edge, or level. That needs synchronizing the async pin (Stage 0 metastability!) and then edge detection on the synchronized value.
// synchronize the async pin, then detect a rising edge
reg [1:0] sync;
reg pin_d;
always @(posedge clk) begin
sync <= {sync[0], gpio_in}; // 2-FF synchronizer
pin_d <= sync[1];
end
wire pin_sync = sync[1];
wire rise_edge = pin_sync & ~pin_d; // 0 -> 1 transition
// set interrupt-pending on an enabled rising edge
always @(posedge clk)
if (rise_edge & int_enable) irq_pending <= 1'b1;
else if (irq_clear) irq_pending <= 1'b0;Synchronize before you detect
A raw external pin is asynchronous — feed it straight into edge-detection logic and you'll get metastability-induced false edges. Always pass it through a 2-FF synchronizer (Stage 0, Day 28) *first*, then detect edges on the clean, synchronized signal. This ordering is a small but real correctness point, and a favorite interview trap.
Ship for Day 73
Why synchronize a GPIO input pin before doing edge detection on it?