📄 fp1eu.vhd
字号:
------------------------------------------------------------------------------ This file is a part of the LEON VHDL model-- Copyright (C) 1999 European Space Agency (ESA)---- This library is free software; you can redistribute it and/or-- modify it under the terms of the GNU Lesser General Public-- License as published by the Free Software Foundation; either-- version 2 of the License, or (at your option) any later version.---- See the file COPYING.LGPL for the full details of the license.------------------------------------------------------------------------------- Entity: fp-- File: fp.vhd-- Author: Jiri Gaisler - ESA/ESTEC-- Description: Parallel floating-point and co-processor interface-- The interface allows one execution unit------------------------------------------------------------------------------library IEEE;use IEEE.std_logic_1164.all;use work.config.all;use work.iface.all;use work.sparcv8.all;use work.ramlib.all;use work.fpulib.all;-- pragma translate_offuse STD.TEXTIO.all;use work.debug.all;-- pragma translate_onentity fp1eu isport ( rst : in std_logic; -- Reset clk : in clk_type; -- main clock iuclk : in clk_type; -- gated IU clock holdn : in std_logic; -- pipeline hold xholdn : in std_logic; -- pipeline hold cpi : in cp_in_type; cpo : out cp_out_type );end;architecture rtl of fp1eu istype rfi_type is record raddr1 : std_logic_vector (3 downto 0); raddr2 : std_logic_vector (3 downto 0); waddr : std_logic_vector (3 downto 0); wdata : std_logic_vector (63 downto 0); wren : std_logic_vector(1 downto 0);end record;type rfo_type is record rdata1 : std_logic_vector (63 downto 0); rdata2 : std_logic_vector (63 downto 0);end record;type cpins_type is (none, cpop, load, store);type pl_ctrl is record -- pipeline control record cpins : cpins_type; -- CP instruction rreg1 : std_logic; -- using rs1 rreg2 : std_logic; -- using rs1 rs1d : std_logic; -- rs1 is double (64-bit) rs2d : std_logic; -- rs2 is double (64-bit) wreg : std_logic; -- write CP regfile rdd : std_logic; -- rd is double (64-bit) wrcc : std_logic; -- write CP condition codes acsr : std_logic; -- access CP control registerend record;type unit_status_type is (free, started, ready);type unit_ctrl is record -- execution unit control record status : unit_status_type; -- unit status rs1 : std_logic_vector (4 downto 0); -- destination register rs2 : std_logic_vector (4 downto 0); -- destination register rd : std_logic_vector (4 downto 0); -- destination register rreg1 : std_logic; -- using rs1 rreg2 : std_logic; -- using rs1 rs1d : std_logic; -- rs1 is double (64-bit) rs2d : std_logic; -- rs2 is double (64-bit) wreg : std_logic; -- will write CP regfile rdd : std_logic; -- rd is double (64-bit) wbok : std_logic; -- ok to write result wrcc : std_logic; -- will write CP condition codes rst : std_logic; -- reset register pc : std_logic_vector (31 downto PCLOW); -- program counter inst : std_logic_vector (31 downto 0); -- instructionend record;type csr_type is record -- CP status register cc : std_logic_vector (1 downto 0); -- condition codes aexc : std_logic_vector (4 downto 0); -- exception codes cexc : std_logic_vector (4 downto 0); -- exception codes tem : std_logic_vector (4 downto 0); -- trap enable mask rd : std_logic_vector (1 downto 0); -- rounding mode tt : std_logic_vector (2 downto 0); -- trap typeend record;type execstate is (nominal, excpend, exception);type reg_type is record -- registers clocked with pipeline start : std_logic; -- start EUend record;type regx_type is record -- registers clocked continuously res : std_logic_vector (63 downto 0); -- write stage result waddr : std_logic_vector (3 downto 0); -- write stage dest wren : std_logic_vector (1 downto 0); -- write stage regfile write enable csr : csr_type; -- co-processor status register start : std_logic; -- start EU starty : std_logic; -- start EU startx : std_logic; -- start EU holdn : std_logic; wbok : std_logic; -- ok to write result state : execstate; -- FP/CP stateend record;signal vcc, gnd, wb : std_logic;signal rfi : rfi_type;signal rfo : rfo_type;signal ex, exin, me, mein, wr, wrin : pl_ctrl;signal r, rin : reg_type;signal rx, rxin : regx_type;signal eui : cp_unit_in_type;signal euo : cp_unit_out_type;signal eu, euin : unit_ctrl;function ldcheck (rdin : std_logic_vector; ldd : std_logic; eu : unit_ctrl) return std_logic isvariable lock : std_logic;variable rd : std_logic_vector(4 downto 0);begin lock := '0'; rd := rdin; if (eu.status > free) then if (eu.rdd = '0') then if ((eu.wreg = '1') and (rd = eu.rd)) or ((eu.rreg1 = '1') and (rd = eu.rs1)) or ((eu.rreg2 = '1') and (rd = eu.rs2)) then lock := '1'; end if; if (ldd = '1') then if ((eu.wreg = '1') and ((rd(4 downto 1) & '1') = eu.rd)) or ((eu.rreg1 = '1') and ((rd(4 downto 1) & '1') = eu.rs1)) or ((eu.rreg2 = '1') and ((rd(4 downto 1) & '1') = eu.rs2)) then lock := '1'; end if; end if; else if ((eu.wreg = '1') and (rd(4 downto 1) = eu.rd(4 downto 1))) or ((eu.rreg1 = '1') and (rd(4 downto 1) = eu.rs1(4 downto 1))) or ((eu.rreg2 = '1') and (rd(4 downto 1) = eu.rs2(4 downto 1))) then lock := '1'; end if; end if; end if; return(lock);end;function stcheck (rdin : std_logic_vector; std : std_logic; eu : unit_ctrl) return std_logic isvariable lock : std_logic;variable rd : std_logic_vector(4 downto 0);begin lock := '0'; rd := rdin; if (eu.status > free) then if (eu.rdd = '0') then if ((eu.wreg = '1') and (rd = eu.rd)) then lock := '1'; end if; if (std = '1') then if ((eu.wreg = '1') and ((rd(4 downto 1) & '1') = eu.rd)) then lock := '1'; end if; end if; else if ((eu.wreg = '1') and (rd(4 downto 1) = eu.rd(4 downto 1))) or ((eu.rreg1 = '1') and (rd(4 downto 1) = eu.rs1(4 downto 1))) or ((eu.rreg2 = '1') and (rd(4 downto 1) = eu.rs2(4 downto 1))) then lock := '1'; end if; end if; end if; return(lock);end;function srccheck (rsin : std_logic_vector; dbl : std_logic; eu : unit_ctrl) return std_logic isvariable lock : std_logic;variable rs : std_logic_vector(4 downto 0);begin lock := '0'; rs := rsin; if (eu.wreg = '1') and (rs(4 downto 1) = eu.rd(4 downto 1)) then if ((dbl or eu.rdd) = '1') or (rs(0) = eu.rd(0)) then lock := '1'; end if; end if; return(lock);end;begin vcc <= '1'; gnd <= '1';-- instruction decoding pipeline : process(cpi, ex, me, wr, eu, euin, r, rx, rfi, rfo, holdn, xholdn, euo, rst, wb) variable op : std_logic_vector(1 downto 0); variable op3 : std_logic_vector(5 downto 0); variable opc : std_logic_vector(8 downto 0); variable stdata : std_logic_vector(31 downto 0); variable rs1, rs2, rd : std_logic_vector(4 downto 0); variable ctrl : pl_ctrl; variable ldlock : std_logic; variable wren : std_logic_vector(1 downto 0); variable waddr : std_logic_vector(3 downto 0); variable rtaddr : std_logic_vector(3 downto 0); variable wrdata : std_logic_vector(63 downto 0); variable rtdata : std_logic_vector(63 downto 0); variable rv : reg_type; variable rxv : regx_type; variable euv : unit_ctrl; variable euiv : cp_unit_in_type; variable ddep : std_logic; variable cpexc : std_logic; variable fpill : std_logic; variable ccv : std_logic; variable qne : std_logic; variable wbv : std_logic; variable op1 : std_logic_vector (63 downto 0); -- operand1 variable op2 : std_logic_vector (63 downto 0); -- operand2 variable opcode : std_logic_vector (9 downto 0); -- FP opcode begin--------------------------------------------------------------- decode stage------------------------------------------------------------- op := cpi.dinst(31 downto 30); op3 := cpi.dinst(24 downto 19); opc := cpi.dinst(13 downto 5); rs1 := cpi.dinst(18 downto 14); rs2 := cpi.dinst(4 downto 0); rd := cpi.dinst(29 downto 25); rv := r; rxv := rx; ctrl.cpins := none; ctrl.wreg := '0'; ctrl.rdd := '0'; ctrl.wrcc := '0'; ctrl.acsr := '0'; ldlock := '0'; ctrl.rreg1 := '0'; ctrl.rreg2 := '0'; ctrl.rs1d := '0'; ctrl.rs2d := '0'; fpill := '0'; stdata := (others => '-'); wren := "00"; cpexc := '0'; ccv := '0'; rv.start := '0'; rxv.wbok := '0'; rxv.start := '0'; euv := eu; if eu.status /= free then qne := '1'; else qne := '0'; end if; euiv.opcode := cpi.ex.inst(19) & cpi.ex.inst(13 downto 5); euiv.start := '0'; euiv.load := '0'; euiv.flush := eu.rst or euin.rst; wbv := '0'; euv.rst := not rst; if (eu.status = started) and (euo.busy = '0') then euv.status := ready; end if; if (eu.status > free) then ccv := ccv or eu.wrcc; end if; -- decode CP instructions case op is when FMT3 => case op3 is when FPOP1 => if rx.state = exception then rxv.state := excpend; rxv.csr.tt := "100"; elsif rx.state = nominal then ctrl.cpins := cpop; ctrl.wreg := '1'; case opc is when FMOVS | FABSS | FNEGS => ctrl.rreg2 := '1'; when FITOS | FSTOI => ctrl.rreg2 := '1'; when FITOD | FSTOD => ctrl.rreg2 := '1'; ctrl.rdd := '1'; when FDTOI | FDTOS => ctrl.rreg2 := '1'; ctrl.rs2d := '1'; when FSQRTS => ctrl.rreg2 := '1'; when FSQRTD => ctrl.rreg2 := '1'; ctrl.rs2d := '1'; ctrl.rdd := '1'; when FADDS | FSUBS | FMULS | FDIVS => ctrl.rreg1 := '1'; ctrl.rreg2 := '1'; when FADDD | FSUBD | FMULD | FDIVD => ctrl.rreg1 := '1'; ctrl.rreg2 := '1'; ctrl.rs1d := '1'; ctrl.rs2d := '1'; ctrl.rdd := '1'; when others => fpill := '1'; -- illegal instuction end case; end if; when FPOP2 => if rx.state = exception then rxv.state := excpend; rxv.csr.tt := "100"; elsif rx.state = nominal then ctrl.cpins := cpop; ctrl.wrcc := '1'; ctrl.rreg1 := '1'; ctrl.rreg2 := '1'; case opc is when FCMPD | FCMPED => ctrl.rs1d := '1'; ctrl.rs2d := '1'; when others => fpill := '1'; -- illegal instuction end case; end if; when others => null; end case; if (ex.cpins = load) and ((cpi.ex.annul or cpi.ex.trap) = '0') and (ex.wreg = '1') then if (ctrl.rreg1 = '1') and (rs1(4 downto 1) = cpi.ex.inst(29 downto 26)) and (((ctrl.rs1d or ex.rdd) = '1') or (rs1(0) = cpi.ex.inst(25))) then ldlock := '1'; end if; if (ctrl.rreg2 = '1') and (rs2(4 downto 1) = cpi.ex.inst(29 downto 26)) and (((ctrl.rs2d or ex.rdd) = '1') or (rs2(0) = cpi.ex.inst(25))) then ldlock := '1'; end if; end if; when LDST => case op3 is when LDF | LDDF => if rx.state = exception then rxv.state := excpend; rxv.csr.tt := "100"; elsif rx.state = nominal then ctrl.rdd := op3(1) and op3(0); ctrl.cpins := load; ctrl.wreg := '1'; -- dst interlock ldlock := ldlock or ldcheck(rd, ctrl.rdd, euin); end if; when STF | STDF => -- check for CP register dependencies if (ex.cpins = load) and ((cpi.ex.annul or cpi.ex.trap) = '0') and (cpi.ex.cnt = "00") and ((rd = cpi.ex.inst(29 downto 25)) or ((rd(4 downto 1) = cpi.ex.inst(29 downto 26)) and (ex.rdd = '1'))) then ldlock := '1'; end if; if rx.state = nominal then ldlock := ldlock or stcheck(rd, (op3(1) and op3(0)), euin); end if; if (ldlock = '0') then ctrl.cpins := store; end if; when STFSR | LDFSR => if (rx.state = exception) and (op3 = LDFSR) then rxv.state := excpend; rxv.csr.tt := "100"; else if (ex.cpins = load) and ((cpi.ex.annul or cpi.ex.trap) = '0') and (cpi.ex.cnt = "00") and (op3 = STFSR) and (ex.acsr = '1') then ldlock := '1'; end if; if (rx.state = nominal) then if (((cpi.ex.annul or cpi.ex.trap) = '0') and (ex.cpins = cpop)) or (eu.status > free) then ldlock := '1'; end if; end if; end if; if (ldlock = '0') then ctrl.acsr := '1'; if op3 = STFSR then ctrl.cpins := store; else ctrl.cpins := load; end if; end if; when STDFQ => if (rx.state = nominal) then rxv.state := excpend; rxv.csr.tt := "100"; else ctrl.cpins := store; end if;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -