命令デコーダとシーケンサの設計


     それでは,命令デコーダとシーケンサの設計を行います.命令デコーダとシー ケンサの記述は穴埋め形式で行ってもらいますが,ソースプログラムは,下の “GET”ボタンを押すことで入手可能です.まず,“GET” ボタンを押して,ソースを各自の作業ディレクトリにダウンロードして下さい .この際に,“Selection”欄でセーブする場所を指定できますので,各 自の作業ディレクトリを指定し“idc_seq.vhd”というファイルネームにして 下さい.

    GET

演習
解説:デコーダ・シーケンサの考え方
演習1:type による型定義 (命令ステートの定義)
演習2:順次処理文による組合せ回路の記述法 (命令デコーダ)
演習3:順次処理文による順序回路の記述法 (ステートマシンその1)
演習4:順序回路における状態遷移の記述法 (ステートマシンその2)
演習5:制御信号の生成

次へ進む ( 解説:デコーダ・シーケンサの考え方 )
以下にサンプルとなるデコーダ・シーケンサ部分のソースを示します.なお,演習に関する部分は 空白としています.
-- IDC_SEQ.VHD for KITE-1
-- KITE-1 Instruction Decoder & Sequencer Unit

library IEEE;
use IEEE.STD_LOGIC_1164.all;

entity IDC_SEQ is
port(
     	IR	: in	STD_LOGIC_VECTOR(15 downto 0);	--命令コードの入力
     	FR	: in	STD_LOGIC_VECTOR(3 downto 0);	--フラグ情報の入力
     	S_ALU	: out	STD_LOGIC_VECTOR(3 downto 0);	--ALU用制御信号
     	IR_R	: out 	STD_LOGIC_VECTOR(2 downto 0);	--IRの読み出し制御信号
     	MREQ	: out	STD_LOGIC;	--メモリ・リクエスト信号
	IORQ	: out 	STD_LOGIC;	--I/Oリクエスト信号
	RW	: out 	STD_LOGIC;	--リード・ライト信号
	ICS	: out	STD_LOGIC;	--命令完了信号
	IR_W	: out	STD_LOGIC;	--IRの書き込み制御信号
	ACC_W	: out	STD_LOGIC;	--ACCの書き込み制御信号
	ACC_R	: out	STD_LOGIC;	--ACCの読み出し制御信号
	PC_W	: out	STD_LOGIC;	--PCの書き込み制御信号
	PC_R	: out	STD_LOGIC;	--PCの読み出し制御信号
	PC_INC 	: out 	STD_LOGIC;	--PCのインクリメント制御信号
	SP_W	: out	STD_LOGIC;	--SPの書き込み制御信号
	SP_R	: out	STD_LOGIC;	--SPの読み出し制御信号
	IX_W	: out	STD_LOGIC;	--IXの書き込み制御信号
	IX_R	: out	STD_LOGIC;	--IXの読み出し制御信号
	MAR_W	: out	STD_LOGIC;	--MARの書き込み制御信号
	BUF1_W	: out	STD_LOGIC;	--BUF1の書き込み制御信号
	BUF2_W	: out	STD_LOGIC;	--BUF2の書き込み制御信号
	BUF2_R	: out	STD_LOGIC;	--BUF2の読み出し制御信号
	FR_W	: out	STD_LOGIC;	--FRの書き込み制御信号
     	S_DBI	: out	STD_LOGIC;	--データ・バスの入力制御信号
	HALT	: out	STD_LOGIC;	--ホルト信号
     	ACK	: in	STD_LOGIC;	--アクナリッジ信号
	CLK	: in	STD_LOGIC;	--シーケンサ用クロック信号
	RESET	: in 	STD_LOGIC);	--リセット信号
end IDC_SEQ;

architecture BEHA of IDC_SEQ is

