Attention
This documentation is a work in progress. Expect to see errors and unfinished things.
flag_xdomain Source File
1`timescale 1ns / 1ns
2module flag_xdomain(
3 input clk1,
4 input flagin_clk1,
5 input clk2,
6 output flagout_clk2
7);
8
9// Step 1: generate 1-bit Gray code
10reg flagtoggle_clk1=0;
11always @(posedge clk1) if (flagin_clk1)
12 flagtoggle_clk1 <= ~flagtoggle_clk1;
13
14// Step 2: cross clock domains
15wire sync1_clk2;
16reg_tech_cdc flagtoggle_cdc(.I(flagtoggle_clk1), .C(clk2), .O(sync1_clk2));
17
18// Step 3: detect transitions
19reg sync2_clk2=0;
20always @(posedge clk2) sync2_clk2 <= sync1_clk2;
21assign flagout_clk2 = sync2_clk2 ^ sync1_clk2;
22
23// Step 4: (simulation-only) complain if this module is abused
24// Too many people wire data_xdomain's .gate_in(1'b1) without understanding
25// how the logic is supposed to work.
26`ifdef SIMULATE
27reg old_flagin=0, warning_sent=0;
28always @(posedge clk1) begin
29 old_flagin <= flagin_clk1;
30 if (flagin_clk1 & old_flagin & ~warning_sent) begin
31 // Don't actually crash, at least not for now.
32 $display("XXXX Warning: flag_xdomain module abuse in %m XXXX");
33 warning_sent <= 1;
34 end
35end
36`endif
37
38endmodule