ClkManager.sv 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. //////////////////////////////////////////////////////////////////////////////////
  2. // Company: TAIR
  3. // Engineer:
  4. //
  5. // Create Date: 10/30/2023 11:24:31 AM
  6. // Design Name:
  7. // Module Name: ClkManager
  8. // Project Name: S5443_V3_FPGA3
  9. // Target Devices: BOARD: BY5443v3. FPGA: xc7s25csga225-2
  10. // Tool Versions:
  11. // Description: This module is a clock distributor. Based on a setting it
  12. // multiplexing cloks that generated either from MMCM or from
  13. // a custom divider.
  14. //
  15. // Dependencies:
  16. //
  17. // Revision:
  18. // Revision 1.0 - File Created
  19. // Additional Comments:
  20. //
  21. //////////////////////////////////////////////////////////////////////////////////
  22. module ClkManager
  23. #(
  24. parameter SPI_NUM = 7,
  25. parameter STAGES = 3,
  26. parameter AXI_DATA_WIDTH = 64,
  27. parameter [AXI_DATA_WIDTH-1:0] SPI_BASE_ADDR = 64'h0000_0000_0000_1000
  28. )
  29. (
  30. input Clk_i,
  31. input RstN_i,
  32. input [AXI_DATA_WIDTH-1:0] WrData_i,
  33. input [AXI_DATA_WIDTH-1:0] WrAddr_i,
  34. input Val_i,
  35. output [SPI_NUM-1:0] SpiClk_o,
  36. output SubSystSyncRst_o
  37. );
  38. //================================================================================
  39. // REG/WIRE
  40. //================================================================================
  41. wire clk0out;
  42. wire clk1out;
  43. wire clk2out;
  44. wire clk3out;
  45. wire clk4out;
  46. wire clk5out;
  47. wire clk6out;
  48. wire locked;
  49. wire [SPI_NUM-1:0] clkOutMMCM;
  50. wire [SPI_NUM-1:0] clkMan;
  51. wire [0:2] clkNum [SPI_NUM-1:0];
  52. wire [0:3] clkDiv [SPI_NUM-1:0];
  53. wire [0:3] clkDivSync [SPI_NUM-1:0];
  54. wire [SPI_NUM-1:0] clkCh;
  55. wire [SPI_NUM-1:0] spiClk;
  56. reg [AXI_DATA_WIDTH-1:0] spiClkReg [SPI_NUM-1:0];
  57. reg [7:0] baudRate [SPI_NUM-1:0];
  58. //================================================================================
  59. // ASSIGNMENTS
  60. //===============================================================================
  61. genvar k;
  62. generate
  63. for (k = 0; k < SPI_NUM; k = k + 1) begin : ClkGenAssignments
  64. assign clkNum[k] = baudRate[k][7:5];
  65. assign clkDiv[k] = baudRate[k][3:0];
  66. assign clkCh[k] = baudRate[k][4];
  67. end
  68. endgenerate
  69. assign SpiClk_o = spiClk;
  70. assign Clk100_o = clk0out;
  71. assign Clk80_o = clk1out;
  72. //================================================================================
  73. // LOCALPARAMS
  74. //================================================================================
  75. //================================================================================
  76. // CODING
  77. //================================================================================
  78. always_ff @(posedge Clk_i) begin
  79. if (!RstN_i) begin
  80. for (int i = 0; i < SPI_NUM; i++) begin
  81. spiClkReg[i] <= {AXI_DATA_WIDTH{1'b0}};
  82. end
  83. end
  84. else begin
  85. if (Val_i) begin
  86. for (int i = 0; i < SPI_NUM; i++) begin
  87. if (WrAddr_i == SPI_BASE_ADDR*i + 64'h1008) begin
  88. spiClkReg[i] <= WrData_i;
  89. end
  90. end
  91. end
  92. end
  93. end
  94. always @(*) begin
  95. if (!RstN_i) begin
  96. for (int i = 0; i < SPI_NUM; i++) begin
  97. baudRate[i] = 0;
  98. end
  99. end
  100. else begin
  101. for (int i = 0; i < SPI_NUM; i++) begin
  102. baudRate[i] = spiClkReg[i][7:0];
  103. end
  104. end
  105. end
  106. genvar i;
  107. generate
  108. for (i = 0; i < SPI_NUM; i = i + 1) begin : ClkGen
  109. ClkDivider ClkDivider (
  110. .Clk_i (clk1out),
  111. .ClkDiv_i (clkDivSync[i]),
  112. .Rst_i (Rst_i),
  113. .Clk_o (clkMan[i])
  114. );
  115. CmdSync #(
  116. .WIDTH (4),
  117. .STAGES (STAGES)
  118. ) CmdSync (
  119. .ClkFast_i (Clk_i),
  120. .ClkSlow_i (clk1out),
  121. .ClkDiv_i (clkDiv[i]),
  122. .ClkDiv_o (clkDivSync[i])
  123. );
  124. MmcmClkMux MmcmClkMux (
  125. .Rst_i (Rst_i),
  126. .clkNum (clkNum[i]),
  127. .Clk0_i (clk0out),
  128. .Clk1_i (clk1out),
  129. .Clk2_i (clk2out),
  130. .Clk3_i (clk3out),
  131. .Clk4_i (clk4out),
  132. .Clk5_i (clk5out),
  133. .Clk6_i (clk6out),
  134. .ClkOutMMCM_o (clkOutMMCM[i])
  135. );
  136. SpiClkMux SpiClkMux (
  137. .Rst_i (Rst_i),
  138. .clkCh (clkCh[i]),
  139. .clkOutMMCM (clkOutMMCM[i]),
  140. .clkMan (clkMan[i]),
  141. .SpiClk_o (spiClk[i])
  142. );
  143. end
  144. endgenerate
  145. MMCM MMCM
  146. (
  147. // Clock out ports
  148. .clk_out1(clk0out), //100 MHz
  149. .clk_out2(clk1out), // 80 MHz
  150. .clk_out3(clk2out), // 70 MHz
  151. .clk_out4(clk3out), // 60MHz
  152. .clk_out5(clk4out), // 50MHz
  153. .clk_out6(clk5out), // 40MHz
  154. .clk_out7(clk6out), // 30MHz
  155. // Status and control signals
  156. .reset(Rst_i), // input reset
  157. .locked(locked), // output locked
  158. // Clock in ports
  159. .clk_in1(Clk_i) // input clk_in1
  160. );
  161. InitRst InitRst
  162. (
  163. .clk_i (clk6out),
  164. .signal_o (SubSystSyncRst_o)
  165. );
  166. endmodule