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