module apb_mux #(parameter APB_CNT = 2, ADDR_BITS = 12, DATA_BITS = 32) ( input apb_clock, input apb_resetn, input apb_in_psel, input apb_in_penable, input apb_in_pwrite, input [ADDR_BITS-1:0] apb_in_paddr, input [DATA_BITS-1:0] apb_in_pwdata, output reg [DATA_BITS-1:0] apb_in_prdata, output reg apb_in_pready, output reg apb_in_pslverr, output [APB_CNT-1:0] apb_out_psel, output [APB_CNT-1:0] apb_out_penable, output [APB_CNT-1:0] apb_out_pwrite, output [APB_CNT*ADDR_BITS-1:0] apb_out_paddr, output [APB_CNT*DATA_BITS-1:0] apb_out_pwdata, input [APB_CNT*DATA_BITS-1:0] apb_out_prdata, input [APB_CNT-1:0] apb_out_pready, input [APB_CNT-1:0] apb_out_pslverr, input [APB_CNT-1:0] apb_select ); genvar i; generate for (i = 0; i < APB_CNT; i = i + 1) begin : gen_per assign apb_out_psel[i] = apb_in_psel & apb_select[i]; assign apb_out_penable[i] = apb_in_penable & apb_select[i]; assign apb_out_pwrite[i] = apb_in_pwrite; assign apb_out_paddr[i*ADDR_BITS+:ADDR_BITS] = apb_in_paddr; assign apb_out_pwdata[i*DATA_BITS+:DATA_BITS] = apb_in_pwdata; end endgenerate reg [APB_CNT-1:0] pr_select; // These extra registers provide better timing to apb_in_prdata always @ (posedge apb_clock or negedge apb_resetn) begin if (!apb_resetn) begin pr_select <= 'b0; end else if (apb_in_psel && !apb_in_penable) begin pr_select <= apb_select; end end integer j; always @ (*) begin apb_in_prdata = 0; apb_in_pready = 1; apb_in_pslverr = 0; for (j = 0; j < APB_CNT; j = j + 1) begin apb_in_prdata = apb_in_prdata | (pr_select[j] ? apb_out_prdata[j*DATA_BITS+:DATA_BITS] : 0); apb_in_pready = apb_in_pready & (pr_select[j] ? apb_out_pready[j] : 1'b1); apb_in_pslverr = apb_in_pslverr | (pr_select[j] ? apb_out_pslverr[j] : 1'b0); end end endmodule