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

📄 decode.vhd

📁 JOP字节码获取的源码
💻 VHD
字号:
--
--	decode.vhd
--
--	cpu decode of JOP3
--	
--	generate control for pc and stack
--
--
--	resources on ACEX1K30-3
--	
--		xxx LCs, 42.0 MHz	
--
--	todo:
--
--
--	2001-07-03	extracted from core.vhd
--	2001-10-28	ldjpc, stjpc
--	2001-10-31	stbc
--	2001-12-04	cp removed
--	2001-12-05	sel_rda, sel_wra: logic from ir (not registered)
--				sel_smux: logic from ir (not registered, no mix addr/rd-ex: nop befor stsp)
--	2001-12-06	moved ir from decode to fetch, jbr unregistered
--	2001-12-07	moved jbr decode to bcfetch, ldi loads consts from ram (addr > 31), jp removed
--	2001-12-08	instruction set changed to 8 bit
--	2002-03-24	new shift instructions
--	2002-12-02	wait instruction for memory
--	2003-02-12	added instruction ld_opd_8u/16u
--	2004-10-07	new alu selection with sel_sub, sel_amux and ena_a
--	2004-10-08	moved bsy/pcwait from decode to fetch
--


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

entity decode is
generic (
	i_width		: integer;		-- instruction width
	addr_width	: integer;		-- address bits of internal ram (sp,...)
	exta_width	: integer		-- address bits of internal io (or 5/4)
);

port (
	clk, reset	: in std_logic;

	instr		: in std_logic_vector(i_width-1 downto 0);
	zf, nf		: in std_logic;		-- nf, eq and lt not used (only brz, brnz)
	eq, lt		: in std_logic;

	br			: out std_logic;
	jbr			: out std_logic;

	ext_addr	: out std_logic_vector(exta_width-1 downto 0);
	rd, wr		: out std_logic;

	dir			: out std_logic_vector(addr_width-1 downto 0);

	sel_sub		: out std_logic;						-- 0..add, 1..sub
	sel_amux		: out std_logic;						-- 0..sum, 1..lmux
	ena_a		: out std_logic;						-- 1..store new value
	sel_bmux	: out std_logic;						-- 0..a, 1..mem
	sel_log		: out std_logic_vector(1 downto 0);		-- pop/st, and, or, xor
	sel_shf		: out std_logic_vector(1 downto 0);		-- sr, sl, sra, (sr)
	sel_lmux	: out std_logic_vector(2 downto 0);		-- log, shift, mem, io, reg
	sel_imux	: out std_logic_vector(1 downto 0);		-- java opds
	sel_rmux	: out std_logic_vector(1 downto 0);		-- sp, vp, jpc
	sel_smux	: out std_logic_vector(1 downto 0);		-- sp, a, sp-1, sp+1

	sel_mmux	: out std_logic;						-- 0..a, 1..b
	sel_rda		: out std_logic_vector(2 downto 0);		-- 
	sel_wra		: out std_logic_vector(2 downto 0);		-- 

	wr_ena		: out std_logic;

	ena_b		: out std_logic;
	ena_vp		: out std_logic;
	ena_jpc		: out std_logic
);
end decode;

architecture rtl of decode is

--
--	Signals
--

--
-- intruction register, shortcut
--
--	signal ir		: std_logic_vector(i_width-1 downto 0);		-- Xilinx does not like this... instruction register
	signal ir		: std_logic_vector(7 downto 0);		-- instruction register

begin

	ir <= instr;		-- registered in fetch

	ext_addr <= ir(exta_width-1 downto 0);	-- address for extension select

--
--	branch, jbranch
--

process(clk, reset, ir, zf)
begin
	if (reset='1') then
		br <= '0';
	elsif rising_edge(clk) then

		br <= '0';
		if((ir(7 downto 5)="010" and zf='1') or		-- bz
			(ir(7 downto 5)="011" and zf='0')) then	-- bnz
			br <= '1';
		end if;

	end if;
end process;

--	wait is decoded direct in fetch.vhd!

process(ir)
begin

	jbr <= '0';
	if (ir="10000010") then		-- jbr: goto and if_xxx
		jbr <= '1';
	end if;

end process;

--
--	addr, read stage:
--		decode from ir (only logic, no register)
--
process(ir, ir(2 downto 0))
begin

-- ram wraddress and wrena are registered

	wr_ena <= '0';
	if (ir(7 downto 5)="101" or			-- 'push' instructions
		ir(7 downto 5)="110" or
		ir(7 downto 5)="111" or
		ir(7 downto 5)="001" or			-- stm
		ir(7 downto 3)="00010") then	-- st, stn

		wr_ena <= '1';
	end if;

	rd <= '0';
	if ir(7 downto 3)="11100" then		-- ld memio
		rd <= '1';
	end if;
	wr <= '0';
	if ir(7 downto 3)="00001" then		-- st memio
		wr <= '1';
	end if;

	sel_imux <= ir(1 downto 0);			-- ld opd_x

-- select for rd/wr address muxes

	dir <= "000" & ir(4 downto 0);

	sel_rda <= "100";					-- sp
	if (ir(7 downto 3)="11101") then	-- ld, ldn
		sel_rda <= ir(2 downto 0);
	end if;
	if (ir(7 downto 5)="101") then		-- ldm
		sel_rda <= "111";
	end if;
	if (ir(7 downto 5)="110") then		-- ldi
		sel_rda <= "111";
		dir <= "001" & ir(4 downto 0);	-- addr > 31 constants
	end if;

	sel_wra <= "100";					-- spp
	if ir(7 downto 3)="00010" then		-- st, stn
		sel_wra <= ir(2 downto 0);
	end if;
	if ir(7 downto 5)="001" then		-- stm
		sel_wra <= "111";
	end if;

