// ========== Copyright Header Begin ========================================== // // OpenSPARC T1 Processor File: fpu_out_ctl.v // Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. // // The above named program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public // License version 2 as published by the Free Software Foundation. // // The above named program is distributed in the hope that it will be // useful, but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // // You should have received a copy of the GNU General Public // License along with this work; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. // // ========== Copyright Header End ============================================ /////////////////////////////////////////////////////////////////////////////// // // FPU output control logic. // /////////////////////////////////////////////////////////////////////////////// module fpu_out_ctl ( d8stg_fdiv_in, m6stg_fmul_in, a6stg_fadd_in, div_id_out_in, m6stg_id_in, add_id_out_in, arst_l, grst_l, rclk, fp_cpx_req_cq, req_thread, dest_rdy, add_dest_rdy, mul_dest_rdy, div_dest_rdy, se, si, so ); input d8stg_fdiv_in; // div pipe output request next cycle input m6stg_fmul_in; // mul pipe output request next cycle input a6stg_fadd_in; // add pipe output request next cycle input [9:0] div_id_out_in; // div pipe output ID next cycle input [9:0] m6stg_id_in; // mul pipe output ID next cycle input [9:0] add_id_out_in; // add pipe output ID next cycle input arst_l; // global async. reset- asserted low input grst_l; // global sync. reset- asserted low input rclk; // global clock output [7:0] fp_cpx_req_cq; // FPU result request to CPX output [1:0] req_thread; // thread ID of result req this cycle output [2:0] dest_rdy; // pipe with result request this cycle output add_dest_rdy; // add pipe result request this cycle output mul_dest_rdy; // mul pipe result request this cycle output div_dest_rdy; // div pipe result request this cycle input se; // scan_enable input si; // scan in output so; // scan out wire reset; wire add_req_in; wire add_req_step; wire add_req; wire div_req_sel; wire mul_req_sel; wire add_req_sel; wire [9:0] out_id; wire [7:0] fp_cpx_req_cq; wire [1:0] req_thread; wire [2:0] dest_rdy_in; wire [2:0] dest_rdy; wire add_dest_rdy; wire mul_dest_rdy; wire div_dest_rdy; dffrl_async #(1) dffrl_out_ctl ( .din (grst_l), .clk (rclk), .rst_l(arst_l), .q (out_ctl_rst_l), .se (se), .si (), .so () ); assign reset= (!out_ctl_rst_l); /////////////////////////////////////////////////////////////////////////////// // // Arbitrate for the output. // // Top priority- divide. // Low priority- round robin arbitration between the add and multiply // pipes. // /////////////////////////////////////////////////////////////////////////////// assign add_req_in= (!add_req); assign add_req_step= add_req_sel || mul_req_sel; dffre_s #(1) i_add_req ( .din (add_req_in), .en (add_req_step), .rst (reset), .clk (rclk), .q (add_req), .se (se), .si (), .so () ); assign div_req_sel= d8stg_fdiv_in; assign mul_req_sel= m6stg_fmul_in && ((!add_req) || (!a6stg_fadd_in)) && (!div_req_sel); assign add_req_sel= a6stg_fadd_in && (add_req || (!m6stg_fmul_in)) && (!div_req_sel); /////////////////////////////////////////////////////////////////////////////// // // Generate the request. // // Input to the output request (CQ) stage. // /////////////////////////////////////////////////////////////////////////////// assign out_id[9:0]= ({10{div_req_sel}} & div_id_out_in[9:0]) | ({10{mul_req_sel}} & m6stg_id_in[9:0]) | ({10{add_req_sel}} & add_id_out_in[9:0]); dff_s #(8) i_fp_cpx_req_cq ( .din (out_id[9:2]), .clk (rclk), .q (fp_cpx_req_cq[7:0]), .se (se), .si (), .so () ); /////////////////////////////////////////////////////////////////////////////// // // Capture the thread. // // Input to the output request (CQ) stage. // /////////////////////////////////////////////////////////////////////////////// dff_s #(2) i_req_thread ( .din (out_id[1:0]), .clk (rclk), .q (req_thread[1:0]), .se (se), .si (), .so () ); /////////////////////////////////////////////////////////////////////////////// // // Capture the pipe that wins the output request. // // Input to the output request (CQ) stage. // /////////////////////////////////////////////////////////////////////////////// assign dest_rdy_in[2:0]= {div_req_sel, mul_req_sel, add_req_sel}; dff_s #(3) i_dest_rdy ( .din (dest_rdy_in[2:0]), .clk (rclk), .q (dest_rdy[2:0]), .se (se), .si (), .so () ); dff_s i_add_dest_rdy ( .din (add_req_sel), .clk (rclk), .q (add_dest_rdy), .se (se), .si (), .so () ); dff_s i_mul_dest_rdy ( .din (mul_req_sel), .clk (rclk), .q (mul_dest_rdy), .se (se), .si (), .so () ); dff_s i_div_dest_rdy ( .din (div_req_sel), .clk (rclk), .q (div_dest_rdy), .se (se), .si (), .so () ); endmodule