OpenCores
URL https://opencores.org/ocsvn/the_wizardry_project/the_wizardry_project/trunk

Subversion Repositories the_wizardry_project

[/] [the_wizardry_project/] [trunk/] [Wizardry/] [VHDL/] [Wizardry Top Level/] [Address Generation/] [JOP/] [decode.vhd] - Rev 22

Compare with Previous | Blame | View Log

--
--
--  This file is a part of JOP, the Java Optimized Processor
--
--  Copyright (C) 2001-2008, Martin Schoeberl (martin@jopdesign.com)
--
--  This program is free software: you can redistribute it and/or modify
--  it under the terms of the GNU General Public License as published by
--  the Free Software Foundation, either version 3 of the License, or
--  (at your option) any later version.
--
--  This program is distributed in the hope that it will be useful,
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--  GNU General Public License for more details.
--
--  You should have received a copy of the GNU General Public License
--  along with this program.  If not, see <http://www.gnu.org/licenses/>.
--
 
 
--
--	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
--	2006-01-12	new ar for local memory addressing: star, ldmi, stmi
--				stioa, stiod, ldiod removed
--	2007-08-31	use addr_width for signal dir
--	2007-09-01	use ram_width from jop_config instead of parameter
--
 
 
library ieee ;
use ieee.std_logic_1164.all ;
use ieee.numeric_std.all ;
 
use work.jop_config.all;
use work.jop_types.all;
 
entity decode is
generic (
	i_width		: integer		-- instruction width
);
 
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(ram_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;
	ena_ar		: 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)
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, stmi
 
		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 0)="00000110"
		or ir(7 downto 0)="00000111"
		or 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 <= std_logic_vector(to_unsigned(0, ram_width-5)) & ir(4 downto 0);
 
	sel_rda <= "110";					-- sp
	if (ir(7 downto 3)="11101") then	-- ld, ldn, ldmi
		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 <= std_logic_vector(to_unsigned(1, ram_width-5)) & 
			ir(4 downto 0);	-- addr > 31 constants
	end if;
 
	sel_wra <= "110";					-- spp
	if ir(7 downto 3)="00010" then		-- st, stn, stmi
		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';
		ena_ar <= '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';
		ena_ar <= '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 "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 "00010100" =>				-- st
			when "00010101" =>				-- stmi
			when "00011000" =>				-- stvp
					ena_vp <= '1';
			when "00011001" =>				-- stjpc
					ena_jpc <= '1';
			when "00011010" =>				-- star
					ena_ar <= '1';
			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 "11100010" =>				-- ldmrd
			when "11100011" =>				-- ldmbsy
			when "11100101" =>				-- ldmul
			when "11101000" =>				-- ld0
			when "11101001" =>				-- ld1
			when "11101010" =>				-- ld2
			when "11101011" =>				-- ld3
			when "11101100" =>				-- ld
			when "11101101" =>				-- ldmi
			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, ldmi
			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;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.