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
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX