/******************************************************************************/
/* */
/* Copyright (c) 1999 Sun Microsystems, Inc. All rights reserved. */
/* */
/* The contents of this file are subject to the current version of the Sun */
/* Community Source License, microSPARCII ("the License"). You may not use */
/* this file except in compliance with the License. You may obtain a copy */
/* of the License by searching for "Sun Community Source License" on the */
/* World Wide Web at http://www.sun.com. See the License for the rights, */
/* obligations, and limitations governing use of the contents of this file. */
/* */
/* Sun Microsystems, Inc. has intellectual property rights relating to the */
/* technology embodied in these files. In particular, and without limitation, */
/* these intellectual property rights may include one or more U.S. patents, */
/* foreign patents, or pending applications. */
/* */
/* Sun, Sun Microsystems, the Sun logo, all Sun-based trademarks and logos, */
/* Solaris, Java and all Java-based trademarks and logos are trademarks or */
/* registered trademarks of Sun Microsystems, Inc. in the United States and */
/* other countries. microSPARC is a trademark or registered trademark of */
/* SPARC International, Inc. All SPARC trademarks are used under license and */
/* are trademarks or registered trademarks of SPARC International, Inc. in */
/* the United States and other countries. Products bearing SPARC trademarks */
/* are based upon an architecture developed by Sun Microsystems, Inc. */
/* */
/******************************************************************************/
// @(#)fp_qst.v 1.17 2/20/93
//
// **********************************************************************
// High-level verilog model of instruction queue (FQ) and store datapath;
// contains fpu instruction and address registers.
//
// **********************************************************************
module fp_qst
(ss_clock, inst_for_int, iu_epc, fsr_out, fprf_dout3, fq_ld_nval,
fq_src_sel, fpstmux_sel_e, hld_ir_d, fq_update, ext_hold,
ext_flush, ir_d, ir_rd_e, ir_rs1_e, ir_rs2_e,
rs1_dbl_issue, fq_rd_used, fq_rs1_dbl, fq_rs1_used,
fq_rs1_0, fq_rs2_0, opf5_q0, fq_ir_0, fq_ir_1, fq_ir_2,
fprf_ra1, fprf_ra2, FpInst, fpm_inst, fp_dout_e);
input [31:0] inst_for_int
; // Input to D-stage instruction register
input [31:2] iu_epc
; // tap from IU E-stage pc (30-bits)
input [22:0] fsr_out
; // output of fsr (non-constant bits)
input [63:0] fprf_dout3
; // store port of fpu reg file
input [2:0] fq_ld_nval
; // queue load control, not validated
input [1:0] fq_src_sel
; // FQ output source mux selects
input ss_clock
, // FPU clock
hld_ir_d
, // inverted load signal for decode register,
// must be gated with ext_hold.
fq_update
, // update fifo for writeback or stdfq
ext_hold
, // IU pipeline held (frozen)
ext_flush
; // FPU flush (IU trap)
input [2:0] fpstmux_sel_e
; // fp_dout_e mux selects
output [31:0] ir_d
; // D-stage instruction register output
output [ 4:0] ir_rd_e
, // E-stage instr. reg. field outputs
ir_rs1_e
,
ir_rs2_e
;
output rs1_dbl_issue
, // operand size of FPop being issued
fq_rs1_0
, // low bit of rs1 reg field
fq_rs2_0
, // low bit of rs2 reg field
opf5_q0
; // opf[5] of fq0
output [ 2:0] fq_rd_used
, // indicates whether or not rd is used
fq_rs1_dbl
, // size of rs1,rs2
fq_rs1_used
; // indicates whether rs1 is used
output [15:0] fq_ir_0
, // fq outputs to rest of fpc
fq_ir_1
,
fq_ir_2
;
output [ 3:0] fprf_ra1
, // FP reg file port 1 read address
fprf_ra2
; // FP reg file port 2 read address
output [ 9:0] FpInst
; // FPop instruction
output [ 1:0] fpm_inst
; // multiplier instruction (size)
output [63:0] fp_dout_e
; // output data bus from FPU into the IU
wire [31:0] ir_d ;
wire [24:0] ir_ibits_e
;
wire [24:0] qi_0
, qi_1
, qi_2
;
wire [15:0] fq_ir_0, fq_ir_1, fq_ir_2 ;
wire [31:2] qa_0
, qa_1
, qa_2
;
wire [63:0] fp_dout_unbuff
;
ME_TIEOFF toff(vdd
,gnd
);
assign opf5_q0 = qi_0[10] ;
// format:
// [15:11] [10] [9:5] [4:0]
// rd op3[0] rs1 rs2
assign fq_ir_0[15:5] = qi_0[24:14] ;
assign fq_ir_0[ 4:0] = qi_0[ 4: 0] ;
assign fq_ir_1[15:5] = qi_1[24:14] ;
assign fq_ir_1[ 4:0] = qi_1[ 4: 0] ;
assign fq_ir_2[15:5] = qi_2[24:14] ;
assign fq_ir_2[ 4:0] = qi_2[ 4: 0] ;
wire no_holds
= ~ext_hold ;
// **********************************************************************
// load controls duplicated in qcore_ctl
wire [2:0] fq_ld
, fq_ld_nh
, fq_ld_ctl
;
assign fq_ld_nh[0] = fq_ld_nval[0] & ~ext_flush ;
assign fq_ld_nh[1] = fq_ld_nval[1] & ~ext_flush ;
assign fq_ld_nh[2] = fq_ld_nval[2] & ~ext_flush ;
// fq_ld[x] = ~ext_hold & fq_ld_nh[x];
// ~fq_ld[x] = ~(ext_hold | ~fq_ld_nh[x]);
// fq_ld_ctl[x] = (~ext_hold & fq_ld_nh[x]) | fq_update;
// ~fq_ld_ctl[x] = (ext_hold | ~fq_ld_nh[x]) & ~fq_update;
// **********************************************************************
// load control for decode register
// hold_d = (ext_hold | hld_ir_d);
wire [3:0] hold_d
;
ME_OR2_B iu_hold_gate_1 (.a(ext_hold), .b(hld_ir_d), .z(hold_d[0]) );
ME_OR2_B iu_hold_gate_2 (.a(ext_hold), .b(hld_ir_d), .z(hold_d[1]) );
ME_OR2_B iu_hold_gate_3 (.a(ext_hold), .b(hld_ir_d), .z(hold_d[2]) );
ME_OR2_B iu_hold_gate_4 (.a(ext_hold), .b(hld_ir_d), .z(hold_d[3]) );
// decode instruction register (FPU copy)
ME_FREG_H_32 ir_reg_d (ss_clock, hold_d[3:0], inst_for_int[31:0], ir_d[31:0] );
// non-constant bits of FPU instructions
// format:
// [24:20] [19] [18:14] [13:5] [4:0]
// rd op3[0] rs1 opf rs2
wire [24:0] ir_ibits_d
= {ir_d[29:25], ir_d[19:0]} ;
// **********************************************************************
// E-stage instruction register
wire ld_ir_e
= ~ext_hold ;
ME_FREGA_1_25 ir_reg_e (ss_clock, ld_ir_e, ir_ibits_d, ir_ibits_e);
assign ir_rd_e = ir_ibits_e[24:20] ;
assign ir_rs1_e = ir_ibits_e[18:14] ;
assign ir_rs2_e = ir_ibits_e[4:0] ;
// **********************************************************************
// fpu queue (FQ) registers (built-in 2:1 mux)
// fq_hold[x] = (ext_hold | ~fq_ld_nh[x]) & ~fq_update;
// fq_sel[x] = ~(ext_hold | ~fq_ld_nh[x]);
ME_FREGA_2_55 fq2_reg ( .clk(ss_clock),
.a(ext_hold), .b(~fq_ld_nh[2]), .c(1'b1),
.d0( 55'b0 ),
.d1( {ir_ibits_e[24:0], iu_epc[31:2]} ),
.Q( {qi_2[24:0], qa_2[31:2]} ));
ME_FREGA_2_55 fq1_reg ( .clk(ss_clock),
.a(ext_hold), .b(~fq_ld_nh[1]), .c(~fq_update),
.d0( {qi_2[24:0], qa_2[31:2]} ),
.d1( {ir_ibits_e[24:0], iu_epc[31:2]} ),
.Q( {qi_1[24:0], qa_1[31:2]} ));
ME_FREGA_2_55 fq0_reg ( .clk(ss_clock),
.a(ext_hold), .b(~fq_ld_nh[0]), .c(~fq_update),
.d0( {qi_1[24:0], qa_1[31:2]} ),
.d1( {ir_ibits_e[24:0], iu_epc[31:2]} ),
.Q( {qi_0[24:0], qa_0[31:2]} ));
// **********************************************************************
// register file read address muxes
ME_MUX_4B_4 rfra1_mux (fq_src_sel[0], fq_src_sel[1], qi_0[18:15], qi_1[18:15],
qi_2[18:15], ir_ibits_e[18:15], fprf_ra1[3:0] );
ME_MUX4B fq_rs1_0_mux (fq_src_sel[0], fq_src_sel[1], qi_0[14], qi_1[14],
qi_2[14], ir_ibits_e[14], fq_rs1_0) ;
ME_MUX_4B_4 rfra2_mux (fq_src_sel[0], fq_src_sel[1], qi_0[4:1], qi_1[4:1],
qi_2[4:1], ir_ibits_e[4:1], fprf_ra2[3:0] );
ME_MUX4B fq_rs2_0_mux (fq_src_sel[0], fq_src_sel[1], qi_0[0], qi_1[0],
qi_2[0], ir_ibits_e[0], fq_rs2_0) ;
// FPop instruction mux
ME_MUX_4B_10 fpinst_mux (fq_src_sel[0], fq_src_sel[1], {qi_0[19], qi_0[13:5]},
{qi_1[19], qi_1[13:5]}, {qi_2[19], qi_2[13:5]},
{ir_ibits_e[19], ir_ibits_e[13:5]}, FpInst[9:0] );
// opf[1]==size of source operands (1==dbl)
ME_MUX4B src_size_mux (fq_src_sel[0], fq_src_sel[1], qi_0[6], qi_1[6], qi_2[6],
ir_ibits_e[6], rs1_dbl_issue) ;
wire [1:0] i_fpm_inst
= {FpInst[5], FpInst[1]};
ME_FD1P2 fpminst_ff (.Q(fpm_inst[1:0]), .CP(ss_clock), .D(i_fpm_inst[1:0]) );
// **********************************************************************
// FQ instruction decodes
// rd reg used = (opf[7] | ~opf[4])
assign fq_rd_used[0] = qi_0[12] | ~qi_0[9] ;
assign fq_rd_used[1] = qi_1[12] | ~qi_1[9] ;
assign fq_rd_used[2] = qi_2[12] | ~qi_2[9] ;
// rs1 reg size = opf[1]
assign fq_rs1_dbl[0] = qi_0[6] ;
assign fq_rs1_dbl[1] = qi_1[6] ;
assign fq_rs1_dbl[2] = qi_2[6] ;
// rs1 reg used = (~opf[7] & opf[6])
assign fq_rs1_used[0] = ~qi_0[12] & qi_0[11] ;
assign fq_rs1_used[1] = ~qi_1[12] & qi_1[11] ;
assign fq_rs1_used[2] = ~qi_2[12] & qi_2[11] ;
// **********************************************************************
// combine non-constant and constant bits
wire [63:0] fq_out
;
assign fq_out[63:32] = {qa_0[31:2], // fq address[31:2]
gnd, gnd }; // fq address[1:0]
assign fq_out[31:0] = {vdd, gnd, // op field [31:0]
qi_0[24:20], // rd field [29:25]
vdd, vdd, gnd, vdd, gnd, // op3 field [24:20]
qi_0[19:0] }; // rest of instr.
// combine non-constant and constant fsr bits
wire [31:0] fsr
= {fsr_out[22:21], // fsr[31:30] : rounding mode
gnd, gnd, // fsr[29:28] : unused
fsr_out[20:16], // fsr[27:23] : trap enable mask
gnd, // fsr[22] : NS bit
gnd, gnd, // fsr[21:20] : reserved
vdd, gnd, gnd, // fsr[19:17] : version number
fsr_out[15:13], // fsr[16:14] : ftt field
fsr_out[12], // fsr[13] : qne bit
gnd, // fsr[12] : unused
fsr_out[11:10], // fsr[11:10] : condition codes
fsr_out[9:5], // fsr[9:5] : aexc field
fsr_out[4:0] }; // fsr[4:0] : cexc field
// fp_dout_e store datapath
// operation fpstmux_sel_e[2:0] fp_dout_e
// stdf 001 = {fprf_dout3[63:32], fprf_dout3[31: 0]}
// stf (even reg) 000 = {fprf_dout3[63:32], fprf_dout3[63:32]}
// stf (odd reg) 011 = {fprf_dout3[31: 0], fprf_dout3[31: 0]}
// stfsr 100 = fsr
// stdfq 111 = fq (instr,adr)
ME_MUX41H32 fpst_mux1 (fp_dout_unbuff[63:32],
fprf_dout3[63:32], fprf_dout3[31:0],
fsr[31:0], fq_out[63:32],
fpstmux_sel_e[1], fpstmux_sel_e[2] );
ME_MUX41H32 fpst_mux0 (fp_dout_unbuff[31:0],
fprf_dout3[63:32], fprf_dout3[31:0],
fsr[31:0], fq_out[31:0],
fpstmux_sel_e[0], fpstmux_sel_e[2] );
ME_BUF32_C fpst_buff1 ( fp_dout_unbuff[63:32], fp_dout_e[63:32] );
ME_BUF32_C fpst_buff0 ( fp_dout_unbuff[31:0], fp_dout_e[31:0] );
endmodule
This page: |
Created: | Thu Aug 19 11:57:39 1999 |
| From: |
../../../sparc_v8/ssparc/fpu/fp_fpc/rtl/fp_qst.v
|