⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tru.vhd

📁 X8086的VHDL源码
💻 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'&reg1(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)&reg2(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 + -