123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- //
- // synchro.v
- //
- // Asynchronous input synchronizer
- //
- //
- // These attributes tell the compiler and fitter respectively
- // to treat these registers as low-level constructs and turn
- // them into a synchronizer chain. No inferring RAMs or anything like that,
- // and pack them close together.
- //
- module synchronizer #(parameter width = 1, parameter stages = 2)
- (
- input rst_n,
- input clk,
- input [width-1:0] d,
- output [width-1:0] q
- );
- // Quartus doesn't support $sformatf() for synthesis, sigh...
- function string tostr(input integer i);
- if (i < 0)
- tostr = {"-",tostr(-i)};
- else if (i >= 10)
- tostr = {tostr(i/10), tostr(i%10)};
- else if (i == 0)
- tostr = "0";
- else if (i == 1)
- tostr = "1";
- else if (i == 2)
- tostr = "2";
- else if (i == 3)
- tostr = "3";
- else if (i == 4)
- tostr = "4";
- else if (i == 5)
- tostr = "5";
- else if (i == 6)
- tostr = "6";
- else if (i == 7)
- tostr = "7";
- else if (i == 8)
- tostr = "8";
- else
- tostr = "9";
- endfunction
- // SYNCHRONIZER_IDENTIFICATION FORCED identifies the *beginning* of
- // the synchro; it needs to be used with AUTO for the other stages or
- // the chains will be broken up for each stage.
- //
- // Because of different attributes, this is not simply qreg[0].
- (*
- syn_preserve = 1,
- altera_attribute =
- {"-name SYNCHRONIZER_IDENTIFICATION FORCED ; ",
- "-name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH ", tostr(stages-1)}
- *)
- reg [width-1:0] qreg0;
- (*
- syn_preserve = 1,
- altera_attribute =
- {"-name SYNCHRONIZER_IDENTIFICATION AUTO ; ",
- "-name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH ", tostr(stages-1)}
- *)
- reg [width-1:0] qreg[stages-1:1];
- always @(posedge clk or negedge rst_n)
- if (~rst_n)
- qreg0 <= {width{1'b0}};
- else
- qreg0 <= d;
- always @(posedge clk or negedge rst_n)
- if (~rst_n)
- qreg[1] <= {width{1'b0}};
- else
- qreg[1] <= qreg0;
- generate
- genvar i;
- for (i = 2; i < stages; i = i + 1)
- begin : stage
- always @(posedge clk or negedge rst_n)
- if (~rst_n)
- qreg[i] <= {width{1'b0}};
- else
- qreg[i] <= qreg[i-1];
- end
- endgenerate
- assign q = qreg[stages-1];
- endmodule // synchronizer
|