memtest.v 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /*
  2. * memtest.v
  3. *
  4. * vim: ts=4 sw=4
  5. *
  6. * Copyright (C) 2020 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 memtest #(
  35. parameter integer ADDR_WIDTH = 32,
  36. // auto
  37. parameter integer AL = ADDR_WIDTH - 1
  38. )(
  39. // Memory interface
  40. output wire [AL:0] mi_addr,
  41. output wire [ 6:0] mi_len,
  42. output wire mi_rw,
  43. output wire mi_valid,
  44. input wire mi_ready,
  45. output wire [31:0] mi_wdata,
  46. output wire [ 3:0] mi_wmsk,
  47. input wire mi_wack,
  48. input wire [31:0] mi_rdata,
  49. input wire mi_rstb,
  50. // Wishbone interface
  51. input wire [31:0] wb_wdata,
  52. output wire [31:0] wb_rdata,
  53. input wire [ 8:0] wb_addr,
  54. input wire wb_we,
  55. input wire wb_cyc,
  56. output wire wb_ack,
  57. // Clock / Reset
  58. input wire clk,
  59. input wire rst
  60. );
  61. // Signals
  62. // -------
  63. // Buffers
  64. wire [ 7:0] bw_waddr;
  65. wire [31:0] bw_wdata;
  66. wire bw_wren;
  67. reg [ 7:0] bw_raddr;
  68. wire [31:0] bw_rdata;
  69. wire bw_rden;
  70. reg [ 7:0] br_waddr;
  71. wire [31:0] br_wdata;
  72. wire br_wren;
  73. wire [ 7:0] br_raddr;
  74. wire [31:0] br_rdata;
  75. wire br_rden;
  76. // Wishbone
  77. reg wb_ack_i;
  78. reg wb_we_cmd;
  79. reg wb_we_addr;
  80. // Commands
  81. reg cmd_valid;
  82. reg cmd_start;
  83. reg cmd_read;
  84. reg [ 6:0] cmd_len;
  85. reg [AL:0] cmd_addr;
  86. reg cmd_dual;
  87. // Validate
  88. reg val_ok;
  89. // Buffers
  90. // -------
  91. ram_sdp #(
  92. .AWIDTH(8),
  93. .DWIDTH(32)
  94. ) buf_wr_I (
  95. .wr_addr(bw_waddr),
  96. .wr_data(bw_wdata),
  97. .wr_ena(bw_wren),
  98. .rd_addr(bw_raddr),
  99. .rd_data(bw_rdata),
  100. .rd_ena(bw_rden),
  101. .clk(clk)
  102. );
  103. ram_sdp #(
  104. .AWIDTH(8),
  105. .DWIDTH(32)
  106. ) buf_rd_I (
  107. .wr_addr(br_waddr),
  108. .wr_data(br_wdata),
  109. .wr_ena(br_wren),
  110. .rd_addr(br_raddr),
  111. .rd_data(br_rdata),
  112. .rd_ena(br_rden),
  113. .clk(clk)
  114. );
  115. // Wishbone interface
  116. // ------------------
  117. // Ack
  118. always @(posedge clk)
  119. wb_ack_i <= wb_cyc & ~wb_ack_i;
  120. assign wb_ack = wb_ack_i;
  121. // Read Mux
  122. assign wb_rdata = wb_ack_i ?
  123. (wb_addr[8] ? br_rdata : { 30'h00000000, val_ok, mi_ready }) :
  124. 32'h00000000;
  125. // Buffer accesses
  126. assign bw_waddr = wb_addr[7:0];
  127. assign bw_wdata = wb_wdata;
  128. assign bw_wren = wb_ack_i & wb_we & wb_addr[8];
  129. assign br_raddr = wb_addr[7:0];
  130. assign br_rden = 1'b1;
  131. // Write Strobes
  132. always @(posedge clk)
  133. if (wb_ack_i) begin
  134. wb_we_cmd <= 1'b0;
  135. wb_we_addr <= 1'b0;
  136. end else begin
  137. wb_we_cmd <= wb_cyc & wb_we & ~wb_addr[8] & ~wb_addr[0];
  138. wb_we_addr <= wb_cyc & wb_we & ~wb_addr[8] & wb_addr[0];
  139. end
  140. always @(posedge clk)
  141. cmd_start <= wb_we_cmd;
  142. always @(posedge clk)
  143. if (rst)
  144. cmd_valid <= 1'b0;
  145. else
  146. cmd_valid <= (cmd_valid & (~mi_ready | cmd_dual)) | cmd_start;
  147. always @(posedge clk)
  148. if (wb_we_cmd)
  149. cmd_dual <= wb_wdata[18];
  150. else if (mi_ready & mi_valid)
  151. cmd_dual <= 1'b0;
  152. always @(posedge clk)
  153. if (wb_we_cmd) begin
  154. cmd_read <= wb_wdata[ 16];
  155. cmd_len <= wb_wdata[ 6: 0];
  156. end
  157. always @(posedge clk)
  158. if (wb_we_addr)
  159. cmd_addr <= wb_wdata[ADDR_WIDTH-1:0];
  160. else if (mi_ready & mi_valid)
  161. cmd_addr <= cmd_addr + cmd_len + 1;
  162. // Memory interface
  163. // ----------------
  164. // Requests
  165. assign mi_addr = cmd_addr;
  166. assign mi_len = cmd_len;
  167. assign mi_rw = cmd_read;
  168. assign mi_valid = cmd_valid;
  169. // Write data (and read-validate)
  170. always @(posedge clk)
  171. if (wb_we_cmd)
  172. bw_raddr <= wb_wdata[15:8];
  173. else
  174. bw_raddr <= bw_raddr + bw_rden;
  175. assign mi_wdata = bw_rdata;
  176. assign mi_wmsk = 4'h0;
  177. assign bw_rden = (cmd_read ? mi_rstb : mi_wack) | cmd_start;
  178. // Read data
  179. assign br_wdata = mi_rdata;
  180. assign br_wren = mi_rstb;
  181. always @(posedge clk)
  182. if (wb_we_cmd)
  183. br_waddr <= wb_wdata[15:8];
  184. else
  185. br_waddr <= br_waddr + mi_rstb;
  186. // Data validation
  187. always @(posedge clk)
  188. if (wb_we_cmd)
  189. val_ok <= val_ok | wb_wdata[17];
  190. else
  191. val_ok <= val_ok & (~mi_rstb | (mi_rdata == bw_rdata));
  192. endmodule