aboutsummaryrefslogtreecommitdiff
/* An arbiter, that always gives priority to M0 */
`default_nettype none

module master_arbiter
  (
   input wire 	      CLK,
   input wire 	      RST,

   output wire 	      M0_ACK_I,
   input wire [19:0]  M0_ADR_O,
   output wire [15:0] M0_DAT_I,
   input wire [15:0]  M0_DAT_O,
   input wire 	      M0_STB_O,
   input wire 	      M0_CYC_O,
   input wire 	      M0_WE_O,
   output wire 	      M0_STALL_I,

   output wire 	      M1_ACK_I,
   input wire [19:0]  M1_ADR_O,
   output wire [15:0] M1_DAT_I,
   input wire [15:0]  M1_DAT_O,
   input wire 	      M1_STB_O,
   input wire 	      M1_CYC_O,
   input wire 	      M1_WE_O,
   output wire 	      M1_STALL_I,

   input wire 	      M_COMBINED_ACK_I,
   output wire [19:0] M_COMBINED_ADR_O,
   input wire [15:0]  M_COMBINED_DAT_I,
   output wire [15:0] M_COMBINED_DAT_O,
   output wire 	      M_COMBINED_STB_O,
   output wire 	      M_COMBINED_CYC_O,
   output wire 	      M_COMBINED_WE_O,
   input wire 	      M_COMBINED_STALL_I
   );

   reg 		      M1_holding_bus;

   wire 	      working;
   wire 	      M0_selected;
   wire 	      M1_selected;

   assign M0_selected = M0_CYC_O && !(M1_holding_bus && M1_CYC_O);
   assign M1_selected = M1_CYC_O && !M0_selected;

   assign M_COMBINED_ADR_O = M0_selected ? M0_ADR_O :
			     M1_selected ? M1_ADR_O : 20'bx;
   assign M_COMBINED_DAT_O = M0_selected ? M0_DAT_O :
			     M1_selected ? M1_DAT_O : 16'bx;
   assign M_COMBINED_STB_O = M0_selected ? M0_STB_O :
			     M1_selected ? M1_STB_O : 0;
   assign M_COMBINED_CYC_O = M0_CYC_O || M1_CYC_O;
   assign M_COMBINED_WE_O = M0_selected ? M0_WE_O :
			    M1_selected ? M1_WE_O : 1'bx;

   assign M0_ACK_I = M0_selected && M_COMBINED_ACK_I;
   assign M0_DAT_I = M_COMBINED_DAT_I;
   assign M0_STALL_I = M1_selected || M_COMBINED_STALL_I;

   assign M1_ACK_I = M1_selected && M_COMBINED_ACK_I;
   assign M1_DAT_I = M_COMBINED_DAT_I;
   assign M1_STALL_I = M0_selected || M_COMBINED_STALL_I;

   always @ (posedge CLK) begin
      if (RST)
	M1_holding_bus <= 0;
      else
	M1_holding_bus <= M1_selected;
   end
endmodule // master_arbiter