/******************************************************************************/
/* */
/* 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. */
/* */
/******************************************************************************/
// @(#)rfrw_ctl.v 1.14 2/20/93
//
// **************************************************************
// High-level verilog model of FPU reg. file read/write control
//
// This module controls FP loads, stores, and result writebacks.
//
// **************************************************************
module rfrw_ctl
(ss_clock, ss_reset, ext_hold, ext_flush,
fload_w, ldf_w,
fstore_d, fprf_ra1, fprf_ra2, op3_d, op3_w,
d_rd, ir_rd_e, w_rd, fq_rd_q0,
rs1_dbl_issue, rd_dbl_q0,
fq_rs1_0, fq_rs2_0, fcmp_q0,
notrap_writeback, exemode,
fsr_ld_nh, rfin_select,
fpstmux_sel_e, fprf_hold_din, fprf_we, fprf_algn1, fprf_algn2,
fprf_byp1, fprf_byp2, fprf_byp3, fprf_wa,
ss_scan_mode);
input ss_clock
, // FPU clock
ss_reset
, // FPU reset
ext_hold
, // IU pipeline held (frozen)
ext_flush
, // FPU flush (IU trap)
fload_w
, // Indicate valid FP LOAD instr in W stage
ldf_w
, // ldf in W stage
fstore_d
; // Indicate valid FP STORE instr in decode
// (includes valid_decode term)
input [3:0] fprf_ra1
, // FP reg file port 1 read address
fprf_ra2
; // FP reg file port 2 read address
input [1:0] op3_d
, // op3[1:0] in D-stage
op3_w
; // op3[1:0] in W-stage
input [4:0] d_rd
; // rd field of decode
input [4:0] ir_rd_e
; // rd field of E-stage
input [4:0] w_rd
, // rd field in W-stage
fq_rd_q0
; // rd field in FQ0
input rs1_dbl_issue
, // operand size of FPop being issued
rd_dbl_q0
, // size of fq0 result
fq_rs1_0
, // low bit of rs1 reg field
fq_rs2_0
, // low bit of rs2 reg field
fcmp_q0
, // fcmp in q0
notrap_writeback
, // writeback q0 if no fpu exception
exemode
; // fpu in execute model
input ss_scan_mode
; // scan enable
output fsr_ld_nh
, // FSR load control (needs ~ext_hold term)
rfin_select
; // data-in source select (D-cache or FPU)
output [2:0] fpstmux_sel_e
; // FPU store data mux controls
output [1:0] fprf_hold_din
, // FP reg file data in register load control
fprf_we
, // FP reg file write enable controls
fprf_algn1
, // FP reg file port 1 alignment controls
fprf_algn2
; // FP reg file port 2 alignment controls
output [5:0] fprf_byp1
, // FP reg file port 1 internal bypass controls
fprf_byp2
, // FP reg file port 2 internal bypass controls
fprf_byp3
; // FP reg file port 3 internal bypass controls
output [3:0] fprf_wa
; // FP reg file write address
wire scan_cut_hold
;
ME_TIEOFF toff(,gnd
);
wire no_holds
= ~ext_hold ;
// state machine clear
wire reset_l
= ~ss_reset ;
// This flip-flop is only used during scan operations.
// It will be connected by the scan-stitcher when this
// block is routed.
ME_FD1R cuthold (.d(gnd), .cp(ss_clock), .cr(reset_l), .q(scan_cut_hold) );
// **********************************************************************
//
// RF write data path controls
//
// lddf (unqual) in W-stage
wire lddf_w
= op3_w[1] & op3_w[0] ;
// ldfsr (unqual) in W-stage
wire ldfsr_w
= ~op3_w[1] & op3_w[0] ;
// odd register write control
wire write_odd
= notrap_writeback ? (rd_dbl_q0 | fq_rd_q0[0]) :
(lddf_w | (ldf_w & w_rd[0])) ;
// even register write control
wire write_even
= notrap_writeback ? (rd_dbl_q0 | ~fq_rd_q0[0]) :
(lddf_w | (ldf_w & ~w_rd[0])) ;
// datain_hold controls fpu reg. file data in register
// (ext_hold & ~notrap_writeback) | ~write_odd;
ME_A2O1_B iu_hold_gate_4 (.a( ext_hold ), .b( ~notrap_writeback ),
.c( ~write_odd ), .z( fprf_hold_din[0] ) );
// (ext_hold & ~notrap_writeback) | ~write_even;
ME_A2O1_B iu_hold_gate_5 (.a( ext_hold ), .b( ~notrap_writeback ),
.c( ~write_even ), .z( fprf_hold_din[1] ) );
// okay for load to write rf
wire allow_load_nh
= fload_w & ~ext_flush & exemode ;
//synopsys translate_off
wire allow_load
= ~ext_hold & allow_load_nh ;
//synopsys translate_on
// okay for wb to write rf
wire allow_wb
= notrap_writeback & ~fcmp_q0 & exemode ;
// FSR load control
wire fsr_ld_nh = ldfsr_w & allow_load_nh ; // requires "& ~ext_hold"
// FP load/FPop writeback address
ME_MUX_2B_4 rfwa_mux (notrap_writeback, w_rd[4:1], fq_rd_q0[4:1], fprf_wa[3:0]) ;
// default select is ld_fpu_w (D-cache output)
assign rfin_select = ~notrap_writeback ;
// odd register write enable
// fprf_we[0] = write_odd & (allow_load | allow_wb) & ~scan_cut_hold;
wire fprf_we_x_0
= allow_load_nh & write_odd & ~scan_cut_hold ;
wire fprf_we_y_0
= allow_wb & write_odd & ~scan_cut_hold ;
ME_AI2O1_C iu_hold_gate_6 (.a( fprf_we_x_0 ), .b( ext_hold ),
.c( fprf_we_y_0 ), .z( fprf_we[0] ) );
// even register write enable
// fprf_we[1] = write_even & (allow_load | allow_wb) & ~scan_cut_hold;
wire fprf_we_x_1
= allow_load_nh & write_even & ~scan_cut_hold ;
wire fprf_we_y_1
= allow_wb & write_even & ~scan_cut_hold ;
ME_AI2O1_C iu_hold_gate_7 (.a( fprf_we_x_1 ), .b( ext_hold ),
.c( fprf_we_y_1 ), .z( fprf_we[1] ) );
// **********************************************************************
//
// RF read data path controls
//
// fp_dout store datapath
// operation fpstmux_sel_e[2:0] fp_dout[63: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]}
// stdf 001 = {fprf_dout3[63:32], fprf_dout3[31: 0]}
// stfsr 100 = fsr
// stdfq 111 = fq (instr,adr)
wire stf_d
= fstore_d & ~op3_d[1] & ~op3_d[0] ;
wire stfsr_d
= fstore_d & ~op3_d[1] & op3_d[0];
wire stdfq_d
= fstore_d & op3_d[1] & ~op3_d[0];
wire stdf_d
= fstore_d & op3_d[1] & op3_d[0];
wire [2:0] fpstmux_sel_d
;
assign fpstmux_sel_d[0] = (stf_d & d_rd[0]) | stdfq_d | stdf_d ;
assign fpstmux_sel_d[1] = (stf_d & d_rd[0]) | stdfq_d ;
assign fpstmux_sel_d[2] = stfsr_d | stdfq_d ;
ME_FDS2LP3 fpstmux_reg (.Q(fpstmux_sel_e[2:0]), .CP(ss_clock), .CR(reset_l),
.D(fpstmux_sel_d[2:0]), .LD(no_holds) );
// rs1 is single from odd register
wire pre_sgl_odd_1
= ~rs1_dbl_issue & fq_rs1_0 ;
ME_FD1P sgl1_ff (.q(sgl_odd_1
), .cp(ss_clock), .d(pre_sgl_odd_1) );
assign fprf_algn1[1] = sgl_odd_1 ;
assign fprf_algn1[0] = ~sgl_odd_1 ;
// rs2 is single from odd register
wire pre_sgl_odd_2
= ~rs1_dbl_issue & fq_rs2_0 ;
ME_FD1P sgl2_ff (.q(sgl_odd_2
), .cp(ss_clock), .d(pre_sgl_odd_2) );
assign fprf_algn2[1] = sgl_odd_2 ;
assign fprf_algn2[0] = ~sgl_odd_2 ;
// reg. file port 1 bypass controls
ME_COMP4 cmp_wa_ra1 (fprf_wa[3:0], fprf_ra1[3:0], match_ra1
);
// byp1_lin = match_ra1 & fprf_we[0] ;
ME_AI2O1_C iu_hold_gate_8 (.a( (match_ra1 & fprf_we_x_0) ), .b( ext_hold ),
.c( (match_ra1 & fprf_we_y_0) ), .z( byp1_lin
) );
// byp1_hin = match_ra1 & fprf_we[1] ;
ME_AI2O1_C iu_hold_gate_9 (.a( (match_ra1 & fprf_we_x_1) ), .b( ext_hold ),
.c( (match_ra1 & fprf_we_y_1) ), .z( byp1_hin
) );
ME_FD1P byp1_lo_ff (.q(fprf_byp1[2]), .qn(fprf_byp1[0]), .cp(ss_clock),
.d(byp1_lin) );
assign fprf_byp1[1] = 1'b0 ;
ME_FD1P byp1_hi_ff (.q(fprf_byp1[5]), .qn(fprf_byp1[3]), .cp(ss_clock),
.d(byp1_hin) );
assign fprf_byp1[4] = 1'b0 ;
// reg. file port 2 bypass controls
ME_COMP4 cmp_wa_ra2 (fprf_wa[3:0], fprf_ra2[3:0], match_ra2
);
// byp2_lin = match_ra2 & fprf_we[0] ;
ME_AI2O1_C iu_hold_gate_10 (.a( (match_ra2 & fprf_we_x_0) ), .b( ext_hold ),
.c( (match_ra2 & fprf_we_y_0) ), .z( byp2_lin
) );
// byp2_hin = match_ra2 & fprf_we[1] ;
ME_AI2O1_C iu_hold_gate_11 (.a( (match_ra2 & fprf_we_x_1) ), .b( ext_hold ),
.c( (match_ra2 & fprf_we_y_1) ), .z( byp2_hin
) );
ME_FD1P byp2_lo_ff (.q(fprf_byp2[2]), .qn(fprf_byp2[0]), .cp(ss_clock),
.d(byp2_lin) );
assign fprf_byp2[1] = 1'b0 ;
ME_FD1P byp2_hi_ff (.q(fprf_byp2[5]), .qn(fprf_byp2[3]), .cp(ss_clock),
.d(byp2_hin) );
assign fprf_byp2[4] = 1'b0 ;
// reg. file port 3 bypass controls
ME_COMP4 cmp_wa_ra3_d (fprf_wa[3:0], d_rd[4:1], match_ra3_d
);
ME_COMP4 cmp_wa_ra3_e (fprf_wa[3:0], ir_rd_e[4:1], match_ra3_e
);
// match_ra3 = ext_hold ? match_ra3_e : match_ra3_d ;
// byp3_lin = match_ra3 & fprf_we[0] ;
wire byp3_lin_a
= match_ra3_d & (fprf_we_x_0 | fprf_we_y_0);
wire byp3_lin_b
= match_ra3_e & fprf_we_y_0;
ME_MUX2B iu_hold_gate_12 (.z(byp3_lin
), .a(byp3_lin_a), .b(byp3_lin_b),
.s(ext_hold) );
// byp3_hin = match_ra3 & fprf_we[1] ;
wire byp3_hin_a
= match_ra3_d & (fprf_we_x_1 | fprf_we_y_1);
wire byp3_hin_b
= match_ra3_e & fprf_we_y_1;
ME_MUX2B iu_hold_gate_13 (.z(byp3_hin
), .a(byp3_hin_a), .b(byp3_hin_b),
.s(ext_hold) );
ME_FD1P byp3_lo_ff (.q(fprf_byp3[2]), .qn(fprf_byp3[0]), .cp(ss_clock),
.d(byp3_lin) );
assign fprf_byp3[1] = 1'b0 ;
ME_FD1P byp3_hi_ff (.q(fprf_byp3[5]), .qn(fprf_byp3[3]), .cp(ss_clock),
.d(byp3_hin) );
assign fprf_byp3[4] = 1'b0 ;
endmodule
This page: |
Created: | Thu Aug 19 11:59:34 1999 |
| From: |
../../../sparc_v8/ssparc/fpu/fp_fpc/rtl/rfrw_ctl.v
|