--シーケンサ用のステート定義
type STATE_TYPE is
	(
	V0,V1,V2,			--Vector Start
	F0,F1,DECO,			--Inst. Fetch
	LD_IM,				--LD Immediate
	LD_D1,LD_D2,LD_D3,		--LD Direct

--@@@@@@@
--
--     演習1 : type による型定義 (命令ステートの定義) 
--
--@@@@@@

	ST_D1,ST_D2,ST_D3,ST_D4,	--ST Direct
	ST_IX1,ST_IX2,ST_IX3,
	ST_IX4,ST_IX5,ST_IX6,		--ST Index
	INN1,INN2,INN3,			--IN
	OUTT1,OUTT2,OUTT3,OUTT4,	--OUT
	JPP,				--JP,JPC,JPS,JPZ,JPV
	CALC_IM1,CALC_IM2,CALC_IM3,	--ADD_IM,SUB_IM,AND_IM,OR_IM,EOR_IM
	CALC_IX1,CALC_IX2,CALC_IX3,
	CALC_IX4,CALC_IX5,CALC_IX6,	--ADD_IX,SUB_IX,AND_IX,OR_IX,EOR_IX
	CALC_REG1,CALC_REG2,CALC_REG3,	--INC,DEC
	CALC1,CALC2,CALC3,		--NOT,LSL,ASL,LSR,ASR,ROL,ROR,SWP
	MVV,				--MV
	CALL1,CALL2,CALL3,CALL4,CALL5,
	CALL6,CALL7,			--CALL
	RET1,RET2,RET3,RET4,RET5,	--RET
	PUSH1,PUSH2,PUSH3,
	PUSH4,PUSH5,PUSH6,		--PUSH
	POP1,POP2,POP3,POP4,POP5,	--POP
	NOP1,				--NOP
	HALT1				--HALT
	);

--命令デコード用の命令定義
type INST_TYPE is
	(
	LD_IM,				--LD 	Immediate
	LD_D,				--LD 	Direct
	LD_IX,				--LD 	Index
	ST_D,				--ST 	Direct
	ST_IX,				--ST 	Index
	CALL,				--CALL
	RET,				--RET
	PUSH,				--PUSH
	POP,				--POP
	ADD_IX,				--ADD 	Index
	SUB_IX,				--SUB 	Index
	AND_IX,				--AND 	Index
	OR_IX,				--OR 	Index
	EOR_IX,				--EOR 	Index
	ADD_IM,				--ADD 	Immediate
	SUB_IM,				--SUB 	Immediate
	AND_IM,				--AND	Immediate
	OR_IM,				--OR 	Immediate
	EOR_IM,				--EOR	Immediate
	NOTT,				--NOT
	INC,				--INC
	DEC,				--DEC
	LSL,				--LSL
	ASL,				--ASL
	LSR,				--LSR
	ASR,				--ASR
	ROLL,				--ROL
	RORR,				--ROR
	SWAP,				--SWAP
	JP,				--JP,JPC,JPS,JPZ,JPV
	HAL,				--HALT
	INN,				--IN
	OUTT,				--OUT
	MV,				--MV
	NOP);				--NOP

signal PRESENT_STATE	: STATE_TYPE;	--シーケンサ用状態遷移変数
signal PRESENT_INST 	: INST_TYPE;	--命令デコード用変数
signal START 		: STD_LOGIC;	

begin
	
--命令デコート部

--@@@@@@@
--
--     演習2 : 順次処理文による組合せ回路の記述法 (命令デコーダ) 
--
--@@@@@@

