|
@@ -6,58 +6,78 @@
|
|
|
* 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, // Address width for 16 registers (4 bits)
|
|
|
- parameter DW = 32 // Data width for the Wishbone interface (32 bits)
|
|
|
+ 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,
|
|
|
- output reg [DW-1:0] wb_rdata,
|
|
|
- input wire wb_cyc,
|
|
|
- output reg wb_ack,
|
|
|
+ // -------------------------
|
|
|
+ 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
|
|
|
|
|
|
- input wire [16*16-1:0] registers_flat_in
|
|
|
+ // -------------------------
|
|
|
+ // Hardware-driven inputs
|
|
|
+ // (16 registers x 16 bits = 256 bits total)
|
|
|
+ // -------------------------
|
|
|
+ input wire [16*16-1:0] registers_flat_in
|
|
|
);
|
|
|
|
|
|
- // Internal registers (16 registers, each 16 bits wide)
|
|
|
- reg [15:0] registers_array[15:0];
|
|
|
+ // Internal 16-bit registers. Indices: 0..15
|
|
|
+ reg [15:0] registers_array [0:15];
|
|
|
|
|
|
- generate
|
|
|
- genvar j;
|
|
|
- for (j = 0; j < 16; j = j + 1) begin : unflatten_ro
|
|
|
- always @(posedge clk or posedge rst) begin
|
|
|
- if (rst) begin
|
|
|
- registers_array[j] <= 16'h0;
|
|
|
- end else begin
|
|
|
- // Continuously update read-only registers
|
|
|
- // from the hardware input
|
|
|
- registers_array[j] <= registers_flat_in[16*(j+1)-1 : 16*j];
|
|
|
- end
|
|
|
- end
|
|
|
- end
|
|
|
- endgenerate
|
|
|
-
|
|
|
- // Always reset the registers on reset signal
|
|
|
+ //-------------------------------------------
|
|
|
+ // 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'h0; // Reset all registers to 0
|
|
|
+ registers_array[i] <= 16'h0000;
|
|
|
end
|
|
|
+ wb_rdata <= 32'h0000_0000;
|
|
|
end else begin
|
|
|
- // Default no ack
|
|
|
+ //-----------------------------------
|
|
|
+ // 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
|
|
|
- // Read operation (read the correct register based on address)
|
|
|
+ wb_ack <= 1'b1;
|
|
|
case (wb_addr)
|
|
|
- 4'b0000: wb_rdata <= {16'h0, registers_array[0]}; // Place 16-bit value in lower half of 32-bit bus
|
|
|
+ 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]};
|
|
@@ -73,13 +93,11 @@ module mailbox_wb_rtl2sw #(
|
|
|
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; // Default error value
|
|
|
+ default: wb_rdata <= 32'hDEAD_BEEF;
|
|
|
endcase
|
|
|
-
|
|
|
- // Acknowledge for exactly 1 cycle
|
|
|
- wb_ack <= 1'b1;
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
|
|
|
endmodule
|
|
|
+
|