mailbox_wb_rtl2sw.v 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /*
  2. * mailbox_wb_rtl2sw.v
  3. *
  4. * vim: ts=4 sw=4
  5. *
  6. * Copyright (C) 2025 Krzysztof Skrzynecki, Jakub Duchniewicz <j.duchniewicz@gmail.com>
  7. * SPDX-License-Identifier: TODO:
  8. */
  9. `default_nettype none
  10. module mailbox_wb_rtl2sw #(
  11. parameter AW = 4, // 16 registers => 4-bit address
  12. parameter DW = 32 // 32-bit Wishbone Data
  13. )(
  14. input wire clk,
  15. input wire rst,
  16. // -------------------------
  17. // Wishbone Interface
  18. // -------------------------
  19. input wire [AW-1:0] wb_addr, // register index (0..15)
  20. input wire [DW-1:0] wb_wdata, // Wishbone write data
  21. input wire wb_we, // Wishbone write enable
  22. input wire wb_cyc, // Wishbone cycle (bus valid)
  23. output reg [DW-1:0] wb_rdata, // Wishbone read data
  24. output reg wb_ack, // Wishbone acknowledge
  25. // -------------------------
  26. // Hardware-driven inputs
  27. // (16 registers x 16 bits = 256 bits total)
  28. // -------------------------
  29. input wire [16*16-1:0] registers_flat_in
  30. );
  31. // Internal 16-bit registers. Indices: 0..15
  32. reg [15:0] registers_array [0:15];
  33. //-------------------------------------------
  34. // A single procedural always block
  35. //-------------------------------------------
  36. integer i;
  37. always @(posedge clk or posedge rst) begin
  38. if (rst) begin
  39. // 1) Reset logic
  40. wb_ack <= 1'b0;
  41. for (i = 0; i < 16; i = i + 1) begin
  42. registers_array[i] <= 16'h0000;
  43. end
  44. wb_rdata <= 32'h0000_0000;
  45. end else begin
  46. //-----------------------------------
  47. // 2) Default: no Wishbone ack
  48. //-----------------------------------
  49. wb_ack <= 1'b0;
  50. //-----------------------------------
  51. // 3) HW vs SW for each register
  52. // - If SW writes (wb_we) to j,
  53. // that overrides the HW input
  54. //-----------------------------------
  55. integer j;
  56. for (j = 0; j < 16; j = j + 1) begin
  57. if (wb_cyc && wb_we && (wb_addr == j)) begin
  58. // CPU write has priority this cycle
  59. registers_array[j] <= wb_wdata[15:0];
  60. end else begin
  61. // Otherwise, updated by HW input
  62. registers_array[j] <= registers_flat_in[16*(j+1)-1 : 16*j];
  63. end
  64. end
  65. //-----------------------------------
  66. // 4) Wishbone read logic
  67. // - If bus is active (wb_cyc),
  68. // read out the requested register
  69. //-----------------------------------
  70. if (wb_cyc) begin
  71. wb_ack <= 1'b1;
  72. case (wb_addr)
  73. 4'b0000: wb_rdata <= {16'h0, registers_array[0]};
  74. 4'b0001: wb_rdata <= {16'h0, registers_array[1]};
  75. 4'b0010: wb_rdata <= {16'h0, registers_array[2]};
  76. 4'b0011: wb_rdata <= {16'h0, registers_array[3]};
  77. 4'b0100: wb_rdata <= {16'h0, registers_array[4]};
  78. 4'b0101: wb_rdata <= {16'h0, registers_array[5]};
  79. 4'b0110: wb_rdata <= {16'h0, registers_array[6]};
  80. 4'b0111: wb_rdata <= {16'h0, registers_array[7]};
  81. 4'b1000: wb_rdata <= {16'h0, registers_array[8]};
  82. 4'b1001: wb_rdata <= {16'h0, registers_array[9]};
  83. 4'b1010: wb_rdata <= {16'h0, registers_array[10]};
  84. 4'b1011: wb_rdata <= {16'h0, registers_array[11]};
  85. 4'b1100: wb_rdata <= {16'h0, registers_array[12]};
  86. 4'b1101: wb_rdata <= {16'h0, registers_array[13]};
  87. 4'b1110: wb_rdata <= {16'h0, registers_array[14]};
  88. 4'b1111: wb_rdata <= {16'h0, registers_array[15]};
  89. default: wb_rdata <= 32'hDEAD_BEEF;
  90. endcase
  91. end
  92. end
  93. end
  94. endmodule