------------------------------------------------------------------------------- -- File name : fpurt_gen_ent.vhd -- Title : FPURTGeneric (entity) -- project : SPARC -- Library : FPURTLIB -- Author(s) : Maxime ROCCA -- Purpose : definition of entity FPURTGeneric -- -- notes : -- ------------------------------------------------------------------------------- -- Modification history : ------------------------------------------------------------------------------- -- Version No : | Author | Mod. Date : | Changes made : ------------------------------------------------------------------------------- -- v 1.0 | MR | 94-03-04 | first version --............................................................................. -- v 1.1 | MR | 94-05-27 | 2nd version -- + modification of timing checkers. ------------------------------------------------------------------------------ -- Copyright MATRA MARCONI SPACE FRANCE -- This library is free software; you can redistribute it and/or -- modify it under the terms of the GNU Library General Public -- License as published by the Free Software Foundation; either -- version 2 of the License, or (at your option) any later version. -- This library 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 -- Library General Public License for more details. -- You should have received a copy of the GNU Library General Public -- License along with this library; if not, write to the Free -- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ------------------------------------------------------------------------------- ---------|---------|---------|---------|---------|---------|---------|--------| library IEEE; use IEEE.Std_Logic_1164.all; library MMS; use MMS.StdIoImp.all; use MMS.StdSim.all; use MMS.StdTiming.all; entity FPURTGeneric is generic( -- Fake default timing values tCY : time := 50 ns; -- Clock cycle tCHL : time := 22 ns; -- CLock High and Low tAS : time := 5 ns; -- A input setup tAH : time := 1 ns; -- A input hold tDIS : time := 5 ns; -- D input setup tDIH : time := 1 ns; -- D input hold tDOD : time := 7 ns; -- D output delay tDOH : time := 6 ns; -- D data valid tDOFFL : time := 7 ns; -- D output turn-off (FLUSH+) tDOHFL : time := 6 ns; -- D output valid (FLUSH+) tDOFOE : time := 7 ns; -- D output turn-off (DOE_N+) tDONOE : time := 7 ns; -- D output turn-on (DOE_N-) tDOHOE : time := 6 ns; -- D output valid (DOE_N-) tFIS : time := 5 ns; -- FINS1/2 input setup tFIH : time := 1 ns; -- FINS1/2 input hold tINS : time := 5 ns; -- INST input setup tINH : time := 1 ns; -- INST input hold tFXS : time := 5 ns; -- FXACK input setup tFXH : time := 1 ns; -- FXACK input hold tFLS : time := 5 ns; -- FLUSH input setup tFLH : time := 1 ns; -- FLUSH input hold tRES : time := 5 ns; -- RESET_N input setup tREH : time := 1 ns; -- RESET_N input hold tMHS : time := 5 ns; -- MHOLD_N input setup tMHH : time := 1 ns; -- MHOLD_N input hold tMDS : time := 5 ns; -- MDS_N input setup tMDH : time := 1 ns; -- MDS_N input hold tFHD : time := 7 ns; -- FHOLD_N output delay tFHH : time := 6 ns; -- FHOLD_N output valid tFHDFI : time := 7 ns; -- FHOLD_N output delay (FINS1/2+) tFHDFL : time := 7 ns; -- FHOLD_N output delay (FLUSH+) tFHDMH : time := 7 ns; -- FHOLD_N output delay (MHOLD_N-) tFCCVD : time := 7 ns; -- FCCV output delay tFCCVH : time := 6 ns; -- FCCV output valid tFCCVDFL : time := 7 ns; -- FCCV output delay (FLUSH+) tFCCVDMH : time := 7 ns; -- FCCV output delay (MHOLD_N-) tFCCD : time := 7 ns; -- FCC output delay tFCCH : time := 6 ns; -- FCC output valid tFED : time := 7 ns; -- FEXC_N output delay tFEH : time := 6 ns; -- FEXC_N output valid tFND : time := 7 ns; -- FNULL output delay tFNH : time := 6 ns; -- FNULL output valid tAPS : time := 7 ns; -- APAR input setup tAPH : time := 6 ns; -- APAR input hold tDPIS : time := 7 ns; -- DPAR input setup tDPIH : time := 6 ns; -- DPAR input hold tDPOD : time := 7 ns; -- DPAR output delay tDPOH : time := 6 ns; -- DPAR output valid tIFS : time := 7 ns; -- IFPAR input setup tIFH : time := 6 ns; -- IFPAR input hold tFIPD : time := 7 ns; -- FIPAR output delay tFIPH : time := 6 ns; -- FIPAR output valid tMCD : time := 7 ns; -- MCERR_N output delay tMCH : time := 6 ns; -- MCERR_N output valid tCMS : time := 5 ns; -- N602MODE_N, CMODE_N input setup tHAS : time := 5 ns; -- HALT_N input setup tHAH : time := 1 ns; -- HALT_N input hold tHAD : time := 7 ns; -- HALT_N asserted to output disable delay tHAE : time := 7 ns; -- HALT_N asserted to output enable delay tERD : time := 7 ns; -- HWERROR_N output delay tERH : time := 6 ns; -- HWERROR_N output valid tTCY : time := 50 ns; -- TCLK Clock Cycle tTMS : time := 5 ns; -- TMS setup tTMH : time := 1 ns; -- TMS hold tTDIS : time := 5 ns; -- TDI setup tTDIH : time := 1 ns; -- TDI hold tTRS : time := 5 ns; -- TRST_N setup tTRH : time := 1 ns; -- TRST_N hold tTDOD : time := 7 ns; -- TDO output delay tTDOH : time := 6 ns -- TDO output valid ); port( -- Note: signals which are functionally output signals but are actually -- inout signals because of the Master/Checker mode have an "*" in the -- comments defining their function. CLK : in std_logic; -- clock signal -- Integer Unit Interface Signals FP_N : inout std_logic; -- Floating-point (Fp) Present FCC : inout std_logic_vector(1 downto 0); --* Fp Condition Codes FCCV : inout std_logic; --* Fp Condition Codes Valid FHOLD_N : inout std_logic; --* Fp Hold FEXC_N : inout std_logic; --* Fp EXCeption FIPAR : inout std_logic; --* Fpu to Iu control PARity FXACK : in std_logic; -- Fp eXception ACKnowledge INST : in std_logic; -- INSTruction fetch FINS1 : in std_logic; -- Fp INStruction in buffer 1 FINS2 : in std_logic; -- Fp INStruction in buffer 2 FLUSH : in std_logic; -- Fp instruction fLUSH IFPAR : in std_logic; -- Iu to Fpu control PARity -- System/Memory Interface Signals A : in std_logic_vector(31 downto 0); -- Address bus APAR : in std_logic; -- Address bus PARity D : inout std_logic_vector(31 downto 0); -- Data bus DPAR : inout std_logic; -- Data bus PARity DOE_N : in std_logic; -- Data Output Enable COE_N : in std_logic; -- Control Output Enable MHOLDA_N : in std_logic; -- Memory HOLD MHOLDB_N : in std_logic; -- Memory HOLD BHOLD_N : in std_logic; -- Bus HOLD MDS_N : in std_logic; -- Memory Data Strobe FNULL : inout std_logic; --* Fpu NULLify cycle RESET_N : in std_logic; -- Reset signal HWERROR_N : out std_logic; -- Hardware error detected CMODE_N : in std_logic; -- master/Checker MODE MCERR_N : out std_logic; -- Comparison Error N602MODE_N : in std_logic; -- Normal 602MODE Operation HALT_N : in std_logic; -- Halt mode -- Coprocessor Interface Signals CHOLD_N : in std_logic; -- Coprocessor hold. CCCV : in std_logic; -- Coprocessor Condition Code Valid. -- Test Access Port (TAP) signals TCLK : in std_logic; -- Test CLocK TRST_N : in std_logic; -- Test ReSeT TMS : in std_logic; -- Test Mode Select TDI : in std_logic; -- Test Data In TDO : out std_logic -- Test Data Out ); begin -- PUT HERE TIMING CHECKERS: SETUP & HOLD TIME + PULSE WIDTH CHECKERS. SigRESET_N : SetupHoldCheck(RESET_N, CLK, EDGE => RISING, SETUP => tRES, HOLD => tREH, PATH => "RESET_N", DelayedData => RESET_N'Delayed(abs(tREH))); SigN602MODE_N : SetupHoldCheck(N602MODE_N, CLK, EDGE => RISING, SETUP => tCMS, HOLD => 0 ns, PATH => "N602MODE_N", DelayedData => N602MODE_N'Delayed(0 ns)); SigCMODE_N : SetupHoldCheck(CMODE_N, CLK, EDGE => RISING, SETUP => tCMS, HOLD => 0 ns, PATH => "CMODE_N", DelayedData => CMODE_N'Delayed(0 ns)); SigHALT_N : SetupHoldCheck(HALT_N, CLK, EDGE => FALLING, SETUP => tHAS, HOLD => tHAH, PATH => "HALT_N", DelayedData => HALT_N'Delayed(abs(tHAH))); SigTMS : SetupHoldCheck(TMS, TCLK, EDGE => RISING, SETUP => tTMS, HOLD => tTMH, PATH => "TMS", DelayedData => TMS'Delayed(abs(tTMH))); SigTDI : SetupHoldCheck(TDI, TCLK, EDGE => RISING, SETUP => tTDIS, HOLD => tTDIH, PATH => "TDI", DelayedData => TDI'Delayed(abs(tTDIH))); SigTRST_N : SetupHoldCheck(TRST_N, TCLK, EDGE => RISING, SETUP => tTRS, HOLD => tTRH, PATH => "TRST_N", DelayedData => TRST_N'Delayed(abs(tTRH))); CLKHigh : PulseCheck(CLK, LEVEL => '1', WIDTH => tCHL, SENSE => MINIMUM, PATH => "CLK"); CLKlow : PulseCheck(CLK, LEVEL => '0', WIDTH => tCHL, SENSE => MINIMUM, PATH => "CLK"); --- CLKCycle : process -- Passive process: checks minimal value for CLK cycle. variable DeltaT : time := 0 ns; variable LastEdge : time := -1 sec; begin if not(CHECK_ON) then wait; -- the process dies here.... end if; wait on CLK until rising_edge(CLK); DeltaT := now - LastEdge; LastEdge := now; assert (DeltaT >= tCY) report "Clock cycle violation: minimal value is " & ToString(tCY) & "; value observed: " & ToString(DeltaT) & "." severity warning; end process CLKCycle; ---- RESET_Nwidth : process -- Passive process: checking on RESET_N width. constant MIN_NB_RESET_CYCLES : natural := 10; variable CountNbResetCycle : natural := 0; begin if not(CHECK_ON) then wait; -- the process dies here.... end if; wait on CLK until rising_edge(CLK); if RESET_N = '1' then if CountNbResetCycle < MIN_NB_RESET_CYCLES and CountNbResetCycle /= 0 then assert FALSE report "Pulse width violation for RESET_N: should stay low for at " & "least " & ToString(MIN_NB_RESET_CYCLES) & " rising clock edges!" severity warning; end if; CountNbResetCycle := 0; elsif RESET_N = '0' then CountNbResetCycle := CountNbResetCycle + 1; end if; end process RESET_Nwidth; end FPURTGeneric; ------------------------------------------------------------- -- File containing timing values for the FPURT VHDL model. -- -- ALL THE TIMING PARAMETERS are given at 125 degrees C, -- 4.5 Volts and in worst case process conditions. -- WARNING: minimal values for output signal propagation -- delay in data sheets are usually given in best conditions, -- i.e -55 Celsius, 5.5 Volts and best case process conditions. -- They must be re-calculated for worst case conditions. ------------------------------------------------------------- package FPURTTimPar is constant tCY : time := 40 ns; constant tCHL : time := 18 ns; constant tAS : time := 3 ns; constant tAH : time := 6 ns; constant tDIS : time := 3 ns; constant tDIH : time := 4 ns; constant tDOD : time := 29 ns; constant tDOH : time := 9 ns; constant tDOFFL : time := 31 ns; constant tDOHFL : time := 0 ns; constant tDOFOE : time := 15 ns; constant tDONOE : time := 15 ns; constant tDOHOE : time := 0 ns; constant tFIS : time := 9 ns; constant tFIH : time := 3 ns; constant tINS : time := 16 ns; constant tINH : time := 2 ns; constant tFXS : time := 16 ns; constant tFXH : time := 2 ns; constant tFLS : time := 21 ns; constant tFLH : time := 2 ns; constant tRES : time := 15 ns; constant tREH : time := 3 ns; constant tMHS : time := 7 ns; constant tMHH : time := 4 ns; constant tMDS : time := 5 ns; constant tMDH : time := 4 ns; constant tFHD : time := 29 ns; constant tFHH : time := 12 ns; constant tFHDFI : time := 16 ns; constant tFHDFL : time := 28 ns; constant tFHDMH : time := 36 ns; constant tFCCVD : time := 29 ns; constant tFCCVH : time := 12 ns; constant tFCCVDFL : time := 28 ns; constant tFCCVDMH : time := 36 ns; constant tFCCD : time := 26 ns; constant tFCCH : time := 12 ns; constant tFED : time := 26 ns; constant tFEH : time := 12 ns; constant tFND : time := 20 ns; constant tFNH : time := 7 ns; constant tAPS : time := 3 ns; constant tAPH : time := 6 ns; constant tDPIS : time := 3 ns; constant tDPIH : time := 4 ns; constant tDPOD : time := 29 ns; constant tDPOH : time := 10 ns; constant tIFS : time := 9 ns; constant tIFH : time := 2 ns; constant tFIPD : time := 28 ns; constant tFIPH : time := 12 ns; constant tMCD : time := 15 ns; constant tMCH : time := 7 ns; constant tCMS : time := 10 ns; constant tHAS : time := 7 ns; constant tHAH : time := 4 ns; constant tHAD : time := 15 ns; -- instead of 18 constant tHAE : time := 15 ns; -- instead of 18 constant tERD : time := 25 ns; constant tERH : time := 7 ns; constant tTCY : time := 100 ns; constant tTMS : time := 20 ns; constant tTMH : time := 8 ns; constant tTDIS : time := 20 ns; constant tTDIH : time := 8 ns; constant tTRS : time := 20 ns; constant tTRH : time := 8 ns; constant tTDOD : time := 30 ns; constant tTDOH : time := 12 ns; end FPURTTimPar; ------------------------------------------------------------------------------- -- File name : fpurt_comp_pck.vhd -- Title : FPURTCompPck -- project : SPARC -- Library : FPURTLIB -- Author(s) : Maxime ROCCA -- Purpose : package to declare components of entities for the FPURT. -- -- notes : Use this package whenever a component is instanciated. -- ------------------------------------------------------------------------------- -- Modification history : ------------------------------------------------------------------------------- -- Version No : | Author | Mod. Date : | Changes made : ------------------------------------------------------------------------------- -- v 1.0 | | 94-03-04 | first version --............................................................................. ------------------------------------------------------------------------------- -- Copyright MATRA MARCONI SPACE FRANCE ------------------------------------------------------------------------------- ---------|---------|---------|---------|---------|---------|---------|--------| library IEEE; use IEEE.Std_Logic_1164.all; library MMS; use MMS.StdSim.all; package FPURTCompPck is component FPURTGeneric generic( -- Fake default timing values tCY : time := 50 ns; -- Clock cycle tCHL : time := 22 ns; -- CLock High and Low tAS : time := 5 ns; -- A input setup tAH : time := 1 ns; -- A input hold tDIS : time := 5 ns; -- D input setup tDIH : time := 1 ns; -- D input hold tDOD : time := 7 ns; -- D output delay tDOH : time := 6 ns; -- D data valid tDOFFL : time := 7 ns; -- D output turn-off (FLUSH+) tDOHFL : time := 6 ns; -- D output valid (FLUSH+) tDOFOE : time := 7 ns; -- D output turn-off (DOE_N+) tDONOE : time := 7 ns; -- D output turn-on (DOE_N-) tDOHOE : time := 6 ns; -- D output valid (DOE_N-) tFIS : time := 5 ns; -- FINS1/2 input setup tFIH : time := 1 ns; -- FINS1/2 input hold tINS : time := 5 ns; -- INST input setup tINH : time := 1 ns; -- INST input hold tFXS : time := 5 ns; -- FXACK input setup tFXH : time := 1 ns; -- FXACK input hold tFLS : time := 5 ns; -- FLUSH input setup tFLH : time := 1 ns; -- FLUSH input hold tRES : time := 5 ns; -- RESET_N input setup tREH : time := 1 ns; -- RESET_N input hold tMHS : time := 5 ns; -- MHOLD_N input setup tMHH : time := 1 ns; -- MHOLD_N input hold tMDS : time := 5 ns; -- MDS_N input setup tMDH : time := 1 ns; -- MDS_N input hold tFHD : time := 7 ns; -- FHOLD_N output delay tFHH : time := 6 ns; -- FHOLD_N output valid tFHDFI : time := 7 ns; -- FHOLD_N output delay (FINS1/2+) tFHDFL : time := 7 ns; -- FHOLD_N output delay (FLUSH+) tFHDMH : time := 7 ns; -- FHOLD_N output delay (MHOLD_N-) tFCCVD : time := 7 ns; -- FCCV output delay tFCCVH : time := 6 ns; -- FCCV output valid tFCCVDFL : time := 7 ns; -- FCCV output delay (FLUSH+) tFCCVDMH : time := 7 ns; -- FCCV output delay (MHOLD_N-) tFCCD : time := 7 ns; -- FCC output delay tFCCH : time := 6 ns; -- FCC output valid tFED : time := 7 ns; -- FEXC_N output delay tFEH : time := 6 ns; -- FEXC_N output valid tFND : time := 7 ns; -- FNULL output delay tFNH : time := 6 ns; -- FNULL output valid tAPS : time := 7 ns; -- APAR input setup tAPH : time := 6 ns; -- APAR input hold tDPIS : time := 7 ns; -- DPAR input setup tDPIH : time := 6 ns; -- DPAR input hold tDPOD : time := 7 ns; -- DPAR output delay tDPOH : time := 6 ns; -- DPAR output valid tIFS : time := 7 ns; -- IFPAR input setup tIFH : time := 6 ns; -- IFPAR input hold tFIPD : time := 7 ns; -- FIPAR output delay tFIPH : time := 6 ns; -- FIPAR output valid tMCD : time := 7 ns; -- MCERR_N output delay tMCH : time := 6 ns; -- MCERR_N output valid tCMS : time := 5 ns; -- N602MODE_N, CMODE_N input setup tHAS : time := 5 ns; -- HALT_N input setup tHAH : time := 1 ns; -- HALT_N input hold tHAD : time := 7 ns; -- HALT_N asserted to output disable delay tHAE : time := 7 ns; -- HALT_N asserted to output enable delay tERD : time := 7 ns; -- HWERROR_N output delay tERH : time := 6 ns; -- HWERROR_N output valid tTCY : time := 50 ns; -- TCLK Clock Cycle tTMS : time := 5 ns; -- TMS setup tTMH : time := 1 ns; -- TMS hold tTDIS : time := 5 ns; -- TDI setup tTDIH : time := 1 ns; -- TDI hold tTRS : time := 5 ns; -- TRST_N setup tTRH : time := 1 ns; -- TRST_N hold tTDOD : time := 7 ns; -- TDO output delay tTDOH : time := 6 ns -- TDO output valid ); port( Clk : in std_logic; -- clock signal -- Integer Unit Interface Signals FP_N : inout std_logic; --* Floating-point (Fp) Present FCC : inout std_logic_vector(1 downto 0); --* Fp Condition Codes FCCV : inout std_logic; --* Fp Condition Codes Valid FHOLD_N : inout std_logic; --* Fp Hold FEXC_N : inout std_logic; --* Fp EXCeption FIPAR : inout std_logic; --* Fpu to Iu control PARity FXACK : in std_logic; -- Fp eXception ACKnowledge INST : in std_logic; -- INSTruction fetch FINS1 : in std_logic; -- Fp INStruction in buffer 1 FINS2 : in std_logic; -- Fp INStruction in buffer 2 FLUSH : in std_logic; -- Fp instruction fLUSH IFPAR : in std_logic; -- Iu to Fpu control PARity -- System/Memory Interface Signals A : in std_logic_vector(31 downto 0); -- Address bus APAR : in std_logic; -- Address bus PARity D : inout std_logic_vector(31 downto 0); -- Data bus DPAR : inout std_logic; -- Data bus PARity DOE_N : in std_logic; -- Data Output Enable COE_N : in std_logic; -- Control Output Enable MHOLDA_N : in std_logic; -- Memory HOLD MHOLDB_N : in std_logic; -- Memory HOLD BHOLD_N : in std_logic; -- Bus HOLD MDS_N : in std_logic; -- Memory Data Strobe FNULL : inout std_logic; --* Fpu NULLify cycle RESET_N : in std_logic; -- Reset signal HWERROR_N : out std_logic; --Hardware error detected CMODE_N : in std_logic; -- master/Checker MODE MCERR_N : out std_logic; -- Comparison Error N602MODE_N : in std_logic; -- Normal 602MODE Operation HALT_N : in std_logic; -- Halt mode -- Coprocessor Interface Signals CHOLD_N : in std_logic; -- Coprocessor hold. CCCV : in std_logic; -- Coprocessor Condition Code Valid. -- Test Access Port (TAP) signals TCLK : in std_logic; -- Test CLocK TRST_N : in std_logic; -- Test ReSeT TMS : in std_logic; -- Test Mode Select TDI : in std_logic; -- Test Data In TDO : out std_logic -- Test Data Out ); end component; -- FPURTGeneric component FPURT generic( T : temperature := T_BOARD; V : voltage := V_BOARD; PROCES : proces_type := PROCES_BOARD; LOAD : capacitance := LOAD_BOARD ); port( Clk : in std_logic; -- clock signal -- Integer Unit Interface Signals FP_N : inout std_logic; --* Floating-point (Fp) Present FCC : inout std_logic_vector(1 downto 0); --* Fp Condition Codes FCCV : inout std_logic; --* Fp Condition Codes Valid FHOLD_N : inout std_logic; --* Fp Hold FEXC_N : inout std_logic; --* Fp EXCeption FIPAR : inout std_logic; --* Fpu to Iu control PARity FXACK : in std_logic; -- Fp eXception ACKnowledge INST : in std_logic; -- INSTruction fetch FINS1 : in std_logic; -- Fp INStruction in buffer 1 FINS2 : in std_logic; -- Fp INStruction in buffer 2 FLUSH : in std_logic; -- Fp instruction fLUSH IFPAR : in std_logic; -- Iu to Fpu control PARity -- System/Memory Interface Signals A : in std_logic_vector(31 downto 0); -- Address bus APAR : in std_logic; -- Address bus PARity D : inout std_logic_vector(31 downto 0); -- Data bus DPAR : inout std_logic; -- Data bus PARity DOE_N : in std_logic; -- Data Output Enable COE_N : in std_logic; -- Control Output Enable MHOLDA_N : in std_logic; -- Memory HOLD MHOLDB_N : in std_logic; -- Memory HOLD BHOLD_N : in std_logic; -- Bus HOLD MDS_N : in std_logic; -- Memory Data Strobe FNULL : inout std_logic; --* Fpu NULLify cycle RESET_N : in std_logic; -- Reset signal HWERROR_N : out std_logic; -- Hardware error detected CMODE_N : in std_logic; -- master/Checker MODE MCERR_N : out std_logic; -- Comparison Error N602MODE_N : in std_logic; -- Normal 602MODE Operation HALT_N : in std_logic; -- Halt mode -- Coprocessor Interface Signals CHOLD_N : in std_logic; -- Coprocessor hold. CCCV : in std_logic; -- Coprocessor Condition Code Valid. -- Test Access Port (TAP) signals TCLK : in std_logic; -- Test CLocK TRST_N : in std_logic; -- Test ReSeT TMS : in std_logic; -- Test Mode Select TDI : in std_logic; -- Test Data In TDO : out std_logic -- Test Data Out ); end component; -- FPURT end FPURTCompPck; ------------------------------------------------------------------------------- -- File name : fpurt_pck.vhd -- Title : FPURTPck -- project : SPARC -- Library : FPURTLIB -- Author(s) : Maxime ROCCA, Jiri Gaisler -- Purpose : -- Package containing SPARC FPURT specific VHDL constructs. -- -- notes : -- To be included when anything defined in this file is used -- in another file. -- ------------------------------------------------------------------------------- -- Modification history : ------------------------------------------------------------------------------- -- Version No : | Author | Mod. Date : | Changes made : ------------------------------------------------------------------------------- -- v 1.0 | MR | 94-03-04 | first version --............................................................................. -- v 1.1 | MR | 94-05-03 | 2nd version -- + VHDL bugs fixed. --............................................................................. -- v 1.2 | JG | 94-09-23 | 3nd version -- Completely new implementation. Replaced MEIKO derived code with behavioral -- to allow free distribution. FPops with NaN as input do NOT behave as real -- device, but this shouldn't matter... ------------------------------------------------------------------------------- -- Copyright MATRA MARCONI SPACE FRANCE -- Copyright ESA/ESTEC ------------------------------------------------------------------------------- ---------|---------|---------|---------|---------|---------|---------|--------| library IEEE; use IEEE.Std_Logic_1164.all; use ieee.Std_logic_arith.all; library SPARC_LIB; use SPARC_LIB.SparcPck.all; use STD.TEXTIO.all; package FPURTPck is -- Pseudo-functions that are constant tables: -- IsFPopRdDouble(Mnemonic) returns TRUE if Mnemonic is a FPop with rd double. -- IsFPopSourceRegDouble(Mnemonic) returns TRUE if Mnemonic is a FPop with -- double precision source registers. -- IsFPopUnimp(Mnemonic) returns TRUE if Mnemonic is an unimplemented FPop. constant IsFPopRdDouble : MnemoTableType; constant IsFPopSourceRegDouble : MnemoTableType; constant IsFPopUnimp : MnemoTableType; -- Pseudo-function that emulates the ROM microcode for the computational core -- of the FPU. It returns a 64-bit data corresponding to the address (i.e the -- index in the table ranging between 0 and 255). -- Floating-point instruction type. type FPInstruction is record Mnemo : SuperInstMnemonic; -- menmonic of a FP instruction. BitInstruction : std_logic_vector(31 downto 0); -- 32-bit value for the -- instruction. BitAddress : std_logic_vector(31 downto 0); -- 32-bit value for the -- address. rs1 : natural; -- source register 1. rs2 : natural; -- source register 2. rd : natural; -- destination register. end record; -- FPInstruction -- Modes of the FPU type FPUmodeType is (RESET_MODE, ERROR_MODE, EXECUTION, PENDING_EXCEPTION, EXCEPTION); -- Floating-point exception types type FPexcMnemonic is ( FP_EXC_DETECTED, -- FP exception has been detected IEEE_EXC, -- IEEE 754 exception UNFINISHED_FPOP, -- Unfinished FPop exception UNIMPLEMENTED_FPOP, -- Unimplemented FPop exception SEQUENCE_ERROR, -- Sequence error exception DATA_BUS_ERROR, -- Data bus error RESTARTABLE_ER -- Restartable error ); type FPexcVectorType is array(FPexcMnemonic) of boolean; --=================== FUNCTIONS declarations ==================== --------------------------------------------------------------------------- -- Decode A as a SPARC instruction and returns the info under the form of -- a FPinstruction record. --------------------------------------------------------------------------- function FPtranscribe(A : std_logic_vector) return FPInstruction; --------------------------------------------------------------------------- -- Returns a non null value if a condition to generate the FHOLD_N signal is -- encountered. --------------------------------------------------------------------------- function FHOLDcondition(signal FINS1 : std_logic; signal FINS2 : std_logic; signal ID1 : FPInstruction; signal ID2 : FPInstruction; signal E : FPInstruction; signal W : FPInstruction; W1 : FPInstruction; signal FQ : FPInstruction ) return natural; --------------------------------------------------------------------------- -- Used in FHOLDcondition: dependency between FPop and FP load. --------------------------------------------------------------------------- function FPop_LDF(signal FPinst : FPInstruction; RegD : natural ) return boolean; --------------------------------------------------------------------------- -- Used in FHOLDcondition: dependency between FPop and FP store. --------------------------------------------------------------------------- function FPop_STF(signal FPinst : FPInstruction; RegD : natural ) return boolean; --------------------------------------------------------------------------- -- Used in FHOLDcondition: dependency between FP load and FPop. --------------------------------------------------------------------------- function LDF_FPop(signal W : FPInstruction; ID : FPInstruction ) return boolean; --------------------------------------------------------------------------- -- Used in FHOLDcondition: dependency betwee FP load double and FPop. --------------------------------------------------------------------------- function LDDF_FPop(W1 : FPInstruction; ID : FPInstruction ) return boolean; --------------------------------------------------------------------------- -- Execution body for the FPURT: instructions are dispatched, executed, and -- the procedure returns the result together with the number of cycles it -- takes to get it. This procedure is the computational core of the FPU. --------------------------------------------------------------------------- procedure ExecuteFPop(FPbitInst : std_logic_vector; RS1vec : std_logic_vector; RS2vec : std_logic_vector; RD : std_logic_vector; TEM2 : std_logic; DEBUG_FLAG : boolean := FALSE; -- debugging purpose. TestNb : integer; -- debugging purpose. Result : out std_logic_vector; tfcc : out std_logic_vector; texc : out std_logic_vector; FPexcVector : out FPexcVectorType; NbCycles : out integer; Fdebug : out text; -- debugging purpose. FCtDebug : out text -- debugging purpose. ); end FPURTPck; -- package -------------------------------------------------------------------------- --^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-- -------------------------------------------------------------------------- package body FPURTPck is subtype single is unsigned(31 downto 0); subtype double is unsigned(63 downto 0); subtype fpexc is std_logic_vector(4 downto 0); ------------------------------ constant IsFPopRdDouble : MnemoTableType := ( FiTOd => TRUE, FsTOd => TRUE, FqTOd => TRUE, FSQRTd => TRUE, FADDd => TRUE, FSUBd => TRUE, FMULd => TRUE, FsMULd => TRUE, -- SPARC v.8 only for FsMULd FDIVd => TRUE, others => FALSE ); ------------------------------ constant IsFPopSourceRegDouble : MnemoTableType := ( FdTOi => TRUE, FdTOs => TRUE, FdTOq => TRUE, FSQRTd => TRUE, FADDd => TRUE, FSUBd => TRUE, FMULd => TRUE, FdMULq => TRUE, -- SPARC v.8 only for FsMULd & FdMULq FDIVd => TRUE, FCMPd => TRUE, FCMPEd => TRUE, others => FALSE ); ------------------------------ constant IsFPopUnimp : MnemoTableType := ( FiTOq => TRUE, FqTOi => TRUE, FsTOq => TRUE, FdTOq => TRUE, FqTOs => TRUE, FqTOd => TRUE, FSQRTq => TRUE, FADDq => TRUE, FSUBq => TRUE, FMULq => TRUE, FsMULd => TRUE, FdMULq => TRUE, -- SPARC v.8 only for FsMULd & FdMULq FDIVq => TRUE, FCMPq => TRUE, FCMPEq => TRUE, others => FALSE ); ------------------------------ function FPtranscribe(A : std_logic_vector) return FPInstruction is constant L : natural := A'length; variable Inst : Instruction; variable Result : FPInstruction; begin assert L = 32 report "(FPtranscribe): invalid vector length!" severity error; Inst := Transcribe(A); Result.Mnemo := Inst.Mnemo; Result.rs1 := Inst.rs1; Result.rs2 := Inst.rs2; Result.rd := Inst.rd; Result.BitInstruction := A; return Result; end FPtranscribe; -- function ------------------------------ function FPop_LDF(signal FPinst : FPInstruction; RegD : natural ) return boolean is begin if IsFPop(FPinst.Mnemo) and (FPinst.rs2 = RegD or (FPURs1IsIn(FPinst.Mnemo) and FPinst.rs1 = RegD) or (not(IsFCMP(FPinst.Mnemo)) and FPinst.rd = RegD) or (IsFPopRdDouble(FPinst.Mnemo) and ( ((FPinst.rd/2)*2) = RegD or ((FPinst.rd/2)*2 + 1) = RegD ) ) or (IsFPopSourceRegDouble(FPinst.Mnemo) and ( ((FPinst.rs2/2)*2) = RegD or ((FPinst.rs2/2)*2 + 1) = RegD or (FPURs1IsIn(FPinst.Mnemo) and ( ((FPinst.rs1/2)*2) = RegD or ((FPinst.rs1/2)*2 + 1) = RegD ) ) ) ) ) then return TRUE; end if; return FALSE; end FPop_LDF; ------------------------------ function FPop_STF(signal FPinst : FPInstruction; RegD : natural ) return boolean is begin if IsFPop(FPinst.Mnemo) and ((not(IsFCMP(FPinst.Mnemo)) and FPinst.rd = RegD) or (IsFPopRdDouble(FPinst.Mnemo) and ( ((FPinst.rd/2)*2) = RegD or ((FPinst.rd/2)*2 + 1) = RegD ) ) ) then return TRUE; end if; return FALSE; end FPop_STF; ------------------------------ function LDF_FPop(signal W : FPInstruction; ID : FPInstruction ) return boolean is begin if W.Mnemo = LDF and (W.rd = ID.rs2 or (FPURs1IsIn(ID.Mnemo) and W.rd = ID.rs1) or (IsFPopSourceRegDouble(ID.Mnemo) and (W.rd = ((ID.rs2/2)*2) or W.rd = ((ID.rs2/2)*2 + 1) or (FPURs1IsIn(ID.Mnemo) and (W.rd = ((ID.rs1/2)*2) or W.rd = ((ID.rs1/2)*2 + 1) ) ) ) ) ) then return TRUE; end if; return FALSE; end LDF_FPop; ------------------------------ function LDDF_FPop(W1 : FPInstruction; ID : FPInstruction ) return boolean is begin if W1.Mnemo = LDDF and -- dependency on both rd and rd+1 of LDDF ((W1.rd = ID.rs2 or (FPURs1IsIn(ID.Mnemo) and W1.rd = ID.rs1) or (IsFPopSourceRegDouble(ID.Mnemo) and (W1.rd = ((ID.rs2/2)*2) or W1.rd = ((ID.rs2/2)*2 + 1) or (FPURs1IsIn(ID.Mnemo) and (W1.rd = ((ID.rs1/2)*2) or W1.rd = ((ID.rs1/2)*2 + 1) ) ) ) ) ) or (W1.rd+1 = ID.rs2 or (FPURs1IsIn(ID.Mnemo) and W1.rd+1 = ID.rs1) or (IsFPopSourceRegDouble(ID.Mnemo) and (W1.rd+1 = ((ID.rs2/2)*2) or W1.rd+1 = ((ID.rs2/2)*2 + 1) or (FPURs1IsIn(ID.Mnemo) and (W1.rd+1 = ((ID.rs1/2)*2) or W1.rd+1 = ((ID.rs1/2)*2 + 1) ) ) ) ) ) ) then return TRUE; end if; return FALSE; end LDDF_FPop; ------------------------------ function FHOLDcondition(signal FINS1 : std_logic; signal FINS2 : std_logic; signal ID1 : FPInstruction; signal ID2 : FPInstruction; signal E : FPInstruction; signal W : FPInstruction; W1 : FPInstruction; signal FQ : FPInstruction ) return natural is variable ID : FPInstruction; variable W1rd_ev : natural; variable W1rd_od : natural; variable IDrd_ev : natural; variable IDrd_od : natural; begin if FINS1 = '1' then ID := ID1; elsif FINS2 = '1' then ID := ID2; else return 0; end if; ---- if (IsFPop(ID.Mnemo) or ID.Mnemo = LDFSR or ID.Mnemo = STFSR) and (IsFPop(E.Mnemo) or IsFPop(W.Mnemo) or IsFPop(FQ.Mnemo)) then return 1; end if; ---- if (ID.Mnemo = LDF or ID.Mnemo = LDDF) and ( FPop_LDF(E, ID.rd) or FPop_LDF(W, ID.rd) or FPop_LDF(FQ, ID.rd) ) then return 1; end if; if ID.Mnemo = LDDF and ( FPop_LDF(E, ID.rd + 1) or FPop_LDF(W, ID.rd + 1) or FPop_LDF(FQ, ID.rd + 1) ) then return 1; end if; ---- if ID.Mnemo = STF and (FPop_STF(E, ID.rd) or FPop_STF(W, ID.rd) or FPop_STF(FQ, ID.rd) ) then return 1; end if; IDrd_ev := (ID.rd/2)*2; IDrd_od := IDrd_ev + 1; if ID.Mnemo = STDF and (FPop_STF(E, IDrd_ev) or FPop_STF(W, IDrd_ev) or FPop_STF(FQ, IDrd_ev) or FPop_STF(E, IDrd_od) or FPop_STF(W, IDrd_od) or FPop_STF(FQ, IDrd_od) ) then return 1; end if; --- if ID.Mnemo = STDFQ and (IsFPop(E.Mnemo) or IsFPop(W.Mnemo) or IsFPop(FQ.Mnemo)) then return 1; end if; ---- if IsFPinst(ID.Mnemo) and not(IsFBfcc(ID.Mnemo)) and (IsFPopUnimp(E.Mnemo) or IsFPopUnimp(W.Mnemo) or IsFPopUnimp(FQ.Mnemo)) then return 1; end if; ---- if (W.Mnemo = LDFSR or W1.Mnemo = LDFSR) and (ID.Mnemo = LDFSR or ID.Mnemo = STFSR or IsFPop(ID.Mnemo)) then return 2; end if; ---- $$$$ WARNING: this condition is fuzzy: to be finalized. $$$$$$$ W1rd_ev := (W1.rd/2)*2; W1rd_od := W1rd_ev + 1; IDrd_ev := (ID.rd/2)*2; IDrd_od := IDrd_ev + 1; if (IsFPop(ID.Mnemo) and (LDF_FPop(W, ID) or LDDF_FPop(W1, ID)) ) or (ID.Mnemo = STF and W.Mnemo = LDF and W.rd = ID.rd) or (ID.Mnemo = STF and W1.Mnemo = LDDF and (ID.rd = W1rd_ev or ID.rd = W1rd_od) ) or (ID.Mnemo = STDF and W.Mnemo = LDF and (W.rd = IDrd_ev or W.rd = IDrd_od) ) or (ID.Mnemo = STDF and W1.Mnemo = LDDF and (W1rd_ev = IDrd_ev or W1rd_ev = IDrd_od or W1rd_od = IDrd_ev or W1rd_od = IDrd_od) ) then return 2; end if; return 0; end FHOLDcondition; ----------------------------- -- Behavioral FP functions to replace structural model -- Jiri Gaisler, 19-09-1996 ------------------------------ procedure ExecuteFPop(FPbitInst : std_logic_vector; RS1vec : std_logic_vector; RS2vec : std_logic_vector; RD : std_logic_vector; TEM2 : std_logic; DEBUG_FLAG : boolean := FALSE; TestNb : integer; Result : out std_logic_vector; tfcc : out std_logic_vector; texc : out std_logic_vector; FPexcVector : out FPexcVectorType; NbCycles : out integer; Fdebug : out text; FCtDebug : out text ) is type Ftype is (QNan, SNan, Zero, Inf, Norm); type Quad is record sign : std_logic; exp : unsigned(14 downto 0); man : unsigned(112 downto 0); v : Ftype; end record; constant SPInf : std_logic_vector(30 downto 0) := "1111111100000000000000000000000"; constant DPInf : std_logic_vector(62 downto 0) := "111111111110000000000000000000000000000000000000000000000000000"; constant SPNaN : std_logic_vector(31 downto 0) := "01111111111111110000000000000000"; constant DPNaN : std_logic_vector(63 downto 0) := "0111111111111111111000000000000000000000000000000000000000000000"; variable cexc : std_logic_vector(4 downto 0); variable dres : std_logic_vector(63 downto 0); variable ns : boolean; variable qs1, qs2, qres : quad; function SIsInf(f1 : std_logic_vector) return boolean is begin return ((f1(30 downto 23) = std_logic_vector'("11111111")) and (f1(22 downto 0) = "00000000000000000000000")); end SIsInf; function DIsInf(f1 : std_logic_vector) return boolean is begin return ((f1(62 downto 52) = std_logic_vector'("11111111111")) and (f1(51 downto 0) = "0000000000000000000000000000000000000000000000000000")); end DIsInf; function SIsZero(f1 : std_logic_vector) return boolean is begin return (f1(30 downto 0) = ext("0",31)); end SIsZero; function DIsZero(f1 : std_logic_vector) return boolean is begin return (f1(62 downto 0) = ext("0",63)); end DIsZero; function SIsNaN(f1 : std_logic_vector) return boolean is begin return ((f1(30 downto 23) = std_logic_vector'("11111111")) and (f1(22 downto 0) /= "00000000000000000000000")); end SIsNaN; function DIsNaN(f1 : std_logic_vector) return boolean is begin return ((f1(62 downto 52) = std_logic_vector'("11111111111")) and (f1(51 downto 0) /= "0000000000000000000000000000000000000000000000000000")); end DIsNaN; function SToQuad(f1: std_logic_vector) return Quad is variable q1 : Quad; begin q1.sign := f1(31); q1.exp := unsigned(ext(f1(30 downto 23),15)) + 16383 - 127; q1.man := unsigned(ext(('1'& f1(22 downto 0) & "00000000000000000000000000000000"),113)); q1.v := Norm; if SIsNaN(f1) then if f1(22) = '1' then q1.v := QNaN; else q1.v := SNaN; end if; elsif SIsInf(f1) then q1.v := Inf; elsif SIsZero(f1) then q1.v := Zero; end if; return(q1); end SToQuad; function DToQuad(f1: std_logic_vector) return Quad is variable q1 : Quad; begin q1.sign := f1(63); q1.exp := unsigned(ext(f1(62 downto 52),15)) + 16383 - 1023; q1.man := unsigned(ext(('1'& f1(51 downto 0) & "000"),113)); q1.v := Norm; if DIsNaN(f1) then if f1(51) = '1' then q1.v := QNaN; else q1.v := SNaN; end if; elsif DIsInf(f1) then q1.v := Inf; elsif DIsZero(f1) then q1.v := Zero; end if; return(q1); end DToQuad; procedure Normalize(q1 : inout quad) is variable i : integer := 0; begin if q1.v = norm then while (i < 113) and (q1.man(112 - i) = '0') loop i := i + 1; end loop; if (i < 57) then q1.man := shr(q1.man, conv_unsigned(57 - i,8)); else q1.man := shl(q1.man, conv_unsigned(i - 57 ,8)); end if; q1.exp := q1.exp + (57 - i); end if; end Normalize; procedure FPround(q : quad; res : inout std_logic_vector; SP : boolean) is variable i, intexp, iexp, isign, exprange, ig : integer; variable utmp : unsigned (14 downto 0); variable Pround : unsigned (112 downto 0) := (others => '0'); variable q1 : quad := q; variable lexp, lman : integer; variable RDL : std_logic_vector(1 downto 0); begin if q1.v = Inf then if SP then res(31 downto 0) := q1.sign & SPInf; else res(63 downto 0) := q1.sign & DPInf; end if; elsif q1.v = Zero then if SP then res(31 downto 0) := q1.sign & ext("0",31); else res(63 downto 0) := q1.sign & ext("0",63); end if; elsif q1.v <= SNan then if SP then res(31 downto 0) := SPNan; else res(63 downto 0) := DPNan; end if; else if SP then lexp := 8; lman := 23; else lexp := 11; lman := 52; end if; ig := 54 -lman; Pround(ig) := '1'; isign := lman + lexp; iexp := isign - 1; exprange := 2; for i in 2 to lexp loop exprange := exprange * 2; end loop; exprange := exprange; i := 0; -- First, we normalize to quad Normalize(q1); -- Round according to RD RDL := RD( 1 downto 0); if ((q1.man(ig downto 1)) /= unsigned(ext("0",ig-1))) or cexc(0) = '1' then cexc(0) := '1'; -- Inexact ieee flag case RDL(1 downto 0) is when "00" => -- round to nearest if ((q1.man(ig downto 0)) > unsigned('1' & ext("0",ig)) ) or (((q1.man(ig downto 0)) = unsigned('1' & ext("0",ig)) ) and (q1.man(ig+1) = '1') ) then q1.man := q1.man + Pround; Normalize(q1); end if; when "01" => -- round to zero (truncate) null; when "10" => -- round to +Inf if q1.sign = '0' then q1.man := q1.man + shl(Pround,"01"); end if; when "11" => -- round to -Inf if q1.sign = '1' then q1.man := q1.man + shl(Pround,"01"); end if; when others => null; end case; end if; res(isign) := q1.sign; utmp := q1.exp + (-16383 + (exprange / 2) -1); res(iexp downto lman) := std_logic_vector(utmp((lexp-1) downto 0)); res(lman-1 downto 0) := std_logic_vector(q1.man(54 downto (54 -lman +1))); -- Check ieee exceptions, improvements here are welcome intexp := conv_integer(q1.exp); if (intexp > ( 16383 + exprange/2 -1)) then cexc(3) := '1'; -- overflow case RDL(1 downto 0) is when "00" => -- round to nearest, return 1 res(iexp downto lman) := '0' & sxt("1",lexp - 1); res(lman-1 downto 0) := ext("0",lman); when "01" => -- round to zero, return largest norm res(iexp downto lman) := sxt("1",lexp - 1) & '0'; res(lman-1 downto 0) := sxt("1",lman); when "10" => -- round to +Inf if res(isign) = '1' then -- most negitive norm res(iexp downto lman) := sxt("1",lexp - 1) & '0'; res(lman-1 downto 0) := sxt("1",lman); else -- +Inf res(iexp downto lman) := sxt("1",lexp); res(lman-1 downto 0) := sxt("0",lman); end if; when "11" => -- round to -Inf if res(isign) = '0' then -- most positive norm res(iexp downto lman) := sxt("1",lexp - 1) & '0'; res(lman-1 downto 0) := sxt("1",lman); else -- -Inf res(iexp downto lman) := sxt("1",lexp); res(lman-1 downto 0) := sxt("0",lman); end if; when others => null; end case; elsif (intexp < (16383 - exprange/2 + 2)) then cexc(2) := '1'; -- underflow, return denorm i := 16383 - intexp + (exprange / 2) - 1; res(iexp downto lman) := ext("0",lexp); res(lman-1 downto 0) := std_logic_vector(shr(q1.man(55 downto 55 - lman +1),(conv_unsigned(i,8)))); end if; end if; if (SP) then res (63 downto 32) := res(31 downto 0); end if; end FPround; procedure fmul(rs1, rs2: Quad; res: out Quad) is variable q1: Quad; begin res.sign := rs1.sign xor rs2.sign; if (rs1.v = Zero) or (rs2.v = Zero) then res.v := Zero; elsif (rs1.v = Inf) or (rs2.v = Inf) then res.v := Inf; else res.v := Norm; res.exp := (rs1.exp - 16383) + rs2.exp - 55; res.man := '0' & (rs1.man(55 downto 0) * rs2.man(55 downto 0)); end if; end fmul; procedure fdiv(rs1, rs2: Quad; res: out Quad) is variable q1,q2: Quad; variable i : integer := 55; begin res.sign := rs1.sign xor rs2.sign; res.exp := (rs1.exp - rs2.exp) + 16383; res.man := unsigned(ext("0",113)); if (rs1.v = Zero) then res.v := Zero; elsif (rs2.v = Inf) then res.v := Zero; else res.v := Norm; q1.man := shl(rs1.man,"0111000"); q2.man := shl(rs2.man,"0111000"); while (i > 0) loop if q2.man <= q1.man then q1.man := q1.man - q2.man; res.man(i) := '1'; end if; i := i - 1; q2.man := shr(q2.man, "01"); end loop; if q1.man /= unsigned(ext("0",113)) then cexc(0) := '1'; -- Inexact end if; end if; end fdiv; procedure fcmp(q1, q2: quad; tfcc: out std_logic_vector) is variable s1, s2 : signed(127 downto 0); begin if ((q1.v = Inf) and (q2.v = Inf) and (q1.sign = q2.sign)) then tfcc := "11"; else s1 := signed(q1.sign & q1.exp & q1.man(111 downto 0)); s2 := signed(q2.sign & q2.exp & q2.man(111 downto 0)); if (s1 < s2) then tfcc := "01"; elsif (s1 > s2) then tfcc := "10"; else tfcc := "00"; end if; end if; end fcmp; procedure faddsub(rs1, rs2: quad; res: out quad; doadd : boolean) is variable s1, s2, exp1, exp2, man1, man2: quad; begin if (rs1.v = Inf) then res := rs1; if (rs2.v = Inf) then if ((doadd and (rs1.sign /= rs2.sign)) or (not doadd and (rs1.sign = rs2.sign))) then cexc(4) := '1'; res.v := QNan; res.sign := '0'; end if; end if; elsif (rs2.v = Inf) then res.v := Inf; if doadd then res.sign := rs2.sign; else res.sign := not rs2.sign; end if; elsif (rs1 = rs2) then res := rs1; if doadd then res.exp := rs1.exp + 1; else res.v := Zero; if RD = "11" then res.sign := '1'; else res.sign := '0'; end if; end if; elsif (rs1.v = Zero) then res := rs2; if (rs2.v = norm) and not doadd then res.sign := not rs2.sign; end if; elsif (rs2.v = Zero) then res := rs1; else if (rs1.exp < rs2.exp) then s1 := rs2; s2 := rs1; if not doadd then s1.sign := not s1.sign; end if; else s1 := rs1; s2 := rs2; if not doadd then s2.sign := not s2.sign; end if; end if; s2.man := shr(s2.man, s1.exp - s2.exp); if (s1.sign = '1') then s1.man := 0 - s1.man; end if; if (s2.sign = '1') then s2.man := 0 - s2.man; end if; s1.man := s1.man + s2.man; s1.sign := s1.man(112); if (s1.man(112) = '1') then s1.man := 0 - s1.man; end if; res := s1; if s1.man = unsigned(ext("0",113)) then res.v := Zero; end if; end if; end; procedure fsqrt(rs1 : quad; res: out quad; sp : boolean) is variable s1, s2, s3, s4, s5 : quad; variable accuracy : integer; begin -- Sqrt calculations according newton/rapson xn = (x2 +s1)/2x if (rs1.v = Norm) then s1 := rs1; s2 := rs1; if SP then accuracy := 16838 - 130; else accuracy := 16838 - 1026; end if; s2.exp := s2.exp - 1; -- s2 is seed, equal to s1/2 loop fmul(s2,s2,s3); Normalize(s3); faddsub(s3, s1, s4, false); Normalize(s4); s4.exp := s4.exp -1; fdiv(s4,s2,s3); Normalize(s3); faddsub(s2, s3, s5, false); Normalize(s5); -- s4 := s1; -- s4.exp := s4.exp -1; -- fdiv(s4,s2,s3); -- Normalize(s3); -- s4 := s2; -- s4.exp := s4.exp -1; -- faddsub(s3, s4, s5, true); -- Normalize(s5); if (s5.v /= norm) or (s3.v /= norm) or (s2 = s5) then exit; end if; s2 := s5; end loop; -- if s5.man(1 downto 0) = unsigned'("11") then -- s5.man := s5.man + 1; -- Normalize(s5); -- elsif s5.man(1 downto 0) = unsigned'("01") then -- s5.man(0) := '0'; -- end if; cexc := "00000"; res := s5; end if; end; procedure fitoq(rs1 : std_logic_vector; res: inout quad) is begin res.sign := rs1(31); if (rs1(31 downto 0) = ext("0",32)) then res.v := Zero; else res.v := Norm; end if; res.exp := conv_unsigned(16383,15); if (rs1(31) = '1') then res.man := unsigned(ext("0",26)) & (0 - unsigned(rs1(31 downto 0))) & unsigned(ext("0",55)); else res.man := unsigned(ext("0",26)) & unsigned(rs1(31 downto 0)) & unsigned(ext("0",55)); end if; Normalize(res); end fitoq; procedure fqtoi(q : quad; res : inout std_logic_vector) is variable tmp : std_logic_vector(0 downto 0); variable q1 : quad; begin q1 := q; if (q1.v = Inf) or (q1.exp > 16383 + 30) then if q1.sign = '0' then cexc(4) := '1'; -- Invalid end if; tmp(0) := not q1.sign; res(31 downto 0) := q1.sign & sxt(tmp, 31); elsif (q1.v = Zero) then res(31 downto 0) := ext("0",32); else if (q1.exp < 16383) then res(31 downto 0) := ext("0",32); cexc(0) := '1'; -- Inexact elsif (q1.exp > 16383 + 30) then res(31 downto 0) := '0' & sxt("1",31); if q1.sign = '1' then res(31 downto 0) := not res(31 downto 0); end if; cexc(0) := '1'; -- Inexact else q1.man := shl(q1.man,q1.exp-16383); if q1.man(54 downto 0) /= unsigned(ext("0",55)) then cexc(0) := '1'; -- Inexact end if; if (q1.sign = '1') then q1.man(55+31 downto 55) := 0 - q1.man(55+31 downto 55); end if; res(31 downto 0) := std_logic_vector(q1.man(55+31 downto 55)); end if; end if; res (63 downto 32) := res(31 downto 0); end fqtoi; variable FpInst : std_logic_vector(9 downto 0); variable LRes : std_logic_vector(63 downto 0); variable opcase : std_logic_vector(2 downto 0); variable lfcc : std_logic_vector(1 downto 0) := "11"; variable SP : boolean; variable Unimp : boolean := false; begin FpInst := FPbitInst(19) & FPbitInst(13 downto 5); FPexcVector := (others => FALSE); SP := FPbitInst(5) = '1'; cexc := "00000"; tfcc := "00"; opcase := (FPbitInst(12 downto 11) & FPbitInst(5)); case opcase is when "000" | "110" => qs2 := DToQuad(RS2vec); if qs2.v = QNan then LRes(63 downto 0) := RS2vec; elsif qs2.v = SNan then LRes(63 downto 0) := DPNan; if FPbitInst(12) = '0' then cexc(4) := '1'; -- Invalid exception end if; end if; when "001" | "111" => qs2 := SToQuad(RS2vec); if qs2.v = QNan then LRes(63 downto 0) := RS2vec(31 downto 0) & RS2vec(31 downto 0); elsif qs2.v = SNan then LRes(63 downto 0) := SPNan & SPNan; if FPbitInst(12) = '0' then cexc(4) := '1'; -- Invalid exception end if; end if; when "010" => qs1 := DToQuad(RS1vec); qs2 := DToQuad(RS2vec); if (qs1.v = SNan) or (qs2.v = SNan) then LRes(63 downto 0) := DPNan; cexc(4) := '1'; -- Invalid exception elsif qs1.v = QNan then LRes(63 downto 0) := RS1vec; elsif qs2.v = QNan then LRes(63 downto 0) := RS2vec; end if; when "011" => qs1 := SToQuad(RS1vec); qs2 := SToQuad(RS2vec); if (qs1.v = SNan) or (qs2.v = SNan) then LRes(63 downto 0) := SPNan & SPNan; cexc(4) := '1'; -- Invalid exception elsif qs1.v = QNan then LRes(63 downto 0) := RS1vec(31 downto 0) & RS1vec(31 downto 0); elsif qs2.v = QNan then LRes(63 downto 0) := RS2vec(31 downto 0) & RS2vec(31 downto 0); end if; when others => null; end case; case FpInst is when "0000001001" => -- fabss if (qs2.v > SNaN) then LRes(63 downto 32) := '0' & RS2vec(30 downto 0); end if; NbCycles := 2; when "0001000001" | "0001000010" => -- fadds/d if (qs1.v > SNan) and (qs2.v > SNaN) then faddsub(qs1, qs2, qres, true); FPround(qres, LRes, SP); end if; NbCycles := 5; when "1001010001" | "1001010010" => -- fcmps/d if (qs1.v <= SNaN) or (qs2.v <= SNaN) then tfcc := "11"; else fcmp(qs1, qs2, tfcc); end if; NbCycles := 5; when "1001010101" | "1001010110" => -- fcmpes/d if (qs1.v <= SNaN) or (qs2.v <= SNaN) then tfcc := "11"; else fcmp(qs1, qs2, lfcc); end if; if lfcc = "11" then cexc(4) := '1'; end if; NbCycles := 5; tfcc := lfcc; when "0001001101" | "0001001110" => -- fdivs/d if (qs1.v > SNaN) and (qs2.v > SNaN) then if (qs1.v = Zero and qs2.v = Zero) or ((qs1.v = Inf) and (qs1.v = Inf)) then cexc(4) := '1'; -- Invalid operation qres.v := SNaN; elsif (qs2.v = Zero) then cexc(1) := '1'; -- Divide by zero qres.v := SNaN; else fdiv(qs1, qs2, qres); end if; FPround(qres, LRes, SP); end if; if SP then NbCycles := 21; else NbCycles := 36; end if; when "0000000001" => -- fmovs LRes(63 downto 0) := RS2vec(31 downto 0) & RS2vec(31 downto 0); cexc := "00000"; NbCycles := 2; when "0001001001" | "0001001010" => -- fmuls/d if ((qs1.v > SNaN) and (qs2.v > SNaN)) then if (qs1.v = Zero and qs2.v = Inf) or (qs1.v = Inf and qs2.v = Zero) then qres.v := QNaN; else fmul(qs1, qs2, qres); end if; FPround(qres, LRes, SP); end if; if SP then NbCycles := 6; else NbCycles := 10; end if; when "0000000101" => -- fnegs if qs2.v > SNaN then LRes(63 downto 32) := not(RS2vec(31)) & RS2vec(30 downto 0); Lres(31 downto 0) := LRes(63 downto 32); end if; NbCycles := 2; when "0000101001" | "0000101010" => -- fsqrs/d NbCycles := 66; if (qs2.v > SNaN) then if (qs2.sign = '1') then cexc(4) := '1'; -- Invalid operation qres.v := SNaN; NbCycles := 7; elsif qs2.v = Zero then NbCycles := 7; qres := qs2; elsif qs2.v = Inf then NbCycles := 7; qres := qs2; elsif qs2.v = norm then if SP then NbCycles := 38; else NbCycles := 66; end if; fsqrt(qs2, qres,SP); end if; FPround(qres, LRes, SP); end if; when "0001000101" | "0001000110" => -- fsub/d if (qs1.v > SNan) and (qs2.v > SNaN) then faddsub(qs1, qs2, qres, false); FPround(qres, LRes, SP); end if; NbCycles := 5; when "0011010010" => -- fdtoi if (qs2.v <= SNan) then cexc(4) := '1'; LRes(31 downto 0) := '1' & ext("0",31); if qs2.sign = '0' then LRes(31 downto 0) := not LRes(31 downto 0); end if; LRes(63 downto 32) := LRes(31 downto 0); else fqtoi(qs2, LRes); end if; NbCycles := 8; when "0011000110" => -- fdtos if qs2.v <= SNan then LRes(63 downto 0) := SPNan & SPNan; if qs2.v = SNan then cexc(4) := '1'; end if; else FPround(qs2, LRes, true); end if; NbCycles := 4; when "0011001000" => -- fitod cexc := "00000"; fitoq(rs2vec,qs2); FPround(qs2, LRes, false); NbCycles := 7; when "0011000100" => -- fitos cexc := "00000"; fitoq(rs2vec,qs2); FPround(qs2, LRes, true); NbCycles := 7; when "0011001001" => -- fstod if qs2.v = QNan then LRes(63 downto 0) := DPNan; LRes(51 downto 51 - 22) := RS2vec(22 downto 0); else if qs2.v = SNan then cexc(4) := '1'; end if; FPround(qs2, LRes, false); end if; NbCycles := 3; when "0011010001" => -- fstoi if (qs2.v <= SNan) then cexc(4) := '1'; LRes(31 downto 0) := '1' & ext("0",31); if qs2.sign = '0' then LRes(31 downto 0) := not LRes(31 downto 0); end if; LRes(63 downto 32) := LRes(31 downto 0); else fqtoi(qs2, LRes); end if; NbCycles := 7; when others => Unimp := true; NbCycles := 2; end case; Result := LRes; texc := cexc; if cexc /= "00000" then FPexcVector(FP_EXC_DETECTED) := TRUE; FPexcVector(IEEE_EXC) := TRUE; elsif Unimp then FPexcVector(FP_EXC_DETECTED) := TRUE; FPexcVector(UNIMPLEMENTED_FPOP) := TRUE; end if; end ExecuteFPop; -- procedure end FPURTPck; -- package body ------------------------------------------------------------------------------- -- File name : fpurt_gen_beh.vhd -- Title : FPURTGeneric (architecture Behave) -- project : SPARC -- Library : FPURT_LIB -- Author(s) : Maxime ROCCA -- Purpose : definition of architecture Behave for FPURTGeneric. It is a beha- -- -vioral description of the FPURT at the highest level. -- -- notes : The entity FPURTGeneric is defined in the file fpurt_gen_ent.vhd. -- ------------------------------------------------------------------------------- -- Modification history : ------------------------------------------------------------------------------- -- Version No : | Author | Date | Changes made : ------------------------------------------------------------------------------- -- v 1.0 | MR | 94-03-04 | first version. -- Compliant with the FPU-RT Device Specification, issue 4++ (i.e certain -- features implemented in this version of the FPU-RT model will only appear in -- the next issue of the FPU-RT Device Specification), except that the copro- -- -cessor interface is not implemented in this version. --............................................................................. -- v 1.1 | MR | 94-05-03 | 2nd version -- + FPURT model is made sensitive to the signals CCCV and CHOLD_N -- + bug fix about LDFSR handling when FINS1/2 is late. -- + bug fix about FEXC_N when STDFQ while FQ empty -- + bug fix on FNULL and FLUSH. -- + bug fix on generation of FCCV when in exception mode -- + generation of FHOLD_N when FCMP(E)q is in W stage (particular case) -- + modif. logical condition in parity bit checking + modif. generation of -- FIPAR -- + bug fix for XHOLD cases on FP store. -- + bug fix: modif. condition for FCCV generation. -- + change name of tap controller -- + modelling of buffers slightly modified. --............................................................................. -- v 1.2 | MR | 94-05-27 | 3rd version -- + modify setup and hold time checkers. --............................................................................. -- v 1.3 | RC | 95-12-11 | 4th version -- + modify data drivers. --............................................................................. -- v 1.4 | JG | 96-02-27 | 5th version -- + bug fix: INST latching -- + bug fix: MDS properly handled -- + bug fix: STDF and STDFQ driving of data bus during second data cycle --............................................................................. -- v 1.5 | JG | 96-03-13 | 6th version -- + bug fix: de-assert FHOLD even if MHOLD is asserted --............................................................................. -- v 1.6 | JG | 96-04-24 | 7th version -- + Changed FHOLD/FCCV generation to FPU rev.B imlpementation -- + Modified pipeline handling during XHOLD -- + Instruction timing should be identical to FPU rev.B --............................................................................. -- v 1.7 | JG | 96-10-01 | 8th version -- + Fixed problem with ldf/fpop interlock ------------------------------------------------------------------------------- -- Copyright MATRA MARCONI SPACE FRANCE ------------------------------------------------------------------------------- ---------|---------|---------|---------|---------|---------|---------|--------| library IEEE; use IEEE.Std_Logic_1164.all; library MMS; use MMS.StdRtl.all; use MMS.StdIoImp.all; library SPARC_LIB; use SPARC_LIB.SparcPck.all; use SPARC_LIB.TAPCompPck.all; library FPURT_LIB; use FPURT_LIB.FPURTPck.all; use STD.TEXTIO.all; architecture vhdl_behavioral of FPURTGeneric is -- constant for modelling purposes constant TRI_STATE32 : std_logic_vector(31 downto 0) := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"; -- Value for the field "ver" of the FSR. constant FSR_VER : std_logic_vector(2 downto 0) := "100"; constant FSR_UNUSED : std_logic := '0'; constant FSR_RES : std_logic_vector(1 downto 0) := "00"; constant RPconst : std_logic_vector(1 downto 0) := "00"; constant NSconst : std_logic := '0'; -- Pipeline registers + floating-point queue (FQ): signal ID1, ID2, E, W : FPInstruction; signal FQ : FPInstruction; signal FQ_rck : FPInstruction; --gd 130995 -- Address register signal DDA : std_logic_vector(31 downto 0); -- Internal signals corresponding to output or bidirectional port signals. -- A signal SIGin corresponds to the output port signal SIG. signal FP_Nin : std_logic; signal FCCin : std_logic_vector(1 downto 0); signal FCCVin : std_logic; signal FHOLD_Nin : std_logic; signal FEXC_Nin : std_logic; signal FIPARin : std_logic; signal Din : std_logic_vector(31 downto 0); signal DPARin : std_logic; signal FNULLin : std_logic; -- Signals used for the IO buffers modelling signal DHCmSig : std_logic; signal CHCmSig : std_logic; signal DOE_Ndel : std_logic; signal COE_Ndel : std_logic; signal HALTsampled : std_logic; -- Signals used for setup/hold timing checkers: conditional checking. signal RESET_Nsamp : std_logic; signal TrigChecking : std_logic; signal TrigChecking_1 : std_logic; signal TrigChecking_2 : std_logic; signal CheckTimBidir_1 : boolean; signal CheckTimBidir_1_i : boolean; signal CheckTimBidir_2 : boolean; signal CheckTimBidir_2_i : boolean; signal XHOLD_N : std_logic; signal Chk_A_en : boolean; signal Chk_FINS1_en : boolean; signal Chk_FINS2_en : boolean; signal Chk_INST_en : boolean; signal Chk_FXACK_en : boolean; signal Chk_FLUSH_en : boolean; signal Chk_MHOLDA_N_en : boolean; signal Chk_MHOLDB_N_en : boolean; signal Chk_BHOLD_N_en : boolean; signal Chk_MDS_N_en : boolean; signal Chk_APAR_en : boolean; signal Chk_IFPAR_en : boolean; signal FSR_spy : std_logic_vector(31 downto 0); -- gd 130995 signal HLDorHLTasserted_spy : boolean := FALSE; -- gd 130995 signal HLDorHLTasserted_rck_spy : boolean := FALSE; signal FPUmode_spy : FPUmodeType := RESET_MODE; -- gd 130995 signal W1_spy, W2_spy : FPInstruction; -- gd 130995 signal Inst_rck : std_logic := '0'; -- gd 140995 signal Inst_samp_rck : std_logic := '0'; -- gd 140995 signal Inst_samp_fck : std_logic := '0'; -- gd 140995 signal Inst_samp : std_logic := '0'; -- gd 140995 signal FPregFile_spy : RegisterFile(31 downto 0); signal CycleCounterx : integer; signal FHOLDcondTypex : natural := 0; signal FHOLD_Nvar_spy : std_logic; -- Configuration of components -- for all : TAP_iufpu use entity SPARC_LIB.tap_iufpu(vhdl_behavioral); begin FPUmodel: process -- W1 & W2: fictitious pipeline stages after the W stage -- W1: "stage" just after W -- W2: "stage" just after W1. variable W1, W2 : FPInstruction; -- CAREFUL: W1 & W2 are variables. -- FPU mode variable FPUmode : FPUmodeType := RESET_MODE; -- Floating-point state register variable FSR : std_logic_vector(31 downto 0); alias RD : std_logic_vector(1 downto 0) is FSR(31 downto 30); alias RP : std_logic_vector(1 downto 0) is FSR(29 downto 28); alias TEM : std_logic_vector(4 downto 0) is FSR(27 downto 23); alias NS : std_logic is FSR(22); alias res : std_logic_vector(1 downto 0) is FSR(21 downto 20); alias ver : std_logic_vector(2 downto 0) is FSR(19 downto 17); alias FTT : std_logic_vector(2 downto 0) is FSR(16 downto 14); alias QNE : std_logic is FSR(13); alias Unused : std_logic is FSR(12); alias FSR_FCC : std_logic_vector(1 downto 0) is FSR(11 downto 10); alias AEXC : std_logic_vector(4 downto 0) is FSR(9 downto 5); alias CEXC : std_logic_vector(4 downto 0) is FSR(4 downto 0); -- Floating-point register file variable FPregFile : RegisterFile(31 downto 0); -- Data objects for FP load instructions variable Data1, Data2 : std_logic_vector(31 downto 0); -- Boolean flag for start-up. variable PowerUp : boolean := TRUE; -- Variables for output signals: for signal SIGNAL, the variable is -- SIGNALvar. pSIGNALvar = value of SIGNALvar in the previous cycle. variable FHOLD_Nvar : std_logic; variable FHOLD_Nvar2 : std_logic := '1'; variable pFHOLD_Nvar2 : std_logic; variable FEXC_Nvar : std_logic; variable pFEXC_Nvar : std_logic; variable FCCvar : std_logic_vector(1 downto 0); variable pFCCvar : std_logic_vector(1 downto 0); variable FCCVvar : std_logic; variable pFCCVvar : std_logic; variable FNULLvar : std_logic; variable pFNULLvar : std_logic; variable pHWERROR_Nvar : std_logic; variable HWERROR_Nvar : std_logic; -- Variable for MDS_N signal variable MDS_Nvar : std_logic; -- Variable for FLUSH signal variable pFLUSHvar : std_logic; -- Boolean variables for signals holding (or freezing) the pipeline. variable HLDorHLTasserted : boolean := FALSE; -- XHOLD_N or HALT_N active variable HLDorHLTasserted_rck : boolean := FALSE; variable FHOLD_Nasserted : boolean := FALSE; variable FCCVlow : boolean := FALSE; -- Variables for execution. variable RS1vec : std_logic_vector(63 downto 0); variable RS2vec : std_logic_vector(63 downto 0); variable FPbitInst : std_logic_vector(31 downto 0); variable CycleCounter : integer; variable Result : std_logic_vector(63 downto 0); variable tfcc : std_logic_vector(1 downto 0); variable texc : std_logic_vector(4 downto 0); variable FPexcVector : FPexcVectorType := (others => FALSE); variable NbCycles : integer; variable texcVar : std_logic_vector(4 downto 0); -- temp. variable -- Variables for FP STORE instructions variable StoreData1 : std_logic_vector(31 downto 0); variable StoreData2 : std_logic_vector(31 downto 0); variable DriveData1 : boolean := FALSE; variable DriveData2 : boolean := FALSE; variable OldDriveData1 : boolean := FALSE; variable OldDriveData2 : boolean := FALSE; variable EmptyTheFQ : boolean := FALSE; -- Variables related to the external hold cases on FP STORE variable SaveDriveData1 : boolean := FALSE; variable SaveDriveData2 : boolean := FALSE; variable SaveActive : boolean := FALSE; -- Variable related to the Master/checker variable CMmismatch : integer := 0; -- Variables related to the FHOLD_N generation variable FHOLDcondType : natural := 0; -- Variable related to the parity bits checking variable ParBitViolCount : integer := -1; variable DPARviol : boolean := FALSE; variable IFPARviol : boolean := FALSE; -- Other variables variable fttSAVE : std_logic_vector(2 downto 0); -- temp variable for ftt variable QNEsave : std_logic; -- temp variable for QNE variable PendingSeqErr : integer := -1; -- used for sequence error cases. variable DeasFHOLDseqErr : boolean := FALSE; -- for sequence error cases. -- Variable for specific case variable LDFSRhold2ndCycle : integer := -1; -- used for hold wen LDFSR -- Files for debugging; only used when in debugging mode. file Fdebug : text is out "DPRegFPU.dbg"; file FCtDebug : text is out "CtRegFPU.dbg"; begin --------------------------------------------- -- Initialization part: body of -- this "if" statement is executed only once. if PowerUp then PowerUp := FALSE; FP_Nin <= '0'; res := FSR_RES; Unused := FSR_UNUSED; ver := FSR_VER; -- Check certain timing parameters values if tDPOH >= tDPOD then assert FALSE report "[FPURTGeneric(Behave)]: parameter tDPOD must be " & "greater than tDPOH after re-computation!" severity failure; end if; if tDOH >= tDOD then assert FALSE report "[FPURTGeneric(Behave)]: parameter tDOD must be " & "greater than tDOH after re-computation!" severity failure; end if; if tFCCH >= tFCCD then assert FALSE report "[FPURTGeneric(Behave)]: parameter tFCCD must be " & "greater than tFCCH after re-computation!" severity failure; end if; if tDOHFL >= tDOFFL then assert FALSE report "[FPURTGeneric(Behave)]: parameter tDOFFL must " & "be greater than tDOHFL after re-computation!" severity failure; end if; if tFIPH >= tFIPD then assert FALSE report "[FPURTGeneric(Behave)]: parameter tFIPD must " & "be greater than tFIPH after re-computation!" severity failure; end if; end if; -------------------------------- wait on Clk, FINS1, FINS2, FLUSH, DHCmSig, CHCmSig, FP_Nin, FCCin, FCCVin, FHOLD_Nin, FEXC_Nin, FIPARin, Din, DPARin, FNULLin; if (FPUmode /= RESET_MODE and FPUmode /= ERROR_MODE) then if rising_edge(Clk) then -- assign pSIGNAL variables pFEXC_Nvar := FEXC_Nvar; pFCCvar := FCCvar; pHWERROR_Nvar := HWERROR_Nvar; -- on each rising clock edge DDA <= A; -- For setup/hold timing checkers. if E.Mnemo = LDF or E.Mnemo = LDFSR or E.Mnemo = LDDF or W.Mnemo = LDDF then TrigChecking <= '1'; else TrigChecking <= '0'; end if; HLDorHLTasserted_rck := HLDorHLTasserted; -- Fix for ldf/fpop interlock problem, 1-10-96 J.Gaisler if not(HLDorHLTasserted or FCCVlow or FHOLD_Nasserted) or ((HLDorHLTasserted or FCCVlow or FHOLD_Nasserted) and IsFPop(E.Mnemo) and not (IsFPop(FQ.Mnemo) or IsFPop(W.Mnemo)) and CycleCounter = -1) then --''''' FP load ''''' if FLUSH = '0' and FPUmode /= EXCEPTION then if W1.Mnemo = LDF then -- delayed loading into register file. FPregFile(W1.rd) := Data1; elsif W1.Mnemo = LDFSR then fttSAVE := ftt; -- ftt, res, Unused, ver, QNE, NS, RP of FSR QNEsave := QNE; -- are NOT loadable. FSR := Data1; ftt := fttSAVE; res := FSR_RES; Unused := FSR_UNUSED; ver := FSR_VER; FCCvar := FSR_FCC; RP := RPconst; NS := NSconst; QNE := QNEsave; end if; if W1.Mnemo = LDDF then FPregFile((W1.rd/2)*2) := Data1; -- Register alignment (even #) end if; if W2.Mnemo = LDDF then -- MDS fix, J.Gaisler 27-02-96 FPregFile((W2.rd/2)*2 + 1) := Data1; -- Register alignment (odd #) end if; end if; if (W.Mnemo = LDF or W.Mnemo = LDDF or W.Mnemo = LDFSR) then Data1 := D; end if; if W1.Mnemo = LDDF then Data1 := D; -- MDS fix, J.Gaisler 27-02-96 end if; end if; if not(HLDorHLTasserted or FCCVlow or FHOLD_Nasserted) then -- Latch INST (J.Gaisler 27-02-96) Inst_samp <= INST; --~~~~~~ IFetch, IDecode, Execute, FP load/store ~~~~~~ --''''' FP store ''''' if EmptyTheFQ then EmptyTheFQ := FALSE; QNE := '0'; FPUmode := EXECUTION; end if; --''''' Assignment of E ''''' if FINS1 = '1' then if FPUmode = EXCEPTION and not(ID1.Mnemo = STF or ID1.Mnemo = STDF or ID1.Mnemo = STFSR or ID1.Mnemo = STDFQ) and PendingSeqErr = -1 then PendingSeqErr := 2; end if; E <= ID1; elsif FINS2 = '1' then if FPUmode = EXCEPTION and not(ID2.Mnemo = STF or ID2.Mnemo = STDF or ID2.Mnemo = STFSR or ID2.Mnemo = STDFQ) and PendingSeqErr = -1 then PendingSeqErr := 2; end if; E <= ID2; elsif ((E.Mnemo = LDF or E.Mnemo = LDDF or E.Mnemo = LDFSR or E.Mnemo = STF or E.Mnemo = STDF or E.Mnemo = STFSR or E.Mnemo = STDFQ) or (W.Mnemo = LDDF or W.Mnemo = STF or W.Mnemo = STDF or W.Mnemo = STDFQ or W1.Mnemo = STDF or W1.Mnemo = STDFQ) ) then E.Mnemo <= IOP; elsif FINS1 = '0' and FINS2 = '0' then E.Mnemo <= NOTHING; else E.Mnemo <= XXX; end if; --''''' Pipeline progression for W, W1, W2 ''''' W2 := W1; W1 := W; W <= E; --''''' Instruction fetch from D bus ''''' if INST = '1' then ID2 <= ID1; ID1 <= FPtranscribe(D); ID1.BitAddress <= DDA; end if; end if; --''''' Sequence error condition ''''' if (PendingSeqErr = 0) or (E.Mnemo = STDFQ and QNE = '0' and not(FHOLD_Nasserted) and not(HLDorHLTasserted)) then FPexcVector(FP_EXC_DETECTED) := TRUE; FPexcVector(SEQUENCE_ERROR) := TRUE; CycleCounter := 1; -- goes into the exception handling part. end if; if PendingSeqErr >= 0 then PendingSeqErr := PendingSeqErr - 1; end if; if W.Mnemo = STDFQ and FPUmode = PENDING_EXCEPTION then FEXC_Nvar := '1'; -- "Kinky" behavior in this case!!! end if; --~~~~~ Effect of FLUSH on the FPU: flush the pipeline ~~~~ if (FLUSH = '1' and pFLUSHvar = '0' and not(HLDorHLTasserted or FCCVlow or FHOLD_Nasserted) ) then E.Mnemo <= ANNULLED; W.Mnemo <= ANNULLED; W1.Mnemo := ANNULLED; W2.Mnemo := ANNULLED; end if; pFLUSHvar := FLUSH; --~~~~~~~ Generation of HWERROR_N: parity bit checking ~~~~~~~~ -- WARNING: Fuzzy behavior!!! --- if N602MODE_N = '1' then if (IFPAR /= OddParityOf(FINS1 & FINS2 & FLUSH & FXACK & INST) and IFPAR /= 'Z' and FINS1 /= 'Z' and FINS2 /= 'Z' and FLUSH /= 'Z' and FXACK /= 'Z' and INST /= 'Z') or (APAR /= OddParityOf(A) and APAR /= 'Z' and A /= TRI_STATE32) then ParBitViolCount := 1; IFPARviol := TRUE; end if; if (INST = '1' or W.mnemo = LDF or W2.Mnemo = LDDF) and DPAR /= OddParityOf(D) and DPAR /= 'Z' and D /= TRI_STATE32 then ParBitViolCount := 1; DPARviol := TRUE; end if; end if; if FTT = "000" then -- WARNING: the timing for signal HWERROR_N may -- be wrong! Not well specified. HWERROR_Nvar := '1'; end if; --~~~~~~ Floating-point queue (FQ) handling ~~~~~~ --~~~~~~ and exception handling ~~~~~~ if QNE = '0' then if IsFPop(W.Mnemo) and FPUmode = EXECUTION and FLUSH = '0' then if IsFPopSourceRegDouble(W.Mnemo) then RS1vec := FPregFile((W.rs1/2)*2) & FPregFile((W.rs1/2)*2+1); RS2vec := FPregFile((W.rs2/2)*2) & FPregFile((W.rs2/2)*2+1); else RS1vec := FPregFile(W.rs1) & FPregFile(W.rs1); RS2vec := FPregFile(W.rs2) & FPregFile(W.rs2); end if; FPbitInst := W.BitInstruction; if VecUnknown(FPbitInst) or VecUnknown(RS2vec) or VecUnknown(RD) or BitUnknown(TEM(2)) or (FPURs1IsIn(W.Mnemo) and VecUnknown(RS1vec)) then Result := (others => 'X'); tfcc := "XX"; texc := "XXXXX"; FPexcVector := (others => FALSE); NbCycles := 2; -- Arbitrary value assert FALSE report "(Architecture of FPURTGeneric): unknown " & "value encountered." severity warning; else ExecuteFPop(FPbitInst, RS1vec, RS2vec, RD, TEM(2), FALSE, 0, Result, tfcc, texc, FPexcVector, NbCycles, Fdebug, FCtDebug); end if; if NbCycles = 2 or IsFPopUnimp(W.Mnemo) then -- because of "kinky" behavior for 2-cycle -- FPop, and unimplemented FPop instructions. CycleCounter := NbCycles; elsif NbCycles > 2 then CycleCounter := NbCycles - 1; end if; FQ <= W; QNE := '1'; -- FQ not empty. if (HLDorHLTasserted or FCCVlow or FHOLD_Nasserted) then W.Mnemo <= NOTHING; -- The instr. in W has moved to the FQ. end if; else FQ.Mnemo <= NOTHING; end if; end if; --------------------------------------------------------------- -- FIX: E and W stage is not sensitive to FHOLD/FCCV -- J.Gaisler 19-04-96 if (HLDorHLTasserted or FCCVlow or FHOLD_Nasserted) and IsFPop(E.Mnemo) and not (IsFPop(FQ.Mnemo) or IsFPop(W.Mnemo)) and CycleCounter = -1 then W2 := W1; W1 := W; W <= E; E.Mnemo <= NOTHING; end if; --------------------------------------------------------------- if CycleCounter >= 0 then CycleCounter := CycleCounter - 1; end if; if ParBitViolCount = 0 then -- parity bit violation handling. ParBitViolCount := -1; CycleCounter := 0; if DPARviol then DPARviol := FALSE; FPexcVector(DATA_BUS_ERROR) := TRUE; FPexcVector(FP_EXC_DETECTED) := TRUE; FPUmode := PENDING_EXCEPTION; end if; if IFPARviol then IFPARviol := FALSE; FPexcVector(RESTARTABLE_ER) := TRUE; FPexcVector(FP_EXC_DETECTED) := TRUE; FPUmode := PENDING_EXCEPTION; end if; elsif ParBitViolCount > 0 then ParBitViolCount := ParBitViolCount - 1; end if; if CycleCounter = 0 then if FPexcVector(FP_EXC_DETECTED) then -- Potential FP exception -- detected if FPexcVector(IEEE_EXC) then -- assign CEXC & AEXC according to TEM CEXC := texc; texcVar := texc and TEM; if texcVar = "00000" then AEXC := AEXC or CEXC; FTT := "000"; -- no exception flagged (AND-masked by TEM). -- Assign FPregFile with Result because no exception occurred -- Note: the register addressing is forced --> data alignment -- in register file. if IsFPopRdDouble(FQ.Mnemo) then FPregFile((FQ.rd/2)*2) := Result(63 downto 32); FPregFile((FQ.rd/2)*2+1) := Result(31 downto 0); elsif not(IsFCMP(FQ.Mnemo)) then FPregFile(FQ.rd) := Result(63 downto 32); elsif IsFCMP(FQ.Mnemo) then FCCvar := tfcc; FSR_FCC := tfcc; end if; QNE := '0'; -- The exec. of the instr. in the FQ is finished. FQ.Mnemo <= NOTHING; else FTT := "001"; FPUmode := PENDING_EXCEPTION; FEXC_Nvar := '0'; end if; elsif FPexcVector(UNFINISHED_FPOP) then -- should not occur FTT := "010"; FPUmode := PENDING_EXCEPTION; FEXC_Nvar := '0'; elsif FPexcVector(UNIMPLEMENTED_FPOP) then FTT := "011"; FPUmode := PENDING_EXCEPTION; FEXC_Nvar := '0'; elsif FPexcVector(SEQUENCE_ERROR) then FTT := "100"; FPUmode := PENDING_EXCEPTION; FEXC_Nvar := '0'; elsif FPexcVector(DATA_BUS_ERROR) then FTT := "101"; -- Data bus error HWERROR_Nvar := '0'; FEXC_Nvar := '0'; elsif FPexcVector(RESTARTABLE_ER) then FTT := "110"; -- Restartable error HWERROR_Nvar := '0'; FEXC_Nvar := '0'; end if; FPexcVector := (others => FALSE); else CEXC := "00000"; FTT := "000"; -- Assign FPregFile with Result because no exception occurred -- Note: the register addressing is forced --> data alignment -- in register file. if IsFPopRdDouble(FQ.Mnemo) then FPregFile((FQ.rd/2)*2) := Result(63 downto 32); FPregFile((FQ.rd/2)*2+1) := Result(31 downto 0); elsif not(IsFCMP(FQ.Mnemo)) then FPregFile(FQ.rd) := Result(63 downto 32); elsif IsFCMP(FQ.Mnemo) then FCCvar := tfcc; FSR_FCC := tfcc; end if; QNE := '0'; -- The execution of the instr. in the FQ is finished. FQ.Mnemo <= NOTHING; end if; end if; --~~~~~~~~~~ Samples FXACK to deassert FEXC_N ~~~~~~~~~ if FXACK = '1' then FEXC_Nvar := '1'; FPUmode := EXCEPTION; end if; --~~~~~~~~~ Instruction/data fetch when cache miss ~~~~~~~~~ if MDS_Nvar = '0' then if Inst_samp = '1' then -- instruction fetch -- gd 140995 ID1 <= FPtranscribe(D); ID1.BitAddress <= DDA; elsif FPUmode /= EXCEPTION then -- data fetch -- gd 140995 if (W1.Mnemo = LDF) or (W1.Mnemo = LDDF) or (W1.Mnemo = LDFSR) or (W2.Mnemo = LDDF) then Data1 := D; -- MDS fix, J.Gaisler 27-02-96 end if; end if; end if; --~~~~ DPAR checking when MDS_N: what if MEXC_N??? ~~~~ if N602MODE_N = '1' and MDS_Nvar = '0' then if (INST = '1' or W.mnemo = LDF or W2.Mnemo = LDDF) and DPAR /= OddParityOf(D) and DPAR /= 'Z' and D /= TRI_STATE32 then ParBitViolCount := 1; DPARviol := TRUE; end if; end if; FQ_rck <= FQ; -- GD 130995 end if; -- rising edge of Clk. -- ^^^^^^^^^^^^^^^^^^^ if falling_edge(Clk) then -- Sample signal MDS_N MDS_Nvar := MDS_N; -- assign pSIGNAL variables pFHOLD_Nvar2 := FHOLD_Nvar2; pFCCVvar := FCCVvar; pFNULLvar := FNULLvar; --~~~ Sampling of XHOLD_N input signals and FHOLD_Nvar, FCCVvar ~~~~ if (MHOLDA_N = '0' or MHOLDB_N = '0' or BHOLD_N = '0' or HALT_N = '0' or CHOLD_N = '0' or CCCV = '0' ) then HLDorHLTasserted := true; else HLDorHLTasserted := false; end if; if FHOLD_Nvar2 = '0' then FHOLD_Nasserted := TRUE; else FHOLD_Nasserted := FALSE; end if; if FCCVvar = '0' then FCCVlow := TRUE; else FCCVlow := FALSE; end if; --~~~ DPAR violation cancelled in case of MHOLD_N ~~~~ if N602MODE_N = '1' and (MHOLDA_N = '0' or MHOLDB_N = '0') and ParBitViolCount /= -1 and DPARviol then DPARviol := FALSE; if not(IFPARviol) then ParBitViolCount := -1; end if; end if; --~~~~~~ Handling of FP compare: FCCV signal ~~~~~~ if (not FHOLD_Nasserted) and (IsFCMP(E.Mnemo) or IsFCMP(W.Mnemo)) and ((FPUmode = EXECUTION) and (FLUSH = '0')) then FCCVvar := '0'; end if; --~~~~~~ Generation of FHOLD_N signal on the falling clock edge ~~~ if FPUmode = EXECUTION and -- FIX: FHOLD is asserted even if MHOLD is active, J.Gaisler 27-02-96 ( ( not(FHOLD_Nasserted) and not(FCCVlow)) or (W.Mnemo = FCMPq or W.Mnemo = FCMPEq) ) then FHOLDcondType := FHOLDcondition(FINS1, FINS2, ID1, ID2, E, W, W1, FQ); if FHOLDcondType = 1 or (FHOLDcondType = 2 and not HLDorHLTasserted) then FHOLD_Nvar := '0'; end if; end if; if PendingSeqErr = 1 then FHOLD_Nvar := '0'; -- case of sequence error. end if; --~~~~~ Deassertion of FHOLD_N and FCCV ~~~~~~~~ if (CycleCounter = 0) then if FHOLD_Nvar = '0' then FHOLD_Nvar := '1'; end if; if FCCVvar = '0' and FCCVlow then FCCVvar := '1'; end if; end if; if LDFSRhold2ndCycle >= 0 then LDFSRhold2ndCycle := LDFSRhold2ndCycle - 1; end if; if ((((W1.Mnemo = LDF or W2.Mnemo = LDDF) and FHOLD_Nasserted and FHOLDcondType /= 1 ) or ( (W.Mnemo = LDF or W1.Mnemo = LDDF) and FHOLD_Nasserted and FHOLDcondType /= 1 ) or ( (W2.Mnemo = LDFSR or (LDFSRhold2ndCycle = 0 and W1.Mnemo = LDFSR)) and FHOLD_Nasserted and FHOLDcondType /= 1))) then FHOLD_Nvar := '1'; end if; if DeasFHOLDseqErr then FHOLD_Nvar := '1'; -- case of sequence error. DeasFHOLDseqErr := FALSE; end if; if PendingSeqErr = 0 then DeasFHOLDseqErr := TRUE; -- case of sequence error. end if; if FHOLD_Nvar = '0' and W.Mnemo = LDFSR then LDFSRhold2ndCycle := 2; end if; ----------------------------------------------------------------------------- -- FIX: if MHOLD and FHOLD are asserted simultaneously, then FHOLD will -- be kept low for one clock after the release of MHOLD. -- MODIFIED 15-04-96 to incorporate new scheme in rev.B if not ( HLDorHLTasserted_rck and HLDorHLTasserted) then FHOLD_Nvar2 := FHOLD_Nvar; end if; FNULLvar := not(FCCVvar and FHOLD_Nvar2); end if; -- falling edge of Clk. -- ^^^^^^^^^^^^^^^^^^^^ end if; --******************** INTERFACE modelling ****************** --'''''' Reset pin sampling ''''' if rising_edge(Clk) then if RESET_N = '0' then FPUmode := RESET_MODE; pFHOLD_Nvar2 := FHOLD_Nvar2; FHOLD_Nvar := '1'; pFEXC_Nvar := FEXC_Nvar; FEXC_Nvar := '1'; pFCCvar := FCCvar; FCCvar := "00"; pFCCVvar := FCCVvar; FCCVvar := '1'; pFNULLvar := FNULLvar; FNULLvar := '0'; pHWERROR_Nvar := HWERROR_Nvar; HWERROR_Nvar := '1'; MCERR_N <= '1' after tMCD; FHOLD_Nin <= '1'; -- Set the writable fields of FSR to zero. RD := "00"; RP := "00"; TEM := "00000"; NS := '0'; QNE := '0'; FSR_FCC := "00"; AEXC := "00000"; CEXC := "00000"; ftt := "000"; -- Reset the pipeline. ID1.Mnemo <= XXX; ID2.Mnemo <= XXX; E.Mnemo <= XXX; W.Mnemo <= XXX; FQ.Mnemo <= XXX; W1.Mnemo := XXX; W2.Mnemo := XXX; -- Reset the address register DDA <= (others => '0'); elsif RESET_N = '1' and FPUmode = RESET_MODE then FPUmode := EXECUTION; TrigChecking <= '1'; -- used for timing checkers. end if; end if; --''''''''' Assign output signals on their corresponding edges '''''''' if (rising_edge(FINS1) or rising_edge(FINS2)) and CLK = '0' and FPUmode = EXECUTION and ( (not(HLDorHLTasserted) and not(FHOLD_Nasserted) and not(FCCVlow)) or (W.Mnemo = FCMPq or W.Mnemo = FCMPEq) ) then FHOLDcondType := FHOLDcondition(FINS1, FINS2, ID1, ID2, E, W, W1, FQ); if FHOLDcondType = 1 or FHOLDcondType = 2 then FHOLD_Nvar := '0'; FHOLD_Nvar2 := '0'; -- FHOLD_Nin <= '0' after tFHDFI; FNULLvar := '1'; if W.Mnemo = LDFSR then LDFSRhold2ndCycle := 2; end if; end if; end if; if rising_edge(FLUSH) then FHOLD_Nvar := '1'; -- FHOLD_Nin <= transport '1' after tFHDFL; FCCVvar := '1'; FCCVin <= transport '1' after tFCCVDFL; end if; if falling_edge(Clk) then if not(HLDorHLTasserted or FCCVlow or FHOLD_Nasserted) then --''''' FP store ''''' if (W.Mnemo = STF or W.Mnemo = STDF or W.Mnemo = STDFQ or W.Mnemo = STFSR ) then case W.Mnemo is when STF => -- OldStoreData := StoreData; -- StoreData := FPregFile(W.rd); StoreData1 := FPregFile(W.rd); OldDriveData1 := DriveData1; DriveData1 := TRUE; when STDF => -- OldStoreData := StoreData; -- StoreData := FPregFile((W.rd/2)*2); -- Register alignment StoreData1 := FPregFile((W.rd/2)*2); -- Register alignment OldDriveData1 := DriveData1; DriveData1 := TRUE; when STDFQ => -- OldStoreData := StoreData; -- StoreData := FQ.BitAddress; StoreData1 := FQ_rck.BitAddress; OldDriveData1 := DriveData1; DriveData1 := TRUE; when STFSR => -- OldStoreData := StoreData; -- StoreData := FSR; StoreData1 := FSR; OldDriveData1 := DriveData1; DriveData1 := TRUE; when others => NULL; end case; else OldDriveData1 := DriveData1; DriveData1 := FALSE; end if; if W1.Mnemo = STDFQ then OldDriveData2 := DriveData2; DriveData2 := TRUE; StoreData2 := FQ.BitInstruction; EmptyTheFQ := TRUE; elsif W1.Mnemo = STDF then OldDriveData2 := DriveData2; DriveData2 := TRUE; StoreData2 := FPregFile((W.rd/2)*2 + 1); -- Register alignment else OldDriveData2 := DriveData2; DriveData2 := FALSE; end if; end if; if (FHOLD_Nvar2 = '1' and pFHOLD_Nvar2 /= '1') then FHOLD_Nin <= '1' after tFHH; elsif (FHOLD_Nvar2 = '0' and pFHOLD_Nvar2 /= '0') then FHOLD_Nin <= '0' after tFHD; end if; if (FCCVvar = '1' and pFCCVvar /= '1') then FCCVin <= '1' after tFCCVH; elsif (FCCVvar = '0' and pFCCVvar /= '0') then FCCVin <= '0' after tFCCVD; end if; ------------------------------------ if DriveData1 and FLUSH = '0' then Din <= StoreData1 after tDOD; DPARin <= OddParityOf(StoreData1) after tDPOD; elsif DriveData2 and FLUSH = '0' then Din <= StoreData2 after tDOD; DPARin <= OddParityOf(StoreData2) after tDPOD; else Din <= (others => 'Z') after tDOH; DPARin <= 'Z' after tDPOH; end if; end if; if rising_edge(FLUSH) and (DriveData1 or DriveData2) then Din <= transport (others => 'X') after tDOHFL, (others => 'Z') after tDOFFL; DPARin <= transport 'X' after tDOHFL, 'Z' after tDOFFL; end if; if rising_edge(Clk) then if (FEXC_Nvar = '1' and pFEXC_Nvar /= '1') then FEXC_Nin <= '1' after tFEH; elsif (FEXC_Nvar = '0' and pFEXC_Nvar /= '0') then FEXC_Nin <= '0' after tFED; end if; if FCCvar /= pFCCvar then FCCin <= "XX" after tFCCH, FCCvar after tFCCD; end if; if (FNULLvar = '1' and pFNULLvar /= '1') then FNULLin <= '1' after tFND; elsif (FNULLvar = '0' and pFNULLvar /= '0') then FNULLin <= '0' after tFNH; end if; if (HWERROR_Nvar = '1' and pHWERROR_Nvar /= '1') then HWERROR_N <= '1' after tERH; elsif (HWERROR_Nvar = '0' and pHWERROR_Nvar /= '0') then HWERROR_N <= '0' after tERD; end if; FIPARin <= 'X' after tFIPH, OddParityOf(FEXC_Nvar & FCCvar & FCCVvar & FHOLD_Nvar2) after tFIPD; end if; --''''''' Master/checker mode operation: generation of MCERR_N ''''''' if CMODE_N = '0' then if rising_edge(CLK) then if CMmismatch = 1 or ((FCCin /= FCC or FEXC_Nin /= FEXC_N or FNULLin /= FNULL or FIPARin /= FIPAR or FP_Nin /= FP_N ) and COE_Ndel = '0' and HALTsampled = '1') then MCERR_N <= '0' after tMCD; else MCERR_N <= '1' after tMCH; end if; if CMmismatch /= 0 then CMmismatch := CMmismatch - 1; end if; elsif falling_edge(CLK) then if HALTsampled = '1' and ( ( (Din /= D or DPARin /= DPAR) and DOE_Ndel = '0' and (OldDriveData1 or OldDriveData2) ) or ((FCCVin /= FCCV or FHOLD_Nin /= FHOLD_N) and COE_Ndel = '0') ) then -- if CLK'last_event > then CMmismatch := 1; -- else -- CMmismatch := 2; -- This is for clock cycle dependency: TBD -- end if; end if; end if; else MCERR_N <= '1' after tMCH; end if; --'''' Tristated Outputs modelling: effects of signals COE_N, '''' --'''' DOE_N, HALT_N and CMODE on the output signals. '''' if DHCmSig'event and DHCmSig = '1' then D <= (others => 'Z'); DPAR <= 'Z'; elsif DHCmSig = '0' then D <= Din; DPAR <= DPARin; elsif DHCmSig = 'U' then D <= (others => 'U'); DPAR <= 'U'; elsif DHCmSig /= '1' then -- should never get here. D <= (others => 'X'); DPAR <= 'X'; end if; if CHCmSig'event and CHCmSig = '1' then FCCV <= 'Z'; FCC <= "ZZ"; FEXC_N <= 'Z'; FHOLD_N <= 'Z'; FNULL <= 'Z'; FIPAR <= 'Z'; FP_N <= 'Z'; elsif CHCmSig = '0' then FCCV <= FCCVin; FCC <= FCCin; FEXC_N <= FEXC_Nin; FHOLD_N <= FHOLD_Nin; FNULL <= FNULLin; FIPAR <= FIPARin; FP_N <= FP_Nin; elsif CHCmSig = 'U' then FCCV <= 'U'; FCC <= "UU"; FEXC_N <= 'U'; FHOLD_N <= 'U'; FNULL <= 'U'; FIPAR <= 'U'; FP_N <= 'U'; elsif CHCmSig /= '1' then -- should never get here. FCCV <= 'X'; FCC <= "XX"; FEXC_N <= 'X'; FHOLD_N <= 'X'; FNULL <= 'X'; FIPAR <= 'X'; FP_N <= 'X'; end if; FSR_spy <= FSR; -- gd 130995 HLDorHLTasserted_spy <= HLDorHLTasserted; -- gd 130995 HLDorHLTasserted_rck_spy <= HLDorHLTasserted_rck; FPUmode_spy <= FPUmode; -- gd 130995 W1_spy <= W1; -- gd 130995 W2_spy <= W2; -- gd 130995 CycleCounterx <= CycleCounter; FHOLDcondTypex <= FHOLDcondType; FPregFile_spy <= FPregFile; FHOLD_Nvar_spy <= FHOLD_Nvar; end process FPUmodel; ------------------------------------------- ------------------------------------------- ------------------------------------------- -- Processes to help model the tri-stated -- output buffers. ------------------------------------------- DHCmSigProcess: DHCmSig <= DOE_Ndel or not(HALTsampled) or not(CMODE_N); CHCmSigProcess: CHCmSig <= COE_Ndel or not(HALTsampled) or not(CMODE_N); SampleHALT_N: process begin wait on CLK; if falling_edge(CLK) then if HALT_N = '0' then HALTsampled <= '0' after tHAD; elsif HALT_N = '1' then HALTsampled <= '1' after tHAE; else HALTsampled <= HALT_N; end if; end if; end process SampleHALT_N; IntermediarySignals: process begin if DOE_N = '0' then DOE_Ndel <= '0' after tDONOE; elsif DOE_N = '1' then DOE_Ndel <= '1' after tDOFOE; else DOE_Ndel <= DOE_N; -- should not happen in normal case end if; if COE_N = '0' then COE_Ndel <= '0' after tDONOE; elsif COE_N = '1' then COE_Ndel <= '1' after tDOFOE; else COE_Ndel <= COE_N; -- should not happen in normal case end if; wait on DOE_N, COE_N; end process IntermediarySignals; ------------------------------------------- -- TAP controller ------------------------------------------- TAPctrller: TAP_iufpu generic map( tTDOD => tTDOD, tTDOH => tTDOH ) port map( TRst_N => TRST_N, TCK => TCLK, TDI => TDI, TMS => TMS, TDO => TDO ); -------------------------------------------------- -- Setup/hold checkers. -------------------------------------------------- GenRESET_Nsamp: process begin if not(CHECK_ON) then wait; -- the process dies here.... end if; wait on CLK until rising_edge(CLK); RESET_Nsamp <= RESET_N; end process GenRESET_Nsamp; ---- XHOLD_N <= MHOLDA_N and MHOLDB_N and BHOLD_N and FHOLD_N and FCCV and CHOLD_N and CCCV; ---- TrigChecking_1 <= TrigChecking after tDIH; GenCheckTimBidir_1_i : process variable Temp : std_logic; begin if not(CHECK_ON) then wait; -- the process dies here.... end if; wait on INST, RESET_Nsamp, TrigChecking_1; Temp := (INST and RESET_Nsamp) or TrigChecking_1; if Temp = '1' then CheckTimBidir_1_i <= TRUE; else CheckTimBidir_1_i <= FALSE; end if; end process GenCheckTimBidir_1_i; CheckTimBidir_1 <= transport CheckTimBidir_1_i and not(D = TRI_STATE32); DbusCheck : DbusSetupHoldCheck(D, CLK, XHOLD_N, SETUP => tDIS, HOLD => tDIH, PATH => "D", DelayedData => D'Delayed(abs(tDIH)), EN_CHECKING => CheckTimBidir_1); ---- TrigChecking_2 <= TrigChecking after tDPIH; GenCheckTimBidir_2_i : process variable Temp : std_logic; begin if not(CHECK_ON) then wait; -- the process dies here.... end if; wait on INST, RESET_Nsamp, TrigChecking_2; Temp := (INST and RESET_Nsamp) or TrigChecking_2; if Temp = '1' then CheckTimBidir_2_i <= TRUE; else CheckTimBidir_2_i <= FALSE; end if; end process GenCheckTimBidir_2_i; CheckTimBidir_2 <= transport CheckTimBidir_2_i and not(DPAR = 'Z'); DPARcheck : DbusSetupHoldCheck(DPAR, CLK, XHOLD_N, SETUP => tDPIS, HOLD => tDPIH, PATH => "DPAR", DelayedData => DPAR'Delayed(abs(tDPIH)), EN_CHECKING => CheckTimBidir_2); --- Chk_A_en <= not(RESET_N = '0') and not(A = TRI_STATE32); SigA : CondSetupHoldCheck(A, CLK, EDGE => RISING, SETUP => tAS, HOLD => tAH, PATH => "A", DelayedData => A'Delayed(abs(tAH)), EN_CHECKING => Chk_A_en); --- Chk_FINS1_en <= not(RESET_N = '0') and not(FINS1 = 'Z'); SigFINS1 : CondSetupHoldCheck(FINS1, CLK, EDGE => RISING, SETUP => tFIS, HOLD => tFIH, PATH => "FINS1", DelayedData => FINS1'Delayed(abs(tFIH)), EN_CHECKING => Chk_FINS1_en); --- Chk_FINS2_en <= not(RESET_N = '0') and not(FINS2 = 'Z'); SigFINS2 : CondSetupHoldCheck(FINS2, CLK, EDGE => RISING, SETUP => tFIS, HOLD => tFIH, PATH => "FINS2", DelayedData => FINS2'Delayed(abs(tFIH)), EN_CHECKING => Chk_FINS2_en); --- Chk_INST_en <= not(RESET_N = '0') and not(INST = 'Z'); SigINST : CondSetupHoldCheck(INST, CLK, EDGE => RISING, SETUP => tINS, HOLD => tINH, PATH => "INST", DelayedData => INST'Delayed(abs(tINH)), EN_CHECKING => Chk_INST_en); --- Chk_FXACK_en <= not(RESET_N = '0') and not(FXACK = 'Z'); SigFXACK : CondSetupHoldCheck(FXACK, CLK, EDGE => RISING, SETUP => tFXS, HOLD => tFXH, PATH => "FXACK", DelayedData => FXACK'Delayed(abs(tFXH)), EN_CHECKING => Chk_FXACK_en); --- Chk_FLUSH_en <= not(RESET_N = '0') and not(FLUSH = 'Z'); SigFLUSH : CondSetupHoldCheck(FLUSH, CLK, EDGE => RISING, SETUP => tFLS, HOLD => tFLH, PATH => "FLUSH", DelayedData => FLUSH'Delayed(abs(tFLH)), EN_CHECKING => Chk_FLUSH_en); --- Chk_MHOLDA_N_en <= not(RESET_N = '0') and not(MHOLDA_N = 'Z'); SigMHOLDA_N : CondSetupHoldCheck(MHOLDA_N, CLK, EDGE => FALLING, SETUP => tMHS, HOLD => tMHH, PATH => "MHOLDA_N", DelayedData => MHOLDA_N'Delayed(abs(tMHH)), EN_CHECKING => Chk_MHOLDA_N_en); --- Chk_MHOLDB_N_en <= not(RESET_N = '0') and not(MHOLDB_N = 'Z'); SigMHOLDB_N : CondSetupHoldCheck(MHOLDB_N, CLK, EDGE => FALLING, SETUP => tMHS, HOLD => tMHH, PATH => "MHOLDB_N", DelayedData => MHOLDB_N'Delayed(abs(tMHH)), EN_CHECKING => Chk_MHOLDB_N_en); --- Chk_BHOLD_N_en <= not(RESET_N = '0') and not(BHOLD_N = 'Z'); SigBHOLD_N : CondSetupHoldCheck(BHOLD_N, CLK, EDGE => FALLING, SETUP => tMHS, HOLD => tMHH, PATH => "BHOLD_N", DelayedData => BHOLD_N'Delayed(abs(tMHH)), EN_CHECKING => Chk_BHOLD_N_en); --- -- SigCHOLD_N : SetupHoldCheck(CHOLD_N, CLK, EDGE => FALLING, -- SETUP => tMHS, HOLD => tMHH, -- PATH => "CHOLD_N", -- DelayedData => CHOLD_N'Delayed(abs(tMHH))); --- -- SigCCCV : SetupHoldCheck(CCCV, CLK, EDGE => FALLING, -- SETUP => tMHS, HOLD => tMHH, -- PATH => "CCCV", -- DelayedData => CCCV'Delayed(abs(tMHH))); --- Chk_MDS_N_en <= not(RESET_N = '0') and not(MDS_N = 'Z'); SigMDS_N : CondSetupHoldCheck(MDS_N, CLK, EDGE => FALLING, SETUP => tMDS, HOLD => tMDH, PATH => "MDS_N", DelayedData => MDS_N'Delayed(abs(tMDH)), EN_CHECKING => Chk_MDS_N_en); --- Chk_APAR_en <= not(RESET_N = '0') and not(APAR = 'Z'); SigAPAR : CondSetupHoldCheck(APAR, CLK, EDGE => RISING, SETUP => tAPS, HOLD => tAPH, PATH => "APAR", DelayedData => APAR'Delayed(abs(tAPH)), EN_CHECKING => Chk_APAR_en); --- Chk_IFPAR_en <= not(RESET_N = '0') and not(IFPAR = 'Z'); SigIFPAR : CondSetupHoldCheck(IFPAR, CLK, EDGE => RISING, SETUP => tIFS, HOLD => tIFH, PATH => "IFPAR", DelayedData => IFPAR'Delayed(abs(tIFH)), EN_CHECKING => Chk_IFPAR_en); end vhdl_behavioral; ------------------------------------------------------------------------------- -- File name : fpurt.vhd -- Title : FPURT -- project : SPARC -- Library : FPURT_LIB -- Author(s) : Maxime ROCCA -- Purpose : definition of entity FPURT (with simulation and timing parameters) -- to be used for board simulation. -- notes : -- ------------------------------------------------------------------------------- -- Modification history : ------------------------------------------------------------------------------- -- Version No : | Author | Mod. Date : | Changes made : ------------------------------------------------------------------------------- -- v 1.0 | MR | 94-03-04 | first version. --............................................................................. -- v 1.1 | MR | 94-05-03 | -- + modification of the value in the record technology. ------------------------------------------------------------------------------- -- Copyright MATRA MARCONI SPACE FRANCE ------------------------------------------------------------------------------- ---------|---------|---------|---------|---------|---------|---------|--------| library IEEE; use IEEE.Std_Logic_1164.all; library MMS; use MMS.StdSim.all; use MMS.StdTiming.all; use MMS.StdIoImp.all; library FPURT_LIB; use FPURT_LIB.FPURTCompPck.FPURTGeneric; use FPURT_LIB.FPURTTimPar.all; entity FPURT is generic( T : temperature := T_BOARD; V : voltage := V_BOARD; PROCES : proces_type := PROCES_BOARD; LOAD : capacitance := LOAD_BOARD ); port( CLK : in std_logic; -- clock signal -- Integer Unit Interface Signals FP_N : inout std_logic; --* Floating-point (Fp) Present FCC : inout std_logic_vector(1 downto 0); --* Fp Condition Codes FCCV : inout std_logic; --* Fp Condition Codes Valid FHOLD_N : inout std_logic; --* Fp Hold FEXC_N : inout std_logic; --* Fp EXCeption FIPAR : inout std_logic; --* Fpu to Iu control PARity FXACK : in std_logic; -- Fp eXception ACKnowledge INST : in std_logic; -- INSTruction fetch FINS1 : in std_logic; -- Fp INStruction in buffer 1 FINS2 : in std_logic; -- Fp INStruction in buffer 2 FLUSH : in std_logic; -- Fp instruction fLUSH IFPAR : in std_logic; -- Iu to Fpu control PARity -- System/Memory Interface Signals A : in std_logic_vector(31 downto 0); -- Address bus APAR : in std_logic; -- Address bus PARity D : inout std_logic_vector(31 downto 0); -- Data bus DPAR : inout std_logic; -- Data bus PARity DOE_N : in std_logic; -- Data Output Enable COE_N : in std_logic; -- Control Output Enable MHOLDA_N : in std_logic; -- Memory HOLD MHOLDB_N : in std_logic; -- Memory HOLD BHOLD_N : in std_logic; -- Bus HOLD MDS_N : in std_logic; -- Memory Data Strobe FNULL : inout std_logic; --* Fpu NULLify cycle RESET_N : in std_logic; -- Reset signal HWERROR_N : out std_logic; -- Hardware error detected CMODE_N : in std_logic; -- master/Checker MODE MCERR_N : out std_logic; -- Comparison Error N602MODE_N : in std_logic; -- Normal 602MODE Operation HALT_N : in std_logic; -- Halt mode -- Coprocessor Interface Signals CHOLD_N : in std_logic; -- Coprocessor hold. CCCV : in std_logic; -- Coprocessor Condition Code Valid. -- Test Access Port (TAP) signals TCLK : in std_logic; -- Test CLocK TRST_N : in std_logic; -- Test ReSeT TMS : in std_logic; -- Test Mode Select TDI : in std_logic; -- Test Data In TDO : out std_logic -- Test Data Out ); end FPURT; architecture WithTiming of FPURT is constant MHS_MC : technology := ( (0.9375, 0.0025, 0.0, 0.0), -- real values (2.0, -0.20, 0.0, 0.0), 0.8, 1.3, 47.0); -- Configuration of components -- for all : FPURTGeneric use entity FPURTLIB.FPURTGeneric(Behave); begin MyFPURTGeneric: FPURTGeneric generic map( tCY => tCY, tCHL => tCHL, tAS => CalcDelay(tAS , MHS_MC, T, V, PROCES), tAH => CalcDelay(tAH , MHS_MC, T, V, PROCES), tDIS => CalcDelay(tDIS , MHS_MC, T, V, PROCES), tDIH => CalcDelay(tDIH , MHS_MC, T, V, PROCES), tDOD => CalcDelay(tDOD , MHS_MC, T, V, PROCES, LOAD), tDOH => CalcDelay(tDOH , MHS_MC, T, V, PROCES, LOAD), tDOFFL => CalcDelay(tDOFFL , MHS_MC, T, V, PROCES, LOAD), tDOHFL => CalcDelay(tDOHFL , MHS_MC, T, V, PROCES, LOAD), tDOFOE => CalcDelay(tDOFOE , MHS_MC, T, V, PROCES, LOAD), tDONOE => CalcDelay(tDONOE , MHS_MC, T, V, PROCES, LOAD), tDOHOE => CalcDelay(tDOHOE , MHS_MC, T, V, PROCES, LOAD), tFIS => CalcDelay(tFIS , MHS_MC, T, V, PROCES), tFIH => CalcDelay(tFIH , MHS_MC, T, V, PROCES), tINS => CalcDelay(tINS , MHS_MC, T, V, PROCES), tINH => CalcDelay(tINH , MHS_MC, T, V, PROCES), tFXS => CalcDelay(tFXS , MHS_MC, T, V, PROCES), tFXH => CalcDelay(tFXH , MHS_MC, T, V, PROCES), tFLS => CalcDelay(tFLS , MHS_MC, T, V, PROCES), tFLH => CalcDelay(tFLH , MHS_MC, T, V, PROCES), tRES => CalcDelay(tRES , MHS_MC, T, V, PROCES), tREH => CalcDelay(tREH , MHS_MC, T, V, PROCES), tMHS => CalcDelay(tMHS , MHS_MC, T, V, PROCES), tMHH => CalcDelay(tMHH , MHS_MC, T, V, PROCES), tMDS => CalcDelay(tMDS , MHS_MC, T, V, PROCES), tMDH => CalcDelay(tMDH , MHS_MC, T, V, PROCES), tFHD => CalcDelay(tFHD , MHS_MC, T, V, PROCES, LOAD), tFHH => CalcDelay(tFHH , MHS_MC, T, V, PROCES, LOAD), tFHDFI => CalcDelay(tFHDFI , MHS_MC, T, V, PROCES, LOAD), tFHDFL => CalcDelay(tFHDFL , MHS_MC, T, V, PROCES, LOAD), tFHDMH => CalcDelay(tFHDMH , MHS_MC, T, V, PROCES, LOAD), tFCCVD => CalcDelay(tFCCVD , MHS_MC, T, V, PROCES, LOAD), tFCCVH => CalcDelay(tFCCVH , MHS_MC, T, V, PROCES, LOAD), tFCCVDFL => CalcDelay(tFCCVDFL, MHS_MC, T, V, PROCES, LOAD), tFCCVDMH => CalcDelay(tFCCVDMH, MHS_MC, T, V, PROCES, LOAD), tFCCD => CalcDelay(tFCCD , MHS_MC, T, V, PROCES, LOAD), tFCCH => CalcDelay(tFCCH , MHS_MC, T, V, PROCES, LOAD), tFED => CalcDelay(tFED , MHS_MC, T, V, PROCES, LOAD), tFEH => CalcDelay(tFEH , MHS_MC, T, V, PROCES, LOAD), tFND => CalcDelay(tFND , MHS_MC, T, V, PROCES, LOAD), tFNH => CalcDelay(tFNH , MHS_MC, T, V, PROCES, LOAD), tAPS => CalcDelay(tAPS , MHS_MC, T, V, PROCES), tAPH => CalcDelay(tAPH , MHS_MC, T, V, PROCES), tDPIS => CalcDelay(tDPIS , MHS_MC, T, V, PROCES), tDPIH => CalcDelay(tDPIH , MHS_MC, T, V, PROCES), tDPOD => CalcDelay(tDPOD , MHS_MC, T, V, PROCES, LOAD), tDPOH => CalcDelay(tDPOH , MHS_MC, T, V, PROCES, LOAD), tIFS => CalcDelay(tIFS , MHS_MC, T, V, PROCES), tIFH => CalcDelay(tIFH , MHS_MC, T, V, PROCES), tFIPD => CalcDelay(tFIPD , MHS_MC, T, V, PROCES, LOAD), tFIPH => CalcDelay(tFIPH , MHS_MC, T, V, PROCES, LOAD), tMCD => CalcDelay(tMCD , MHS_MC, T, V, PROCES, LOAD), tMCH => CalcDelay(tMCH , MHS_MC, T, V, PROCES, LOAD), tCMS => CalcDelay(tCMS , MHS_MC, T, V, PROCES), tHAS => CalcDelay(tHAS , MHS_MC, T, V, PROCES), tHAH => CalcDelay(tHAH , MHS_MC, T, V, PROCES), tHAD => CalcDelay(tHAD , MHS_MC, T, V, PROCES, LOAD), tHAE => CalcDelay(tHAE , MHS_MC, T, V, PROCES, LOAD), tERD => CalcDelay(tERD , MHS_MC, T, V, PROCES, LOAD), tERH => CalcDelay(tERH , MHS_MC, T, V, PROCES, LOAD), tTCY => tTCY, tTMS => CalcDelay(tTMS , MHS_MC, T, V, PROCES), tTMH => CalcDelay(tTMH , MHS_MC, T, V, PROCES), tTDIS => CalcDelay(tTDIS, MHS_MC, T, V, PROCES), tTDIH => CalcDelay(tTDIH, MHS_MC, T, V, PROCES), tTRS => CalcDelay(tTRS , MHS_MC, T, V, PROCES), tTRH => CalcDelay(tTRH , MHS_MC, T, V, PROCES), tTDOD => CalcDelay(tTDOD, MHS_MC, T, V, PROCES, LOAD), tTDOH => CalcDelay(tTDOH, MHS_MC, T, V, PROCES, LOAD) ) port map( CLK, -- Integer Unit Interface Signals FP_N, -- Floating-point (Fp) Present FCC, -- Fp Condition Codes FCCV, -- Fp Condition Codes Valid FHOLD_N, -- Fp Hold FEXC_N, -- Fp EXCeption FIPAR, -- Fpu to Iu control PARit FXACK, -- Fp eXception ACKnowledge INST, -- INSTruction fetch FINS1, -- Fp INStruction in buffer 1 FINS2, -- Fp INStruction in buffer 2 FLUSH, -- Fp instruction fLUSH IFPAR, -- Iu to Fpu control PARity -- System/Memory Interface Signals A, -- Address bus APAR, -- Address bus PARity D, -- Data bus DPAR, -- Data bus PARity DOE_N, -- Data Output Enable COE_N, -- Control Output Enable MHOLDA_N, -- Memory HOLD MHOLDB_N, -- Memory HOLD BHOLD_N, -- Bus HOLD MDS_N, -- Memory Data Strobe FNULL, -- Fpu NULLify cycle RESET_N, -- Reset signal HWERROR_N, -- Hardware error detected CMODE_N, -- Slave MODE MCERR_N, -- Comparison Error N602MODE_N, -- Normal 602MODE Operation HALT_N, -- Halt mode -- Coprocessor Interface Signals CHOLD_N, -- Coprocessor hold. CCCV, -- Coprocessor Condition Code Valid. -- Test Access Port (TAP) signals TCLK, -- Test CLocK TRST_N, -- Test ReSeT TMS, -- Test Mode Select TDI, -- Test Data In TDO -- Test Data Out ); end WithTiming; <div align="center"><br /><script type="text/javascript"><!-- google_ad_client = "pub-7293844627074885"; //468x60, Created at 07. 11. 25 google_ad_slot = "8619794253"; google_ad_width = 468; google_ad_height = 60; //--></script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script><br /> </div>