|
@@ -0,0 +1,88 @@
|
|
|
|
+/*
|
|
|
|
+ * mailbox_wb.v
|
|
|
|
+ *
|
|
|
|
+ * vim: ts=4 sw=4
|
|
|
|
+ *
|
|
|
|
+ * Copyright (C) 2025 Krzysztof Skrzynecki, Jakub Duchniewicz <j.duchniewicz@gmail.com>
|
|
|
|
+ * SPDX-License-Identifier: TODO:
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+`default_nettype none
|
|
|
|
+
|
|
|
|
+module mailbox_wb #(
|
|
|
|
+ parameter AW = 4, // Address width for 16 registers (4 bits)
|
|
|
|
+ parameter DW = 16 // Data width for each register (16 bits)
|
|
|
|
+)(
|
|
|
|
+ input wire clk,
|
|
|
|
+ input wire rst,
|
|
|
|
+ // Wishbone Interface
|
|
|
|
+ input wire [AW-1:0] wb_addr,
|
|
|
|
+ input wire [DW-1:0] wb_wdata,
|
|
|
|
+ output reg [DW-1:0] wb_rdata,
|
|
|
|
+ input wire wb_we,
|
|
|
|
+ input wire wb_cyc,
|
|
|
|
+ output reg wb_ack,
|
|
|
|
+
|
|
|
|
+ // Custom hardware side (RTL)
|
|
|
|
+ output reg [DW-1:0] registers [15:0] // 16 registers of 16 bits width
|
|
|
|
+);
|
|
|
|
+
|
|
|
|
+ // Always reset the registers on reset signal
|
|
|
|
+ integer i;
|
|
|
|
+ always @(posedge clk or posedge rst) begin
|
|
|
|
+ if (rst) begin
|
|
|
|
+ wb_ack <= 1'b0;
|
|
|
|
+ for (i = 0; i < 16; i = i + 1) begin
|
|
|
|
+ registers[i] <= 16'h0; // Reset all registers to 0
|
|
|
|
+ end
|
|
|
|
+ end else begin
|
|
|
|
+ // Handle Wishbone communication
|
|
|
|
+ wb_ack <= wb_cyc;
|
|
|
|
+
|
|
|
|
+ // Write operation (if write enable is active)
|
|
|
|
+ if (wb_we && wb_cyc) begin
|
|
|
|
+ case (wb_addr)
|
|
|
|
+ 4'b0000: registers[0] <= wb_wdata;
|
|
|
|
+ 4'b0001: registers[1] <= wb_wdata;
|
|
|
|
+ 4'b0010: registers[2] <= wb_wdata;
|
|
|
|
+ 4'b0011: registers[3] <= wb_wdata;
|
|
|
|
+ 4'b0100: registers[4] <= wb_wdata;
|
|
|
|
+ 4'b0101: registers[5] <= wb_wdata;
|
|
|
|
+ 4'b0110: registers[6] <= wb_wdata;
|
|
|
|
+ 4'b0111: registers[7] <= wb_wdata;
|
|
|
|
+ 4'b1000: registers[8] <= wb_wdata;
|
|
|
|
+ 4'b1001: registers[9] <= wb_wdata;
|
|
|
|
+ 4'b1010: registers[10] <= wb_wdata;
|
|
|
|
+ 4'b1011: registers[11] <= wb_wdata;
|
|
|
|
+ 4'b1100: registers[12] <= wb_wdata;
|
|
|
|
+ 4'b1101: registers[13] <= wb_wdata;
|
|
|
|
+ 4'b1110: registers[14] <= wb_wdata;
|
|
|
|
+ 4'b1111: registers[15] <= wb_wdata;
|
|
|
|
+ endcase
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ // Read operation (read the correct register based on address)
|
|
|
|
+ case (wb_addr)
|
|
|
|
+ 4'b0000: wb_rdata <= registers[0];
|
|
|
|
+ 4'b0001: wb_rdata <= registers[1];
|
|
|
|
+ 4'b0010: wb_rdata <= registers[2];
|
|
|
|
+ 4'b0011: wb_rdata <= registers[3];
|
|
|
|
+ 4'b0100: wb_rdata <= registers[4];
|
|
|
|
+ 4'b0101: wb_rdata <= registers[5];
|
|
|
|
+ 4'b0110: wb_rdata <= registers[6];
|
|
|
|
+ 4'b0111: wb_rdata <= registers[7];
|
|
|
|
+ 4'b1000: wb_rdata <= registers[8];
|
|
|
|
+ 4'b1001: wb_rdata <= registers[9];
|
|
|
|
+ 4'b1010: wb_rdata <= registers[10];
|
|
|
|
+ 4'b1011: wb_rdata <= registers[11];
|
|
|
|
+ 4'b1100: wb_rdata <= registers[12];
|
|
|
|
+ 4'b1101: wb_rdata <= registers[13];
|
|
|
|
+ 4'b1110: wb_rdata <= registers[14];
|
|
|
|
+ 4'b1111: wb_rdata <= registers[15];
|
|
|
|
+ default: wb_rdata <= 16'hDEAD; // Default error value
|
|
|
|
+ endcase
|
|
|
|
+ end
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+endmodule
|
|
|
|
+
|