📄 tru.vhd
字号:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use WORK.UPAC.ALL;
entity TRU is
port( I_CLK : in std_logic;
I_RST : in std_logic;
I_TREG1 : in std_logic_vector(15 downto 0 );
I_TREG2 : in std_logic_vector(15 downto 0 );
I_TMPRW : in std_logic_vector( 1 downto 0 );
I_D16HL : in std_logic;
I_BW : in std_logic;
I_DIVF : in std_logic;
I_QUOF : in std_logic;
I_MULCS : in std_logic_vector( 1 downto 0 );
I_2SETTR2 : in std_logic; --for sp+2
I_1SETTR2 : in std_logic; --for INC('1':set 1 to tmp2)
I_REG3 : in std_logic; --for reg3
I_TMPCS : in std_logic_vector( 4 downto 0 );
I_SE : in std_logic; --for sign extension("1"extension,"0"null)
O_TREG1 : out std_logic_vector(15 downto 0 );
O_TREG2 : out std_logic_vector(15 downto 0 );
O_SIGNPLS : out std_logic; --for idiv(sign check)
O_SIGNDIV : out std_logic; --for idiv(sign check)
O_BSIGNDIV : out std_logic; --for idiv(sign check)
O_SIGNTR1 : out std_logic; --for idiv(sign check)
O_BSIGNTR1 : out std_logic; --for idiv(sign check)
O_SIGNTR2 : out std_logic; --for idiv(sign check)
O_LSBTR2 : out std_logic; --for MUL(reg2(0):1,0check)
O_BORROW : out std_logic;
O_REG1 : out std_logic_vector(15 downto 0 ); --for test
O_REG2 : out std_logic_vector(15 downto 0 ); --for test
O_TR1PLS : out std_logic_vector(15 downto 0 );
O_TR2DIV : out std_logic_vector(15 downto 0 )
);
end TRU;
architecture RTL of TRU is
signal reg1 : std_logic_vector(15 downto 0);
signal reg2 : std_logic_vector(15 downto 0);
signal plus_reg : std_logic_vector(15 downto 0);
signal div_reg : std_logic_vector(15 downto 0);
signal top : std_logic;
begin
O_REG1 <= reg1; --for test
O_REG2 <= reg2;
O_SIGNPLS <= plus_reg(15); --for idiv(sign check)
O_SIGNTR2 <= reg2(15);
O_SIGNTR1 <= reg1(15);
O_BSIGNTR1 <= reg1(7);
O_SIGNDIV <= div_reg(15);
O_LSBTR2 <= reg2(0); --for MUL
O_BSIGNDIV <= div_reg(7); --for idiv(16/8)
process(I_TMPCS,plus_reg,reg1)
begin
if (I_TMPCS = "01011" or I_TMPCS = "01110") then
O_TR1PLS <= plus_reg;
else
O_TR1PLS <= reg1;
end if;
end process;
process(I_TMPCS,div_reg,reg2)
begin
if ((I_TMPCS = "01010" or I_TMPCS = "01011")
or (I_TMPCS = "01101" or I_TMPCS = "01110")) then
O_TR2DIV <= div_reg;
else
O_TR2DIV <= reg2;
end if;
end process;
process(I_TMPCS,plus_reg,reg1)
begin
if (I_TMPCS = "00011" or I_TMPCS = "11111") then
O_TREG1 <= reg1;
elsif (I_TMPCS = "00111" or I_TMPCS = "11110") then
O_TREG1 <= plus_reg;
else
O_TREG1 <= "ZZZZZZZZZZZZZZZZ";
end if;
end process;
process(I_TMPCS,reg2)
begin
if (I_TMPCS = "00101" or I_TMPCS = "11111" or I_TMPCS = "11110") then
O_TREG2 <= reg2;
else
O_TREG2 <= "ZZZZZZZZZZZZZZZZ";
end if;
end process;
process (I_BW,I_DIVF,reg1(0),top)
begin --for div(borrow)
if (I_DIVF = '1') then
if (I_BW = '0') then
O_BORROW <= reg1(0);
else
O_BORROW <= top;
end if;
else
O_BORROW <= '0';
end if;
end process;
REG1_TMP :
process(I_CLK,I_RST,I_DIVF,I_TMPCS,I_TREG1,I_QUOF,reg1,plus_reg,I_D16HL,
I_MULCS,I_TMPRW,I_SE)
begin
if(I_RST = RST_ACT)then
reg1 <= "0000000000000000";
elsif (I_CLK'event and I_CLK = '0') then
if (I_DIVF = '1') then
case I_TMPCS is
when "00010" =>
reg1 <= I_TREG1;
when "01001" =>
reg1 <= "0000000000000000";
when "01010" =>
if (I_QUOF = '1') then
reg1 <= I_TREG1;
end if;
when "01100" =>
reg1 <= reg1(14 downto 0)&plus_reg(15);
when "10000" =>
reg1 <= not(reg1) + "0000000000000001";
when "10001" =>
reg1 <= not(reg1) + "0000000000000001"; --for idiv(32/16odd)
when "11011" =>
reg1 <= (others => '0');
when "11100" =>
reg1 <= (others => '0');
when "11101" =>
reg1 <= (others => '0');
when others =>
null;
end case;
elsif (I_D16HL = '1') then
case I_TMPRW is
when "11" =>
reg1(15 downto 8) <= I_TREG1(7 downto 0);
when "01" =>
reg1(15 downto 8) <= I_TREG1(7 downto 0);
when others =>
null;
end case;
elsif(I_MULCS /= "00")then
case I_MULCS is
when "01" =>
reg1 <= "0000000000000000"; --reg1 clear
when "11" =>
reg1 <= '0'®1(15 downto 1); --shift reg
when others =>
null;
end case;
else
case I_TMPRW is
when "11" =>
if (I_SE = '1')then
reg1 <= ((not(I_TREG1(15 downto 7)))&"0000000")
+ ("000000001"&I_TREG1(6 downto 0)); --sign extension
else
reg1 <= I_TREG1;
end if;
when "01" =>
if (I_SE = '1')then
reg1 <= ((not(I_TREG1(15 downto 7)))&"0000000")
+ ("000000001"&I_TREG1(6 downto 0)); --sign extension
else
reg1 <= I_TREG1;
end if;
when others =>
null;
end case;
end if;
end if;
end process;
REG2_TMP :
process(I_CLK,I_RST,I_DIVF,I_TMPCS,I_TREG2,I_QUOF,reg2,plus_reg,I_D16HL,
I_MULCS,I_TMPRW,I_SE,I_2SETTR2,I_1SETTR2)
begin
if(I_RST = RST_ACT)then
reg2 <= "0000000000000000";
elsif (I_CLK'event and I_CLK = '0') then
if (I_DIVF = '1') then
case I_TMPCS is
when "00100" =>
reg2 <= I_TREG2;
when "01010" =>
reg2(0) <= I_QUOF;
when"01011" =>
reg2(0) <= I_QUOF;
when "01100" =>
reg2 <= reg2(14 downto 0)&'0';
when "10000" =>
reg2 <= not(reg2) + "0000000000000001";
when "10011" =>
reg2 <= not(reg2) + "0000000000000001"; --(16/8dividend,quotient)
when "10101" =>
reg2 <= not(reg2) + "0000000000000001";
when "10110" =>
reg2 <= not(reg2) + "0000000000000001";
when "10111" =>
if(reg2 = "0000000000000000")then
reg2 <= (others => '0');
else
reg2 <= not(reg2) + "0000000000000001";
end if;
when "11000" =>
reg2 <= not(reg2) + "0000000000000001";
when "11010" =>
reg2 <= not(reg2) + "0000000000000001";
when "11100" =>
if(reg2 = "0000000000000000")then
reg2 <= (others => '0');
else
reg2 <= not(reg2) + "0000000000000001";
end if;
when "11101" =>
if(reg2 = "0000000000000000")then
reg2 <= (others => '0');
else
reg2 <= not(reg2) + "0000000000000001";
end if;
when others =>
null;
end case;
elsif (I_D16HL = '1') then
case I_TMPRW is
when "11" =>
reg2(15 downto 8) <= I_TREG2(7 downto 0);
when "10" =>
reg2(15 downto 8) <= I_TREG2(7 downto 0);
when others =>
null;
end case;
elsif(I_MULCS /= "00")then
case I_MULCS is
when "11" =>
reg2 <= plus_reg(0)®2(15 downto 1);
when others =>
null;
end case;
else
case I_TMPRW is
when "11" =>
if (I_2SETTR2 = '1')then
reg2 <= "0000000000000010";
elsif(I_SE = '1')then
reg2 <= ((not(I_TREG2(15 downto 7)))&"0000000")
+ ("000000001"&I_TREG2(6 downto 0)); --sign extension
elsif(I_1SETTR2 = '1')then
reg2 <= "0000000000000001"; --for INC
else
reg2 <= I_TREG2;
end if;
when "10" =>
if (I_SE = '1')then
reg2 <= ((not(I_TREG2(15 downto 7)))&"0000000")
+ ("000000001"&I_TREG2(6 downto 0)); --sign extension
elsif(I_2SETTR2 = '1')then
reg2 <= "0000000000000010";
elsif(I_1SETTR2 = '1')then
reg2 <= "0000000000000001"; --for INC
else
reg2 <= I_TREG2;
end if;
when "01" =>
if(I_2SETTR2 = '1')then
reg2 <= "0000000000000010";
end if;
when others =>
null;
end case;
end if;
end if;
end process;
PLUSREG :
process(I_CLK,I_RST,I_DIVF,I_TMPCS,I_TREG1,I_QUOF,reg1,reg2,plus_reg,
I_MULCS,I_TMPRW,I_REG3)
begin
if(I_RST = RST_ACT)then
plus_reg <= "0000000000000000";
elsif (I_CLK'event and I_CLK = '0') then
if (I_DIVF = '1') then
case I_TMPCS is
when "00110" =>
plus_reg <= I_TREG1;
when "01000" =>
plus_reg <= "0000000000000000";
when"01011" =>
if (I_QUOF = '1') then
plus_reg <= I_TREG1;
end if;
when "01100" =>
plus_reg <= plus_reg(14 downto 0) & reg2(15);
when "10010" =>
plus_reg <= not(plus_reg) + "0000000000000001"; --(16/8odd)
when "10101" =>
plus_reg <= not(plus_reg) + "0000000000000001";
when "10111" =>
if(reg2 = "0000000000000000")then
plus_reg <= not(plus_reg) + "0000000000000001";
else
plus_reg <= not(plus_reg); --(32/16divident)
end if;
when "11000" =>
plus_reg <= (others => '0');
when "11001" =>
plus_reg <= (others => '0');
when "11010" =>
plus_reg <= (others => '0');
when "11100" =>
if(reg2 = "0000000000000000")then
plus_reg <= not(plus_reg) + "0000000000000001";
else
plus_reg <= not(plus_reg); --(32/16divident)
end if;
when "11101" =>
if(reg2 = "0000000000000000")then
plus_reg <= not(plus_reg) + "0000000000000001";
else
plus_reg <= not(plus_reg); --(32/16divident)
end if;
when others =>
null;
end case;
elsif(I_MULCS /= "00") then
case I_MULCS is
when "01" =>
plus_reg <= (others => '0'); --plus_reg clear
when "10" =>
plus_reg <= I_TREG1; --tmp1in=>plus_reg
when "11" =>
plus_reg <= reg1(0)&plus_reg(15 downto 1);
when others =>
null;
end case;
else
case I_TMPRW is
when "11" =>
if (I_REG3 = '1')then
plus_reg <= I_TREG1; --reg3 input
end if;
when "01" =>
if (I_REG3 = '1')then
plus_reg <= I_TREG1; --reg3 input
end if;
when others =>
null;
end case;
end if;
end if;
end process;
DIVREG :
process(I_CLK,I_RST,I_DIVF,I_TMPCS,I_TREG2,div_reg,
I_MULCS)
begin
if (I_RST = RST_ACT) then
div_reg <= "0000000000000000";
elsif (I_CLK'event and I_CLK = '0') then
if (I_DIVF = '1') then
case I_TMPCS is
when "00001" =>
div_reg <= I_TREG2;
when "10100" =>
div_reg <= not(div_reg) + "0000000000000001"; --(divisor)
when "10110" =>
div_reg <= not(div_reg) + "0000000000000001"; --(composition16/8)
when "10111" =>
div_reg <= not(div_reg) + "0000000000000001"; --(composition32/16)
when "11001" =>
div_reg <= not(div_reg) + "0000000000000001";
when "11010" =>
div_reg <= not(div_reg) + "0000000000000001";
when "11011" =>
div_reg <= not(div_reg) + "0000000000000001";
when "11101" =>
div_reg <= not(div_reg) + "0000000000000001";
when others =>
null;
end case;
elsif(I_MULCS /= "00")then
if (I_MULCS = "01") then
div_reg <= I_TREG2; --tmp2in=>div_reg
end if;
end if;
end if;
end process;
TOP :
process(reg1,I_CLK,I_RST,I_DIVF)
begin
if(I_RST='0')then
top <= '0';
elsif (I_CLK'event and I_CLK = '0') then
if (I_DIVF = '1') then
if (I_TMPCS = "01100") then
top <= reg1(15);
end if;
end if;
end if;
end process;
end RTL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -