spi_reg.v 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /*
  2. * spi_reg.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 spi_reg #(
  35. parameter ADDR = 8'h00,
  36. parameter integer BYTES = 1
  37. )(
  38. // Bus interface
  39. input wire [7:0] addr,
  40. input wire [7:0] data,
  41. input wire first,
  42. input wire strobe,
  43. // Reset
  44. input wire [(8*BYTES)-1:0] rst_val,
  45. // Output
  46. output wire [(8*BYTES)-1:0] out_val,
  47. output wire out_stb,
  48. // Clock / Reset
  49. input wire clk,
  50. input wire rst
  51. );
  52. localparam integer WIDTH = 8*BYTES;
  53. // Signals
  54. wire [WIDTH-1:0] nxt_val;
  55. reg [WIDTH-1:0] cur_val;
  56. wire [BYTES-1:0] hit_delay;
  57. wire hit;
  58. reg out_stb_i;
  59. // History
  60. generate
  61. if (BYTES > 1) begin
  62. reg [WIDTH-9:0] history;
  63. reg [BYTES-2:0] bc;
  64. always @(posedge clk or posedge rst)
  65. if (rst) begin
  66. history <= 0;
  67. bc <= 0;
  68. end else if (strobe) begin
  69. history <= nxt_val[WIDTH-9: 0];
  70. bc <= hit_delay[BYTES-2:0];
  71. end
  72. assign nxt_val = { history, data };
  73. assign hit_delay = { bc, first };
  74. end else begin
  75. assign nxt_val = data;
  76. assign hit_delay = { first };
  77. end
  78. endgenerate
  79. // Address match
  80. assign hit = hit_delay[BYTES-1] & strobe & (addr == ADDR);
  81. // Value register
  82. always @(posedge clk or posedge rst)
  83. if (rst)
  84. cur_val <= rst_val;
  85. else if (hit)
  86. cur_val <= nxt_val;
  87. always @(posedge clk)
  88. out_stb_i <= hit;
  89. assign out_val = cur_val;
  90. assign out_stb = out_stb_i;
  91. endmodule // spi_reg