`timescale 1ns/1ps module wb_gpio ( input wire i_wb_clk, input wire i_wb_rst, // optional; tie low if unused input wire [31:0] i_wb_adr, // optional; can ignore for single-reg input wire [31:0] i_wb_dat, input wire [3:0] i_wb_sel, input wire i_wb_we, input wire i_wb_stb, output reg [31:0] o_wb_rdt, output reg o_wb_ack, output reg [31:0] o_gpio ); initial o_gpio <= 32'h00000000; initial o_wb_rdt <= 32'h00000000; // One-cycle ACK pulse per request (works even if stb stays high) always @(posedge i_wb_clk) begin if (i_wb_rst) begin o_wb_ack <= 1'b0; end else begin o_wb_ack <= i_wb_stb & ~o_wb_ack; // pulse while stb asserted end end // Read data (combinational or registered; registered here) always @(posedge i_wb_clk) begin if (i_wb_rst) begin o_wb_rdt <= 32'h0; end else if (i_wb_stb && !i_wb_we) begin o_wb_rdt <= o_gpio; end end // Write latch (update on the acknowledged cycle) always @(posedge i_wb_clk) begin if (i_wb_rst) begin o_gpio <= 32'h0; end else if (i_wb_stb && i_wb_we && (i_wb_stb & ~o_wb_ack)) begin // Apply byte enables (so sb works if the master uses sel) if (i_wb_sel[0]) o_gpio[7:0] <= i_wb_dat[7:0]; if (i_wb_sel[1]) o_gpio[15:8] <= i_wb_dat[15:8]; if (i_wb_sel[2]) o_gpio[23:16] <= i_wb_dat[23:16]; if (i_wb_sel[3]) o_gpio[31:24] <= i_wb_dat[31:24]; end end endmodule module tb_serving(); // Clock and reset generation reg clk; reg resetn; initial clk <= 1'b0; always #4.17 clk <= !clk; initial begin resetn <= 1'b1; #(4.17*40) resetn <= 1'b0; #(4.17*40) resetn <= 1'b1; end; // Default run initial begin $dumpfile("out.vcd"); $dumpvars; #5_000 $finish; end; wire [31:0] wb_adr; wire [31:0] wb_dat; wire [3:0] wb_sel; wire wb_we; wire wb_stb; wire [31:0] wb_rdt; wire wb_ack; wire [31:0] GPIO; serving #( .memfile("../sw/blinky/blinky.hex"), .memsize(8192), .sim(1'b0), .RESET_STRATEGY("MINI"), .WITH_CSR(1) ) serv ( .i_clk(clk), .i_rst(!resetn), .i_timer_irq(1'b0), .i_wb_rdt(wb_rdt), .i_wb_ack(wb_ack), .o_wb_adr(wb_adr), .o_wb_dat(wb_dat), .o_wb_sel(wb_sel), .o_wb_we(wb_we), .o_wb_stb(wb_stb) ); wb_gpio gpio ( .i_wb_clk(clk), .i_wb_dat(wb_dat), .i_wb_we(wb_we), .i_wb_stb(wb_stb), .i_wb_sel(wb_sel), .o_wb_rdt(wb_rdt), .o_wb_ack(wb_ack), .o_gpio(GPIO) ); endmodule