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

📄 bcfetch.vhd

📁 JOP内核字节码获取
💻 VHD
字号:
--
--	bcfetch.vhd
--
--	Java bc fetch and address translation for JVM
--
--	resources on ACEX1K30-3
--
--		bytecode LCs, max ca. xx MHz
--
--	todo:
--
--	2001-11-16	split from fetch.vhd, register jpaddr instead of jinstr
--	2001-12-06	unregistered!!! jpaddr, jbr registered (moved from decode)
--	2001-12-07	removed mux befor jbc ram, jbr unregistered selects addr. for jpc
--				decode goto and if_bytecode from jinstr
--	2002-03-24	autoincrement of jpc on bc_wr
--	2002-10-21	added if(non)null
--	2003-02-22	registered jbc ram
--	2003-08-14	move wr-addr load and autoincrement to ajbc.vhd (now 32 bit interface)
--	2003-08-15	interrupt handling
--	2004-04-06	removed signal jfetch from interrupt mux (is in fetch allready)
--				different mux for jpc and jbc rdaddr, register jump address calculation
--	2004-09-11	move jbc to mem
--	2005-01-17	move interrupt mux to jtbl.vhd (mux after the table)
--
--	TODO:	use 'running' bit and generate jbr here!
--


library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity bcfetch is

generic (
	jpc_width	: integer;		-- address bits of java byte code pc
	pc_width	: integer		-- address bits of internal instruction rom
);
port (
	clk, reset	: in std_logic;

	jpc_out		: out std_logic_vector(jpc_width-1 downto 0);	-- jpc read
	din			: in std_logic_vector(31 downto 0);				-- A from stack
	jpc_wr		: in std_logic;

--	connection to bytecode cache

	jbc_addr	: out std_logic_vector(jpc_width-1 downto 0);
	jbc_data	: in std_logic_vector(7 downto 0);

	jfetch		: in std_logic;
	jopdfetch	: in std_logic;

	zf, nf		: in std_logic;
	eq, lt		: in std_logic;

	jbr			: in std_logic;

	irq			: in std_logic;			-- interrupt request (positiv edge sensitive)
	irq_ena		: in std_logic;			-- interrupt enable (pendig int is fired on ena)

	jpaddr		: out std_logic_vector(pc_width-1 downto 0);	-- address for JVM
	opd			: out std_logic_vector(15 downto 0)				-- operands
);
end bcfetch;

architecture rtl of bcfetch is

--
--	jtbl component (generated vhdl file from Jopa!)
--
--	logic rom (unregistered)
--
component jtbl is
port (
	bcode	: in std_logic_vector(7 downto 0);
	int_pend	: in  std_logic;
	q		: out std_logic_vector(pc_width-1 downto 0)
);
end component;


	signal jbc_mux	: std_logic_vector(jpc_width-1 downto 0);
	signal jbc_q	: std_logic_vector(7 downto 0);

	signal jpc		: std_logic_vector(jpc_width-1 downto 0);
	signal jpc_br	: std_logic_vector(jpc_width-1 downto 0);
	signal jmp_addr	: std_logic_vector(jpc_width-1 downto 0);

	signal jinstr	: std_logic_vector(7 downto 0);
	signal tp		: std_logic_vector(3 downto 0);
	signal jmp		: std_logic;

	signal jopd		: std_logic_vector(15 downto 0);

--
--	signals for interrupt handling
--
	signal irq_gate		: std_logic;
	signal irq_dly		: std_logic;
	signal trig			: std_logic;
	signal int_pend		: std_logic;
	signal sys_int		: std_logic;

	signal bytecode		: std_logic_vector(7 downto 0);

begin

--
--	interrupt processing at bytecode fetch level
--
process(clk, reset) begin

	if (reset='1') then
		irq_dly <= '0';
		int_pend <= '0';
	elsif rising_edge(clk) then

		irq_dly <= irq_gate;
		if trig='1' then
			int_pend <= '1';
		elsif sys_int='1' or irq_ena='0' then
			int_pend <= '0';
		end if;
	end if;

end process;

	irq_gate <= irq and irq_ena;
	trig <= irq_gate and not irq_dly;
	sys_int <= int_pend and jfetch;

--
--	bytecode mux on interrupt
--		jpc is one too high after generating sys_int
--		this is corrected in jvm.asm
--
--	we do not depend on sys_int in this mux for jfetch (do we?)
--	jfetch is allready used in the mux after the jump table
--
--	interrupt mux is now in jtbl.vhd

--
--	java byte code fetch and branch
--

	bytecode <= jbc_q;		-- register this for an additional pipeline stage

	cmp_jtbl: jtbl port map(bytecode, int_pend, jpaddr);

	jbc_addr <= jbc_mux;
	jbc_q <= jbc_data;


--
--	decode if and goto byte codes
--
process(clk, jinstr) begin

	if rising_edge(clk) then
		case jinstr is

