mirror of
https://github.com/olofk/serv.git
synced 2026-03-02 17:44:43 +00:00
153 lines
5.9 KiB
Verilog
153 lines
5.9 KiB
Verilog
module serv_auto_decode
|
|
#(parameter [0:0] MDU = 1'b0)
|
|
(
|
|
input wire i_clk,
|
|
//Input
|
|
input wire i_en,
|
|
input wire i_imm30,
|
|
input wire [2:0] i_funct3,
|
|
input wire [4:0] i_opcode,
|
|
//MDU/Ext/CSR
|
|
input wire i_imm25,
|
|
output reg [2:0] o_ext_funct3,
|
|
output reg o_mdu_op,
|
|
input wire i_op20,
|
|
input wire i_op21,
|
|
input wire i_op22,
|
|
input wire i_op26,
|
|
output reg o_e_op,
|
|
output reg o_ebreak,
|
|
output reg o_ctrl_mret,
|
|
output reg o_csr_en,
|
|
output reg o_csr_addr1,
|
|
output reg o_csr_addr0,
|
|
output reg o_csr_mstatus_en,
|
|
output reg o_csr_mie_en,
|
|
output reg o_csr_mcause_en,
|
|
output reg o_csr_source1,
|
|
output reg o_csr_source0,
|
|
output reg o_csr_d_sel,
|
|
output reg o_csr_imm_en,
|
|
output reg o_rd_csr_en,
|
|
//Output
|
|
output wire o_branch_op,
|
|
output wire o_ctrl_jal_or_jalr,
|
|
output wire o_slt_or_branch,
|
|
output wire o_alu_rd_sel1,
|
|
output wire o_op_b_source,
|
|
output wire o_immdec_ctrl3,
|
|
output wire o_immdec_ctrl0,
|
|
output wire o_immdec_en0,
|
|
output wire o_immdec_ctrl1,
|
|
output wire o_bufreg_rs1_en,
|
|
output wire o_immdec_ctrl2,
|
|
output wire o_cond_branch,
|
|
output wire o_immdec_en1,
|
|
output wire o_immdec_en2,
|
|
output wire o_immdec_en3,
|
|
output wire o_bne_or_bge,
|
|
output wire o_rd_alu_en,
|
|
output wire o_sh_right,
|
|
output wire o_alu_cmp_sig,
|
|
output wire o_mem_signed,
|
|
output wire o_shift_op,
|
|
output wire o_alu_bool_op0,
|
|
output wire o_two_stage_op,
|
|
output wire o_rd_mem_en,
|
|
output wire o_dbus_en,
|
|
output wire o_bufreg_imm_en,
|
|
output wire o_alu_rd_sel0,
|
|
output wire o_bufreg_clr_lsb,
|
|
output wire o_ctrl_pc_rel,
|
|
output wire o_alu_sub,
|
|
output wire o_alu_bool_op1,
|
|
output wire o_bufreg_sh_signed,
|
|
output wire o_alu_cmp_eq,
|
|
output wire o_mem_word,
|
|
output wire o_ctrl_utype,
|
|
output wire o_mem_cmd,
|
|
output wire o_rd_op,
|
|
output wire o_alu_rd_sel2,
|
|
output wire o_mem_half);
|
|
|
|
reg imm30;
|
|
reg [2:0] funct3;
|
|
reg [4:0] opcode;
|
|
|
|
always @(posedge i_clk)
|
|
if (i_en) begin
|
|
imm30 <= i_imm30;
|
|
funct3 <= i_funct3;
|
|
opcode <= i_opcode;
|
|
end
|
|
assign o_branch_op = opcode[4];
|
|
assign o_ctrl_jal_or_jalr = o_branch_op; assign o_slt_or_branch = opcode[4] | (funct3[1] & opcode[2] & ~funct3[2]);
|
|
assign o_alu_rd_sel1 = o_slt_or_branch; assign o_op_b_source = opcode[4] | (opcode[3] & ~opcode[0]);
|
|
assign o_immdec_ctrl3 = o_op_b_source; assign o_immdec_ctrl0 = opcode[3] & ~opcode[0] & ~opcode[2];
|
|
assign o_immdec_en0 = o_immdec_ctrl0; assign o_immdec_ctrl1 = (~opcode[0] & ~opcode[4]) | (opcode[0] & ~opcode[1] & ~opcode[2]);
|
|
assign o_bufreg_rs1_en = o_immdec_ctrl1; assign o_immdec_ctrl2 = opcode[4] & ~opcode[0];
|
|
assign o_cond_branch = o_immdec_ctrl2; assign o_immdec_en1 = opcode[1] | (opcode[0] & ~opcode[4]);
|
|
assign o_immdec_en2 = opcode[0] | ~opcode[3];
|
|
assign o_immdec_en3 = opcode[1] | ~opcode[3] | (opcode[0] & ~opcode[4]) | (~opcode[0] & ~opcode[2]);
|
|
assign o_bne_or_bge = (opcode[2] & ~opcode[0]) | (funct3[0] & opcode[3] & ~opcode[0]);
|
|
assign o_rd_alu_en = o_bne_or_bge; assign o_sh_right = (funct3[2] & opcode[2]) | (opcode[4] & ~funct3[1]) | (~funct3[0] & ~funct3[2]) | (~funct3[2] & ~opcode[2]);
|
|
assign o_alu_cmp_sig = o_sh_right; assign o_mem_signed = o_sh_right; assign o_shift_op = (funct3[0] & funct3[2] & opcode[2]) | (funct3[0] & opcode[2] & ~funct3[1]);
|
|
assign o_alu_bool_op0 = o_shift_op; assign o_two_stage_op = ~opcode[2] | (funct3[0] & ~funct3[1] & ~opcode[0]) | (funct3[1] & ~funct3[2] & ~opcode[0]);
|
|
assign o_rd_mem_en = ~opcode[2] & ~opcode[4];
|
|
assign o_dbus_en = o_rd_mem_en; assign o_bufreg_imm_en = ~opcode[2] | (~funct3[0] & ~funct3[1] & ~funct3[2]);
|
|
assign o_alu_rd_sel0 = o_bufreg_imm_en; assign o_bufreg_clr_lsb = opcode[1] | (opcode[0] & ~opcode[3]) | (opcode[4] & ~opcode[0]) | (funct3[1] & opcode[2] & ~opcode[0]) | (imm30 & opcode[2] & opcode[3] & ~funct3[2] & ~opcode[0]);
|
|
assign o_ctrl_pc_rel = o_bufreg_clr_lsb; assign o_alu_sub = o_bufreg_clr_lsb; assign o_alu_bool_op1 = o_bufreg_clr_lsb; assign o_bufreg_sh_signed = (opcode[4] & ~funct3[2]) | (imm30 & opcode[2] & ~funct3[1]) | (funct3[1] & ~funct3[2] & ~opcode[2]);
|
|
assign o_alu_cmp_eq = o_bufreg_sh_signed; assign o_mem_word = o_bufreg_sh_signed; assign o_ctrl_utype = (opcode[0] & ~opcode[4]) | (opcode[3] & ~opcode[2] & ~opcode[4]);
|
|
assign o_mem_cmd = o_ctrl_utype; assign o_rd_op = opcode[0] | opcode[2] | ~opcode[3];
|
|
assign o_alu_rd_sel2 = (funct3[1] & funct3[2]) | (funct3[0] & ~opcode[2]) | (funct3[2] & opcode[2] & ~funct3[0]);
|
|
assign o_mem_half = o_alu_rd_sel2;
|
|
//MDU/CSR/Ext
|
|
reg imm25;
|
|
reg op20;
|
|
reg op21;
|
|
reg op22;
|
|
reg op26;
|
|
|
|
always @(posedge i_clk)
|
|
if (i_en) begin
|
|
imm25 <= i_imm25;
|
|
funct3 <= i_funct3;
|
|
opcode <= i_opcode;
|
|
op20 <= i_op20;
|
|
op21 <= i_op21;
|
|
op22 <= i_op22;
|
|
op26 <= i_op26;
|
|
end
|
|
|
|
assign o_mdu_op = MDU & (opcode == 5'b01100) & imm25;
|
|
assign o_ext_funct3 = funct3;
|
|
assign o_ebreak = op20;
|
|
assign o_ctrl_mret = opcode[4] & opcode[2] & !(|funct3) & op21;
|
|
assign o_e_op = opcode[4] & opcode[2] & !(|funct3) & !op21;
|
|
/* assign o_rd_csr_en = opcode[4] & opcode[2] & (|funct3);
|
|
assign o_csr_en = op20 | (op26 & !op21);
|
|
assign o_csr_mstatus_en = !op26 & !op22;
|
|
assign o_csr_mie_en = !op26 & op22 & !op20;
|
|
assign o_csr_mcause_en = op21 & !op20;
|
|
assign o_csr_source1 = funct3[1];
|
|
assign o_csr_source0 = funct3[0];
|
|
assign o_csr_d_sel = funct3[2];
|
|
assign o_csr_imm_en = opcode[4] & opcode[2] & funct3[2];
|
|
assign o_csr_addr1 = op26 & op20;
|
|
assign o_csr_addr0 = !op26 | op21;
|
|
*/
|
|
assign o_rd_csr_en = 1'b0;
|
|
assign o_csr_en = 1'b0;
|
|
assign o_csr_mstatus_en = 1'b0;
|
|
assign o_csr_mie_en = 1'b0;
|
|
assign o_csr_mcause_en = 1'b0;
|
|
assign o_csr_source1 = 1'b0;
|
|
assign o_csr_source0 = 1'b0;
|
|
assign o_csr_d_sel = 1'b0;
|
|
assign o_csr_imm_en = 1'b0;
|
|
assign o_csr_addr1 = 1'b0;
|
|
assign o_csr_addr0 = 1'b0;
|
|
|
|
|
|
endmodule
|