mirror of
https://github.com/olofk/serv.git
synced 2025-04-22 12:57:09 -04:00
pre/post works. mem broken
This commit is contained in:
parent
e59fe5346a
commit
2b7bddbb08
7 changed files with 1605 additions and 305 deletions
|
@ -3,65 +3,26 @@ module serv_decode
|
|||
#(parameter [0:0] PRE_REGISTER = 1,
|
||||
parameter [0:0] MDU = 0)
|
||||
(
|
||||
input wire clk,
|
||||
input wire clk,
|
||||
//Input
|
||||
input wire [31:2] i_wb_rdt,
|
||||
input wire i_wb_en,
|
||||
input wire i_wb_en,
|
||||
//To state
|
||||
output reg o_sh_right,
|
||||
output reg o_bne_or_bge,
|
||||
output reg o_cond_branch,
|
||||
output reg o_e_op,
|
||||
output reg o_ebreak,
|
||||
output reg o_branch_op,
|
||||
output reg o_shift_op,
|
||||
output reg o_slt_or_branch,
|
||||
output reg o_rd_op,
|
||||
output reg o_two_stage_op,
|
||||
output reg o_dbus_en,
|
||||
//MDU
|
||||
output reg o_mdu_op,
|
||||
//Extension
|
||||
output reg [2:0] o_ext_funct3,
|
||||
//To bufreg
|
||||
output reg o_bufreg_rs1_en,
|
||||
output reg o_bufreg_imm_en,
|
||||
output reg o_bufreg_clr_lsb,
|
||||
output reg o_bufreg_sh_signed,
|
||||
output reg o_e_op,//xx
|
||||
output reg o_ebreak,//xx
|
||||
//To ctrl
|
||||
output reg o_ctrl_jal_or_jalr,
|
||||
output reg o_ctrl_utype,
|
||||
output reg o_ctrl_pc_rel,
|
||||
output reg o_ctrl_mret,
|
||||
//To alu
|
||||
output reg o_alu_sub,
|
||||
output reg [1:0] o_alu_bool_op,
|
||||
output reg o_alu_cmp_eq,
|
||||
output reg o_alu_cmp_sig,
|
||||
output reg [2:0] o_alu_rd_sel,
|
||||
//To mem IF
|
||||
output reg o_mem_signed,
|
||||
output reg o_mem_word,
|
||||
output reg o_mem_half,
|
||||
output reg o_mem_cmd,
|
||||
output reg o_ctrl_mret,//xx
|
||||
//To CSR
|
||||
output reg o_csr_en,
|
||||
output reg [1:0] o_csr_addr,
|
||||
output reg o_csr_mstatus_en,
|
||||
output reg o_csr_mie_en,
|
||||
output reg o_csr_mcause_en,
|
||||
output reg [1:0] o_csr_source,
|
||||
output reg o_csr_d_sel,
|
||||
output reg o_csr_imm_en,
|
||||
output reg o_mtval_pc,
|
||||
//To top
|
||||
output reg [3:0] o_immdec_ctrl,
|
||||
output reg [3:0] o_immdec_en,
|
||||
output reg o_op_b_source,
|
||||
output reg o_csr_en,//xx
|
||||
output reg [1:0] o_csr_addr,//xx
|
||||
output reg o_csr_mstatus_en,//xx
|
||||
output reg o_csr_mie_en,//xx
|
||||
output reg o_csr_mcause_en,//xx
|
||||
output reg [1:0] o_csr_source,//xx
|
||||
output reg o_csr_d_sel,//xx
|
||||
output reg o_csr_imm_en,//xx
|
||||
//To RF IF
|
||||
output reg o_rd_mem_en,
|
||||
output reg o_rd_csr_en,
|
||||
output reg o_rd_alu_en);
|
||||
output reg o_rd_csr_en);//xx
|
||||
|
||||
reg [4:0] opcode;
|
||||
reg [2:0] funct3;
|
||||
|
@ -73,91 +34,14 @@ module serv_decode
|
|||
reg imm25;
|
||||
reg imm30;
|
||||
|
||||
wire co_mdu_op = MDU & (opcode == 5'b01100) & imm25;
|
||||
|
||||
wire co_two_stage_op =
|
||||
~opcode[2] | (funct3[0] & ~funct3[1] & ~opcode[0] & ~opcode[4]) |
|
||||
(funct3[1] & ~funct3[2] & ~opcode[0] & ~opcode[4]) | co_mdu_op;
|
||||
wire co_shift_op = (opcode[2] & ~funct3[1]) & !co_mdu_op;
|
||||
wire co_slt_or_branch = (opcode[4] | (funct3[1] & opcode[2]) | (imm30 & opcode[2] & opcode[3] & ~funct3[2])) & !co_mdu_op;
|
||||
wire co_branch_op = opcode[4];
|
||||
wire co_dbus_en = ~opcode[2] & ~opcode[4];
|
||||
wire co_mtval_pc = opcode[4];
|
||||
wire co_mem_word = funct3[1];
|
||||
wire co_rd_alu_en = !opcode[0] & opcode[2] & !opcode[4] & !co_mdu_op;
|
||||
wire co_rd_mem_en = (!opcode[2] & !opcode[0]) | co_mdu_op;
|
||||
wire [2:0] co_ext_funct3 = funct3;
|
||||
|
||||
//jal,branch = imm
|
||||
//jalr = rs1+imm
|
||||
//mem = rs1+imm
|
||||
//shift = rs1
|
||||
wire co_bufreg_rs1_en = !opcode[4] | (!opcode[1] & opcode[0]);
|
||||
wire co_bufreg_imm_en = !opcode[2];
|
||||
|
||||
//Clear LSB of immediate for BRANCH and JAL ops
|
||||
//True for BRANCH and JAL
|
||||
//False for JALR/LOAD/STORE/OP/OPIMM?
|
||||
wire co_bufreg_clr_lsb = opcode[4] & ((opcode[1:0] == 2'b00) | (opcode[1:0] == 2'b11));
|
||||
|
||||
//Conditional branch
|
||||
//True for BRANCH
|
||||
//False for JAL/JALR
|
||||
wire co_cond_branch = !opcode[0];
|
||||
|
||||
wire co_ctrl_utype = !opcode[4] & opcode[2] & opcode[0];
|
||||
wire co_ctrl_jal_or_jalr = opcode[4] & opcode[0];
|
||||
|
||||
//PC-relative operations
|
||||
//True for jal, b* auipc
|
||||
//False for jalr, lui
|
||||
wire co_ctrl_pc_rel = (opcode[2:0] == 3'b000) |
|
||||
(opcode[1:0] == 2'b11) |
|
||||
(opcode[4:3] == 2'b00);
|
||||
//Write to RD
|
||||
//True for OP-IMM, AUIPC, OP, LUI, SYSTEM, JALR, JAL, LOAD
|
||||
//False for STORE, BRANCH, MISC-MEM
|
||||
wire co_rd_op = (opcode[2] |
|
||||
(!opcode[2] & opcode[4] & opcode[0]) |
|
||||
(!opcode[2] & !opcode[3] & !opcode[0]));
|
||||
|
||||
//
|
||||
//funct3
|
||||
//
|
||||
|
||||
wire co_sh_right = funct3[2];
|
||||
wire co_bne_or_bge = funct3[0];
|
||||
|
||||
//Matches system ops except eceall/ebreak/mret
|
||||
wire csr_op = opcode[4] & opcode[2] & (|funct3);
|
||||
|
||||
|
||||
//op20
|
||||
wire co_ebreak = op20;
|
||||
|
||||
|
||||
//opcode & funct3 & op21
|
||||
|
||||
wire co_ctrl_mret = opcode[4] & opcode[2] & op21 & !(|funct3);
|
||||
//Matches system opcodes except CSR accesses (funct3 == 0)
|
||||
//and mret (!op21)
|
||||
wire co_e_op = opcode[4] & opcode[2] & !op21 & !(|funct3);
|
||||
|
||||
//opcode & funct3 & imm30
|
||||
|
||||
wire co_bufreg_sh_signed = imm30;
|
||||
|
||||
/*
|
||||
True for sub, b*, slt*
|
||||
False for add*
|
||||
op opcode f3 i30
|
||||
b* 11000 xxx x t
|
||||
addi 00100 000 x f
|
||||
slt* 0x100 01x x t
|
||||
add 01100 000 0 f
|
||||
sub 01100 000 1 t
|
||||
*/
|
||||
wire co_alu_sub = funct3[1] | funct3[0] | (opcode[3] & imm30) | opcode[4];
|
||||
//csr_op matches system ops except eceall/ebreak/mret
|
||||
//e_op matches system opcodes except CSR accesses (funct3 == 0) and mret (!op21)
|
||||
wire co_rd_csr_en = opcode[4] & opcode[2] & (|funct3);
|
||||
wire co_ctrl_mret = opcode[4] & opcode[2] & !(|funct3) & op21;
|
||||
wire co_e_op = opcode[4] & opcode[2] & !(|funct3) & !op21;
|
||||
|
||||
/*
|
||||
Bits 26, 22, 21 and 20 are enough to uniquely identify the eight supported CSR regs
|
||||
|
@ -182,55 +66,17 @@ module serv_decode
|
|||
|
||||
//true for mtvec,mscratch,mepc and mtval
|
||||
//false for mstatus, mie, mcause
|
||||
wire csr_valid = op20 | (op26 & !op21);
|
||||
wire co_csr_en = op20 | (op26 & !op21);
|
||||
|
||||
wire co_rd_csr_en = csr_op;
|
||||
|
||||
wire co_csr_en = csr_op & csr_valid;
|
||||
wire co_csr_mstatus_en = csr_op & !op26 & !op22;
|
||||
wire co_csr_mie_en = csr_op & !op26 & op22 & !op20;
|
||||
wire co_csr_mcause_en = csr_op & op21 & !op20;
|
||||
wire co_csr_mstatus_en = !op26 & !op22;
|
||||
wire co_csr_mie_en = !op26 & op22 & !op20;
|
||||
wire co_csr_mcause_en = op21 & !op20;
|
||||
|
||||
wire [1:0] co_csr_source = funct3[1:0];
|
||||
wire co_csr_d_sel = funct3[2];
|
||||
wire co_csr_imm_en = opcode[4] & opcode[2] & funct3[2];
|
||||
wire [1:0] co_csr_addr = {op26 & op20, !op26 | op21};
|
||||
|
||||
wire co_alu_cmp_eq = funct3[2:1] == 2'b00;
|
||||
|
||||
wire co_alu_cmp_sig = ~((funct3[0] & funct3[1]) | (funct3[1] & funct3[2]));
|
||||
|
||||
wire co_mem_cmd = opcode[3];
|
||||
wire co_mem_signed = ~funct3[2];
|
||||
wire co_mem_half = funct3[0];
|
||||
|
||||
wire [1:0] co_alu_bool_op = funct3[1:0];
|
||||
|
||||
wire [3:0] co_immdec_ctrl;
|
||||
//True for S (STORE) or B (BRANCH) type instructions
|
||||
//False for J type instructions
|
||||
assign co_immdec_ctrl[0] = opcode[3:0] == 4'b1000;
|
||||
//True for OP-IMM, LOAD, STORE, JALR (I S)
|
||||
//False for LUI, AUIPC, JAL (U J)
|
||||
assign co_immdec_ctrl[1] = (opcode[1:0] == 2'b00) | (opcode[2:1] == 2'b00);
|
||||
assign co_immdec_ctrl[2] = opcode[4] & !opcode[0];
|
||||
assign co_immdec_ctrl[3] = opcode[4];
|
||||
|
||||
wire [3:0] co_immdec_en;
|
||||
assign co_immdec_en[3] = opcode[4] | opcode[3] | opcode[2] | !opcode[0]; //B I J S U
|
||||
assign co_immdec_en[2] = (opcode[4] & opcode[2]) | !opcode[3] | opcode[0]; // I J U
|
||||
assign co_immdec_en[1] = (opcode[2:1] == 2'b01) | (opcode[2] & opcode[0]) | co_csr_imm_en;// J U
|
||||
assign co_immdec_en[0] = ~co_rd_op; //B S
|
||||
|
||||
wire [2:0] co_alu_rd_sel;
|
||||
assign co_alu_rd_sel[0] = (funct3 == 3'b000); // Add/sub
|
||||
assign co_alu_rd_sel[1] = (funct3[2:1] == 2'b01); //SLT*
|
||||
assign co_alu_rd_sel[2] = funct3[2]; //Bool
|
||||
|
||||
//0 (OP_B_SOURCE_IMM) when OPIMM
|
||||
//1 (OP_B_SOURCE_RS2) when BRANCH or OP
|
||||
wire co_op_b_source = opcode[3];
|
||||
|
||||
generate
|
||||
if (PRE_REGISTER) begin
|
||||
|
||||
|
@ -248,37 +94,9 @@ module serv_decode
|
|||
end
|
||||
|
||||
always @(*) begin
|
||||
o_sh_right = co_sh_right;
|
||||
o_bne_or_bge = co_bne_or_bge;
|
||||
o_cond_branch = co_cond_branch;
|
||||
o_dbus_en = co_dbus_en;
|
||||
o_mtval_pc = co_mtval_pc;
|
||||
o_two_stage_op = co_two_stage_op;
|
||||
o_e_op = co_e_op;
|
||||
o_ebreak = co_ebreak;
|
||||
o_branch_op = co_branch_op;
|
||||
o_shift_op = co_shift_op;
|
||||
o_slt_or_branch = co_slt_or_branch;
|
||||
o_rd_op = co_rd_op;
|
||||
o_mdu_op = co_mdu_op;
|
||||
o_ext_funct3 = co_ext_funct3;
|
||||
o_bufreg_rs1_en = co_bufreg_rs1_en;
|
||||
o_bufreg_imm_en = co_bufreg_imm_en;
|
||||
o_bufreg_clr_lsb = co_bufreg_clr_lsb;
|
||||
o_bufreg_sh_signed = co_bufreg_sh_signed;
|
||||
o_ctrl_jal_or_jalr = co_ctrl_jal_or_jalr;
|
||||
o_ctrl_utype = co_ctrl_utype;
|
||||
o_ctrl_pc_rel = co_ctrl_pc_rel;
|
||||
o_ctrl_mret = co_ctrl_mret;
|
||||
o_alu_sub = co_alu_sub;
|
||||
o_alu_bool_op = co_alu_bool_op;
|
||||
o_alu_cmp_eq = co_alu_cmp_eq;
|
||||
o_alu_cmp_sig = co_alu_cmp_sig;
|
||||
o_alu_rd_sel = co_alu_rd_sel;
|
||||
o_mem_signed = co_mem_signed;
|
||||
o_mem_word = co_mem_word;
|
||||
o_mem_half = co_mem_half;
|
||||
o_mem_cmd = co_mem_cmd;
|
||||
o_csr_en = co_csr_en;
|
||||
o_csr_addr = co_csr_addr;
|
||||
o_csr_mstatus_en = co_csr_mstatus_en;
|
||||
|
@ -287,12 +105,7 @@ module serv_decode
|
|||
o_csr_source = co_csr_source;
|
||||
o_csr_d_sel = co_csr_d_sel;
|
||||
o_csr_imm_en = co_csr_imm_en;
|
||||
o_immdec_ctrl = co_immdec_ctrl;
|
||||
o_immdec_en = co_immdec_en;
|
||||
o_op_b_source = co_op_b_source;
|
||||
o_rd_csr_en = co_rd_csr_en;
|
||||
o_rd_alu_en = co_rd_alu_en;
|
||||
o_rd_mem_en = co_rd_mem_en;
|
||||
end
|
||||
|
||||
end else begin
|
||||
|
@ -310,37 +123,9 @@ module serv_decode
|
|||
|
||||
always @(posedge clk) begin
|
||||
if (i_wb_en) begin
|
||||
o_sh_right <= co_sh_right;
|
||||
o_bne_or_bge <= co_bne_or_bge;
|
||||
o_cond_branch <= co_cond_branch;
|
||||
o_e_op <= co_e_op;
|
||||
o_ebreak <= co_ebreak;
|
||||
o_two_stage_op <= co_two_stage_op;
|
||||
o_dbus_en <= co_dbus_en;
|
||||
o_mtval_pc <= co_mtval_pc;
|
||||
o_branch_op <= co_branch_op;
|
||||
o_shift_op <= co_shift_op;
|
||||
o_slt_or_branch <= co_slt_or_branch;
|
||||
o_rd_op <= co_rd_op;
|
||||
o_mdu_op <= co_mdu_op;
|
||||
o_ext_funct3 <= co_ext_funct3;
|
||||
o_bufreg_rs1_en <= co_bufreg_rs1_en;
|
||||
o_bufreg_imm_en <= co_bufreg_imm_en;
|
||||
o_bufreg_clr_lsb <= co_bufreg_clr_lsb;
|
||||
o_bufreg_sh_signed <= co_bufreg_sh_signed;
|
||||
o_ctrl_jal_or_jalr <= co_ctrl_jal_or_jalr;
|
||||
o_ctrl_utype <= co_ctrl_utype;
|
||||
o_ctrl_pc_rel <= co_ctrl_pc_rel;
|
||||
o_ctrl_mret <= co_ctrl_mret;
|
||||
o_alu_sub <= co_alu_sub;
|
||||
o_alu_bool_op <= co_alu_bool_op;
|
||||
o_alu_cmp_eq <= co_alu_cmp_eq;
|
||||
o_alu_cmp_sig <= co_alu_cmp_sig;
|
||||
o_alu_rd_sel <= co_alu_rd_sel;
|
||||
o_mem_signed <= co_mem_signed;
|
||||
o_mem_word <= co_mem_word;
|
||||
o_mem_half <= co_mem_half;
|
||||
o_mem_cmd <= co_mem_cmd;
|
||||
o_csr_en <= co_csr_en;
|
||||
o_csr_addr <= co_csr_addr;
|
||||
o_csr_mstatus_en <= co_csr_mstatus_en;
|
||||
|
@ -349,12 +134,7 @@ module serv_decode
|
|||
o_csr_source <= co_csr_source;
|
||||
o_csr_d_sel <= co_csr_d_sel;
|
||||
o_csr_imm_en <= co_csr_imm_en;
|
||||
o_immdec_ctrl <= co_immdec_ctrl;
|
||||
o_immdec_en <= co_immdec_en;
|
||||
o_op_b_source <= co_op_b_source;
|
||||
o_rd_csr_en <= co_rd_csr_en;
|
||||
o_rd_alu_en <= co_rd_alu_en;
|
||||
o_rd_mem_en <= co_rd_mem_en;
|
||||
end
|
||||
end
|
||||
|
||||
|
|
658
rtl/serv_mem_decode.v
Normal file
658
rtl/serv_mem_decode.v
Normal file
|
@ -0,0 +1,658 @@
|
|||
module serv_auto_decode
|
||||
#(parameter [0:0] MDU = 1'b0,
|
||||
parameter [0:0] CSR = 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_sub,
|
||||
output wire o_alu_bool_op1,
|
||||
output wire o_op_b_source,
|
||||
output wire o_mem_cmd,
|
||||
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_ctrl3,
|
||||
output wire o_two_stage_op,
|
||||
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_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_rd_sel1,
|
||||
output wire o_bufreg_sh_signed,
|
||||
output wire o_alu_cmp_eq,
|
||||
output wire o_mem_half,
|
||||
output wire o_ctrl_utype,
|
||||
output wire o_rd_op,
|
||||
output wire o_alu_rd_sel2,
|
||||
output wire o_mem_word);
|
||||
|
||||
(* ram_style = "block" *) reg [19:0] mem [0:511];
|
||||
reg [19:0] d;
|
||||
|
||||
initial begin
|
||||
mem[0] = 20'h46b50;
|
||||
mem[1] = 20'h00000;
|
||||
mem[2] = 20'h00000;
|
||||
mem[3] = 20'h00000;
|
||||
mem[4] = 20'h44710;
|
||||
mem[5] = 20'h68380;
|
||||
mem[6] = 20'h00000;
|
||||
mem[7] = 20'h00000;
|
||||
mem[8] = 20'h0625c;
|
||||
mem[9] = 20'h00000;
|
||||
mem[10] = 20'h00000;
|
||||
mem[11] = 20'h00000;
|
||||
mem[12] = 20'h44404;
|
||||
mem[13] = 20'h60380;
|
||||
mem[14] = 20'h00000;
|
||||
mem[15] = 20'h00000;
|
||||
mem[16] = 20'h00000;
|
||||
mem[17] = 20'h00000;
|
||||
mem[18] = 20'h00000;
|
||||
mem[19] = 20'h00000;
|
||||
mem[20] = 20'h00000;
|
||||
mem[21] = 20'h00000;
|
||||
mem[22] = 20'h00000;
|
||||
mem[23] = 20'h00000;
|
||||
mem[24] = 20'h1c26f;
|
||||
mem[25] = 20'h44157;
|
||||
mem[26] = 20'h00000;
|
||||
mem[27] = 20'h4c3c7;
|
||||
mem[28] = 20'h00000;
|
||||
mem[29] = 20'h00000;
|
||||
mem[30] = 20'h00000;
|
||||
mem[31] = 20'h00000;
|
||||
mem[32] = 20'h56b50;
|
||||
mem[33] = 20'h00000;
|
||||
mem[34] = 20'h00000;
|
||||
mem[35] = 20'h00000;
|
||||
mem[36] = 20'h41750;
|
||||
mem[37] = 20'h68380;
|
||||
mem[38] = 20'h00000;
|
||||
mem[39] = 20'h00000;
|
||||
mem[40] = 20'h1625c;
|
||||
mem[41] = 20'h00000;
|
||||
mem[42] = 20'h00000;
|
||||
mem[43] = 20'h00000;
|
||||
mem[44] = 20'h41454;
|
||||
mem[45] = 20'h60380;
|
||||
mem[46] = 20'h00000;
|
||||
mem[47] = 20'h00000;
|
||||
mem[48] = 20'h00000;
|
||||
mem[49] = 20'h00000;
|
||||
mem[50] = 20'h00000;
|
||||
mem[51] = 20'h00000;
|
||||
mem[52] = 20'h00000;
|
||||
mem[53] = 20'h00000;
|
||||
mem[54] = 20'h00000;
|
||||
mem[55] = 20'h00000;
|
||||
mem[56] = 20'h1c66f;
|
||||
mem[57] = 20'h44157;
|
||||
mem[58] = 20'h00000;
|
||||
mem[59] = 20'h4c3c7;
|
||||
mem[60] = 20'h00000;
|
||||
mem[61] = 20'h00000;
|
||||
mem[62] = 20'h00000;
|
||||
mem[63] = 20'h00000;
|
||||
mem[64] = 20'hc6350;
|
||||
mem[65] = 20'h00000;
|
||||
mem[66] = 20'h00000;
|
||||
mem[67] = 20'h00000;
|
||||
mem[68] = 20'h48f52;
|
||||
mem[69] = 20'h68380;
|
||||
mem[70] = 20'h00000;
|
||||
mem[71] = 20'h00000;
|
||||
mem[72] = 20'h8625c;
|
||||
mem[73] = 20'h00000;
|
||||
mem[74] = 20'h00000;
|
||||
mem[75] = 20'h00000;
|
||||
mem[76] = 20'h48c46;
|
||||
mem[77] = 20'h60380;
|
||||
mem[78] = 20'h00000;
|
||||
mem[79] = 20'h00000;
|
||||
mem[80] = 20'h00000;
|
||||
mem[81] = 20'h00000;
|
||||
mem[82] = 20'h00000;
|
||||
mem[83] = 20'h00000;
|
||||
mem[84] = 20'h00000;
|
||||
mem[85] = 20'h00000;
|
||||
mem[86] = 20'h00000;
|
||||
mem[87] = 20'h00000;
|
||||
mem[88] = 20'h00000;
|
||||
mem[89] = 20'h44157;
|
||||
mem[90] = 20'h00000;
|
||||
mem[91] = 20'h4c3c7;
|
||||
mem[92] = 20'h00000;
|
||||
mem[93] = 20'h00000;
|
||||
mem[94] = 20'h00000;
|
||||
mem[95] = 20'h00000;
|
||||
mem[96] = 20'h00000;
|
||||
mem[97] = 20'h00000;
|
||||
mem[98] = 20'h00000;
|
||||
mem[99] = 20'h00000;
|
||||
mem[100] = 20'h48752;
|
||||
mem[101] = 20'h68380;
|
||||
mem[102] = 20'h00000;
|
||||
mem[103] = 20'h00000;
|
||||
mem[104] = 20'h00000;
|
||||
mem[105] = 20'h00000;
|
||||
mem[106] = 20'h00000;
|
||||
mem[107] = 20'h00000;
|
||||
mem[108] = 20'h48446;
|
||||
mem[109] = 20'h60380;
|
||||
mem[110] = 20'h00000;
|
||||
mem[111] = 20'h00000;
|
||||
mem[112] = 20'h00000;
|
||||
mem[113] = 20'h00000;
|
||||
mem[114] = 20'h00000;
|
||||
mem[115] = 20'h00000;
|
||||
mem[116] = 20'h00000;
|
||||
mem[117] = 20'h00000;
|
||||
mem[118] = 20'h00000;
|
||||
mem[119] = 20'h00000;
|
||||
mem[120] = 20'h00000;
|
||||
mem[121] = 20'h44157;
|
||||
mem[122] = 20'h00000;
|
||||
mem[123] = 20'h4c3c7;
|
||||
mem[124] = 20'h00000;
|
||||
mem[125] = 20'h00000;
|
||||
mem[126] = 20'h00000;
|
||||
mem[127] = 20'h00000;
|
||||
mem[128] = 20'h46350;
|
||||
mem[129] = 20'h00000;
|
||||
mem[130] = 20'h00000;
|
||||
mem[131] = 20'h00000;
|
||||
mem[132] = 20'hc0710;
|
||||
mem[133] = 20'h68380;
|
||||
mem[134] = 20'h00000;
|
||||
mem[135] = 20'h00000;
|
||||
mem[136] = 20'h00000;
|
||||
mem[137] = 20'h00000;
|
||||
mem[138] = 20'h00000;
|
||||
mem[139] = 20'h00000;
|
||||
mem[140] = 20'hc0404;
|
||||
mem[141] = 20'h60380;
|
||||
mem[142] = 20'h00000;
|
||||
mem[143] = 20'h00000;
|
||||
mem[144] = 20'h00000;
|
||||
mem[145] = 20'h00000;
|
||||
mem[146] = 20'h00000;
|
||||
mem[147] = 20'h00000;
|
||||
mem[148] = 20'h00000;
|
||||
mem[149] = 20'h00000;
|
||||
mem[150] = 20'h00000;
|
||||
mem[151] = 20'h00000;
|
||||
mem[152] = 20'h0ca6f;
|
||||
mem[153] = 20'h44157;
|
||||
mem[154] = 20'h00000;
|
||||
mem[155] = 20'h4c3c7;
|
||||
mem[156] = 20'h00000;
|
||||
mem[157] = 20'h00000;
|
||||
mem[158] = 20'h00000;
|
||||
mem[159] = 20'h00000;
|
||||
mem[160] = 20'h56350;
|
||||
mem[161] = 20'h00000;
|
||||
mem[162] = 20'h00000;
|
||||
mem[163] = 20'h00000;
|
||||
mem[164] = 20'h41f50;
|
||||
mem[165] = 20'h68380;
|
||||
mem[166] = 20'h00000;
|
||||
mem[167] = 20'h00000;
|
||||
mem[168] = 20'h00000;
|
||||
mem[169] = 20'h00000;
|
||||
mem[170] = 20'h00000;
|
||||
mem[171] = 20'h00000;
|
||||
mem[172] = 20'h41c54;
|
||||
mem[173] = 20'h60380;
|
||||
mem[174] = 20'h00000;
|
||||
mem[175] = 20'h00000;
|
||||
mem[176] = 20'h00000;
|
||||
mem[177] = 20'h00000;
|
||||
mem[178] = 20'h00000;
|
||||
mem[179] = 20'h00000;
|
||||
mem[180] = 20'h00000;
|
||||
mem[181] = 20'h00000;
|
||||
mem[182] = 20'h00000;
|
||||
mem[183] = 20'h00000;
|
||||
mem[184] = 20'h0ce6f;
|
||||
mem[185] = 20'h44157;
|
||||
mem[186] = 20'h00000;
|
||||
mem[187] = 20'h4c3c7;
|
||||
mem[188] = 20'h00000;
|
||||
mem[189] = 20'h00000;
|
||||
mem[190] = 20'h00000;
|
||||
mem[191] = 20'h00000;
|
||||
mem[192] = 20'h00000;
|
||||
mem[193] = 20'h00000;
|
||||
mem[194] = 20'h00000;
|
||||
mem[195] = 20'h00000;
|
||||
mem[196] = 20'hc0712;
|
||||
mem[197] = 20'h68380;
|
||||
mem[198] = 20'h00000;
|
||||
mem[199] = 20'h00000;
|
||||
mem[200] = 20'h00000;
|
||||
mem[201] = 20'h00000;
|
||||
mem[202] = 20'h00000;
|
||||
mem[203] = 20'h00000;
|
||||
mem[204] = 20'hc0406;
|
||||
mem[205] = 20'h60380;
|
||||
mem[206] = 20'h00000;
|
||||
mem[207] = 20'h00000;
|
||||
mem[208] = 20'h00000;
|
||||
mem[209] = 20'h00000;
|
||||
mem[210] = 20'h00000;
|
||||
mem[211] = 20'h00000;
|
||||
mem[212] = 20'h00000;
|
||||
mem[213] = 20'h00000;
|
||||
mem[214] = 20'h00000;
|
||||
mem[215] = 20'h00000;
|
||||
mem[216] = 20'h0c26f;
|
||||
mem[217] = 20'h44157;
|
||||
mem[218] = 20'h00000;
|
||||
mem[219] = 20'h4c3c7;
|
||||
mem[220] = 20'h00000;
|
||||
mem[221] = 20'h00000;
|
||||
mem[222] = 20'h00000;
|
||||
mem[223] = 20'h00000;
|
||||
mem[224] = 20'h00000;
|
||||
mem[225] = 20'h00000;
|
||||
mem[226] = 20'h00000;
|
||||
mem[227] = 20'h00000;
|
||||
mem[228] = 20'hc1712;
|
||||
mem[229] = 20'h68380;
|
||||
mem[230] = 20'h00000;
|
||||
mem[231] = 20'h00000;
|
||||
mem[232] = 20'h00000;
|
||||
mem[233] = 20'h00000;
|
||||
mem[234] = 20'h00000;
|
||||
mem[235] = 20'h00000;
|
||||
mem[236] = 20'hc1406;
|
||||
mem[237] = 20'h60380;
|
||||
mem[238] = 20'h00000;
|
||||
mem[239] = 20'h00000;
|
||||
mem[240] = 20'h00000;
|
||||
mem[241] = 20'h00000;
|
||||
mem[242] = 20'h00000;
|
||||
mem[243] = 20'h00000;
|
||||
mem[244] = 20'h00000;
|
||||
mem[245] = 20'h00000;
|
||||
mem[246] = 20'h00000;
|
||||
mem[247] = 20'h00000;
|
||||
mem[248] = 20'h0c66f;
|
||||
mem[249] = 20'h44157;
|
||||
mem[250] = 20'h00000;
|
||||
mem[251] = 20'h4c3c7;
|
||||
mem[252] = 20'h00000;
|
||||
mem[253] = 20'h00000;
|
||||
mem[254] = 20'h00000;
|
||||
mem[255] = 20'h00000;
|
||||
mem[256] = 20'h46b50;
|
||||
mem[257] = 20'h00000;
|
||||
mem[258] = 20'h00000;
|
||||
mem[259] = 20'h00000;
|
||||
mem[260] = 20'h44710;
|
||||
mem[261] = 20'h68380;
|
||||
mem[262] = 20'h00000;
|
||||
mem[263] = 20'h00000;
|
||||
mem[264] = 20'h0625c;
|
||||
mem[265] = 20'h00000;
|
||||
mem[266] = 20'h00000;
|
||||
mem[267] = 20'h00000;
|
||||
mem[268] = 20'h44406;
|
||||
mem[269] = 20'h60380;
|
||||
mem[270] = 20'h00000;
|
||||
mem[271] = 20'h00000;
|
||||
mem[272] = 20'h00000;
|
||||
mem[273] = 20'h00000;
|
||||
mem[274] = 20'h00000;
|
||||
mem[275] = 20'h00000;
|
||||
mem[276] = 20'h00000;
|
||||
mem[277] = 20'h00000;
|
||||
mem[278] = 20'h00000;
|
||||
mem[279] = 20'h00000;
|
||||
mem[280] = 20'h1c26f;
|
||||
mem[281] = 20'h44157;
|
||||
mem[282] = 20'h00000;
|
||||
mem[283] = 20'h4c3c7;
|
||||
mem[284] = 20'h00000;
|
||||
mem[285] = 20'h00000;
|
||||
mem[286] = 20'h00000;
|
||||
mem[287] = 20'h00000;
|
||||
mem[288] = 20'h56b50;
|
||||
mem[289] = 20'h00000;
|
||||
mem[290] = 20'h00000;
|
||||
mem[291] = 20'h00000;
|
||||
mem[292] = 20'h00000;
|
||||
mem[293] = 20'h68380;
|
||||
mem[294] = 20'h00000;
|
||||
mem[295] = 20'h00000;
|
||||
mem[296] = 20'h1625c;
|
||||
mem[297] = 20'h00000;
|
||||
mem[298] = 20'h00000;
|
||||
mem[299] = 20'h00000;
|
||||
mem[300] = 20'h00000;
|
||||
mem[301] = 20'h60380;
|
||||
mem[302] = 20'h00000;
|
||||
mem[303] = 20'h00000;
|
||||
mem[304] = 20'h00000;
|
||||
mem[305] = 20'h00000;
|
||||
mem[306] = 20'h00000;
|
||||
mem[307] = 20'h00000;
|
||||
mem[308] = 20'h00000;
|
||||
mem[309] = 20'h00000;
|
||||
mem[310] = 20'h00000;
|
||||
mem[311] = 20'h00000;
|
||||
mem[312] = 20'h1c66f;
|
||||
mem[313] = 20'h44157;
|
||||
mem[314] = 20'h00000;
|
||||
mem[315] = 20'h4c3c7;
|
||||
mem[316] = 20'h00000;
|
||||
mem[317] = 20'h00000;
|
||||
mem[318] = 20'h00000;
|
||||
mem[319] = 20'h00000;
|
||||
mem[320] = 20'hc6350;
|
||||
mem[321] = 20'h00000;
|
||||
mem[322] = 20'h00000;
|
||||
mem[323] = 20'h00000;
|
||||
mem[324] = 20'h48f52;
|
||||
mem[325] = 20'h68380;
|
||||
mem[326] = 20'h00000;
|
||||
mem[327] = 20'h00000;
|
||||
mem[328] = 20'h8625c;
|
||||
mem[329] = 20'h00000;
|
||||
mem[330] = 20'h00000;
|
||||
mem[331] = 20'h00000;
|
||||
mem[332] = 20'h00000;
|
||||
mem[333] = 20'h60380;
|
||||
mem[334] = 20'h00000;
|
||||
mem[335] = 20'h00000;
|
||||
mem[336] = 20'h00000;
|
||||
mem[337] = 20'h00000;
|
||||
mem[338] = 20'h00000;
|
||||
mem[339] = 20'h00000;
|
||||
mem[340] = 20'h00000;
|
||||
mem[341] = 20'h00000;
|
||||
mem[342] = 20'h00000;
|
||||
mem[343] = 20'h00000;
|
||||
mem[344] = 20'h00000;
|
||||
mem[345] = 20'h44157;
|
||||
mem[346] = 20'h00000;
|
||||
mem[347] = 20'h4c3c7;
|
||||
mem[348] = 20'h00000;
|
||||
mem[349] = 20'h00000;
|
||||
mem[350] = 20'h00000;
|
||||
mem[351] = 20'h00000;
|
||||
mem[352] = 20'h00000;
|
||||
mem[353] = 20'h00000;
|
||||
mem[354] = 20'h00000;
|
||||
mem[355] = 20'h00000;
|
||||
mem[356] = 20'h48752;
|
||||
mem[357] = 20'h68380;
|
||||
mem[358] = 20'h00000;
|
||||
mem[359] = 20'h00000;
|
||||
mem[360] = 20'h00000;
|
||||
mem[361] = 20'h00000;
|
||||
mem[362] = 20'h00000;
|
||||
mem[363] = 20'h00000;
|
||||
mem[364] = 20'h00000;
|
||||
mem[365] = 20'h60380;
|
||||
mem[366] = 20'h00000;
|
||||
mem[367] = 20'h00000;
|
||||
mem[368] = 20'h00000;
|
||||
mem[369] = 20'h00000;
|
||||
mem[370] = 20'h00000;
|
||||
mem[371] = 20'h00000;
|
||||
mem[372] = 20'h00000;
|
||||
mem[373] = 20'h00000;
|
||||
mem[374] = 20'h00000;
|
||||
mem[375] = 20'h00000;
|
||||
mem[376] = 20'h00000;
|
||||
mem[377] = 20'h44157;
|
||||
mem[378] = 20'h00000;
|
||||
mem[379] = 20'h4c3c7;
|
||||
mem[380] = 20'h00000;
|
||||
mem[381] = 20'h00000;
|
||||
mem[382] = 20'h00000;
|
||||
mem[383] = 20'h00000;
|
||||
mem[384] = 20'h46350;
|
||||
mem[385] = 20'h00000;
|
||||
mem[386] = 20'h00000;
|
||||
mem[387] = 20'h00000;
|
||||
mem[388] = 20'hc0710;
|
||||
mem[389] = 20'h68380;
|
||||
mem[390] = 20'h00000;
|
||||
mem[391] = 20'h00000;
|
||||
mem[392] = 20'h00000;
|
||||
mem[393] = 20'h00000;
|
||||
mem[394] = 20'h00000;
|
||||
mem[395] = 20'h00000;
|
||||
mem[396] = 20'h00000;
|
||||
mem[397] = 20'h60380;
|
||||
mem[398] = 20'h00000;
|
||||
mem[399] = 20'h00000;
|
||||
mem[400] = 20'h00000;
|
||||
mem[401] = 20'h00000;
|
||||
mem[402] = 20'h00000;
|
||||
mem[403] = 20'h00000;
|
||||
mem[404] = 20'h00000;
|
||||
mem[405] = 20'h00000;
|
||||
mem[406] = 20'h00000;
|
||||
mem[407] = 20'h00000;
|
||||
mem[408] = 20'h0ca6f;
|
||||
mem[409] = 20'h44157;
|
||||
mem[410] = 20'h00000;
|
||||
mem[411] = 20'h4c3c7;
|
||||
mem[412] = 20'h00000;
|
||||
mem[413] = 20'h00000;
|
||||
mem[414] = 20'h00000;
|
||||
mem[415] = 20'h00000;
|
||||
mem[416] = 20'h56350;
|
||||
mem[417] = 20'h00000;
|
||||
mem[418] = 20'h00000;
|
||||
mem[419] = 20'h00000;
|
||||
mem[420] = 20'h51f50;
|
||||
mem[421] = 20'h68380;
|
||||
mem[422] = 20'h00000;
|
||||
mem[423] = 20'h00000;
|
||||
mem[424] = 20'h00000;
|
||||
mem[425] = 20'h00000;
|
||||
mem[426] = 20'h00000;
|
||||
mem[427] = 20'h00000;
|
||||
mem[428] = 20'h51c54;
|
||||
mem[429] = 20'h60380;
|
||||
mem[430] = 20'h00000;
|
||||
mem[431] = 20'h00000;
|
||||
mem[432] = 20'h00000;
|
||||
mem[433] = 20'h00000;
|
||||
mem[434] = 20'h00000;
|
||||
mem[435] = 20'h00000;
|
||||
mem[436] = 20'h00000;
|
||||
mem[437] = 20'h00000;
|
||||
mem[438] = 20'h00000;
|
||||
mem[439] = 20'h00000;
|
||||
mem[440] = 20'h0ce6f;
|
||||
mem[441] = 20'h44157;
|
||||
mem[442] = 20'h00000;
|
||||
mem[443] = 20'h4c3c7;
|
||||
mem[444] = 20'h00000;
|
||||
mem[445] = 20'h00000;
|
||||
mem[446] = 20'h00000;
|
||||
mem[447] = 20'h00000;
|
||||
mem[448] = 20'h00000;
|
||||
mem[449] = 20'h00000;
|
||||
mem[450] = 20'h00000;
|
||||
mem[451] = 20'h00000;
|
||||
mem[452] = 20'hc0712;
|
||||
mem[453] = 20'h68380;
|
||||
mem[454] = 20'h00000;
|
||||
mem[455] = 20'h00000;
|
||||
mem[456] = 20'h00000;
|
||||
mem[457] = 20'h00000;
|
||||
mem[458] = 20'h00000;
|
||||
mem[459] = 20'h00000;
|
||||
mem[460] = 20'h00000;
|
||||
mem[461] = 20'h60380;
|
||||
mem[462] = 20'h00000;
|
||||
mem[463] = 20'h00000;
|
||||
mem[464] = 20'h00000;
|
||||
mem[465] = 20'h00000;
|
||||
mem[466] = 20'h00000;
|
||||
mem[467] = 20'h00000;
|
||||
mem[468] = 20'h00000;
|
||||
mem[469] = 20'h00000;
|
||||
mem[470] = 20'h00000;
|
||||
mem[471] = 20'h00000;
|
||||
mem[472] = 20'h0c26f;
|
||||
mem[473] = 20'h44157;
|
||||
mem[474] = 20'h00000;
|
||||
mem[475] = 20'h4c3c7;
|
||||
mem[476] = 20'h00000;
|
||||
mem[477] = 20'h00000;
|
||||
mem[478] = 20'h00000;
|
||||
mem[479] = 20'h00000;
|
||||
mem[480] = 20'h00000;
|
||||
mem[481] = 20'h00000;
|
||||
mem[482] = 20'h00000;
|
||||
mem[483] = 20'h00000;
|
||||
mem[484] = 20'hc1712;
|
||||
mem[485] = 20'h68380;
|
||||
mem[486] = 20'h00000;
|
||||
mem[487] = 20'h00000;
|
||||
mem[488] = 20'h00000;
|
||||
mem[489] = 20'h00000;
|
||||
mem[490] = 20'h00000;
|
||||
mem[491] = 20'h00000;
|
||||
mem[492] = 20'h00000;
|
||||
mem[493] = 20'h60380;
|
||||
mem[494] = 20'h00000;
|
||||
mem[495] = 20'h00000;
|
||||
mem[496] = 20'h00000;
|
||||
mem[497] = 20'h00000;
|
||||
mem[498] = 20'h00000;
|
||||
mem[499] = 20'h00000;
|
||||
mem[500] = 20'h00000;
|
||||
mem[501] = 20'h00000;
|
||||
mem[502] = 20'h00000;
|
||||
mem[503] = 20'h00000;
|
||||
mem[504] = 20'h0c66f;
|
||||
mem[505] = 20'h44157;
|
||||
mem[506] = 20'h00000;
|
||||
mem[507] = 20'h4c3c7;
|
||||
mem[508] = 20'h00000;
|
||||
mem[509] = 20'h00000;
|
||||
mem[510] = 20'h00000;
|
||||
mem[511] = 20'h00000;
|
||||
end
|
||||
|
||||
always @(posedge i_clk)
|
||||
if (i_en)
|
||||
d <= mem[{i_imm30,i_funct3,i_opcode}];
|
||||
|
||||
assign o_branch_op = d[0];
|
||||
assign o_ctrl_jal_or_jalr = o_branch_op;
|
||||
assign o_slt_or_branch = d[1];
|
||||
assign o_alu_sub = o_slt_or_branch;
|
||||
assign o_alu_bool_op1 = o_slt_or_branch;
|
||||
assign o_op_b_source = d[2];
|
||||
assign o_mem_cmd = o_op_b_source;
|
||||
assign o_immdec_ctrl0 = d[3];
|
||||
assign o_immdec_en0 = o_immdec_ctrl0;
|
||||
assign o_immdec_ctrl1 = d[4];
|
||||
assign o_bufreg_rs1_en = o_immdec_ctrl1;
|
||||
assign o_immdec_ctrl2 = d[5];
|
||||
assign o_cond_branch = o_immdec_ctrl2;
|
||||
assign o_immdec_ctrl3 = d[6];
|
||||
assign o_two_stage_op = o_immdec_ctrl3;
|
||||
assign o_immdec_en1 = d[7];
|
||||
assign o_immdec_en2 = d[8];
|
||||
assign o_immdec_en3 = d[9];
|
||||
assign o_bne_or_bge = d[10];
|
||||
assign o_rd_alu_en = o_bne_or_bge;
|
||||
assign o_sh_right = d[11];
|
||||
assign o_alu_cmp_sig = o_sh_right;
|
||||
assign o_mem_signed = o_sh_right;
|
||||
assign o_shift_op = d[12];
|
||||
assign o_alu_bool_op0 = o_shift_op;
|
||||
assign o_rd_mem_en = d[13];
|
||||
assign o_dbus_en = o_rd_mem_en;
|
||||
assign o_bufreg_imm_en = d[14];
|
||||
assign o_alu_rd_sel0 = o_bufreg_imm_en;
|
||||
assign o_bufreg_clr_lsb = d[15];
|
||||
assign o_ctrl_pc_rel = o_bufreg_clr_lsb;
|
||||
assign o_alu_rd_sel1 = o_bufreg_clr_lsb;
|
||||
assign o_bufreg_sh_signed = d[16];
|
||||
assign o_alu_cmp_eq = o_bufreg_sh_signed;
|
||||
assign o_mem_half = o_bufreg_sh_signed;
|
||||
assign o_ctrl_utype = d[17];
|
||||
assign o_rd_op = d[18];
|
||||
assign o_alu_rd_sel2 = d[19];
|
||||
assign o_mem_word = o_alu_rd_sel2;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_en) begin
|
||||
//MDU/CSR/Ext
|
||||
o_mdu_op <= MDU & (i_opcode == 5'b01100) & i_imm25;
|
||||
o_ext_funct3 <= MDU ? i_funct3 : 3'b000;
|
||||
o_ebreak <= CSR & (i_op20);
|
||||
o_rd_csr_en <= CSR & (i_opcode[4] & i_opcode[2] & (|i_funct3));
|
||||
o_ctrl_mret <= CSR & (i_opcode[4] & i_opcode[2] & !(|i_funct3) & i_op21);
|
||||
o_e_op <= CSR & (i_opcode[4] & i_opcode[2] & !(|i_funct3) & !i_op21);
|
||||
o_csr_en <= CSR & (i_op20 | (i_op26 & !i_op21));
|
||||
o_csr_mstatus_en <= CSR & (!i_op26 & !i_op22);
|
||||
o_csr_mie_en <= CSR & (!i_op26 & i_op22 & !i_op20);
|
||||
o_csr_mcause_en <= CSR & ( i_op21 & !i_op20);
|
||||
o_csr_source1 <= CSR & (i_funct3[1]);
|
||||
o_csr_source0 <= CSR & (i_funct3[0]);
|
||||
o_csr_d_sel <= CSR & (i_funct3[2]);
|
||||
o_csr_imm_en <= CSR & (i_opcode[4] & i_opcode[2] & i_funct3[2]);
|
||||
o_csr_addr1 <= CSR & (i_op26 & i_op20);
|
||||
o_csr_addr0 <= CSR & (!i_op26 | i_op21);
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
177
rtl/serv_post_reg_decode.v
Normal file
177
rtl/serv_post_reg_decode.v
Normal file
|
@ -0,0 +1,177 @@
|
|||
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 reg o_branch_op,
|
||||
output wire o_ctrl_jal_or_jalr,
|
||||
output reg o_slt_or_branch,
|
||||
output wire o_alu_rd_sel1,
|
||||
output reg o_op_b_source,
|
||||
output wire o_immdec_ctrl3,
|
||||
output reg o_immdec_ctrl0,
|
||||
output wire o_immdec_en0,
|
||||
output reg o_immdec_ctrl1,
|
||||
output wire o_bufreg_rs1_en,
|
||||
output reg o_immdec_ctrl2,
|
||||
output wire o_cond_branch,
|
||||
output reg o_immdec_en1,
|
||||
output reg o_immdec_en2,
|
||||
output reg o_immdec_en3,
|
||||
output reg o_bne_or_bge,
|
||||
output wire o_rd_alu_en,
|
||||
output reg o_sh_right,
|
||||
output wire o_alu_cmp_sig,
|
||||
output wire o_mem_signed,
|
||||
output reg o_shift_op,
|
||||
output wire o_alu_bool_op0,
|
||||
output reg o_two_stage_op,
|
||||
output reg o_rd_mem_en,
|
||||
output wire o_dbus_en,
|
||||
output reg o_bufreg_imm_en,
|
||||
output wire o_alu_rd_sel0,
|
||||
output reg o_bufreg_clr_lsb,
|
||||
output wire o_ctrl_pc_rel,
|
||||
output wire o_alu_sub,
|
||||
output wire o_alu_bool_op1,
|
||||
output reg o_bufreg_sh_signed,
|
||||
output wire o_alu_cmp_eq,
|
||||
output wire o_mem_word,
|
||||
output reg o_ctrl_utype,
|
||||
output wire o_mem_cmd,
|
||||
output reg o_rd_op,
|
||||
output reg o_alu_rd_sel2,
|
||||
output wire o_mem_half);
|
||||
|
||||
// lajjbbbbbblllllsssassxoasssassssxssoa
|
||||
// uuaaenlglgbhwbhbhwdllornlrrdulllorrrn
|
||||
// iillqetete uu dttridlladblttrla d
|
||||
// p r uu iiii iiii u
|
||||
// c u
|
||||
//branch_op |0011111111000000000000000000000000000|
|
||||
//slt_or_branch | 11111111000000000110000000001100000|
|
||||
//op_b_source |0011111111000001110000000001111111111|
|
||||
//immdec_ctrl0 |0000111111000001110000000000000000000|
|
||||
//immdec_ctrl1 |000100000011111111111111111 1 11 |
|
||||
//immdec_ctrl2 |000011111100000000000000000 |
|
||||
//immdec_en1 |1110000000000000000000000000000000000|
|
||||
//immdec_en2 |1111000000111110001111111110000000000|
|
||||
//immdec_en3 |1110111111111111111111111110000000000|
|
||||
//bne_or_bge |000001010100000 1111111111111111111|
|
||||
//sh_right | 110011 00 10 011 010 11 |
|
||||
//shift_op | 0000000000000000 00001111 10001101|
|
||||
//two_stage_op |0011111111111111110110001110011101100|
|
||||
//rd_mem_en |0000000000111111110000000000000000000|
|
||||
//bufreg_imm_en | 11111111111111111000000001100000000|
|
||||
//bufreg_clr_lsb |0110111111000000000110110000101100011|
|
||||
//bufreg_sh_signed | 11000000100001 00 01 00 01 |
|
||||
//ctrl_utype |1100000000000001110000000000000000000|
|
||||
//rd_op |1111000000111110001111111111111111111|
|
||||
//alu_rd_sel2 | 010010100001110000000010011|
|
||||
//20 signals
|
||||
//
|
||||
always @(posedge i_clk)
|
||||
if (i_en) begin
|
||||
o_branch_op <= i_opcode[4];
|
||||
o_slt_or_branch <= i_opcode[4] | (i_funct3[1] & i_opcode[2] & ~i_funct3[2]);
|
||||
o_op_b_source <= i_opcode[4] | (i_opcode[3] & ~i_opcode[0]);
|
||||
o_immdec_ctrl0 <= i_opcode[3] & ~i_opcode[0] & ~i_opcode[2];
|
||||
o_immdec_ctrl1 <= (~i_opcode[0] & ~i_opcode[4]) | (i_opcode[0] & ~i_opcode[1] & ~i_opcode[2]);
|
||||
o_immdec_ctrl2 <= i_opcode[4] & ~i_opcode[0];
|
||||
o_immdec_en1 <= i_opcode[1] | (i_opcode[0] & ~i_opcode[4]);
|
||||
o_immdec_en2 <= i_opcode[0] | ~i_opcode[3];
|
||||
o_immdec_en3 <= i_opcode[1] | ~i_opcode[3] | (i_opcode[0] & ~i_opcode[4]) | (~i_opcode[0] & ~i_opcode[2]);
|
||||
o_bne_or_bge <= (i_opcode[2] & ~i_opcode[0]) | (i_funct3[0] & i_opcode[3] & ~i_opcode[0]);
|
||||
o_sh_right <= (i_funct3[2] & i_opcode[2]) | (i_opcode[4] & ~i_funct3[1]) | (~i_funct3[0] & ~i_funct3[2]) | (~i_funct3[2] & ~i_opcode[2]);
|
||||
o_shift_op <= (i_funct3[0] & i_funct3[2] & i_opcode[2]) | (i_funct3[0] & i_opcode[2] & ~i_funct3[1]);
|
||||
o_two_stage_op <= ~i_opcode[2] | (i_funct3[0] & ~i_funct3[1] & ~i_opcode[0]) | (i_funct3[1] & ~i_funct3[2] & ~i_opcode[0]);
|
||||
o_rd_mem_en <= ~i_opcode[2] & ~i_opcode[4];
|
||||
o_bufreg_imm_en <= ~i_opcode[2] | (~i_funct3[0] & ~i_funct3[1] & ~i_funct3[2]);
|
||||
o_bufreg_clr_lsb <= i_opcode[1] | (i_opcode[0] & ~i_opcode[3]) | (i_opcode[4] & ~i_opcode[0]) | (i_funct3[1] & i_opcode[2] & ~i_opcode[0]) | (i_imm30 & i_opcode[2] & i_opcode[3] & ~i_funct3[2] & ~i_opcode[0]);
|
||||
o_bufreg_sh_signed <= (i_opcode[4] & ~i_funct3[2]) | (i_imm30 & i_opcode[2] & ~i_funct3[1]) | (i_funct3[1] & ~i_funct3[2] & ~i_opcode[2]);
|
||||
o_ctrl_utype <= (i_opcode[0] & ~i_opcode[4]) | (i_opcode[3] & ~i_opcode[2] & ~i_opcode[4]);
|
||||
o_rd_op <= i_opcode[0] | i_opcode[2] | ~i_opcode[3];
|
||||
o_alu_rd_sel2 <= (i_funct3[1] & i_funct3[2]) | (i_funct3[0] & ~i_opcode[2]) | (i_funct3[2] & i_opcode[2] & ~i_funct3[0]);
|
||||
//MDU/CSR/Ext
|
||||
o_mdu_op <= MDU & (i_opcode == 5'b01100) & i_imm25;
|
||||
// o_ext_funct3 <= i_funct3;
|
||||
o_ebreak <= i_op20;
|
||||
o_ctrl_mret <= i_opcode[4] & i_opcode[2] & !(|i_funct3) & i_op21;
|
||||
o_e_op <= i_opcode[4] & i_opcode[2] & !(|i_funct3) & !i_op21;
|
||||
/*
|
||||
o_rd_csr_en <= i_opcode[4] & i_opcode[2] & (|i_funct3);
|
||||
o_csr_en <= i_op20 | (i_op26 & !i_op21);
|
||||
o_csr_mstatus_en <= !i_op26 & !i_op22;
|
||||
o_csr_mie_en <= !i_op26 & i_op22 & !i_op20;
|
||||
o_csr_mcause_en <= i_op21 & !i_op20;
|
||||
o_csr_source1 <= i_funct3[1];
|
||||
o_csr_source0 <= i_funct3[0];
|
||||
o_csr_d_sel <= i_funct3[2];
|
||||
o_csr_imm_en <= i_opcode[4] & i_opcode[2] & i_funct3[2];
|
||||
o_csr_addr1 <= i_op26 & i_op20;
|
||||
o_csr_addr0 <= !i_op26 | i_op21;
|
||||
*/end
|
||||
always @(*) begin
|
||||
o_ext_funct3 <= 3'd0;
|
||||
o_rd_csr_en <= 1'b0;
|
||||
o_csr_en <= 1'b0;
|
||||
o_csr_mstatus_en <= 1'b0;
|
||||
o_csr_mie_en <= 1'b0;
|
||||
o_csr_mcause_en <= 1'b0;
|
||||
o_csr_source1 <= 1'b0;
|
||||
o_csr_source0 <= 1'b0;
|
||||
o_csr_d_sel <= 1'b0;
|
||||
o_csr_imm_en <= 1'b0;
|
||||
o_csr_addr1 <= 1'b0;
|
||||
o_csr_addr0 <= 1'b0;
|
||||
end
|
||||
|
||||
assign o_ctrl_jal_or_jalr = o_branch_op;
|
||||
assign o_alu_rd_sel1 = o_slt_or_branch;
|
||||
assign o_immdec_ctrl3 = o_op_b_source;
|
||||
assign o_immdec_en0 = o_immdec_ctrl0;
|
||||
assign o_bufreg_rs1_en = o_immdec_ctrl1;
|
||||
assign o_cond_branch = o_immdec_ctrl2;
|
||||
assign o_rd_alu_en = o_bne_or_bge;
|
||||
assign o_alu_cmp_sig = o_sh_right;
|
||||
assign o_mem_signed = o_sh_right;
|
||||
assign o_alu_bool_op0 = o_shift_op;
|
||||
assign o_dbus_en = o_rd_mem_en;
|
||||
assign o_alu_rd_sel0 = o_bufreg_imm_en;
|
||||
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_alu_cmp_eq = o_bufreg_sh_signed;
|
||||
assign o_mem_word = o_bufreg_sh_signed;
|
||||
assign o_mem_cmd = o_ctrl_utype;
|
||||
assign o_mem_half = o_alu_rd_sel2;
|
||||
|
||||
|
||||
endmodule
|
152
rtl/serv_pre_reg_decode.v
Normal file
152
rtl/serv_pre_reg_decode.v
Normal file
|
@ -0,0 +1,152 @@
|
|||
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
|
162
rtl/serv_top.v
162
rtl/serv_top.v
|
@ -94,7 +94,6 @@ module serv_top
|
|||
wire alu_rd;
|
||||
wire mem_rd;
|
||||
wire csr_rd;
|
||||
wire mtval_pc;
|
||||
|
||||
wire ctrl_pc_en;
|
||||
wire jump;
|
||||
|
@ -229,71 +228,110 @@ module serv_top
|
|||
.i_rf_ready (i_rf_ready),
|
||||
.o_rf_rd_en (rd_en));
|
||||
|
||||
serv_decode
|
||||
#(.PRE_REGISTER (PRE_REGISTER),
|
||||
.MDU(MDU))
|
||||
decode
|
||||
wire pshift_op;
|
||||
wire pslt_or_branch;
|
||||
wire prd_op;
|
||||
wire ptwo_stage_op;
|
||||
wire pbufreg_rs1_en;
|
||||
wire pbufreg_imm_en;
|
||||
wire pdbus_en;
|
||||
wire pimmdec_en1;
|
||||
wire prd_alu_en;
|
||||
wire pjal_or_jalr;
|
||||
wire prd_mem_en;
|
||||
wire timmdec_ctrl3;
|
||||
|
||||
|
||||
assign shift_op = pshift_op & !mdu_op;
|
||||
assign slt_or_branch = pslt_or_branch & !mdu_op;
|
||||
assign rd_op = prd_op | rd_csr_en;
|
||||
assign two_stage_op = ptwo_stage_op & !rd_csr_en | mdu_op;
|
||||
assign bufreg_rs1_en = pbufreg_rs1_en | mdu_op;
|
||||
assign bufreg_imm_en = pbufreg_imm_en & !mdu_op;
|
||||
assign dbus_en = pdbus_en & !mdu_op;
|
||||
assign immdec_en[1] = pimmdec_en1 | csr_imm_en;
|
||||
assign rd_alu_en = prd_alu_en & !rd_csr_en & !mdu_op;
|
||||
assign jal_or_jalr = pjal_or_jalr & !rd_csr_en;
|
||||
assign rd_mem_en = prd_mem_en /*& !rd_csr_en*/ | mdu_op;
|
||||
assign immdec_ctrl[3] = timmdec_ctrl3 | rd_csr_en;
|
||||
|
||||
serv_auto_decode #(.MDU (MDU)) autodec
|
||||
(
|
||||
.clk (clk),
|
||||
.i_clk (clk),
|
||||
//Input
|
||||
.i_wb_rdt (i_ibus_rdt[31:2]),
|
||||
.i_wb_en (i_ibus_ack),
|
||||
//To state
|
||||
.o_bne_or_bge (bne_or_bge),
|
||||
.o_cond_branch (cond_branch),
|
||||
.o_dbus_en (dbus_en),
|
||||
.i_imm30 (i_ibus_rdt[30]),
|
||||
.i_funct3 (i_ibus_rdt[14:12]),
|
||||
.i_opcode (i_ibus_rdt[6:2]),
|
||||
.i_en (i_ibus_ack),
|
||||
//CSR/MDU
|
||||
.i_imm25 (i_ibus_rdt[25]),
|
||||
.o_ext_funct3 (o_ext_funct3),
|
||||
.o_mdu_op (mdu_op),
|
||||
|
||||
.i_op20 (i_ibus_rdt[20]),
|
||||
.i_op21 (i_ibus_rdt[21]),
|
||||
.i_op22 (i_ibus_rdt[22]),
|
||||
.i_op26 (i_ibus_rdt[26]),
|
||||
.o_e_op (e_op),
|
||||
.o_ebreak (ebreak),
|
||||
.o_branch_op (branch_op),
|
||||
.o_shift_op (shift_op),
|
||||
.o_slt_or_branch (slt_or_branch),
|
||||
.o_rd_op (rd_op),
|
||||
.o_sh_right (sh_right),
|
||||
.o_mdu_op (mdu_op),
|
||||
.o_two_stage_op (two_stage_op),
|
||||
//Extension
|
||||
.o_ext_funct3 (o_ext_funct3),
|
||||
|
||||
//To bufreg
|
||||
.o_bufreg_rs1_en (bufreg_rs1_en),
|
||||
.o_bufreg_imm_en (bufreg_imm_en),
|
||||
.o_bufreg_clr_lsb (bufreg_clr_lsb),
|
||||
.o_bufreg_sh_signed (bufreg_sh_signed),
|
||||
//To bufreg2
|
||||
.o_op_b_source (op_b_sel),
|
||||
//To ctrl
|
||||
.o_ctrl_jal_or_jalr (jal_or_jalr),
|
||||
.o_ctrl_utype (utype),
|
||||
.o_ctrl_pc_rel (pc_rel),
|
||||
.o_ctrl_mret (mret),
|
||||
//To alu
|
||||
.o_alu_sub (alu_sub),
|
||||
.o_alu_bool_op (alu_bool_op),
|
||||
.o_alu_cmp_eq (alu_cmp_eq),
|
||||
.o_alu_cmp_sig (alu_cmp_sig),
|
||||
.o_alu_rd_sel (alu_rd_sel),
|
||||
//To mem IF
|
||||
.o_mem_cmd (o_dbus_we),
|
||||
.o_mem_signed (mem_signed),
|
||||
.o_mem_word (mem_word),
|
||||
.o_mem_half (mem_half),
|
||||
//To CSR
|
||||
.o_csr_en (csr_en),
|
||||
.o_csr_addr (csr_addr),
|
||||
.o_csr_en (csr_en ),
|
||||
.o_csr_addr1 (csr_addr[1] ),
|
||||
.o_csr_addr0 (csr_addr[0] ),
|
||||
.o_csr_mstatus_en (csr_mstatus_en),
|
||||
.o_csr_mie_en (csr_mie_en),
|
||||
.o_csr_mcause_en (csr_mcause_en),
|
||||
.o_csr_source (csr_source),
|
||||
.o_csr_d_sel (csr_d_sel),
|
||||
.o_csr_imm_en (csr_imm_en),
|
||||
.o_mtval_pc (mtval_pc ),
|
||||
//To top
|
||||
.o_immdec_ctrl (immdec_ctrl),
|
||||
.o_immdec_en (immdec_en),
|
||||
.o_csr_mie_en (csr_mie_en ),
|
||||
.o_csr_mcause_en (csr_mcause_en ),
|
||||
.o_csr_source1 (csr_source[1] ),
|
||||
.o_csr_source0 (csr_source[0] ),
|
||||
.o_csr_d_sel (csr_d_sel ),
|
||||
.o_csr_imm_en (csr_imm_en ),
|
||||
//To RF IF
|
||||
.o_rd_mem_en (rd_mem_en),
|
||||
.o_rd_csr_en (rd_csr_en),
|
||||
.o_rd_alu_en (rd_alu_en));
|
||||
|
||||
// .o_mtval_pc (),
|
||||
//To alu
|
||||
.o_op_b_source (op_b_sel),
|
||||
.o_sh_right (sh_right ),
|
||||
.o_bne_or_bge (bne_or_bge ),
|
||||
.o_cond_branch (cond_branch ),
|
||||
.o_branch_op (branch_op ),
|
||||
.o_shift_op (pshift_op ),
|
||||
.o_slt_or_branch (pslt_or_branch),
|
||||
.o_rd_op (prd_op ),
|
||||
.o_two_stage_op (ptwo_stage_op ),
|
||||
.o_dbus_en (pdbus_en ),
|
||||
.o_bufreg_rs1_en (pbufreg_rs1_en ),
|
||||
.o_bufreg_imm_en (pbufreg_imm_en ),
|
||||
.o_bufreg_clr_lsb (bufreg_clr_lsb ),
|
||||
.o_bufreg_sh_signed (bufreg_sh_signed),
|
||||
.o_ctrl_jal_or_jalr (pjal_or_jalr ),
|
||||
.o_ctrl_utype (utype ),
|
||||
.o_ctrl_pc_rel (pc_rel ),
|
||||
.o_alu_sub (alu_sub ),
|
||||
.o_alu_bool_op1 (alu_bool_op[1]),
|
||||
.o_alu_bool_op0 (alu_bool_op[0]),
|
||||
.o_alu_cmp_eq (alu_cmp_eq ),
|
||||
.o_alu_cmp_sig (alu_cmp_sig ),
|
||||
.o_alu_rd_sel2 (alu_rd_sel[2] ),
|
||||
.o_alu_rd_sel1 (alu_rd_sel[1] ),
|
||||
.o_alu_rd_sel0 (alu_rd_sel[0] ),
|
||||
.o_mem_signed (mem_signed ),
|
||||
.o_mem_word (mem_word ),
|
||||
.o_mem_half (mem_half ),
|
||||
.o_mem_cmd (o_dbus_we ),
|
||||
.o_immdec_ctrl0 (immdec_ctrl[0]),
|
||||
.o_immdec_ctrl1 (immdec_ctrl[1]),
|
||||
.o_immdec_ctrl2 (immdec_ctrl[2]),
|
||||
.o_immdec_ctrl3 (timmdec_ctrl3),
|
||||
.o_immdec_en0 (immdec_en[0] ),
|
||||
.o_immdec_en1 (pimmdec_en1 ),
|
||||
.o_immdec_en2 (immdec_en[2] ),
|
||||
.o_immdec_en3 (immdec_en[3] ),
|
||||
.o_rd_mem_en (prd_mem_en),
|
||||
.o_rd_alu_en (prd_alu_en ));
|
||||
|
||||
|
||||
serv_immdec immdec
|
||||
(
|
||||
|
@ -431,12 +469,12 @@ module serv_top
|
|||
.i_trap (trap),
|
||||
.i_mret (mret),
|
||||
.i_mepc (o_ibus_adr[0]),
|
||||
.i_mtval_pc (mtval_pc),
|
||||
.i_mtval_pc (branch_op),
|
||||
.i_bufreg_q (bufreg_q),
|
||||
.i_bad_pc (bad_pc),
|
||||
.o_csr_pc (csr_pc),
|
||||
//CSR write port
|
||||
.i_csr_en (csr_en),
|
||||
.i_csr_en (csr_en & rd_csr_en),
|
||||
.i_csr_addr (csr_addr),
|
||||
.i_csr (csr_in),
|
||||
//RD write port
|
||||
|
@ -496,7 +534,7 @@ module serv_top
|
|||
.i_cnt3 (cnt3),
|
||||
.i_cnt7 (cnt7),
|
||||
.i_cnt_done (cnt_done),
|
||||
.i_mem_op (!mtval_pc),
|
||||
.i_mem_op (dbus_en),
|
||||
.i_mtip (i_timer_irq),
|
||||
.i_trap (trap),
|
||||
.o_new_irq (new_irq),
|
||||
|
@ -504,9 +542,9 @@ module serv_top
|
|||
.i_e_op (e_op),
|
||||
.i_ebreak (ebreak),
|
||||
.i_mem_cmd (o_dbus_we),
|
||||
.i_mstatus_en (csr_mstatus_en),
|
||||
.i_mie_en (csr_mie_en ),
|
||||
.i_mcause_en (csr_mcause_en ),
|
||||
.i_mstatus_en (rd_csr_en & csr_mstatus_en),
|
||||
.i_mie_en (rd_csr_en & csr_mie_en ),
|
||||
.i_mcause_en (rd_csr_en & csr_mcause_en ),
|
||||
.i_csr_source (csr_source),
|
||||
.i_mret (mret),
|
||||
.i_csr_d_sel (csr_d_sel),
|
||||
|
|
|
@ -11,6 +11,7 @@ filesets:
|
|||
- rtl/serv_alu.v
|
||||
- rtl/serv_csr.v
|
||||
- rtl/serv_ctrl.v
|
||||
- rtl/serv_mem_decode.v
|
||||
- rtl/serv_decode.v
|
||||
- rtl/serv_immdec.v
|
||||
- rtl/serv_mem_if.v
|
||||
|
|
494
sw/decodegen.py
Normal file
494
sw/decodegen.py
Normal file
|
@ -0,0 +1,494 @@
|
|||
from sympy.logic import SOPform
|
||||
from sympy import symbols
|
||||
from functools import partial, reduce
|
||||
from itertools import product, combinations
|
||||
import networkx as nx
|
||||
import z3
|
||||
|
||||
HEADER = """module serv_auto_decode
|
||||
#(parameter [0:0] MDU = 1'b0,
|
||||
parameter [0:0] CSR = 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
|
||||
{ports});
|
||||
|
||||
{body}
|
||||
endmodule
|
||||
"""
|
||||
|
||||
def printmap(ctrlmap):
|
||||
s = ""
|
||||
l = max([len(x) for x in ctrlmap])
|
||||
s+=' '*(l+2)+"lajjbbbbbblllllsssassxoasssassssxssoa\n"
|
||||
s+=' '*(l+2)+"uuaaenlglgbhwbhbhwdllornlrrdulllorrrn\n"
|
||||
s+=' '*(l+2)+"iillqetete uu dttridlladblttrla d\n"
|
||||
s+=' '*(l+2)+" p r uu iiii iiii u \n"
|
||||
s+=' '*(l+2)+" c u \n"
|
||||
|
||||
for k,v in ctrlmap.items():
|
||||
s += f"{k:<{l}} |{v}|\n"
|
||||
s += f"{len(ctrlmap)} signals\n"
|
||||
return s
|
||||
|
||||
def merge(d, dst, src):
|
||||
l = list(d[dst])
|
||||
for i in range(len(l)):
|
||||
if l[i] == ' ':
|
||||
l[i] = d[src][i]
|
||||
elif l[i] == '1' and d[src][i] == '0':
|
||||
raise Exception
|
||||
elif l[i] == '0' and d[src][i] == '1':
|
||||
raise Exception
|
||||
d[dst] = ''.join(l)
|
||||
d.pop(src)
|
||||
|
||||
def merge_signals(ctrlmap):
|
||||
#Merge control signals and keep track of which signals that have been combined
|
||||
|
||||
# We build a graph of signals as nodes and merge conflicts as edges. We use z3 to find
|
||||
# an optimal coloring of the graph. All nodes of the same color will have no conflicts
|
||||
# and can be merged
|
||||
|
||||
solver = z3.Optimize()
|
||||
|
||||
node_colors = {}
|
||||
|
||||
g = nx.Graph()
|
||||
|
||||
color_count = z3.Int('color_count')
|
||||
|
||||
# Create a node for every signal
|
||||
for sig in ctrlmap:
|
||||
g.add_node(sig)
|
||||
node_colors[sig] = node_color = z3.Int('color_' + sig)
|
||||
|
||||
solver.add(node_color >= 0, node_color < color_count)
|
||||
|
||||
# Conflicting signals may not get the same color
|
||||
for sig_i, sig_j in combinations(ctrlmap, 2):
|
||||
collide = any(
|
||||
i != j and ' ' not in (i, j)
|
||||
for i, j in zip(ctrlmap[sig_i], ctrlmap[sig_j])
|
||||
)
|
||||
if collide:
|
||||
g.add_edge(sig_i, sig_j)
|
||||
solver.add(node_colors[sig_i] != node_colors[sig_j])
|
||||
|
||||
# We use networkx to find the largest clique. All nodes in that clique will have to get
|
||||
# distinct colors. Since the numbering of colors is arbitrary, we can without loss of
|
||||
# generality decide a fixed numbering of the colors of that clique. This kind of
|
||||
# symmetry breaking is essential for performance here.
|
||||
for i, sig in enumerate(max(nx.find_cliques(g), key=len)):
|
||||
solver.add(node_colors[sig] == i)
|
||||
|
||||
solver.minimize(color_count)
|
||||
|
||||
if solver.check() != z3.sat:
|
||||
raise Exception("optmization failed") # Shouldn't happen
|
||||
|
||||
model = solver.model()
|
||||
|
||||
print(f"Found coloring using {model[color_count]} colors")
|
||||
|
||||
merged_signals = {}
|
||||
merge_by_color = {}
|
||||
|
||||
for signal in list(ctrlmap):
|
||||
color = model[node_colors[signal]]
|
||||
if color in merge_by_color:
|
||||
other_signal = merge_by_color[color]
|
||||
merge(ctrlmap, other_signal, signal)
|
||||
merged_signals.setdefault(other_signal, []).append(signal)
|
||||
else:
|
||||
merge_by_color[color] = signal
|
||||
|
||||
if merged_signals:
|
||||
for k,v in merged_signals.items():
|
||||
print(f"Merged {', '.join(v)} into {k}")
|
||||
return (ctrlmap, merged_signals)
|
||||
|
||||
def map2signals(ctrlmap):
|
||||
for k,v in ctrlmap.items():
|
||||
ctrl_signals = {}
|
||||
t = []
|
||||
f = []
|
||||
for i,op in enumerate(ops):
|
||||
#Only rv32i for now
|
||||
if i > 36:
|
||||
continue
|
||||
|
||||
if v[i] == '1':
|
||||
t.append(op)
|
||||
elif v[i] == '0':
|
||||
f.append(op)
|
||||
ctrl_signals[k] = (t,f)
|
||||
return ctrl_signals
|
||||
|
||||
def minterms(s):
|
||||
return list(map(partial(reduce, lambda x, y: 2*x + y), product(*([0, 1] if z == 'x' else [int(z)] for z in s))))
|
||||
|
||||
def map2minterms(bitmap):
|
||||
m = []
|
||||
falsies = []
|
||||
for i,op in enumerate(ops):
|
||||
#Only rv32i for now
|
||||
if i > 36:
|
||||
continue
|
||||
|
||||
if bitmap[i] == '1':
|
||||
m += minterms(ops[op])
|
||||
elif bitmap[i] == '0':
|
||||
falsies += minterms(ops[op])
|
||||
return (m, falsies)
|
||||
|
||||
def write_post_reg_logic_decoder(ctrlmap, merged_signals):
|
||||
signames = [
|
||||
'i_imm30',
|
||||
'i_funct3[2]',
|
||||
'i_funct3[1]',
|
||||
'i_funct3[0]',
|
||||
'i_opcode[4]',
|
||||
'i_opcode[3]',
|
||||
'i_opcode[2]',
|
||||
'i_opcode[1]',
|
||||
'i_opcode[0]',
|
||||
]
|
||||
syms = [*symbols(' '.join(signames))]
|
||||
ports = []
|
||||
body = '\n'.join('//'+x for x in printmap(ctrlmap).split('\n'))
|
||||
body += "\nalways @(posedge i_clk)\n"
|
||||
body += " if (i_en) begin\n"
|
||||
body2 =" end\n\n"
|
||||
for sig, bitmap in ctrlmap.items():
|
||||
#Find all conditions signals must be true and false
|
||||
(t, f) = map2minterms(bitmap)
|
||||
|
||||
#Use Quine-McCluskey to minimize the logic expressions needed for each
|
||||
#control signal. Don't cares are the ones that are neither listed as
|
||||
#true or false
|
||||
dc = set(range(2**9))-set(t)-set(f)
|
||||
s = SOPform(syms, t, dc)
|
||||
|
||||
ports.append(f"output reg o_{sig}")
|
||||
|
||||
#Output final control signal expression
|
||||
body += f" o_{sig} <= {s};\n"
|
||||
if sig in merged_signals:
|
||||
for alias in merged_signals[sig]:
|
||||
ports.append(f"output wire o_{alias}")
|
||||
body2 += f" assign o_{alias} = o_{sig};\n"
|
||||
|
||||
#Some extra signals
|
||||
body += " //MDU/CSR/Ext\n"
|
||||
body += " o_mdu_op <= MDU & (i_opcode == 5'b01100) & i_imm25;\n"
|
||||
body += " o_ext_funct3 <= i_funct3;\n"
|
||||
body += " o_ebreak <= i_op20;\n"
|
||||
body += " o_rd_csr_en <= i_opcode[4] & i_opcode[2] & (|i_funct3);\n"
|
||||
body += " o_ctrl_mret <= i_opcode[4] & i_opcode[2] & !(|i_funct3) & i_op21;\n"
|
||||
body += " o_e_op <= i_opcode[4] & i_opcode[2] & !(|i_funct3) & !i_op21;\n"
|
||||
body += " o_csr_en <= i_op20 | (i_op26 & !i_op21);\n"
|
||||
body += " o_csr_mstatus_en <= !i_op26 & !i_op22;\n"
|
||||
body += " o_csr_mie_en <= !i_op26 & i_op22 & !i_op20;\n"
|
||||
body += " o_csr_mcause_en <= i_op21 & !i_op20;\n"
|
||||
body += " o_csr_source1 <= i_funct3[1];\n"
|
||||
body += " o_csr_source0 <= i_funct3[0];\n"
|
||||
body += " o_csr_d_sel <= i_funct3[2];\n"
|
||||
body += " o_csr_imm_en <= i_opcode[4] & i_opcode[2] & i_funct3[2];\n"
|
||||
body += " o_csr_addr1 <= i_op26 & i_op20;\n"
|
||||
body += " o_csr_addr0 <= !i_op26 | i_op21;\n"
|
||||
|
||||
with open('serv_post_reg_decode.v', 'w') as f:
|
||||
f.write(HEADER.format(ports=',\n '.join(ports), body=body+body2+'\n'))
|
||||
|
||||
def write_pre_reg_logic_decoder(ctrlmap, merged_signals):
|
||||
signames = [
|
||||
'imm30',
|
||||
'funct3[2]',
|
||||
'funct3[1]',
|
||||
'funct3[0]',
|
||||
'opcode[4]',
|
||||
'opcode[3]',
|
||||
'opcode[2]',
|
||||
'opcode[1]',
|
||||
'opcode[0]',
|
||||
]
|
||||
syms = [*symbols(' '.join(signames))]
|
||||
ports = []
|
||||
body = """ 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
|
||||
"""
|
||||
|
||||
for sig, bitmap in ctrlmap.items():
|
||||
#Find all conditions signals must be true and false
|
||||
(t, f) = map2minterms(bitmap)
|
||||
|
||||
#Use Quine-McCluskey to minimize the logic expressions needed for each
|
||||
#control signal. Don't cares are the ones that are neither listed as
|
||||
#true or false
|
||||
dc = set(range(2**9))-set(t)-set(f)
|
||||
s = SOPform(syms, t, dc)
|
||||
|
||||
ports.append(f"output wire o_{sig}")
|
||||
|
||||
#Output final control signal expression
|
||||
body += f" assign o_{sig} = {s};\n"
|
||||
if sig in merged_signals:
|
||||
for alias in merged_signals[sig]:
|
||||
ports.append(f"output wire o_{alias}")
|
||||
body += f" assign o_{alias} = o_{sig};"
|
||||
|
||||
#Some extra signals
|
||||
body += "\n"
|
||||
body += " //MDU/CSR/Ext\n"
|
||||
body += "always @(posedge i_clk)\n"
|
||||
body += " if (i_en) begin\n"
|
||||
body += " imm25 <= i_imm25;\n"
|
||||
body += " funct3 <= i_funct3;\n"
|
||||
body += " opcode <= i_opcode;\n"
|
||||
body += " op20 <= i_op20;\n"
|
||||
body += " op21 <= i_op21;\n"
|
||||
body += " op22 <= i_op22;\n"
|
||||
body += " op26 <= i_op26;\n"
|
||||
body += " end\n"
|
||||
body += " assign o_mdu_op = MDU & (opcode == 5'b01100) & imm25;\n"
|
||||
body += " assign o_ext_funct3 = funct3;\n"
|
||||
body += " assign o_ebreak = op20;\n"
|
||||
body += " assign o_rd_csr_en = opcode[4] & opcode[2] & (|funct3);\n"
|
||||
body += " assign o_ctrl_mret = opcode[4] & opcode[2] & !(|funct3) & op21;\n"
|
||||
body += " assign o_e_op = opcode[4] & opcode[2] & !(|funct3) & !op21;\n"
|
||||
body += " assign o_csr_en = op20 | (op26 & !op21);\n"
|
||||
body += " assign o_csr_mstatus_en = !op26 & !op22;\n"
|
||||
body += " assign o_csr_mie_en = !op26 & op22 & !op20;\n"
|
||||
body += " assign o_csr_mcause_en = op21 & !op20;\n"
|
||||
body += " assign o_csr_source1 = funct3[1];\n"
|
||||
body += " assign o_csr_source0 = funct3[0];\n"
|
||||
body += " assign o_csr_d_sel = funct3[2];\n"
|
||||
body += " assign o_csr_imm_en = opcode[4] & opcode[2] & funct3[2];\n"
|
||||
body += " assign o_csr_addr1 = op26 & op20;\n"
|
||||
body += " assign o_csr_addr0 = !op26 | op21;\n"
|
||||
|
||||
with open('serv_pre_reg_decode.v', 'w') as f:
|
||||
f.write(HEADER.format(ports=',\n '.join(ports), body=body))
|
||||
|
||||
def write_mem_decoder(ctrlmap, merged_signals):
|
||||
ports = []
|
||||
mem = [0]*512
|
||||
|
||||
width = len(ctrlmap)
|
||||
body = """ (* ram_style = "block" *) reg [{msb}:0] mem [0:511];
|
||||
reg [{msb}:0] d;
|
||||
|
||||
initial begin
|
||||
{mem} end
|
||||
|
||||
always @(posedge i_clk)
|
||||
if (i_en)
|
||||
d <= mem[{{i_imm30,i_funct3,i_opcode}}];
|
||||
|
||||
"""
|
||||
|
||||
s = ""
|
||||
for i, (sig, bitmap) in enumerate(ctrlmap.items()):
|
||||
#Find all conditions signals must be true
|
||||
#Rest can be zero
|
||||
(t, _) = map2minterms(bitmap)
|
||||
for x in t:
|
||||
mem[x] += 2**i
|
||||
body += f" assign o_{sig} = d[{i}];\n"
|
||||
|
||||
ports.append(f"output wire o_{sig}")
|
||||
|
||||
if sig in merged_signals:
|
||||
for alias in merged_signals[sig]:
|
||||
ports.append(f"output wire o_{alias}")
|
||||
body += f" assign o_{alias} = o_{sig};\n"
|
||||
|
||||
for i, m in enumerate(mem):
|
||||
s += f" mem[{i}] = {width}'h{m:0{(width+3)//4}x};\n"
|
||||
|
||||
body += "\nalways @(posedge i_clk) begin\n"
|
||||
body += "if (i_en) begin\n"
|
||||
body += " //MDU/CSR/Ext\n"
|
||||
body += " o_mdu_op <= MDU & (i_opcode == 5'b01100) & i_imm25;\n"
|
||||
body += " o_ext_funct3 <= MDU ? i_funct3 : 3'b000;\n"
|
||||
body += " o_ebreak <= CSR & (i_op20);\n"
|
||||
body += " o_rd_csr_en <= CSR & (i_opcode[4] & i_opcode[2] & (|i_funct3));\n"
|
||||
body += " o_ctrl_mret <= CSR & (i_opcode[4] & i_opcode[2] & !(|i_funct3) & i_op21);\n"
|
||||
body += " o_e_op <= CSR & (i_opcode[4] & i_opcode[2] & !(|i_funct3) & !i_op21);\n"
|
||||
body += " o_csr_en <= CSR & (i_op20 | (i_op26 & !i_op21));\n"
|
||||
body += " o_csr_mstatus_en <= CSR & (!i_op26 & !i_op22);\n"
|
||||
body += " o_csr_mie_en <= CSR & (!i_op26 & i_op22 & !i_op20);\n"
|
||||
body += " o_csr_mcause_en <= CSR & ( i_op21 & !i_op20);\n"
|
||||
body += " o_csr_source1 <= CSR & (i_funct3[1]);\n"
|
||||
body += " o_csr_source0 <= CSR & (i_funct3[0]);\n"
|
||||
body += " o_csr_d_sel <= CSR & (i_funct3[2]);\n"
|
||||
body += " o_csr_imm_en <= CSR & (i_opcode[4] & i_opcode[2] & i_funct3[2]);\n"
|
||||
body += " o_csr_addr1 <= CSR & (i_op26 & i_op20);\n"
|
||||
body += " o_csr_addr0 <= CSR & (!i_op26 | i_op21);\n"
|
||||
body += "end\n"
|
||||
body += "end\n"
|
||||
|
||||
with open('serv_mem_decode.v', 'w') as f:
|
||||
f.write(HEADER.format(ports=',\n '.join(ports), body=body.format(msb=width-1, mem=s)))
|
||||
|
||||
|
||||
#imm30, funct3, opcode
|
||||
ops = {
|
||||
'lui' : 'x' + 'xxx' + '01101',
|
||||
'auipc' : 'x' + 'xxx' + '00101',
|
||||
'jal' : 'x' + 'xxx' + '11011',
|
||||
'jalr' : 'x' + 'xxx' + '11001',#funct3 = 000?
|
||||
'beq' : 'x' + '000' + '11000',
|
||||
'bne' : 'x' + '001' + '11000',
|
||||
'blt' : 'x' + '100' + '11000',
|
||||
'bge' : 'x' + '101' + '11000',
|
||||
'bltu' : 'x' + '110' + '11000',
|
||||
'bgeu' : 'x' + '111' + '11000',
|
||||
'lb' : 'x' + '000' + '00000',
|
||||
'lh' : 'x' + '001' + '00000',
|
||||
'lw' : 'x' + '010' + '00000',
|
||||
'lbu' : 'x' + '100' + '00000',
|
||||
'lhu' : 'x' + '101' + '00000',
|
||||
'sb' : 'x' + '000' + '01000',
|
||||
'sh' : 'x' + '001' + '01000',
|
||||
'sw' : 'x' + '010' + '01000',
|
||||
'addi' : 'x' + '000' + '00100',
|
||||
'slti' : 'x' + '010' + '00100',
|
||||
'sltiu' : 'x' + '011' + '00100',
|
||||
'xori' : 'x' + '100' + '00100',
|
||||
'ori' : 'x' + '110' + '00100',
|
||||
'andi' : 'x' + '111' + '00100',
|
||||
'slli' : '0' + '001' + '00100',
|
||||
'srli' : '0' + '101' + '00100',
|
||||
'srai' : '1' + '101' + '00100',
|
||||
'add' : '0' + '000' + '01100',
|
||||
'sub' : '1' + '000' + '01100',
|
||||
'sll' : '0' + '001' + '01100',
|
||||
'slt' : '0' + '010' + '01100',
|
||||
'sltu' : '0' + '011' + '01100',
|
||||
'xor' : '0' + '100' + '01100',
|
||||
'srl' : '0' + '101' + '01100',
|
||||
'sra' : '1' + '101' + '01100',
|
||||
'or' : '0' + '110' + '01100',
|
||||
'and' : '0' + '111' + '01100',
|
||||
'fence' : 'x' + 'xxx' + '00011',#funct3=000?
|
||||
'ecall' : 'x' + '000' + '11100',#ebreak same but op20=1
|
||||
'csrrw' : 'x' + '001' + '11100',
|
||||
'csrrs' : 'x' + '010' + '11100',
|
||||
'csrrc' : 'x' + '011' + '11100',
|
||||
'csrrwi': 'x' + '101' + '11100',
|
||||
'csrrsi': 'x' + '110' + '11100',
|
||||
'csrrci': 'x' + '111' + '11100',
|
||||
}
|
||||
|
||||
###################################
|
||||
###################################
|
||||
###################################
|
||||
|
||||
|
||||
#Map of all required true/false conditions for each op.
|
||||
#This should ideally be created automatically from riscv-formal runs
|
||||
#TODO: Extend with optional ISA extensions (M, Zicsr, Zifencei..)
|
||||
|
||||
#ebreak = ecall with op20=1
|
||||
ctrlmap = \
|
||||
{
|
||||
#UUJRBBBBBBIIIIISSSIIIIIIIIIRRRRRRRRRR
|
||||
#lajjbbbbbblllllsssassxoasssassssxssoa
|
||||
#uuaaenlglgbhwbhbhwdllornlrrdulllorrrn
|
||||
#iillqetete uu dttridlladblttrla d
|
||||
# p r uu iiii iiii u
|
||||
# c u
|
||||
'branch_op' : ' 1111111100000000 00 000 000 00 ',
|
||||
'slt_or_branch' : ' 1111111100000000 11 000 011 00 ',
|
||||
'op_b_source' : ' 11111111000001110000000001111111111',
|
||||
'immdec_ctrl0' : ' 0 11111100000111000000000 ',
|
||||
'immdec_ctrl1' : '000 11111111111111111 ',
|
||||
'immdec_ctrl2' : '000 11111100000000000000000 ',
|
||||
'immdec_ctrl3' : '001 ',
|
||||
'immdec_en0' : '0000111111000001110000000000000000000',
|
||||
'immdec_en1' : '1110000000000000000000000000000000000',
|
||||
'immdec_en2' : '1111000000111110001111111110000000000',
|
||||
'immdec_en3' : '1110111111111111111111111110000000000',
|
||||
'bne_or_bge' : ' 010101 ',
|
||||
'sh_right' : ' 011 0 11 ',
|
||||
'cond_branch' : ' 00111111 ',
|
||||
'shift_op' : ' 0000000000000000 00 111 100 11 ',
|
||||
'two_stage_op' : '0011111111111111110110001110011101100',
|
||||
'rd_alu_en' : '0000 00000 1111111111111111111',
|
||||
'rd_mem_en' : '0000 11111 0000000000000000000',
|
||||
'dbus_en' : ' 0000000011111111 00 000 000 00 ',
|
||||
'bufreg_rs1_en' : ' 0100000011111111 111 1 11 ',
|
||||
'bufreg_imm_en' : ' 1111111111111111 000 0 00 ',
|
||||
'bufreg_clr_lsb' : ' 1011111100000000 000 0 00 ',
|
||||
'bufreg_sh_signed': ' 01 01 ',
|
||||
'ctrl_jal_or_jalr': '0011 00000 0000000000000000000',
|
||||
'ctrl_utype' : '110000000000000 0000000000000000000',
|
||||
'ctrl_pc_rel' : '0110111111 ',
|
||||
'rd_op' : '1111000000111110001111111111111111111',
|
||||
'alu_sub' : ' 111111 011 01 11 ',
|
||||
'alu_bool_op1' : ' 011000 0 00011',
|
||||
'alu_bool_op0' : ' 001111 1 01101',
|
||||
'alu_cmp_eq' : ' 110000 00 00 ',
|
||||
'alu_cmp_sig' : ' 1100 10 10 ',
|
||||
'alu_rd_sel0' : ' 1000000001100000000',
|
||||
'alu_rd_sel1' : ' 0110000000001100000',
|
||||
'alu_rd_sel2' : ' 0001110000000010011',
|
||||
'mem_signed' : ' 11 00 ',
|
||||
'mem_word' : ' 00100001 ',
|
||||
'mem_half' : ' 01001010 ',
|
||||
'mem_cmd' : ' 00000111 ',
|
||||
# 'mtval_pc' : ' 1111111100000000 ',
|
||||
}
|
||||
|
||||
print(printmap(ctrlmap))
|
||||
|
||||
print("\nMerging control signals")
|
||||
(ctrlmap, merged_signals) = merge_signals(ctrlmap)
|
||||
print(printmap(ctrlmap))
|
||||
|
||||
#Create the various decoders
|
||||
print("Creating mem decoder")
|
||||
write_mem_decoder(ctrlmap, merged_signals)
|
||||
|
||||
#print("Writing post-registered logic decoder")
|
||||
#write_post_reg_logic_decoder(ctrlmap, merged_signals)
|
||||
#
|
||||
#print("Writing pre-registered logic decoder")
|
||||
#write_pre_reg_logic_decoder(ctrlmap, merged_signals)
|
Loading…
Add table
Add a link
Reference in a new issue