--			when "10011001" => tp <= "1001";	-- ifeq
--			when "10011010" => tp <= "1010";	-- ifne
--			when "10011011" => tp <= "1011";	-- iflt
--			when "10011100" => tp <= "1100";	-- ifge
--			when "10011101" => tp <= "1101";	-- ifgt
--			when "10011110" => tp <= "1110";	-- ifle

--			when "10011111" => tp <= "1111";	-- if_icmpeq
--			when "10100000" => tp <= "0000";	-- if_icmpne
--			when "10100001" => tp <= "0001";	-- if_icmplt
--			when "10100010" => tp <= "0010";	-- if_icmpge
--			when "10100011" => tp <= "0011";	-- if_icmpgt
--			when "10100100" => tp <= "0100";	-- if_icmple

			when "10100101" => tp <= "1111";	-- if_acmpeq
			when "10100110" => tp <= "0000";	-- if_acmpne
--			when "10100111" => tp <= "0111";	-- goto

			when "11000110" => tp <= "1001";	-- ifnull
			when "11000111" => tp <= "1010";	-- ifnonnull

			when others => tp <= jinstr(3 downto 0);
		end case;
	end if;

end process;

process(tp, jbr, zf, nf, eq, lt)
begin

	jmp <= '0';
	if (jbr='1') then
		case tp is
			when "1001" =>			-- ifeq, ifnull
				if (zf='1') then
					jmp <= '1';
				end if;
			when "1010" =>			-- ifne, ifnonnull
				if (zf='0') then
					jmp <= '1';
				end if;
			when "1011" =>			-- iflt
				if (nf='1') then
					jmp <= '1';
				end if;
			when "1100" =>			-- ifge
				if (nf='0') then
					jmp <= '1';
				end if;
			when "1101" =>			-- ifgt
				if (zf='0' and nf='0') then
					jmp <= '1';
				end if;
			when "1110" =>			-- ifle
				if (zf='1' or nf='1') then
					jmp <= '1';
				end if;

			when "1111" =>			-- if_icmpeq, if_acmpeq
				if (eq='1') then
					jmp <= '1';
				end if;
			when "0000" =>			-- if_icmpne, if_acmpne
				if (eq='0') then
					jmp <= '1';
				end if;
			when "0001" =>			-- if_icmplt
				if (lt='1') then
					jmp <= '1';
				end if;
			when "0010" =>			-- if_icmpge
				if (lt='0') then
					jmp <= '1';
				end if;
			when "0011" =>			-- if_icmpgt
				if (eq='0' and lt='0') then
					jmp <= '1';
				end if;
			when "0100" =>			-- if_icmple
				if (eq='1' or lt='1') then
					jmp <= '1';
				end if;

			when "0111" =>			-- goto
				jmp <= '1';

			when others =>
				null;
		end case;
	end if;

end process;

--
--	jbc read address mux (is registered in ram)
--		no write from din
--
process(din, jpc, jmp_addr, jopd, jfetch, jopdfetch, jmp)

begin

	if (jmp='1') then
		jbc_mux <= jmp_addr;
	elsif (jfetch='1' or jopdfetch='1') then
		jbc_mux <= std_logic_vector(unsigned(jpc) + 1);
	else
		jbc_mux <= jpc;
	end if;

end process;

--
--	jpc mux conatins also din
--
process(clk, reset)

begin
	if (reset='1') then

		jpc <= std_logic_vector(to_unsigned(0, jpc_width));

	elsif rising_edge(clk) then

		if (jpc_wr='1') then
			jpc <= din(jpc_width-1 downto 0);
		elsif (jmp='1') then
			jpc <= jmp_addr;
		elsif (jfetch='1' or jopdfetch='1') then
			jpc <= std_logic_vector(unsigned(jpc) + 1);
		else
			jpc <= jpc;
		end if;

	end if;
end process;

	jpc_out <= jpc;


--
--	use this without register
--
--		jmp_addr <= std_logic_vector(unsigned(jpc_br) +
--			unsigned(jopd(jpc_width-1 downto 0)));

process(clk)
begin
	if rising_edge(clk) then

		-- from jbc_q + jopd low!
		jmp_addr <= std_logic_vector(unsigned(jpc_br) +
			unsigned(jopd(jpc_width-1-8 downto 0) & jbc_q));

		if (jfetch='1') then
			jpc_br <= jpc;		-- save start address of instruction for branch
			jinstr <= jbc_q;
		end if;

	end if;
end process;

process(clk, reset)

begin
	if (reset='1') then
		jopd <= (others => '0');
	elsif rising_edge(clk) then
		jopd(7 downto 0) <= jbc_q;
		if (jopdfetch='1') then
			jopd(15 downto 8) <= jopd(7 downto 0);
		end if;
	end if;
end process;

	opd <= jopd;

end rtl;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -