123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- /*
- * mailbox_wb_rtl2sw.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_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
|