xclk_wb.v 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /*
  2. * xclk_wb.v
  3. *
  4. * vim: ts=4 sw=4
  5. *
  6. * Copyright (C) 2019 Sylvain Munaut <tnt@246tNt.com>
  7. * All rights reserved.
  8. *
  9. * BSD 3-clause, see LICENSE.bsd
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions are met:
  13. * * Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. * * Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in the
  17. * documentation and/or other materials provided with the distribution.
  18. * * Neither the name of the <organization> nor the
  19. * names of its contributors may be used to endorse or promote products
  20. * derived from this software without specific prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  23. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  24. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  25. * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  26. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  27. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  28. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  29. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. */
  33. `default_nettype none
  34. module xclk_wb #(
  35. parameter integer DW = 16,
  36. parameter integer AW = 16
  37. )(
  38. // Slave bus interface
  39. input wire [AW-1:0] s_addr,
  40. input wire [DW-1:0] s_wdata,
  41. output reg [DW-1:0] s_rdata,
  42. input wire s_cyc,
  43. output wire s_ack,
  44. input wire s_we,
  45. input wire s_clk,
  46. // Master bus interface
  47. output wire [AW-1:0] m_addr,
  48. output wire [DW-1:0] m_wdata,
  49. input wire [DW-1:0] m_rdata,
  50. output wire m_cyc,
  51. input wire m_ack,
  52. output wire m_we,
  53. input wire m_clk,
  54. // Reset
  55. input wire rst
  56. );
  57. // Signals
  58. // -------
  59. reg s_cyc_d;
  60. reg m_cyc_i;
  61. wire s_req_i;
  62. wire m_req_i;
  63. wire s_ack_i;
  64. reg s_ack_d;
  65. reg m_ack_i;
  66. reg [DW-1:0] m_rdata_i;
  67. // Data and address
  68. // ----------------
  69. // These will have settled down for some time while we pass around
  70. // the handshake signals, so we can just connect them
  71. // Ideally we'd still need a maxdelay constraint between clock domains
  72. assign m_addr = s_addr;
  73. assign m_wdata = s_wdata;
  74. assign m_we = s_we;
  75. // Still need to capture data during ack
  76. always @(posedge m_clk)
  77. if (m_ack)
  78. m_rdata_i <= m_rdata;
  79. // ... and ensure its zero cycle-accurately
  80. always @(posedge s_clk)
  81. if (s_ack_i || ~s_cyc)
  82. s_rdata <= 0;
  83. else
  84. s_rdata <= m_rdata_i;
  85. // Handshake
  86. // ---------
  87. always @(posedge s_clk)
  88. begin
  89. s_cyc_d <= s_cyc;
  90. s_ack_d <= s_ack_i;
  91. end
  92. assign s_req_i = s_cyc & (~s_cyc_d | s_ack_d);
  93. xclk_strobe xclk_req (
  94. .in_stb(s_req_i),
  95. .in_clk(s_clk),
  96. .out_stb(m_req_i),
  97. .out_clk(m_clk),
  98. .rst(rst)
  99. );
  100. always @(posedge m_clk or posedge rst)
  101. if (rst)
  102. m_cyc_i <= 1'b0;
  103. else
  104. m_cyc_i <= (m_cyc_i | m_req_i) & ~m_ack;
  105. assign m_cyc = m_cyc_i;
  106. xclk_strobe xclk_ack (
  107. .in_stb(m_ack),
  108. .in_clk(m_clk),
  109. .out_stb(s_ack_i),
  110. .out_clk(s_clk),
  111. .rst(rst)
  112. );
  113. assign s_ack = s_ack_i;
  114. endmodule