-- select for sp update

	sel_smux <= "00";				-- sp = sp
	if(ir(7)='0') then			-- 'pop' instruction
		sel_smux <= "01";			-- --sp
	end if;
	if(ir(7 downto 5)="101" or	-- 'push' instruction
		ir(7 downto 5)="110" or
		ir(7 downto 5)="111") then
		sel_smux <= "10";			-- ++sp
	end if;
	if (ir="00011011") then			-- st sp
		sel_smux <= "11";			-- sp = a
	end if;
			
end process;

--
--	ex stage
--

process(clk, reset)
begin

	if (reset='1') then
		sel_sub <= '0';
		sel_amux <= '0';
		ena_a <= '0';
		sel_bmux <= '0';
		sel_log <= "00";
		sel_shf <= "00";
		sel_lmux <= "000";
		sel_rmux <= "00";
		sel_mmux <= '0';
		ena_b <= '0';
		ena_vp <= '0';
		ena_jpc <= '0';

	elsif rising_edge(clk) then

		sel_log <= "00";
		if (ir(7 downto 2)="000000") then		-- pop, and, or, xor
			sel_log <= ir(1 downto 0);
		end if;

		sel_shf <= ir(1 downto 0);

		sel_sub <= '1';			-- default is subtract for lt-flag
		sel_amux <= '1';			-- default is lmux
		ena_a <= '1';			-- default is enable
		ena_vp <= '0';
		ena_jpc <= '0';

		case ir is

			when "00000000" =>				-- pop
			when "00000001" =>				-- and
			when "00000010" =>				-- or
			when "00000011" =>				-- xor
			when "00000100" =>				-- add
					sel_sub <= '0';
					sel_amux <= '0';
			when "00000101" =>				-- sub
					sel_amux <= '0';
			when "00001000" =>				-- stioa
			when "00001001" =>				-- stiod
			when "00001010" =>				-- stmra
			when "00001011" =>				-- stmwa
			when "00001100" =>				-- stmwd
			when "00001101" =>				-- stopa
			when "00001110" =>				-- stopb
			when "00010000" =>				-- st0
			when "00010001" =>				-- st1
			when "00010010" =>				-- st2
			when "00010011" =>				-- st3
			when "00010101" =>				-- st
			when "00011000" =>				-- stvp
					ena_vp <= '1';
			when "00011001" =>				-- stjpc
					ena_jpc <= '1';
--			when "00011010" =>				-- free, stbc not used
			when "00011011" =>				-- stsp
			when "00011100" =>				-- ushr
			when "00011101" =>				-- shl
			when "00011110" =>				-- shr
--			when "001-----" =>				-- stm
--			when "010-----" =>				-- bz
--			when "011-----" =>				-- bnz
			when "10000000" =>				-- nop
					ena_a <= '0';
			when "10000001" =>				-- wait
					ena_a <= '0';
			when "10000010" =>				-- jbr
					ena_a <= '0';
--			when "101-----" =>				-- ldm
--			when "110-----" =>				-- ldi
			when "11100001" =>				-- ldiod
			when "11100010" =>				-- ldmrd
			when "11100011" =>				-- ldmbsy
			when "11100101" =>				-- ldmul
			when "11101000" =>				-- ld0
			when "11101001" =>				-- ld1
			when "11101010" =>				-- ld2
			when "11101011" =>				-- ld3
			when "11101101" =>				-- ld
			when "11110000" =>				-- ldsp
			when "11110001" =>				-- ldvp
			when "11110010" =>				-- ldjpc
			when "11110100" =>				-- ld_opd_8u
			when "11110101" =>				-- ld_opd_8s
			when "11110110" =>				-- ld_opd_16u
			when "11110111" =>				-- ld_opd_16s
			when "11111000" =>				-- dup
					ena_a <= '0';

			when others =>
				null;
		end case;


		sel_lmux <= "000";		-- log

		if ir(7 downto 2)="000111" then				-- ushr, shl, shr
			sel_lmux <= "001";
		end if;

		if ir(7 downto 5)="101" then				-- ldm
			sel_lmux <= "010";
		end if;
		if ir(7 downto 5)="110" then				-- ldi
			sel_lmux <= "010";
		end if;

		if ir(7 downto 3)="11101" then				-- ld, ldn
			sel_lmux <= "010";
		end if;

		if ir(7 downto 2)="111101" then				-- ld_opd_x
			sel_lmux <= "011";
		end if;

		if ir(7 downto 3)="11100" then				-- ld io
			sel_lmux <= "100";
		end if;

		if ir(7 downto 2)="111100" then				-- ldsp, ldvp, ldjpc
			sel_lmux <= "101";
		end if;

									-- default 'pop'
		sel_bmux <= '1';			-- mem
		sel_mmux <= '0';			-- a
		if (ir(7)='1') then		-- 'push' and 'no stack change'
			sel_bmux <= '0';		-- a
			sel_mmux <= '1';		-- b
		end if;

		ena_b <= '1';
		if (ir(7 downto 5)="100") then	-- 'no stack change' (nop, jbr)
			ena_b <= '0';
		end if;

		sel_rmux <= ir(1 downto 0);			-- ldsp, ldvp, ldjpc

	end if;
end process;

end rtl;

⌨️ 快捷键说明

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