module or1200_wbmux_cm4(
		clk_i_cml_1,
		clk_i_cml_2,
		clk_i_cml_3,
		
	// Clock and reset
	clk, rst,

	// Internal i/f
	wb_freeze, rfwb_op,
	muxin_a, muxin_b, muxin_c, muxin_d,
	muxout, muxreg, muxreg_valid
);


input clk_i_cml_1;
input clk_i_cml_2;
input clk_i_cml_3;
reg  wb_freeze_cml_3;
reg [ 3 - 1 : 0 ] rfwb_op_cml_3;
reg [ 3 - 1 : 0 ] rfwb_op_cml_2;
reg [ 3 - 1 : 0 ] rfwb_op_cml_1;
reg [ 32 - 1 : 0 ] muxin_a_cml_2;
reg [ 32 - 1 : 0 ] muxin_d_cml_2;
reg [ 32 - 1 : 0 ] muxout_cml_3;
reg [ 32 - 1 : 0 ] muxreg_cml_3;
reg [ 32 - 1 : 0 ] muxreg_cml_2;
reg [ 32 - 1 : 0 ] muxreg_cml_1;
reg  muxreg_valid_cml_3;
reg  muxreg_valid_cml_2;
reg  muxreg_valid_cml_1;



parameter width = `OR1200_OPERAND_WIDTH;

//
// I/O
//

//
// Clock and reset
//
input				clk;
input				rst;

//
// Internal i/f
//
input				wb_freeze;
input	[`OR1200_RFWBOP_WIDTH-1:0]	rfwb_op;
input	[width-1:0]		muxin_a;
input	[width-1:0]		muxin_b;
input	[width-1:0]		muxin_c;
input	[width-1:0]		muxin_d;
output	[width-1:0]		muxout;
output	[width-1:0]		muxreg;
output				muxreg_valid;

//
// Internal wires and regs
//
reg	[width-1:0]		muxout;
reg	[width-1:0]		muxreg;
reg				muxreg_valid;

//
// Registered output from the write-back multiplexer
//

// SynEDA CoreMultiplier
// assignment(s): muxreg, muxreg_valid
// replace(s): wb_freeze, muxout, muxreg, rfwb_op, muxreg_valid
always @(posedge clk or posedge rst) begin
	if (rst) begin
		muxreg <= #1 32'd0;
		muxreg_valid <= #1 1'b0;
	end
	else begin  muxreg_valid <= muxreg_valid_cml_3; muxreg <= muxreg_cml_3; if (!wb_freeze_cml_3) begin
		muxreg <= #1 muxout_cml_3;
		muxreg_valid <= #1 rfwb_op_cml_3[0];
	end end
end

//
// Write-back multiplexer
//

// SynEDA CoreMultiplier
// assignment(s): muxout
// replace(s): rfwb_op, muxin_a, muxin_d
always @(muxin_a_cml_2 or muxin_b or muxin_c or muxin_d_cml_2 or rfwb_op_cml_2) begin
`ifdef OR1200_ADDITIONAL_SYNOPSYS_DIRECTIVES
	case(rfwb_op_cml_2[`OR1200_RFWBOP_WIDTH-1:1]) // synopsys parallel_case infer_mux
`else
	case(rfwb_op_cml_2[`OR1200_RFWBOP_WIDTH-1:1]) // synopsys parallel_case
`endif
		2'b00: muxout = muxin_a_cml_2;
		2'b01: begin
			muxout = muxin_b;
`ifdef OR1200_VERBOSE
// synopsys translate_off
			$display("  WBMUX: muxin_b %h", muxin_b);
// synopsys translate_on
`endif
		end
		2'b10: begin
			muxout = muxin_c;
`ifdef OR1200_VERBOSE
// synopsys translate_off
			$display("  WBMUX: muxin_c %h", muxin_c);
// synopsys translate_on
`endif
		end
		2'b11: begin
			muxout = muxin_d_cml_2 + 32'h8;
`ifdef OR1200_VERBOSE
// synopsys translate_off
			$display("  WBMUX: muxin_d %h", muxin_d + 4'h8);
// synopsys translate_on
`endif
		end
	endcase
end


always @ (posedge clk_i_cml_1) begin
rfwb_op_cml_1 <= rfwb_op;
muxreg_cml_1 <= muxreg;
muxreg_valid_cml_1 <= muxreg_valid;
end
always @ (posedge clk_i_cml_2) begin
rfwb_op_cml_2 <= rfwb_op_cml_1;
muxin_a_cml_2 <= muxin_a;
muxin_d_cml_2 <= muxin_d;
muxreg_cml_2 <= muxreg_cml_1;
muxreg_valid_cml_2 <= muxreg_valid_cml_1;
end
always @ (posedge clk_i_cml_3) begin
wb_freeze_cml_3 <= wb_freeze;
rfwb_op_cml_3 <= rfwb_op_cml_2;
muxout_cml_3 <= muxout;
muxreg_cml_3 <= muxreg_cml_2;
muxreg_valid_cml_3 <= muxreg_valid_cml_2;
end
endmodule