mailbox_wb_rtl2sw.v 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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, // Address width for 16 registers (4 bits)
  12. parameter DW = 32 // Data width for the Wishbone interface (32 bits)
  13. )(
  14. input wire clk,
  15. input wire rst,
  16. // Wishbone Interface
  17. input wire [AW-1:0] wb_addr,
  18. output reg [DW-1:0] wb_rdata,
  19. input wire wb_cyc,
  20. output reg wb_ack,
  21. input wire [16*16-1:0] registers_flat_in
  22. );
  23. // Internal registers (16 registers, each 16 bits wide)
  24. reg [15:0] registers_array[15:0];
  25. generate
  26. genvar j;
  27. for (j = 0; j < 16; j = j + 1) begin : unflatten_ro
  28. always @(posedge clk or posedge rst) begin
  29. if (rst) begin
  30. registers_array[j] <= 16'h0;
  31. end else begin
  32. // Continuously update read-only registers
  33. // from the hardware input
  34. registers_array[j] <= registers_flat_in[16*(j+1)-1 : 16*j];
  35. end
  36. end
  37. end
  38. endgenerate
  39. // Always reset the registers on reset signal
  40. integer i;
  41. always @(posedge clk or posedge rst) begin
  42. if (rst) begin
  43. wb_ack <= 1'b0;
  44. for (i = 0; i < 16; i = i + 1) begin
  45. registers_array[i] <= 16'h0; // Reset all registers to 0
  46. end
  47. end else begin
  48. // Default no ack
  49. wb_ack <= 1'b0;
  50. if (wb_cyc) begin
  51. // Read operation (read the correct register based on address)
  52. case (wb_addr)
  53. 4'b0000: wb_rdata <= {16'h0, registers_array[0]}; // Place 16-bit value in lower half of 32-bit bus
  54. 4'b0001: wb_rdata <= {16'h0, registers_array[1]};
  55. 4'b0010: wb_rdata <= {16'h0, registers_array[2]};
  56. 4'b0011: wb_rdata <= {16'h0, registers_array[3]};
  57. 4'b0100: wb_rdata <= {16'h0, registers_array[4]};
  58. 4'b0101: wb_rdata <= {16'h0, registers_array[5]};
  59. 4'b0110: wb_rdata <= {16'h0, registers_array[6]};
  60. 4'b0111: wb_rdata <= {16'h0, registers_array[7]};
  61. 4'b1000: wb_rdata <= {16'h0, registers_array[8]};
  62. 4'b1001: wb_rdata <= {16'h0, registers_array[9]};
  63. 4'b1010: wb_rdata <= {16'h0, registers_array[10]};
  64. 4'b1011: wb_rdata <= {16'h0, registers_array[11]};
  65. 4'b1100: wb_rdata <= {16'h0, registers_array[12]};
  66. 4'b1101: wb_rdata <= {16'h0, registers_array[13]};
  67. 4'b1110: wb_rdata <= {16'h0, registers_array[14]};
  68. 4'b1111: wb_rdata <= {16'h0, registers_array[15]};
  69. default: wb_rdata <= 32'hDEAD_BEEF; // Default error value
  70. endcase
  71. // Acknowledge for exactly 1 cycle
  72. wb_ack <= 1'b1;
  73. end
  74. end
  75. end
  76. endmodule