📄 fp.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 co-processor interface
-- The interface allows any number of parallel execution unit
-- As an example, two Meiko FPUs and two FMOVE units have been attached
------------------------------------------------------------------------------
-- FPU support unit - performs FMOVS, FNEGS, FABSS
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned."+";
use IEEE.std_logic_unsigned."-";
use IEEE.std_logic_unsigned.conv_integer;
use work.leon_iface.all;
entity fpaux is
port (
rst : in std_logic; -- Reset
clk : in std_logic; -- clock
eui : in cp_unit_in_type; -- inputs
euo : out cp_unit_out_type -- outputs
);
end;
architecture rtl of fpaux is
type reg_type is record
op : std_logic_vector (31 downto 0); -- operand
ins : std_logic_vector (1 downto 0); -- operand
end record;
signal r, rin : reg_type;
begin
comb: process(rst, eui, r)
variable rv : reg_type;
variable ready : std_logic;
variable sign : std_logic;
begin
rv := r;
if eui.start = '1' then rv.ins := eui.opcode(3 downto 2); end if;
if eui.load = '1' then rv.op := eui.op2(63 downto 32); end if;
case r.ins is
when "00" => sign := r.op(31); -- fmovs
when "01" => sign := not r.op(31); -- fnegs
when others => sign := '0'; -- fabss
end case;
euo.res(63 downto 29) <= sign & "000" & r.op(30 downto 0);
euo.res(28 downto 0) <= (others => '0');
euo.busy <= '0';
euo.exc <= (others => '0');
euo.cc <= (others => '0');
rin <= rv;
end process;
-- registers
regs : process(clk)
begin
if rising_edge(clk) then
r <= rin;
end if;
end process;
end;
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned."+";
use IEEE.std_logic_unsigned."-";
use IEEE.std_logic_unsigned.conv_integer;
use work.leon_config.all;
use work.leon_iface.all;
use work.sparcv8.all;
use work.ramlib.all;
use work.fpulib.all;
-- pragma translate_off
library MMS;
use MMS.stdioimp.all;
use STD.TEXTIO.all;
use work.debug.all;
-- pragma translate_on
entity fp is
port (
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 fp is
constant EUTYPES : integer := 1; -- number of execution unit types
--constant EUTYPES : integer := 1; -- number of execution unit types
constant EU1NUM : integer := 2; -- number of execution unit 1 types
constant EU2NUM : integer := 1; -- number of execution unit 2 types
constant EUMAX : integer := 2; -- maximum number of any execution unit
--constant EUTOT : integer := 2; -- total number of execution units
constant EUTOT : integer := 2; -- total number of execution units
subtype euindex is integer range 0 to EUMAX-1;
subtype eumindex is integer range 0 to EUTOT-1;
subtype eutindex is integer range 0 to EUTYPES-1;
-- array to define how many execution units of each type
type euconf_arr is array (0 to 2) of euindex; -- one more than necessay to avoid modeltech bug
constant euconf : euconf_arr := (EU1NUM-1, EU2NUM-1,0);
--constant euconf : euconf_arr := (EU1NUM,1);
type eu_fifo_arr is array (0 to EUTOT-1) of eutindex;
type eu_fifo_type is record
first : eumindex;
last : eumindex;
fifo : eu_fifo_arr;
end record;
type euq_type is record
first : euindex;
last : euindex;
end record;
type euq_arr is array (0 to EUTYPES-1) of euq_type;
type 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 register
first : euindex;
end record;
type unit_status_type is (exception, 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)
wb : std_logic; -- result being written back
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); -- instruction
end 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 type
end record;
type execstate is (nominal, excpend, exception);
type reg_type is record -- registers clocked with pipeline
eufirst : euindex;
eulast : euindex;
sdep : std_logic; -- data dependency ex/me/wr
eut : integer range 0 to EUTYPES-1; -- type EU to start
eui : integer range 0 to EUMAX-1; -- index EU to start
start : std_logic; -- start EU
weut : integer range 0 to EUTYPES-1; -- write stage eut
weui : integer range 0 to EUMAX-1; -- write stage eui
end 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;
state : execstate; -- using rs1
end record;
type unit_ctrl_arr is array (0 to EUMAX-1) of unit_ctrl;
type unit_ctrl_arr_arr is array (0 to EUTYPES-1) of unit_ctrl_arr;
type eui_arr is array (0 to EUMAX-1) of cp_unit_in_type;
type euo_arr is array (0 to EUMAX-1) of cp_unit_out_type;
type eui_arr_arr is array (0 to EUTYPES) of eui_arr;
type euo_arr_arr is array (0 to EUTYPES) of euo_arr;
signal vcc, gnd : 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 : eui_arr_arr;
signal euo : euo_arr_arr;
signal eu, euin : unit_ctrl_arr_arr;
signal euq, euqin : euq_arr;
signal euf, eufin : eu_fifo_type;
component fpaux
port (
rst : in std_logic; -- Reset
clk : in std_logic; -- clock
eui : in cp_unit_in_type; -- inputs
euo : out cp_unit_out_type -- outputs
);
end component;
function ldcheck (rdin : std_logic_vector; ldd : std_logic; eu : unit_ctrl)
return std_logic is
variable 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 is
variable 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 is
variable lock : std_logic;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -