2
0

synchro.v 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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. // Quartus doesn't support $sformatf() for synthesis, sigh...
  20. function string tostr(input integer i);
  21. if (i < 0)
  22. tostr = {"-",tostr(-i)};
  23. else if (i >= 10)
  24. tostr = {tostr(i/10), tostr(i%10)};
  25. else if (i == 0)
  26. tostr = "0";
  27. else if (i == 1)
  28. tostr = "1";
  29. else if (i == 2)
  30. tostr = "2";
  31. else if (i == 3)
  32. tostr = "3";
  33. else if (i == 4)
  34. tostr = "4";
  35. else if (i == 5)
  36. tostr = "5";
  37. else if (i == 6)
  38. tostr = "6";
  39. else if (i == 7)
  40. tostr = "7";
  41. else if (i == 8)
  42. tostr = "8";
  43. else
  44. tostr = "9";
  45. endfunction
  46. // SYNCHRONIZER_IDENTIFICATION FORCED identifies the *beginning* of
  47. // the synchro; it needs to be used with AUTO for the other stages or
  48. // the chains will be broken up for each stage.
  49. //
  50. // Because of different attributes, this is not simply qreg[0].
  51. (*
  52. syn_preserve = 1,
  53. altera_attribute =
  54. {"-name SYNCHRONIZER_IDENTIFICATION FORCED ; ",
  55. "-name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH ", tostr(stages-1)}
  56. *)
  57. reg [width-1:0] qreg0;
  58. (*
  59. syn_preserve = 1,
  60. altera_attribute =
  61. {"-name SYNCHRONIZER_IDENTIFICATION AUTO ; ",
  62. "-name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH ", tostr(stages-1)}
  63. *)
  64. reg [width-1:0] qreg[stages-1:1];
  65. always @(posedge clk or negedge rst_n)
  66. if (~rst_n)
  67. qreg0 <= {width{1'b0}};
  68. else
  69. qreg0 <= d;
  70. always @(posedge clk or negedge rst_n)
  71. if (~rst_n)
  72. qreg[1] <= {width{1'b0}};
  73. else
  74. qreg[1] <= qreg0;
  75. generate
  76. genvar i;
  77. for (i = 2; i < stages; i = i + 1)
  78. begin : stage
  79. always @(posedge clk or negedge rst_n)
  80. if (~rst_n)
  81. qreg[i] <= {width{1'b0}};
  82. else
  83. qreg[i] <= qreg[i-1];
  84. end
  85. endgenerate
  86. assign q = qreg[stages-1];
  87. endmodule // synchronizer