M6809 INDEXED Addressing Mode

M6809 鬼門の INDEXED アドレッシングモードだらだら作ってたら何となくできた。多分まだバグあります。ホテルで Verilog あまり書く気が起こらない。。。

M6809 鬼門の INDEXED アドレッシングモードだらだら作ってたら何となくできた。多分まだバグあります。ホテルで Verilog あまり書く気が起こらない。。。

  • タグ:
  • タグはありません
/*-----------------------------------------------------------------------------------
	[AmIndexed]
		Implements the INDEXED addressing mode.
		JMP INDEXED completes in this stage.
-----------------------------------------------------------------------------------*/
module AmIndexed(
	input			i_Clk, i_nReset, i_Proceed,

`ifdef MULTIPLEXED_CORE
	input	[ 1:0]	i_RegSel,			// up to 4 reg sets
`endif

	input			i_AmIdx,			// set during main state "IDECODE"
	input	[ 7:0]	i_PB,
	input			i_LEA,
	input			i_JMP,

	output			o_EOAM,
	output			o_EOI,
	output			o_LoadXH, o_LoadXL, o_LoadYH, o_LoadYL,
	output			o_LoadUH, o_LoadUL, o_LoadSH, o_LoadSL,
	output			o_LoadPC, o_IncPC,
	output			o_AluInC_1, o_LoadAluC7, o_HoldDIN, o_LoadPB,

	output			o_VMA,

	output			o_AluInA_XH, o_AluInA_XL, o_AluInA_YH, o_AluInA_YL,
	output			o_AluInA_UH, o_AluInA_UL, o_AluInA_SH, o_AluInA_SL,
	output			o_AluInA_PCH, o_AluInA_PCL,
	output			o_AluInB_A, o_AluInB_B, o_AluInB_DIN, o_AluInC_AluC7,
	output			o_AluOp_ADC, o_AluOp_SBC,
	output			o_ReadMemPC,

	output			o_Adder16InA_X, o_Adder16InA_Y, o_Adder16InA_U, o_Adder16InA_S,
	output			o_Adder16InA_PC, o_Adder16InA_AOB,
	output			o_Adder16InB_D, o_Adder16InB_DIB16, o_Adder16InB_DIB5, o_Adder16InB_ALU,
	output			o_DataBus_ALU,
	output			o_LoadAddrOutBuf, o_LoadDataInBufH
);

	parameter		NC = `NUM_CORE-1;
	integer			i = 0;
	reg		[31:0]	r_ST[0:NC];

	/*-----------------------------------------------------------------------------------
		[Post Byte Decoder]
		------------------------+--------------------------
			     DIRECT         |        INDIRECT
		 PostByte   MN     ~ #  |  PostByte    MN      ~ #
		------------------------+--------------------------
		 0RRnnnnn   n,R    1 0  |  --
		 1RR00000   ,R+    2 0  |  --
		 1RR00001   ,R++   3 0  |  1RR10001   [,R++]   6 0
		 1RR00010   ,-R    2 0  |  --
		 1RR00011   ,--R   3 0  |  1RR10011   [,--R]   6 0
		 1RR00100   ,R     0 0  |  1RR10100   [,R]     3 0
		 1RR00101   B,R    1 0  |  1RR10101   [B,R]    4 0
		 1RR00110   A,R    1 0  |  1RR10110   [A,R]    4 0
		 1RR01000   n,R    1 1  |  1RR11000   [n,R]    4 1
		 1RR01001   n,R    4 2  |  1RR11001   [n,R]    7 2
		 1RR01011   D,R    4 0  |  1RR11011   [D,R]    7 0
		 1xx01100   n,PCR  1 1  |  1xx11100   [n,PCR]  4 1
		 1xx01101   n,PCR  5 2  |  1xx11101   [n,PCR]  8 2
		 --                     |  10011111   [n]      5 2
		------------------------+--------------------------
		 X:RR=00, Y:RR=01, U:RR=10, S:RR=11
	-----------------------------------------------------------------------------------*/
	// 2-to-4 decoder
	function	[3:0]	dec2to4;
		input	[1:0]	in;
		case (in)
			2'h0:	dec2to4 = 4'b0001;
			2'h1:	dec2to4 = 4'b0010;
			2'h2:	dec2to4 = 4'b0100;
			2'h3:	dec2to4 = 4'b1000;
		endcase
	endfunction

	// 3-to-8 decoder
	function	[7:0]	dec3to8;
		input	[2:0]	in;
		case (in)
			3'h0:	dec3to8 = 8'b00000001;
			3'h1:	dec3to8 = 8'b00000010;
			3'h2:	dec3to8 = 8'b00000100;
			3'h3:	dec3to8 = 8'b00001000;
			3'h4:	dec3to8 = 8'b00010000;
			3'h5:	dec3to8 = 8'b00100000;
			3'h6:	dec3to8 = 8'b01000000;
			3'h7:	dec3to8 = 8'b10000000;
		endcase
	endfunction

	wire	[ 7:0]	w_im			=	dec3to8(i_PB[4:2]);
	wire	[ 3:0]	w_il			=	dec2to4(i_PB[1:0]);
	wire	[ 3:0]	w_rr			=	dec2to4(i_PB[6:5]);

	wire			w_dir_n5_r		=	~i_PB[7];						// n5,R      (+0b1c)

	wire			w_dir_r_i		=	w_im[0] & w_il[0];				// ,R+       (+0b2c)
	wire			w_dir_r_i2		=	w_im[0] & w_il[1];				// ,R++      (+0b3c)
	wire			w_dir_r_d		=	w_im[0] & w_il[2];				// ,-R       (+0b2c)
	wire			w_dir_r_d2		=	w_im[0] & w_il[3];				// ,--R      (+0b3c)
	wire			w_ind_r_i2		=	w_im[4] & w_il[1];				// [,R++]    (+0b6c)
	wire			w_ind_r_d2		=	w_im[4] & w_il[3];				// [,--R]    (+0b6c)

	wire			w_dir_0_r		=	w_im[1] & w_il[0];				//  ,R       (+0b0c)
	wire			w_dir_b_r		=	w_im[1] & w_il[1];				// B,R       (+0b1c)
	wire			w_dir_a_r		=	w_im[1] & w_il[2];				// A,R       (+0b1c)
	wire			w_ind_0_r		=	w_im[5] & w_il[0];				// [ ,R]     (+0b3c)	
	wire			w_ind_b_r		=	w_im[5] & w_il[1];				// [B,R]     (+0b4c)
	wire			w_ind_a_r		=	w_im[5] & w_il[2];				// [A,R]     (+0b4c)

	wire			w_dir_n8_r		=	w_im[2] & w_il[0];				// n8,R      (+1b1c)
	wire			w_dir_n16_r		=	w_im[2] & w_il[1];				// n16,R     (+2b4c)
	wire			w_dir_d_r		=	w_im[2] & w_il[3];				// D,R       (+0b4c)
	wire			w_ind_n8_r		=	w_im[6] & w_il[0];				// [n8, R]   (+1b4c)
	wire			w_ind_n16_r		=	w_im[6] & w_il[1];				// [n16,R]   (+2b7c)
	wire			w_ind_d_r		=	w_im[6] & w_il[3];				// [D,R]     (+0b7c)

	wire			w_dir_n8_pcr	=	w_im[3] & w_il[0];				// n8, PCR   (+1b1c)
	wire			w_dir_n16_pcr	=	w_im[3] & w_il[1];				// n16,PCR   (+2b5c)
	wire			w_ind_n8_pcr	=	w_im[7] & w_il[0];				// [n8, PCR] (+1b4c)
	wire			w_ind_n16_pcr	=	w_im[7] & w_il[1];				// [n16,PCR] (+2b8c)
	wire			w_ind_n16		=	w_im[7] & w_il[3] & w_rr[0];	// [n16]     (+2b5c)

	wire			w_idx_x			=	w_rr[0];
	wire			w_idx_y			=	w_rr[1];
	wire			w_idx_u			=	w_rr[2];
	wire			w_idx_s			=	w_rr[3];

	/*-----------------------------------------------------------------------------------
		internal signals
	-----------------------------------------------------------------------------------*/
	wire			w_start			=	i_AmIdx;
	wire			w_opdec			=	r_ST[i_RegSel][1];

	// ,R+ / ,R++ / ,-R / ,--R / [,R++] / [,--R]
	wire			w_r_i			=	w_dir_r_i|w_dir_r_i2|w_ind_r_i2;
	wire			w_r_d			=	w_dir_r_d|w_dir_r_d2|w_ind_r_d2;
	wire			w_dir_r_i_d		=	w_dir_r_i|w_dir_r_i2|w_dir_r_d|w_dir_r_d2;
	wire			w_r_i_d			=	w_r_i|w_r_d;
	wire			w_r_i_d_j		=	r_ST[i_RegSel][3] & (w_dir_r_i|w_dir_r_d);
	wire			w_r_i_d_inc_aob	=	r_ST[i_RegSel][10];

	// ,R / B,R / A,R / [,R] / [B,R] / [A,R]
	wire			w_dir_ind_0_r	=	w_dir_0_r|w_ind_0_r;
	wire			w_dir_r_br_ar	=	w_dir_0_r|w_dir_b_r|w_dir_a_r;
	wire			w_ind_r_br_ar	=	w_ind_0_r|w_ind_b_r|w_ind_a_r;
	wire			w_br_ar			=	w_dir_b_r|w_dir_a_r|w_ind_b_r|w_ind_a_r;
	wire			w_r_br_ar		=	w_dir_r_br_ar|w_ind_r_br_ar;
	wire			w_ind_r_ar_br_j	=	r_ST[i_RegSel][17] & w_ind_r_br_ar;

	// n8,R / n16,R / D,R / [n8,R] / [n16,R] / [D,R]
	wire			w_dir_n16r_dr	=	w_dir_n16_r|w_dir_d_r;
	wire			w_ind_n16r_dr	=	w_ind_n16_r|w_ind_d_r;
	wire			w_n8r			=	w_dir_n8_r|w_ind_n8_r;
	wire			w_n16r_dr		=	w_dir_n16r_dr|w_ind_n16r_dr;
	wire			w_ind_n8r_j		=	r_ST[i_RegSel][20] & w_ind_n8_r;
	wire			w_ind_n16r_dr_j	=	r_ST[i_RegSel][29] & w_ind_n16r_dr;

	// n8,PCR / n16,PCR / [n8,PCR] / [n16,PCR] / [n16]
	wire			w_n8_pcr		=	w_dir_n8_pcr|w_ind_n8_pcr;
	wire			w_n16_pcr		=	w_dir_n16_pcr|w_ind_n16_pcr;
	wire			w_n16_j1		=	r_ST[i_RegSel][23] & w_ind_n16;
	wire			w_ind_n8_pcr_j	=	r_ST[i_RegSel][20] & w_ind_n8_pcr;
	wire			w_ind_n16_pcr_j	=	r_ST[i_RegSel][29] & w_ind_n16_pcr;
	wire			w_ind_n16_j2	=	r_ST[i_RegSel][29] & w_ind_n16;

	wire			w_ind_j			=	w_ind_r_ar_br_j		|
										w_ind_n8r_j			|
										w_ind_n16r_dr_j		|
										w_ind_n8_pcr_j		|
										w_ind_n16_pcr_j		|
										w_ind_n16_j2;

	wire			w_out_r			=	r_ST[i_RegSel][2] & w_r_i | r_ST[i_RegSel][6] & w_r_d	|
										r_ST[i_RegSel][17]										|
										r_ST[i_RegSel][20] & ~w_n8_pcr							|
										r_ST[i_RegSel][29] & ~(w_n16_pcr|w_ind_n16);

	wire			w_incdec_rl		=	r_ST[i_RegSel][2] | r_ST[i_RegSel][4];
	wire			w_incdec_rh		=	r_ST[i_RegSel][3] | r_ST[i_RegSel][5];

	wire			w_inc_xl		=	w_incdec_rl & w_r_i & w_idx_x;
	wire			w_inc_xh		=	w_incdec_rh & w_r_i & w_idx_x;
	wire			w_inc_yl		=	w_incdec_rl & w_r_i & w_idx_y;
	wire			w_inc_yh		=	w_incdec_rh & w_r_i & w_idx_y;
	wire			w_inc_ul		=	w_incdec_rl & w_r_i & w_idx_u;
	wire			w_inc_uh		=	w_incdec_rh & w_r_i & w_idx_u;
	wire			w_inc_sl		=	w_incdec_rl & w_r_i & w_idx_s;
	wire			w_inc_sh		=	w_incdec_rh & w_r_i & w_idx_s;

	wire			w_dec_xl		=	w_incdec_rl & w_r_d & w_idx_x;
	wire			w_dec_xh		=	w_incdec_rh & w_r_d & w_idx_x;
	wire			w_dec_yl		=	w_incdec_rl & w_r_d & w_idx_y;
	wire			w_dec_yh		=	w_incdec_rh & w_r_d & w_idx_y;
	wire			w_dec_ul		=	w_incdec_rl & w_r_d & w_idx_u;
	wire			w_dec_uh		=	w_incdec_rh & w_r_d & w_idx_u;
	wire			w_dec_sl		=	w_incdec_rl & w_r_d & w_idx_s;
	wire			w_dec_sh		=	w_incdec_rh & w_r_d & w_idx_s;

	wire			w_inc_aob		=	w_r_i_d_inc_aob;

	/*-----------------------------------------------------------------------------------
		[State Machine]
			[    0]: fetch PB
			[    1]: decode PB, fetch next byte, branch state
			[ 2- 8]: ,R+ / ,R++ / ,-R / ,--R
			[ 9-14]: [,R++] / [,--R] / [,R] / [B,R] / [A,R] / [n8,R] / [n16,R] / [D,R] / [n8,PCR] / [n16,PCR] / [n16]
			[15-17]: ,R / B,R / A,R 
			[18-20]: n8,R / n8,PCR / n5,R
			[21-29]: n16,R / D,R / n16,PCR
	-----------------------------------------------------------------------------------*/
	wire			w_n5r_n8r_n8pcr	= w_dir_n5_r|w_n8r|w_n8_pcr;
	wire			w_n16r_dr_n16pcr= w_n16r_dr|w_n16_pcr|w_ind_n16;
	always @(posedge i_Clk or negedge i_nReset) begin
		if (!i_nReset) begin
			for (i = 0; i <= NC; i=i+1) begin
				r_ST[i] <= 0;
			end
		end
		else if (i_Proceed) begin
			if (o_EOAM)						r_ST[i_RegSel] <= 0;
			else if (w_start)				r_ST[i_RegSel][0] <= 1;
			else if (w_opdec) begin
				if (w_r_i_d)				r_ST[i_RegSel] <= r_ST[i_RegSel] << 1;
				else if (w_dir_ind_0_r)		r_ST[i_RegSel] <= 1<<17;
				else if (w_br_ar)			r_ST[i_RegSel] <= 1<<15;
				else if (w_n5r_n8r_n8pcr)	r_ST[i_RegSel] <= 1<<18;
				else if (w_n16r_dr_n16pcr)	r_ST[i_RegSel] <= 1<<21;
				else						r_ST[i_RegSel] <= 1<<31; // invalid pb 
			end
			else if (w_r_i_d_j)				r_ST[i_RegSel] <= 1<<6;
			else if (w_n16_j1)				r_ST[i_RegSel] <= 1<<28;
			else if (w_ind_j)				r_ST[i_RegSel] <= 1<<9;
			else							r_ST[i_RegSel] <= r_ST[i_RegSel] << 1;
		end
	end

	/*-----------------------------------------------------------------------------------
		[output]
	-----------------------------------------------------------------------------------*/
	assign	o_EOAM				=	r_ST[i_RegSel][8] & ~(w_ind_r_i2|w_ind_r_d2)				|
									r_ST[i_RegSel][14]											|
									r_ST[i_RegSel][17] & w_dir_r_br_ar							|
									r_ST[i_RegSel][20] & (w_dir_n5_r|w_dir_n8_r|w_dir_n8_pcr)	|
									r_ST[i_RegSel][29] & (w_dir_n16r_dr|w_dir_n16_pcr)			|
									r_ST[i_RegSel][31];	// invalid pb

	assign	o_EOI				=	o_EOAM & i_JMP;

	assign	o_LoadXH			=	w_incdec_rh & w_idx_x;
	assign	o_LoadXL			=	w_incdec_rl & w_idx_x;
	assign	o_LoadYH			=	w_incdec_rh & w_idx_y;
	assign	o_LoadYL			=	w_incdec_rl & w_idx_y;
	assign	o_LoadUH			=	w_incdec_rh & w_idx_u;
	assign	o_LoadUL			=	w_incdec_rl & w_idx_u;
	assign	o_LoadSH			=	w_incdec_rh & w_idx_s;
	assign	o_LoadSL			=	w_incdec_rl & w_idx_s;

	assign	o_LoadPC			=	o_EOAM & i_JMP;

	assign	o_IncPC				=	r_ST[i_RegSel][1] & (w_n8r|w_n16r_dr|w_n8_pcr|w_n16_pcr|w_ind_n16)	|
									r_ST[i_RegSel][22];

	assign	o_LoadAluC7			=	w_incdec_rl;
	assign	o_LoadPB			=	r_ST[i_RegSel][0];

	assign	o_HoldDIN			=	r_ST[i_RegSel][18] & w_dir_n5_r	|
									r_ST[i_RegSel][25]				|
									r_ST[i_RegSel][27];

	assign	o_VMA				=	(|r_ST[i_RegSel][5:2])												|
									r_ST[i_RegSel][1] & ~(w_dir_ind_0_r|w_n16r_dr|w_n16_pcr|w_ind_n16)	|
									r_ST[i_RegSel][11]													|
									r_ST[i_RegSel][13] & i_LEA											|
									r_ST[i_RegSel][16] & w_dir_r_br_ar & i_LEA							|
									r_ST[i_RegSel][19] & (w_dir_n5_r|w_dir_n8_r|w_dir_n8_pcr) & i_LEA	|
									r_ST[i_RegSel][28] & (w_dir_n16r_dr|w_dir_n16_pcr) & i_LEA			|
									(|r_ST[i_RegSel][26:22]);

	assign	o_AluInA_XH			=	w_incdec_rh & w_idx_x;
	assign	o_AluInA_XL			=	w_incdec_rl & w_idx_x;
	assign	o_AluInA_YH			=	w_incdec_rh & w_idx_y;
	assign	o_AluInA_YL			=	w_incdec_rl & w_idx_y;
	assign	o_AluInA_UH			=	w_incdec_rh & w_idx_u;
	assign	o_AluInA_UL			=	w_incdec_rl & w_idx_u;
	assign	o_AluInA_SH			=	w_incdec_rh & w_idx_s;
	assign	o_AluInA_SL			=	w_incdec_rl & w_idx_s;
	assign	o_AluInA_PCH		=	0;
	assign	o_AluInA_PCL		=	0;
	assign	o_AluInB_A			=	r_ST[i_RegSel][17] & (w_dir_a_r|w_ind_a_r);
	assign	o_AluInB_B			=	r_ST[i_RegSel][17] & (w_dir_b_r|w_ind_b_r);

	assign	o_AluInB_DIN		=	r_ST[i_RegSel][20];

	assign	o_AluInC_1			=	w_incdec_rl & w_r_i	|
									w_inc_aob;

	assign	o_AluInC_AluC7		=	w_incdec_rh;

	assign	o_AluOp_ADC			=	(w_incdec_rl|w_incdec_rh) & w_r_i	|
									w_inc_aob							|
									r_ST[i_RegSel][17]					|
									r_ST[i_RegSel][20];

	assign	o_AluOp_SBC			=	(w_incdec_rl|w_incdec_rh) & w_r_d;

	assign	o_ReadMemPC			=	r_ST[i_RegSel][0]	|
									r_ST[i_RegSel][21];

	assign	o_Adder16InA_X		= 	w_out_r & w_idx_x;
	assign	o_Adder16InA_Y		= 	w_out_r & w_idx_y;
	assign	o_Adder16InA_U		= 	w_out_r & w_idx_u;
	assign	o_Adder16InA_S		= 	w_out_r & w_idx_s;

	assign	o_Adder16InA_PC		= 	r_ST[i_RegSel][20] & w_n8_pcr	|
									r_ST[i_RegSel][29] & w_n16_pcr;

	assign	o_Adder16InA_AOB	=	w_inc_aob;
	assign	o_Adder16InB_D		= 	r_ST[i_RegSel][29] & (w_dir_d_r|w_ind_d_r);
	assign	o_Adder16InB_DIB16	= 	r_ST[i_RegSel][14]	|
									r_ST[i_RegSel][29] & (w_dir_n16_r|w_ind_n16_r|w_n16_pcr|w_ind_n16);

	assign	o_Adder16InB_DIB5	=	r_ST[i_RegSel][20] & w_dir_n5_r;

	assign	o_Adder16InB_ALU	=	w_inc_aob|r_ST[i_RegSel][17]		|
									r_ST[i_RegSel][20] & ~w_dir_n5_r;

	assign	o_DataBus_ALU		=	o_AluOp_ADC|o_AluOp_SBC;

	assign	o_LoadAddrOutBuf	=	w_out_r | w_inc_aob							|
									r_ST[i_RegSel][14]							|
									r_ST[i_RegSel][20] & w_n8_pcr				|
									r_ST[i_RegSel][29] & (w_n16_pcr|w_ind_n16);

	assign	o_LoadDataInBufH	=	r_ST[i_RegSel][10]	|
									r_ST[i_RegSel][21];

endmodule