mailbox_wb_rtl2sw.v 3.1 KB

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