Files
neulacpu/lacpu/rtl/mycpu/inst_decoder.v

538 lines
21 KiB
Verilog

module inst_decoder(
input [31:0] inst,
output src1_is_pc,
output src2_is_imm,
output src2_is_4,
output src_reg_is_rd,
output [ 4:0] rj,
output [ 4:0] rk,
output [ 4:0] rd,
output [31:0] imm,
output [ 4:0] dest,
// alu
output [11:0] alu_op,
// mul div
output [ 3:0] mul_div_op,
output mul_div_sign,
// branch
output [ 8:0] branch_op,
output [ 5:0] load_op,
output [ 2:0] store_op,
// csr
input excp_adef,
input [ 1:0] csr_plv,
input csr_has_int,
output csr_we,
output [ 6:0] csr_op,
output [13:0] csr_addr,
output csr_wdata_sel,
output [31:0] csr_vec_l,
output reg_we
);
wire dest_is_r1;
wire dest_is_rj;
wire [ 5:0] op_31_26;
wire [ 3:0] op_25_22;
wire [ 1:0] op_21_20;
wire [ 4:0] op_19_15;
wire [63:0] op_31_26_d;
wire [15:0] op_25_22_d;
wire [ 3:0] op_21_20_d;
wire [31:0] op_19_15_d;
wire [31:0] rd_d;
wire [31:0] rj_d;
wire [31:0] rk_d;
wire [11:0] i12;
wire [13:0] i14;
wire [19:0] i20;
wire [15:0] i16;
wire [25:0] i26;
wire [13:0] csr_idx;
wire inst_add_w;
wire inst_sub_w;
wire inst_slt;
wire inst_sltu;
wire inst_nor;
wire inst_and;
wire inst_or;
wire inst_xor;
wire inst_lu12i_w;
wire inst_addi_w;
wire inst_slti;
wire inst_sltui;
wire inst_pcaddi;
wire inst_pcaddu12i;
//wire inst_andn;
//wire inst_orn;
wire inst_andi;
wire inst_ori;
wire inst_xori;
wire inst_mul_w;
wire inst_mulh_w;
wire inst_mulh_wu;
wire inst_div_w;
wire inst_mod_w;
wire inst_div_wu;
wire inst_mod_wu;
wire inst_slli_w;
wire inst_srli_w;
wire inst_srai_w;
wire inst_sll_w;
wire inst_srl_w;
wire inst_sra_w;
wire inst_jirl;
wire inst_b;
wire inst_bl;
wire inst_beq;
wire inst_bne;
wire inst_blt;
wire inst_bge;
wire inst_bltu;
wire inst_bgeu;
wire inst_ll_w;
wire inst_sc_w;
wire inst_ld_b;
wire inst_ld_bu;
wire inst_ld_h;
wire inst_ld_hu;
wire inst_ld_w;
wire inst_st_b;
wire inst_st_h;
wire inst_st_w;
wire inst_syscall;
wire inst_break;
wire inst_csrrd;
wire inst_csrwr;
wire inst_csrxchg;
wire inst_ertn;
wire inst_rdcntid_w;
wire inst_rdcntvl_w;
wire inst_rdcntvh_w;
//wire inst_idle;
//wire inst_tlbsrch;
//wire inst_tlbrd;
//wire inst_tlbwr;
//wire inst_tlbfill;
//wire inst_invtlb;
//wire inst_cacop;
//wire inst_preld;
wire inst_dbar;
wire inst_ibar;
wire need_ui5;
wire need_si12;
wire need_ui12;
wire need_si14_pc;
wire need_si16_pc;
wire need_si20;
wire need_si20_pc;
wire need_si26_pc;
wire inst_valid;
wire excp_ine;
wire kernel_inst;
wire excp_ipe;
assign op_31_26 = inst[31:26];
assign op_25_22 = inst[25:22];
assign op_21_20 = inst[21:20];
assign op_19_15 = inst[19:15];
assign rd = inst[ 4: 0];
assign rj = inst[ 9: 5];
assign rk = inst[14:10];
assign i12 = inst[21:10];
assign i14 = inst[23:10];
assign i20 = inst[24: 5];
assign i16 = inst[25:10];
assign i26 = {inst[ 9: 0], inst[25:10]};
assign csr_idx = inst[23:10];
decoder_6_64 u_dec0(.in(op_31_26 ), .out(op_31_26_d ));
decoder_4_16 u_dec1(.in(op_25_22 ), .out(op_25_22_d ));
decoder_2_4 u_dec2(.in(op_21_20 ), .out(op_21_20_d ));
decoder_5_32 u_dec3(.in(op_19_15 ), .out(op_19_15_d ));
decoder_5_32 u_dec4(.in(rd ), .out(rd_d ));
decoder_5_32 u_dec5(.in(rj ), .out(rj_d ));
decoder_5_32 u_dec6(.in(rk ), .out(rk_d ));
assign inst_add_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h00];
assign inst_sub_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h02];
assign inst_slt = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h04];
assign inst_sltu = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h05];
assign inst_nor = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h08];
assign inst_and = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h09];
assign inst_or = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h0a];
assign inst_xor = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h0b];
//assign inst_orn = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h0c];
//assign inst_andn = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h0d];
assign inst_sll_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h0e];
assign inst_srl_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h0f];
assign inst_sra_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h10];
assign inst_mul_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h18];
assign inst_mulh_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h19];
assign inst_mulh_wu = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h1a];
assign inst_div_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h2] & op_19_15_d[5'h00];
assign inst_mod_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h2] & op_19_15_d[5'h01];
assign inst_div_wu = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h2] & op_19_15_d[5'h02];
assign inst_mod_wu = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h2] & op_19_15_d[5'h03];
assign inst_break = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h2] & op_19_15_d[5'h14];
assign inst_syscall = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h2] & op_19_15_d[5'h16];
assign inst_slli_w = op_31_26_d[6'h00] & op_25_22_d[4'h1] & op_21_20_d[2'h0] & op_19_15_d[5'h01];
assign inst_srli_w = op_31_26_d[6'h00] & op_25_22_d[4'h1] & op_21_20_d[2'h0] & op_19_15_d[5'h09];
assign inst_srai_w = op_31_26_d[6'h00] & op_25_22_d[4'h1] & op_21_20_d[2'h0] & op_19_15_d[5'h11];
//assign inst_idle = op_31_26_d[6'h01] & op_25_22_d[4'h9] & op_21_20_d[2'h0] & op_19_15_d[5'h11];
//assign inst_invtlb = op_31_26_d[6'h01] & op_25_22_d[4'h9] & op_21_20_d[2'h0] & op_19_15_d[5'h13];
assign inst_dbar = op_31_26_d[6'h0e] & op_25_22_d[4'h1] & op_21_20_d[2'h3] & op_19_15_d[5'h04];
assign inst_ibar = op_31_26_d[6'h0e] & op_25_22_d[4'h1] & op_21_20_d[2'h3] & op_19_15_d[5'h05];
assign inst_slti = op_31_26_d[6'h00] & op_25_22_d[4'h8];
assign inst_sltui = op_31_26_d[6'h00] & op_25_22_d[4'h9];
assign inst_addi_w = op_31_26_d[6'h00] & op_25_22_d[4'ha];
assign inst_andi = op_31_26_d[6'h00] & op_25_22_d[4'hd];
assign inst_ori = op_31_26_d[6'h00] & op_25_22_d[4'he];
assign inst_xori = op_31_26_d[6'h00] & op_25_22_d[4'hf];
assign inst_ld_b = op_31_26_d[6'h0a] & op_25_22_d[4'h0];
assign inst_ld_h = op_31_26_d[6'h0a] & op_25_22_d[4'h1];
assign inst_ld_w = op_31_26_d[6'h0a] & op_25_22_d[4'h2];
assign inst_st_b = op_31_26_d[6'h0a] & op_25_22_d[4'h4];
assign inst_st_h = op_31_26_d[6'h0a] & op_25_22_d[4'h5];
assign inst_st_w = op_31_26_d[6'h0a] & op_25_22_d[4'h6];
assign inst_ld_bu = op_31_26_d[6'h0a] & op_25_22_d[4'h8];
assign inst_ld_hu = op_31_26_d[6'h0a] & op_25_22_d[4'h9];
//assign inst_cacop = op_31_26_d[6'h01] & op_25_22_d[4'h8];
//assign inst_preld = op_31_26_d[6'h0a] & op_25_22_d[4'hb];
assign inst_jirl = op_31_26_d[6'h13];
assign inst_b = op_31_26_d[6'h14];
assign inst_bl = op_31_26_d[6'h15];
assign inst_beq = op_31_26_d[6'h16];
assign inst_bne = op_31_26_d[6'h17];
assign inst_blt = op_31_26_d[6'h18];
assign inst_bge = op_31_26_d[6'h19];
assign inst_bltu = op_31_26_d[6'h1a];
assign inst_bgeu = op_31_26_d[6'h1b];
assign inst_lu12i_w = op_31_26_d[6'h05] & ~inst[25];
assign inst_pcaddi = op_31_26_d[6'h06] & ~inst[25];
assign inst_pcaddu12i = op_31_26_d[6'h07] & ~inst[25];
assign inst_csrxchg = op_31_26_d[6'h01] & ~inst[25] & ~inst[24] & (~rj_d[5'h00] & ~rj_d[5'h01]); //rj != 0,1
assign inst_ll_w = op_31_26_d[6'h08] & ~inst[25] & ~inst[24];
assign inst_sc_w = op_31_26_d[6'h08] & ~inst[25] & inst[24];
assign inst_csrrd = op_31_26_d[6'h01] & ~inst[25] & ~inst[24] & rj_d[5'h00];
assign inst_csrwr = op_31_26_d[6'h01] & ~inst[25] & ~inst[24] & rj_d[5'h01];
assign inst_rdcntid_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h0] & op_19_15_d[5'h00] & rk_d[5'h18] & rd_d[5'h00];
assign inst_rdcntvl_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h0] & op_19_15_d[5'h00] & rk_d[5'h18] & rj_d[5'h00] & !rd_d[5'h00];
assign inst_rdcntvh_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h0] & op_19_15_d[5'h00] & rk_d[5'h19] & rj_d[5'h00];
assign inst_ertn = op_31_26_d[6'h01] & op_25_22_d[4'h9] & op_21_20_d[2'h0] & op_19_15_d[5'h10] & rk_d[5'h0e] & rj_d[5'h00] & rd_d[5'h00];
//assign inst_tlbsrch = op_31_26_d[6'h01] & op_25_22_d[4'h9] & op_21_20_d[2'h0] & op_19_15_d[5'h10] & rk_d[5'h0a] & rj_d[5'h00] & rd_d[5'h00];
//assign inst_tlbrd = op_31_26_d[6'h01] & op_25_22_d[4'h9] & op_21_20_d[2'h0] & op_19_15_d[5'h10] & rk_d[5'h0b] & rj_d[5'h00] & rd_d[5'h00];
//assign inst_tlbwr = op_31_26_d[6'h01] & op_25_22_d[4'h9] & op_21_20_d[2'h0] & op_19_15_d[5'h10] & rk_d[5'h0c] & rj_d[5'h00] & rd_d[5'h00];
//assign inst_tlbfill = op_31_26_d[6'h01] & op_25_22_d[4'h9] & op_21_20_d[2'h0] & op_19_15_d[5'h10] & rk_d[5'h0d] & rj_d[5'h00] & rd_d[5'h00];
assign src_reg_is_rd = inst_beq |
inst_bne |
inst_blt |
inst_bltu |
inst_bge |
inst_bgeu |
inst_st_b |
inst_st_h |
inst_st_w |
inst_sc_w |
inst_csrwr |
inst_csrxchg;
assign src1_is_pc = inst_jirl |
inst_bl |
inst_pcaddi |
inst_pcaddu12i;
assign src2_is_imm = inst_slli_w |
inst_srli_w |
inst_srai_w |
inst_addi_w |
inst_slti |
inst_sltui |
inst_andi |
inst_ori |
inst_xori |
inst_pcaddi |
inst_pcaddu12i |
inst_ld_b |
inst_ld_h |
inst_ld_w |
inst_ld_bu |
inst_ld_hu |
inst_st_b |
inst_st_h |
inst_st_w |
inst_ll_w |
inst_sc_w |
inst_lu12i_w ;
//inst_cacop |
//inst_preld ;
assign src2_is_4 = inst_jirl |
inst_bl;
assign dest_is_r1 = inst_bl;
assign dest_is_rj = inst_rdcntid_w;
assign dest = (dest_is_r1) ? 5'd1 :
(dest_is_rj) ? rj :
rd;
// alu_op
assign alu_op[ 0] = inst_add_w |
inst_addi_w |
//inst_ld_b |
//inst_ld_h |
//inst_ld_w |
//inst_st_b |
//inst_st_h |
//inst_st_w |
//inst_ld_bu |
//inst_ld_hu |
//inst_ll_w |
//inst_sc_w |
inst_jirl |
inst_bl |
inst_pcaddi |
inst_pcaddu12i;
//inst_cacop |
//inst_preld ;
assign alu_op[ 1] = inst_sub_w;
assign alu_op[ 2] = inst_slt | inst_slti;
assign alu_op[ 3] = inst_sltu | inst_sltui;
assign alu_op[ 4] = inst_and | inst_andi;
assign alu_op[ 5] = inst_nor;
assign alu_op[ 6] = inst_or | inst_ori;
assign alu_op[ 7] = inst_xor | inst_xori;
assign alu_op[ 8] = inst_sll_w | inst_slli_w;
assign alu_op[ 9] = inst_srl_w | inst_srli_w;
assign alu_op[10] = inst_sra_w | inst_srai_w;
assign alu_op[11] = inst_lu12i_w;
//assign alu_op[12] = inst_andn;
//assign alu_op[13] = inst_orn;
// imm
assign need_ui5 = inst_slli_w | inst_srli_w | inst_srai_w;
assign need_si12 = inst_addi_w |
inst_ld_b |
inst_ld_h |
inst_ld_w |
inst_st_b |
inst_st_h |
inst_st_w |
inst_ld_bu |
inst_ld_hu |
inst_slti |
inst_sltui;
//inst_cacop |
//inst_preld ;
assign need_ui12 = inst_andi | inst_ori | inst_xori;
assign need_si14_pc = inst_ll_w | inst_sc_w;
assign need_si16_pc = inst_jirl |
inst_beq |
inst_bne |
inst_blt |
inst_bge |
inst_bltu |
inst_bgeu;
assign need_si20 = inst_lu12i_w | inst_pcaddu12i;
assign need_si20_pc = inst_pcaddi;
assign need_si26_pc = inst_b | inst_bl;
assign imm = ({32{need_ui5 }} & {27'b0, rk} ) |
({32{need_si12 }} & {{20{i12[11]}}, i12} ) |
({32{need_ui12 }} & {20'b0, i12} ) |
({32{need_si14_pc}} & {{16{i14[13]}}, i14, 2'b0}) |
({32{need_si16_pc}} & {{14{i16[15]}}, i16, 2'b0}) |
({32{need_si20 }} & {i20, 12'b0} ) |
({32{need_si20_pc}} & {{10{i20[19]}}, i20, 2'b0}) |
({32{need_si26_pc}} & {{ 4{i26[25]}}, i26, 2'b0}) ;
// mul_div
assign mul_div_op[ 0] = inst_mul_w;
assign mul_div_op[ 1] = inst_mulh_w | inst_mulh_wu;
assign mul_div_op[ 2] = inst_div_w | inst_div_wu;
assign mul_div_op[ 3] = inst_mod_w | inst_mod_wu;
assign mul_div_sign = inst_mul_w | inst_mulh_w | inst_div_w | inst_mod_w;
// branch_op
assign branch_op = {inst_beq,
inst_bne,
inst_blt,
inst_bge,
inst_bltu,
inst_bgeu,
inst_jirl,
inst_bl,
inst_b
};
// load_op store_op
assign load_op = {inst_ld_b,
inst_ld_h,
inst_ld_w,
inst_ld_bu,
inst_ld_hu,
inst_ll_w
};
assign store_op = {inst_st_b,
inst_st_h,
inst_st_w
};
assign reg_we = ~inst_st_b &
~inst_st_h &
~inst_st_w &
~inst_beq &
~inst_bne &
~inst_blt &
~inst_bge &
~inst_bltu &
~inst_bgeu &
~inst_b &
~inst_syscall &
//~inst_tlbsrch &
//~inst_tlbrd &
//~inst_tlbwr &
//~inst_tlbfill &
//~inst_invtlb &
//~inst_cacop &
//~inst_preld &
~inst_dbar &
~inst_ibar ;
// csr
assign csr_we = inst_csrwr | inst_csrxchg;
assign csr_op = {inst_csrrd,
inst_csrwr,
inst_csrxchg,
inst_rdcntid_w,
inst_rdcntvh_w,
inst_rdcntvl_w,
inst_sc_w
};
assign csr_addr = inst[23:10];
assign csr_wdata_sel = inst_csrxchg;
assign csr_vec_l = {25'b0, excp_adef, excp_ipe, excp_ine, inst_break, inst_syscall, inst_ertn, csr_has_int};
assign inst_valid = inst_add_w |
inst_sub_w |
inst_slt |
inst_sltu |
inst_nor |
inst_and |
inst_or |
inst_xor |
inst_sll_w |
inst_srl_w |
inst_sra_w |
inst_mul_w |
inst_mulh_w |
inst_mulh_wu |
inst_div_w |
inst_mod_w |
inst_div_wu |
inst_mod_wu |
inst_break |
inst_syscall |
inst_slli_w |
inst_srli_w |
inst_srai_w |
//inst_idle |
inst_slti |
inst_sltui |
inst_addi_w |
inst_andi |
inst_ori |
inst_xori |
inst_ld_b |
inst_ld_h |
inst_ld_w |
inst_st_b |
inst_st_h |
inst_st_w |
inst_ld_bu |
inst_ld_hu |
inst_ll_w |
inst_sc_w |
inst_jirl |
inst_b |
inst_bl |
inst_beq |
inst_bne |
inst_blt |
inst_bge |
inst_bltu |
inst_bgeu |
inst_lu12i_w |
inst_pcaddu12i |
inst_csrrd |
inst_csrwr |
inst_csrxchg |
inst_rdcntid_w |
inst_rdcntvh_w |
inst_rdcntvl_w |
inst_ertn |
//inst_cacop |
//inst_preld |
inst_dbar |
inst_ibar ;
//inst_tlbsrch |
//inst_tlbrd |
//inst_tlbwr |
//inst_tlbfill |
//(inst_invtlb && (rd == 5'd0 ||
// rd == 5'd1 ||
// rd == 5'd2 ||
// rd == 5'd3 ||
// rd == 5'd4 ||
// rd == 5'd5 ||
// rd == 5'd6 )); //invtlb valid op
assign excp_ine = ~inst_valid;
assign kernel_inst = inst_csrrd |
inst_csrwr |
inst_csrxchg |
//inst_cacop |
//inst_tlbsrch |
//inst_tlbrd |
//inst_tlbwr |
//inst_tlbfill |
//inst_invtlb |
inst_ertn ;
//inst_idle ;
assign excp_ipe = kernel_inst && (csr_plv == 2'b11);
endmodule