/* * servile_mux.v : Simple Wishbone mux for the servile convenience wrapper. * * SPDX-FileCopyrightText: 2024 Olof Kindgren * SPDX-License-Identifier: Apache-2.0 */ module servile_mux #(parameter [0:0] sim = 1'b0, //Enable simulation features parameter [31:0] sim_sig_adr = 32'h80000000, parameter [31:0] sim_halt_adr = 32'h90000000) ( input wire i_clk, input wire i_rst, input wire [31:0] i_wb_cpu_adr, input wire [31:0] i_wb_cpu_dat, input wire [3:0] i_wb_cpu_sel, input wire i_wb_cpu_we, input wire i_wb_cpu_stb, output wire [31:0] o_wb_cpu_rdt, output wire o_wb_cpu_ack, output wire [31:0] o_wb_mem_adr, output wire [31:0] o_wb_mem_dat, output wire [3:0] o_wb_mem_sel, output wire o_wb_mem_we, output wire o_wb_mem_stb, input wire [31:0] i_wb_mem_rdt, input wire i_wb_mem_ack, output wire [31:0] o_wb_ext_adr, output wire [31:0] o_wb_ext_dat, output wire [3:0] o_wb_ext_sel, output wire o_wb_ext_we, output wire o_wb_ext_stb, input wire [31:0] i_wb_ext_rdt, input wire i_wb_ext_ack); wire sig_en; wire halt_en; reg sim_ack; wire ext = (i_wb_cpu_adr[31:30] != 2'b00); assign o_wb_cpu_rdt = ext ? i_wb_ext_rdt : i_wb_mem_rdt; assign o_wb_cpu_ack = i_wb_ext_ack | i_wb_mem_ack | sim_ack; assign o_wb_mem_adr = i_wb_cpu_adr; assign o_wb_mem_dat = i_wb_cpu_dat; assign o_wb_mem_sel = i_wb_cpu_sel; assign o_wb_mem_we = i_wb_cpu_we; assign o_wb_mem_stb = i_wb_cpu_stb & !ext & !(sig_en|halt_en); assign o_wb_ext_adr = i_wb_cpu_adr; assign o_wb_ext_dat = i_wb_cpu_dat; assign o_wb_ext_sel = i_wb_cpu_sel; assign o_wb_ext_we = i_wb_cpu_we; assign o_wb_ext_stb = i_wb_cpu_stb & ext & !(sig_en|halt_en); generate if (sim) begin integer f = 0; assign sig_en = |f & i_wb_cpu_we & (i_wb_cpu_adr == sim_sig_adr); assign halt_en = i_wb_cpu_we & (i_wb_cpu_adr == sim_halt_adr); reg [1023:0] signature_file; initial /* verilator lint_off WIDTH */ if ($value$plusargs("signature=%s", signature_file)) begin $display("Writing signature to %0s", signature_file); f = $fopen(signature_file, "w"); end /* verilator lint_on WIDTH */ always @(posedge i_clk) begin sim_ack <= 1'b0; if (i_wb_cpu_stb & !sim_ack) begin sim_ack <= sig_en|halt_en; if (sig_en & (f != 0)) $fwrite(f, "%c", i_wb_cpu_dat[7:0]); else if(halt_en) begin $display("Test complete"); $finish; end end if (i_rst) sim_ack <= 1'b0; end end else begin assign sig_en = 1'b0; assign halt_en = 1'b0; initial sim_ack = 1'b0; end endgenerate endmodule