// Simple 2:1 alternating (round-robin) arbiter. // Switches master on ACK from slave unless selected master asserts LOCK. // Data from slave is sent to both masters. Address and data bus widths // are configurable, as is granularity. Default is 32-bit addresses and // data with byte granularity. module WB_ARB_2M (CLK_I, RST_I, SELECT_O, M0_ADR_I, M0_DAT_I, M0_DAT_O, M0_LOCK_I, M0_CYC_I, M0_STB_I, M0_WE_I, M0_SEL_I, M0_ACK_O, M0_ERR_O, M0_RTY_O, M1_ADR_I, M1_DAT_I, M1_DAT_O, M1_LOCK_I, M1_CYC_I, M1_STB_I, M1_WE_I, M1_SEL_I, M1_ACK_O, M1_ERR_O, M1_RTY_O, S_ADR_O, S_DAT_O, S_DAT_I, S_LOCK_O, S_CYC_O, S_STB_O, S_WE_O, S_SEL_O, S_ACK_I, S_ERR_I, S_RTY_I); parameter ADDR_WIDTH = 30; parameter DATA_WIDTH = 32; parameter SEL_WIDTH = 4; input CLK_I, RST_I; output SELECT_O; input [ADDR_WIDTH-1:0] M0_ADR_I, M1_ADR_I; input [DATA_WIDTH-1:0] M0_DAT_I, M1_DAT_I; output [DATA_WIDTH-1:0] M0_DAT_O, M1_DAT_O; input M0_LOCK_I, M1_LOCK_I; input M0_CYC_I, M1_CYC_I; input M0_STB_I, M1_STB_I; input M0_WE_I, M1_WE_I; input [SEL_WIDTH-1:0] M0_SEL_I, M1_SEL_I; output M0_ACK_O, M1_ACK_O; output M0_ERR_O, M1_ERR_O; output M0_RTY_O, M1_RTY_O; output [ADDR_WIDTH-1:0] S_ADR_O; output [DATA_WIDTH-1:0] S_DAT_O; input [DATA_WIDTH-1:0] S_DAT_I; output S_LOCK_O, S_CYC_O; output S_STB_O, S_WE_O; output [SEL_WIDTH-1:0] S_SEL_O; input S_ACK_I, S_ERR_I, S_RTY_I; reg SELECT_O = 1'bX; assign M0_DAT_O = ~SELECT_O ? S_DAT_I : 256'dX; assign M1_DAT_O = SELECT_O ? S_DAT_I : 256'dX; assign M0_ACK_O = S_ACK_I & ~SELECT_O; assign M1_ACK_O = S_ACK_I & SELECT_O; assign M0_ERR_O = S_ERR_I & ~SELECT_O; assign M1_ERR_O = S_ERR_I & SELECT_O; assign M0_RTY_O = S_RTY_I & ~SELECT_O; assign M1_RTY_O = S_RTY_I & SELECT_O; assign S_ADR_O = SELECT_O ? M1_ADR_I : M0_ADR_I; assign S_DAT_O = SELECT_O ? M1_DAT_I : M0_DAT_I; assign S_LOCK_O = SELECT_O ? M1_LOCK_I : M0_LOCK_I; assign S_CYC_O = SELECT_O ? M1_CYC_I : M0_CYC_I; assign S_STB_O = SELECT_O ? M1_STB_I : M0_STB_I; assign S_WE_O = SELECT_O ? M1_WE_I : M0_WE_I; assign S_SEL_O = SELECT_O ? M1_SEL_I : M0_SEL_I; wire CYC_END = (S_ACK_I | S_ERR_I | S_RTY_I); always @(posedge CLK_I) begin casex ({S_LOCK_O, CYC_END, M1_CYC_I, M0_CYC_I}) 4'b1XXX: SELECT_O <= SELECT_O; 4'b0111: SELECT_O <= ~SELECT_O; 4'b0X10: SELECT_O <= 1'b1; 4'b0X01: SELECT_O <= 1'b0; 4'b0XXX: SELECT_O <= SELECT_O; endcase end endmodule