begin
	case IR(15 downto 12) is
		when "0000" => PRESENT_INST <= LD_D; 
		when "0001" => PRESENT_INST <= ST_D;  
		when "0010" => PRESENT_INST <= CALL;
		when "0011" => PRESENT_INST <= JP;   
		when "0100" => 
			if FR(0) = '1' then 
				PRESENT_INST <= JP;	-- JPc
			else 
				PRESENT_INST <= NOP;
			end if;
		when "0101" =>				-- JPz
			if FR(2) = '1' then  
				PRESENT_INST <= JP;
			else 
				PRESENT_INST <= NOP;
			end if;
		when "0110" => 				-- JPs
			if FR(3) = '1' then 
				PRESENT_INST <= JP;
			else 
				PRESENT_INST <= NOP;
			end if; 
		when "0111" => 				-- JPv
			if FR(1) = '1' then 
				PRESENT_INST <= JP;
			else 
				PRESENT_INST <= NOP;
			end if;
		when others => PRESENT_INST <= HAL;
	end case;
	case IR(15 downto 10) is
		   	when "111110"  => PRESENT_INST <= HAL;
			when "110010"  => PRESENT_INST <= INN;
			when "110011"  => PRESENT_INST <= OUTT;
			when "110101"  => PRESENT_INST <= PUSH;
			when "110100"  => PRESENT_INST <= POP;
			when "111000"  => PRESENT_INST <= RET;
			when "111100"  => PRESENT_INST <= MV; 
			when "111111"  => PRESENT_INST <= NOP;
			when "100010"  => PRESENT_INST <= INC;
			when "100011"  => PRESENT_INST <= DEC;
			when "101000"  => PRESENT_INST <= LSL;
			when "101001"  => PRESENT_INST <= ASL;
			when "101010"  => PRESENT_INST <= LSR;
			when "101011"  => PRESENT_INST <= ASR;
			when "101100"  => PRESENT_INST <= ROLL;
			when "101101"  => PRESENT_INST <= RORR;
			when "101111"  => PRESENT_INST <= SWAP; 
			when "100111"  => PRESENT_INST <= NOTT;
			when others    => NULL;
	end case;
	case IR(15 downto 8) is
			when "11000001" => PRESENT_INST <= LD_IM;
			when "10010001" => PRESENT_INST <= OR_IM;
			when "10000001" => PRESENT_INST <= ADD_IM;
			when "10000101" => PRESENT_INST <= SUB_IM;
			when "10010101" => PRESENT_INST <= EOR_IM;
			when "10011001" => PRESENT_INST <= AND_IM;

--@@@@@@@
--
--     演習2 : 順次処理文による組合せ回路の記述法 (命令デコーダ) 
--
--@@@@@@

			when "11000110" => PRESENT_INST <= ST_IX;
			when "10000010" => PRESENT_INST <= ADD_IX;
			when "10000110" => PRESENT_INST <= SUB_IX;
			when "10011010" => PRESENT_INST <= AND_IX;
			when "10010010" => PRESENT_INST <= OR_IX;
			when "10010110" => PRESENT_INST <= EOR_IX;
			when others     => NULL;
	end case;
end process DECODE_PROC;


