2
0

synchro.sv 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. //
  2. // synchro.v
  3. //
  4. // Asynchronous input synchronizer
  5. //
  6. //
  7. // These attributes tell the compiler and fitter respectively
  8. // to treat these registers as low-level constructs and turn
  9. // them into a synchronizer chain. No inferring RAMs or anything like that,
  10. // and pack them close together.
  11. //
  12. module synchronizer #(parameter width = 1, parameter stages = 2)
  13. (
  14. input rst_n,
  15. input clk,
  16. input [width-1:0] d,
  17. output [width-1:0] q
  18. );
  19. // SYNCHRONIZER_IDENTIFICATION FORCED identifies the *beginning* of
  20. // the synchro; it needs to be used with AUTO for the other stages or
  21. // the chains will be broken up for each stage.
  22. //
  23. // Because of different attributes, this is not simply qreg[0].
  24. (*
  25. syn_preserve = 1,
  26. altera_attribute =
  27. {"-name SYNCHRONIZER_IDENTIFICATION FORCED ; ",
  28. "-name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH ", tostr(stages-1)}
  29. *)
  30. reg [width-1:0] qreg0;
  31. (*
  32. syn_preserve = 1,
  33. altera_attribute =
  34. {"-name SYNCHRONIZER_IDENTIFICATION AUTO ; ",
  35. "-name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH ", tostr(stages-1)}
  36. *)
  37. reg [width-1:0] qreg[stages-1:1];
  38. always @(posedge clk or negedge rst_n)
  39. if (~rst_n)
  40. qreg0 <= {width{1'b0}};
  41. else
  42. qreg0 <= d;
  43. always @(posedge clk or negedge rst_n)
  44. if (~rst_n)
  45. qreg[1] <= {width{1'b0}};
  46. else
  47. qreg[1] <= qreg0;
  48. generate
  49. genvar i;
  50. for (i = 2; i < stages; i = i + 1)
  51. begin : stage
  52. always @(posedge clk or negedge rst_n)
  53. if (~rst_n)
  54. qreg[i] <= {width{1'b0}};
  55. else
  56. qreg[i] <= qreg[i-1];
  57. end
  58. endgenerate
  59. assign q = qreg[stages-1];
  60. endmodule // synchronizer