`default_nettype none // Safe observation of a monotonic source-domain counter. The Gray encoding // changes one bit per increment; two destination flops isolate metastability. module gray_counter_sync #( parameter int unsigned WIDTH = 64 ) ( input wire logic src_clk, input wire logic src_rst, input wire logic [WIDTH-1:0] src_binary, input wire logic dst_clk, input wire logic dst_rst, output logic [WIDTH-1:0] dst_binary ); logic [WIDTH-1:0] src_gray; (* ASYNC_REG = "TRUE" *) logic [WIDTH-1:0] gray_sync1; (* ASYNC_REG = "TRUE" *) logic [WIDTH-1:0] gray_sync2; integer i; always_ff @(posedge src_clk) begin if (src_rst) src_gray <= '0; else src_gray <= (src_binary >> 1) ^ src_binary; end always_ff @(posedge dst_clk) begin if (dst_rst) begin gray_sync1 <= '0; gray_sync2 <= '0; end else begin gray_sync1 <= src_gray; gray_sync2 <= gray_sync1; end end always_comb begin dst_binary[WIDTH-1] = gray_sync2[WIDTH-1]; for (i = WIDTH-2; i >= 0; i = i - 1) dst_binary[i] = dst_binary[i+1] ^ gray_sync2[i]; end endmodule `default_nettype wire