/* * mailbox_wb_rtl2sw.v * * vim: ts=4 sw=4 * * Copyright (C) 2025 Krzysztof Skrzynecki, Jakub Duchniewicz * SPDX-License-Identifier: TODO: */ `default_nettype none module mailbox_wb_rtl2sw #( parameter AW = 4, // 16 registers => 4-bit address parameter DW = 32 // 32-bit Wishbone Data )( input wire clk, input wire rst, // ------------------------- // Wishbone Interface // ------------------------- input wire [AW-1:0] wb_addr, // register index (0..15) input wire [DW-1:0] wb_wdata, // Wishbone write data input wire wb_we, // Wishbone write enable input wire wb_cyc, // Wishbone cycle (bus valid) output reg [DW-1:0] wb_rdata, // Wishbone read data output reg wb_ack, // Wishbone acknowledge // ------------------------- // Hardware-driven inputs // (16 registers x 16 bits = 256 bits total) // ------------------------- input wire [16*16-1:0] registers_flat_in ); // Internal 16-bit registers. Indices: 0..15 reg [15:0] registers_array [0:15]; //------------------------------------------- // A single procedural always block //------------------------------------------- integer i; always @(posedge clk or posedge rst) begin if (rst) begin // 1) Reset logic wb_ack <= 1'b0; for (i = 0; i < 16; i = i + 1) begin registers_array[i] <= 16'h0000; end wb_rdata <= 32'h0000_0000; end else begin //----------------------------------- // 2) Default: no Wishbone ack //----------------------------------- wb_ack <= 1'b0; //----------------------------------- // 3) HW vs SW for each register // - If SW writes (wb_we) to j, // that overrides the HW input //----------------------------------- integer j; for (j = 0; j < 16; j = j + 1) begin if (wb_cyc && wb_we && (wb_addr == j)) begin // CPU write has priority this cycle registers_array[j] <= wb_wdata[15:0]; end else begin // Otherwise, updated by HW input registers_array[j] <= registers_flat_in[16*(j+1)-1 : 16*j]; end end //----------------------------------- // 4) Wishbone read logic // - If bus is active (wb_cyc), // read out the requested register //----------------------------------- if (wb_cyc) begin wb_ack <= 1'b1; case (wb_addr) 4'b0000: wb_rdata <= {16'h0, registers_array[0]}; 4'b0001: wb_rdata <= {16'h0, registers_array[1]}; 4'b0010: wb_rdata <= {16'h0, registers_array[2]}; 4'b0011: wb_rdata <= {16'h0, registers_array[3]}; 4'b0100: wb_rdata <= {16'h0, registers_array[4]}; 4'b0101: wb_rdata <= {16'h0, registers_array[5]}; 4'b0110: wb_rdata <= {16'h0, registers_array[6]}; 4'b0111: wb_rdata <= {16'h0, registers_array[7]}; 4'b1000: wb_rdata <= {16'h0, registers_array[8]}; 4'b1001: wb_rdata <= {16'h0, registers_array[9]}; 4'b1010: wb_rdata <= {16'h0, registers_array[10]}; 4'b1011: wb_rdata <= {16'h0, registers_array[11]}; 4'b1100: wb_rdata <= {16'h0, registers_array[12]}; 4'b1101: wb_rdata <= {16'h0, registers_array[13]}; 4'b1110: wb_rdata <= {16'h0, registers_array[14]}; 4'b1111: wb_rdata <= {16'h0, registers_array[15]}; default: wb_rdata <= 32'hDEAD_BEEF; endcase end end end endmodule