-- シーケンサ用スタート信号の生成

	START_LATCH : process(CLK)
	begin
		if (CLK'event and CLK = '1') then
			START <= RESET;
		end if;
	end process START_LATCH;

--シーケンサ部(状態遷移)

--@@@@@@@
--
--     演習3 : 順次処理文による順序回路の記述法 (ステートマシンその1) 
--
--@@@@@@

  case  PRESENT_STATE is
	when V0 =>					--ベクトルスタート
		if START = '1' then
			 PRESENT_STATE <= V1;  
		end if;
	when V1 => 
		if ACK = '1' then
                    	PRESENT_STATE <= V2;
		end if;
	when V2 => 	PRESENT_STATE <= F0;
	when F0 => 	PRESENT_STATE <= F1;		--命令フェッチ
        when F1 => 
		if ACK = '1' then
			PRESENT_STATE <= DECO;
		end if;
	when DECO =>					--命令デコード
	 	case PRESENT_INST is
			when LD_IM =>		PRESENT_STATE <= LD_IM;
			when LD_D =>		PRESENT_STATE <= LD_D1;
			when LD_IX =>		PRESENT_STATE <= LD_IX1;
			when ST_D =>		PRESENT_STATE <= ST_D1;
			when ST_IX =>		PRESENT_STATE <= ST_IX1;
			when INN =>		PRESENT_STATE <= INN1;
			when OUTT =>		PRESENT_STATE <= OUTT1;
			when JP =>		PRESENT_STATE <= JPP;
			when MV =>		PRESENT_STATE <= MVV;
			when ADD_IX | SUB_IX | AND_IX | OR_IX | EOR_IX =>
						PRESENT_STATE <= CALC_IX1;
			when ADD_IM | SUB_IM | AND_IM | OR_IM | EOR_IM => 
						PRESENT_STATE <= CALC_IM1;
			when INC | DEC => 	PRESENT_STATE <= CALC_REG1;
			when NOTT | LSL | ASL | LSR | ASR | ROLL | RORR | SWAP =>
						PRESENT_STATE <= CALC1;
			when CALL =>		PRESENT_STATE <= CALL1;
			when RET =>		PRESENT_STATE <= RET1;
			when PUSH =>		PRESENT_STATE <= PUSH1;
			when POP => 		PRESENT_STATE <= POP1;
			when NOP =>		PRESENT_STATE <= NOP1;
			when HAL =>		PRESENT_STATE <= HALT1;
			when others =>		PRESENT_STATE <= HALT1;
		end case;
	when LD_IM => 	PRESENT_STATE <= F0;		--LD Immediate
	when LD_D1 => 	PRESENT_STATE <= LD_D2;		--LD Direct
	when LD_D2 =>	
		if ACK = '1' then
			PRESENT_STATE <= LD_D3;
		end if;
	when LD_D3 => 	PRESENT_STATE <= F0;

--@@@@@@@
--
--     演習4 :  順序回路における状態遷移の記述法 (ステートマシンその2) 
--
--@@@@@@

	when ST_D1 => 	PRESENT_STATE <= ST_D2;		--ST Direct
	when ST_D2 => 	PRESENT_STATE <= ST_D3;
	when ST_D3 =>
		if ACK = '1' then
			PRESENT_STATE <= ST_D4;
		end if;
	when ST_D4 => 	PRESENT_STATE <= F0;
	when ST_IX1 =>	PRESENT_STATE <= ST_IX2;	--ST Index
	when ST_IX2 => 	PRESENT_STATE <= ST_IX3;
	when ST_IX3 =>	PRESENT_STATE <= ST_IX4;
	when ST_IX4 =>	PRESENT_STATE <= ST_IX5;
	when ST_IX5 =>
		if ACK = '1' then
			PRESENT_STATE <= ST_IX6;
		end if;
	when ST_IX6 =>	PRESENT_STATE <= F0;
	when INN1 => 	PRESENT_STATE <= INN2;		--IN
	when INN2 =>
		if ACK = '1' then
			PRESENT_STATE <= INN3;
		end if;
	when INN3 => 	PRESENT_STATE <= F0;
	when OUTT1 => 	PRESENT_STATE <= OUTT2;		--OUT
	when OUTT2 => 	PRESENT_STATE <= OUTT3;
	when OUTT3 =>
		if ACK = '1' then
			PRESENT_STATE <= OUTT4;
		end if;
	when OUTT4 => PRESENT_STATE <= F0;
	when JPP => 	PRESENT_STATE <= F0;		--JP
	when MVV => 	PRESENT_STATE <= F0;		--MV
	when CALC_IX1 =>PRESENT_STATE <= CALC_IX2;	--CALC Index
	when CALC_IX2 =>PRESENT_STATE <= CALC_IX3;
	when CALC_IX3 =>PRESENT_STATE <= CALC_IX4;
	when CALC_IX4 =>
		if ACK = '1' then
			PRESENT_STATE <= CALC_IX5;
		end if;
	when CALC_IX5 =>PRESENT_STATE <= CALC_IX6;
	when CALC_IX6 =>PRESENT_STATE <= F0;			
	when CALC_IM1 =>PRESENT_STATE <= CALC_IM2;	--CALC Immediate
	when CALC_IM2 =>PRESENT_STATE <= CALC_IM3;
	when CALC_IM3 =>PRESENT_STATE <= F0;
	when CALC_REG1=>PRESENT_STATE <= CALC_REG2;	--CALC REG
	when CALC_REG2=>PRESENT_STATE <= CALC_REG3;
	when CALC_REG3=>PRESENT_STATE <= F0;
	when CALC1 =>	PRESENT_STATE <= CALC2;		--CALC
	when CALC2 =>	PRESENT_STATE <= CALC3;
	when CALC3 =>	PRESENT_STATE <= F0;
	when CALL1 =>	PRESENT_STATE <= CALL2;		--CALL
	when CALL2 =>	PRESENT_STATE <= CALL3;
	when CALL3 =>	PRESENT_STATE <= CALL4;
	when CALL4 =>	PRESENT_STATE <= CALL5;
	when CALL5 =>
		if ACK = '1' then
			PRESENT_STATE <= CALL6;
		end if;
	when CALL6 =>	PRESENT_STATE <= CALL7;
	when CALL7 =>	PRESENT_STATE <= F0;
	when RET1 =>	PRESENT_STATE <= RET2;		--RET
	when RET2 =>	PRESENT_STATE <= RET3;
	when RET3 =>	PRESENT_STATE <= RET4;
	when RET4 =>
		if ACK = '1' then
			PRESENT_STATE <= RET5;
		end if;
	when RET5 =>	PRESENT_STATE <= F0;
	when PUSH1 =>	PRESENT_STATE <= PUSH2;		--PUSH
	when PUSH2 =>	PRESENT_STATE <= PUSH3;
	when PUSH3 =>	PRESENT_STATE <= PUSH4;	
	when PUSH4 =>	PRESENT_STATE <= PUSH5;
	when PUSH5 =>
		if ACK = '1' then
			PRESENT_STATE <= PUSH6;
		end if;
	when PUSH6 =>	PRESENT_STATE <= F0;
	when POP1 =>	PRESENT_STATE <= POP2;		--POP
	when POP2 =>	PRESENT_STATE <= POP3;
	when POP3 =>	PRESENT_STATE <= POP4;
	when POP4 =>
		if ACK = '1' then
			PRESENT_STATE <= POP5;
		end if;
	when POP5 =>	PRESENT_STATE <= F0;
	when NOP1 => 	PRESENT_STATE <= F0;
	when HALT1 => 	PRESENT_STATE <= HALT1;
	when others => 	PRESENT_STATE <= V0;
	end case;
end if;
end process SEQ_PROC;

	--シーケンサ部(出力信号生成)
	OUTPUT_SIGNALS : process(PRESENT_STATE,PRESENT_INST,
			IR(7),IR(3 downto 0))
	begin
		--出力信号の初期化
		MREQ <= '0';
		RW <= '0';
		IORQ <= '0';
		IR_W <= '0';		IR_R <= "110";
		ACC_W <= '0';		ACC_R <= '0';
		PC_W <= '0';		PC_R <= '0';	PC_INC <= '0';
		SP_W <= '0';		SP_R <= '0';
		IX_W <= '0';		IX_R <= '0';
		BUF1_W <= '0';
		BUF2_W <= '0';		BUF2_R <= '0';
		MAR_W <= '0';
		FR_W <= '0';
		S_ALU <= "0000";
		ICS <= '0';
		HALT <= '0';
		S_DBI <= '0';
		
		case (PRESENT_STATE) is
		when V0 =>	HALT 	<= '1';		--Vector Start
		when V1 =>	MREQ 	<= '1';
		when V2 =>	MREQ 	<= '1';
				PC_W 	<= '1';
				S_DBI 	<= '1';
		when F0 =>	PC_R 	<= '1';		--Inst. Fetch
				PC_INC	<= '1';
				MAR_W 	<= '1';
		when F1 =>	MREQ 	<= '1';
		when DECO =>	MREQ 	<= '1';
				IR_W 	<= '1';
				S_DBI 	<= '1';
		when LD_IM =>	IR_R 	<= "101";	--LD Immediate
				ACC_W 	<= '1';
				ICS 	<= '1';
		when LD_D1 =>	IR_R 	<= "011";	--LD Direct
				MAR_W 	<= '1';
		when LD_D2 =>	MREQ 	<= '1';
		when LD_D3 =>	MREQ 	<= '1';
				ACC_W 	<= '1';
				S_DBI 	<= '1';
				ICS 	<= '1';

--@@@@@@@
--
--     演習5 : 制御信号の生成
--
--@@@@@@

		when ST_D1 =>	IR_R 	<= "011";	--ST Direct
				MAR_W 	<= '1';
		when ST_D2 =>	RW 	<= '1';
				ACC_R 	<= '1';
		when ST_D3 =>	RW 	<= '1';
				ACC_R 	<= '1';
				MREQ 	<= '1';
		when ST_D4 =>	RW 	<= '1';
				ACC_R 	<= '1';
				ICS 	<= '1';
		when ST_IX1 =>	IX_R	<= '1';		--ST Index
				BUF1_W	<= '1';
		when ST_IX2 =>	if IR(7) = '1' then	
					IR_R <= "001";
				else
					IR_R <= "101";
				end if;
				BUF2_W 	<= '1';
		when ST_IX3 =>	BUF2_R	<= '1';
				MAR_W	<= '1';
		when ST_IX4 =>	RW 	<= '1';
				ACC_R	<= '1';
		when ST_IX5 =>	RW	<= '1';
				ACC_R	<= '1';
				MREQ	<= '1';
		when ST_IX6 =>	RW	<= '1';
				ACC_R	<= '1';
				ICS	<= '1';
		when INN1 =>	IR_R 	<= "101";	--IN
				MAR_W 	<= '1';
		when INN2 =>	IORQ 	<= '1';
		when INN3 =>	IORQ 	<= '1';
				ACC_W 	<= '1';
				S_DBI 	<= '1';
				ICS 	<= '1';
		when OUTT1 =>	IR_R 	<= "101";	--OUT
				MAR_W 	<= '1';
		when OUTT2 =>	RW 	<= '1';
				ACC_R 	<= '1';
		when OUTT3 =>	RW 	<= '1';
				ACC_R 	<= '1';
				IORQ 	<= '1';
		when OUTT4 =>	RW 	<= '1';
				ACC_R 	<= '1';
				ICS 	<= '1';
		when JPP =>	IR_R 	<= "011";	--JP
				PC_W 	<= '1';
				ICS 	<= '1';
		when MVV =>				--MV
				case IR(1 downto 0) is	
			               	when "00" => ACC_R <= '1';
			              	when "01" => SP_R <= '1';
			               	when "10" => IX_R <= '1';
			               	when "11" => PC_R <= '1';
			               	when others => NULL;
			        end case;
			        case IR(3 downto 2) is
			               	when "00" => ACC_W <= '1';
			               	when "01" => SP_W <= '1';
			               	when "10" => IX_W <= '1';
			               	when "11" => PC_W <= '1';
			               	when others => NULL;
			        end case;
				ICS 	<= '1';
		when CALC_IX1 =>IX_R	<= '1';		--CALC Index
				BUF1_W	<= '1';
		when CALC_IX2 =>if IR(7) = '1' then
					IR_R <= "001";
				else
					IR_R <= "101";
				end if;
				BUF2_W 	<= '1';
		when CALC_IX3 =>BUF2_R	<= '1';
				MAR_W	<= '1';
		when CALC_IX4 =>ACC_R	<= '1';
				BUF1_W 	<= '1';
				MREQ 	<= '1';
		when CALC_IX5 =>BUF2_W	<= '1';
				FR_W	<= '1';
				MREQ	<= '1';
				S_DBI 	<= '1';
				case PRESENT_INST is
					when ADD_IX =>	S_ALU <= "0000";
					when SUB_IX =>	S_ALU <= "0001";
					when AND_IX =>	S_ALU <= "0101";
					when OR_IX  =>	S_ALU <= "0100";
					when EOR_IX =>	S_ALU <= "0110";
					when others =>	S_ALU <= "0000";
				end case;
		when CALC_IX6 =>BUF2_R 	<= '1';
				ACC_W	<= '1';
				ICS	<= '1';
		when CALC_IM1 =>BUF1_W 	<= '1';		--CALC Immediate
				ACC_R 	<= '1';
		when CALC_IM2 =>BUF2_W 	<= '1';
				FR_W 	<= '1';
				case PRESENT_INST is
					when ADD_IM =>	S_ALU <= "0000";
							if IR(7) = '1' then
								IR_R <= "001";
							else
								IR_R <= "101";
							end if;
					when SUB_IM =>	S_ALU <= "0001";
							if IR(7) = '1' then
								IR_R <= "001";
							else
								IR_R <= "101";
							end if;
					when AND_IM =>	S_ALU <= "0101";
							IR_R  <= "001";
					when OR_IM  =>	S_ALU <= "0100";
							IR_R  <= "101";
					when EOR_IM =>	S_ALU <= "0110";
							IR_R  <= "101";
					when others =>	S_ALU <= "0000";
				end case;
		when CALC_IM3 =>ACC_W 	<= '1';
				BUF2_R 	<= '1';
				ICS 	<= '1';
		when CALC_REG1 =>			--CALC REG
				BUF1_W <= '1';
				case IR(1 downto 0) is
			               	when "00" => ACC_R <= '1';
			              	when "01" => SP_R <= '1';
			               	when "10" => IX_R <= '1';
			               	when "11" => PC_R <= '1';
			               	when others => NULL;
			        end case;
		when CALC_REG2 =>
				FR_W 	<= '1';
				BUF2_W 	<= '1';
				if PRESENT_INST = INC then
					S_ALU <= "0010";
				else
					S_ALU <= "0011";
				end if;
		when CALC_REG3 =>
				BUF2_R 	<= '1';
				case IR(3 downto 2) is
			               	when "00" => ACC_W <= '1';
			               	when "01" => SP_W <= '1';
			               	when "10" => IX_W <= '1';
			               	when "11" => PC_W <= '1';
			               	when others => NULL;
			        end case;
		                ICS 	<= '1';			
		when CALC1 =>	BUF1_W 	<= '1';		--CALC
				ACC_R	<= '1';
		when CALC2 =>	BUF2_W	<= '1';
				FR_W 	<= '1';
				case PRESENT_INST is
					when NOTT =>	S_ALU <= "0111";
					when LSL =>	S_ALU <= "1000";
					when ASL =>	S_ALU <= "1001";
					when LSR =>	S_ALU <= "1010";
					when ASR =>	S_ALU <= "1011";
					when ROLL =>	S_ALU <= "1100";
					when RORR =>	S_ALU <= "1101";
					when SWAP =>	S_ALU <= "1110";
					when others =>	S_ALU <= "0000";
				end case;
		when CALC3 =>	BUF2_R	<= '1';
				ACC_W	<= '1';
				ICS	<= '1';			
		when CALL1 =>	SP_R 	<= '1';		--CALL
				BUF1_W	<= '1';
		when CALL2 =>	BUF2_W	<= '1';
				S_ALU 	<= "0011";
		when CALL3 =>	BUF2_R	<= '1';
				SP_W	<= '1';
				MAR_W	<= '1';
		when CALL4 =>	RW	<= '1';
				PC_R 	<= '1';
		when CALL5 =>	RW 	<= '1';
				PC_R	<= '1';
				MREQ	<= '1';
		when CALL6 =>	RW	<= '1';
				PC_R	<= '1';
		when CALL7 =>	IR_R	<= "011";
				PC_W	<= '1';
				ICS	<= '1';
		when RET1 =>	SP_R	<= '1';		--RET
				BUF1_W  <= '1';
				MAR_W 	<= '1';
		when RET2 =>	BUF2_W	<= '1';
				S_ALU	<= "0010";
		when RET3 =>	BUF2_R	<= '1';
				SP_W	<= '1';
		when RET4 =>	MREQ	<= '1';
		when RET5 =>	MREQ	<= '1';
				S_DBI	<= '1';
				PC_W	<= '1';
				ICS	<= '1';
		when PUSH1 =>	SP_R	<= '1';		--PUSH
				BUF1_W	<= '1';
		when PUSH2 =>	BUF2_W	<= '1';
				S_ALU	<= "0011";
		when PUSH3 =>	BUF2_R	<= '1';
				SP_W	<= '1';
				MAR_W	<= '1';
		when PUSH4 =>	RW	<= '1';
				ACC_R	<= '1';
		when PUSH5 =>	RW	<= '1';
				ACC_R	<= '1';
				MREQ	<= '1';
		when PUSH6 =>	RW	<= '1';
				ACC_R	<= '1';
				ICS	<= '1';
		when POP1 =>	SP_R	<= '1';		--POP
				BUF1_W	<= '1';
				MAR_W	<= '1';
		when POP2 =>	BUF2_W	<= '1';
				S_ALU	<= "0010";
		when POP3 =>	BUF2_R	<= '1';
				SP_W 	<= '1';
		when POP4 =>	MREQ 	<= '1';
		when POP5 =>	MREQ	<= '1';
				S_DBI	<= '1';
				ACC_W	<= '1';
				ICS	<= '1';
		when NOP1 => 	ICS 	<= '1';		--NOP
		when HALT1 => 	ICS 	<= '1';		--HALT
				HALT 	<= '1';
		when others => 	HALT 	<= '1';
		end case;
	end process OUTPUT_SIGNALS;

end BEHA;


演習
解説:デコーダ・シーケンサの考え方
演習1:type による型定義 (命令ステートの定義)
演習2:順次処理文による組合せ回路の記述法 (命令デコーダ)
演習3:順次処理文による順序回路の記述法 (ステートマシンその1)
演習4:順序回路における状態遷移の記述法 (ステートマシンその2)
演習5:制御信号の生成


ホーム シーケンサの設計 シミュレーション 辞書
This is my e-mail address:
arch_www < www@cs.kumamoto-u.ac.jp >
Copyright(C)KITE Microprocessor Project,1996