module serv_debug #(parameter W = 1, parameter RESET_PC = 0, //Internally calculated. Do not touch parameter B=W-1) ( `ifdef RISCV_FORMAL output reg rvfi_valid = 1'b0, output reg [63:0] rvfi_order = 64'd0, output reg [31:0] rvfi_insn = 32'd0, output reg rvfi_trap = 1'b0, output reg rvfi_halt = 1'b0, // Not used output reg rvfi_intr = 1'b0, // Not used output reg [1:0] rvfi_mode = 2'b11, // Not used output reg [1:0] rvfi_ixl = 2'b01, // Not used output reg [4:0] rvfi_rs1_addr, output reg [4:0] rvfi_rs2_addr, output reg [31:0] rvfi_rs1_rdata, output reg [31:0] rvfi_rs2_rdata, output reg [4:0] rvfi_rd_addr, output wire [31:0] rvfi_rd_wdata, output reg [31:0] rvfi_pc_rdata, output wire [31:0] rvfi_pc_wdata, output reg [31:0] rvfi_mem_addr, output reg [3:0] rvfi_mem_rmask, output reg [3:0] rvfi_mem_wmask, output reg [31:0] rvfi_mem_rdata, output reg [31:0] rvfi_mem_wdata, input wire [31:0] i_dbus_adr, input wire [31:0] i_dbus_dat, input wire [3:0] i_dbus_sel, input wire i_dbus_we, input wire [31:0] i_dbus_rdt, input wire i_dbus_ack, input wire i_ctrl_pc_en, input wire [B:0] rs1, input wire [B:0] rs2, input wire [4:0] rs1_addr, input wire [4:0] rs2_addr, input wire [3:0] immdec_en, input wire rd_en, input wire trap, input wire i_rf_ready, input wire i_ibus_cyc, input wire two_stage_op, input wire init, input wire [31:0] i_ibus_adr, `endif input wire i_clk, input wire i_rst, input wire [31:0] i_ibus_rdt, input wire i_ibus_ack, input wire [4:0] i_rd_addr, input wire i_cnt_en, input wire [B:0] i_csr_in, input wire i_csr_mstatus_en, input wire i_csr_mie_en, input wire i_csr_mcause_en, input wire i_csr_en, input wire [1:0] i_csr_addr, input wire i_wen0, input wire [B:0] i_wdata0, input wire i_cnt_done); reg update_rd = 1'b0; reg update_mscratch; reg update_mtvec; reg update_mepc; reg update_mtval; reg update_mstatus; reg update_mie; reg update_mcause; reg [31:0] dbg_rd = 32'hxxxxxxxx; reg [31:0] dbg_csr = 32'hxxxxxxxx; reg [31:0] dbg_mstatus = 32'hxxxxxxxx; reg [31:0] dbg_mie = 32'hxxxxxxxx; reg [31:0] dbg_mcause = 32'hxxxxxxxx; reg [31:0] dbg_mscratch = 32'hxxxxxxxx; reg [31:0] dbg_mtvec = 32'hxxxxxxxx; reg [31:0] dbg_mepc = 32'hxxxxxxxx; reg [31:0] dbg_mtval = 32'hxxxxxxxx; reg [31:0] x1 = 32'hxxxxxxxx; reg [31:0] x2 = 32'hxxxxxxxx; reg [31:0] x3 = 32'hxxxxxxxx; reg [31:0] x4 = 32'hxxxxxxxx; reg [31:0] x5 = 32'hxxxxxxxx; reg [31:0] x6 = 32'hxxxxxxxx; reg [31:0] x7 = 32'hxxxxxxxx; reg [31:0] x8 = 32'hxxxxxxxx; reg [31:0] x9 = 32'hxxxxxxxx; reg [31:0] x10 = 32'hxxxxxxxx; reg [31:0] x11 = 32'hxxxxxxxx; reg [31:0] x12 = 32'hxxxxxxxx; reg [31:0] x13 = 32'hxxxxxxxx; reg [31:0] x14 = 32'hxxxxxxxx; reg [31:0] x15 = 32'hxxxxxxxx; reg [31:0] x16 = 32'hxxxxxxxx; reg [31:0] x17 = 32'hxxxxxxxx; reg [31:0] x18 = 32'hxxxxxxxx; reg [31:0] x19 = 32'hxxxxxxxx; reg [31:0] x20 = 32'hxxxxxxxx; reg [31:0] x21 = 32'hxxxxxxxx; reg [31:0] x22 = 32'hxxxxxxxx; reg [31:0] x23 = 32'hxxxxxxxx; reg [31:0] x24 = 32'hxxxxxxxx; reg [31:0] x25 = 32'hxxxxxxxx; reg [31:0] x26 = 32'hxxxxxxxx; reg [31:0] x27 = 32'hxxxxxxxx; reg [31:0] x28 = 32'hxxxxxxxx; reg [31:0] x29 = 32'hxxxxxxxx; reg [31:0] x30 = 32'hxxxxxxxx; reg [31:0] x31 = 32'hxxxxxxxx; always @(posedge i_clk) begin update_rd <= i_cnt_done & i_wen0; if (i_wen0) dbg_rd <= {i_wdata0,dbg_rd[31:W]}; //End of instruction that writes to RF if (update_rd) begin case (i_rd_addr) 5'd1 : x1 <= dbg_rd; 5'd2 : x2 <= dbg_rd; 5'd3 : x3 <= dbg_rd; 5'd4 : x4 <= dbg_rd; 5'd5 : x5 <= dbg_rd; 5'd6 : x6 <= dbg_rd; 5'd7 : x7 <= dbg_rd; 5'd8 : x8 <= dbg_rd; 5'd9 : x9 <= dbg_rd; 5'd10 : x10 <= dbg_rd; 5'd11 : x11 <= dbg_rd; 5'd12 : x12 <= dbg_rd; 5'd13 : x13 <= dbg_rd; 5'd14 : x14 <= dbg_rd; 5'd15 : x15 <= dbg_rd; 5'd16 : x16 <= dbg_rd; 5'd17 : x17 <= dbg_rd; 5'd18 : x18 <= dbg_rd; 5'd19 : x19 <= dbg_rd; 5'd20 : x20 <= dbg_rd; 5'd21 : x21 <= dbg_rd; 5'd22 : x22 <= dbg_rd; 5'd23 : x23 <= dbg_rd; 5'd24 : x24 <= dbg_rd; 5'd25 : x25 <= dbg_rd; 5'd26 : x26 <= dbg_rd; 5'd27 : x27 <= dbg_rd; 5'd28 : x28 <= dbg_rd; 5'd29 : x29 <= dbg_rd; 5'd30 : x30 <= dbg_rd; 5'd31 : x31 <= dbg_rd; default : ; endcase end update_mscratch <= i_cnt_done & i_csr_en & (i_csr_addr == 2'b00); update_mtvec <= i_cnt_done & i_csr_en & (i_csr_addr == 2'b01); update_mepc <= i_cnt_done & i_csr_en & (i_csr_addr == 2'b10); update_mtval <= i_cnt_done & i_csr_en & (i_csr_addr == 2'b11); update_mstatus <= i_cnt_done & i_csr_mstatus_en; update_mie <= i_cnt_done & i_csr_mie_en; update_mcause <= i_cnt_done & i_csr_mcause_en; if (i_cnt_en) dbg_csr <= {i_csr_in, dbg_csr[31:W]}; if (update_mscratch) dbg_mscratch <= dbg_csr; if (update_mtvec) dbg_mtvec <= dbg_csr; if (update_mepc ) dbg_mepc <= dbg_csr; if (update_mtval) dbg_mtval <= dbg_csr; if (update_mstatus) dbg_mstatus <= dbg_csr; if (update_mie) dbg_mie <= dbg_csr; if (update_mcause) dbg_mcause <= dbg_csr; end reg LUI, AUIPC, JAL, JALR, BEQ, BNE, BLT, BGE, BLTU, BGEU, LB, LH, LW, LBU, LHU, SB, SH, SW, ADDI, SLTI, SLTIU, XORI, ORI, ANDI,SLLI, SRLI, SRAI, ADD, SUB, SLL, SLT, SLTU, XOR, SRL, SRA, OR, AND, FENCE, ECALL, EBREAK; reg CSRRW, CSRRS, CSRRC, CSRRWI, CSRRSI, CSRRCI; reg OTHER; always @(posedge i_clk) begin if (i_ibus_ack) begin LUI <= 1'b0; AUIPC <= 1'b0; JAL <= 1'b0; JALR <= 1'b0; BEQ <= 1'b0; BNE <= 1'b0; BLT <= 1'b0; BGE <= 1'b0; BLTU <= 1'b0; BGEU <= 1'b0; LB <= 1'b0; LH <= 1'b0; LW <= 1'b0; LBU <= 1'b0; LHU <= 1'b0; SB <= 1'b0; SH <= 1'b0; SW <= 1'b0; ADDI <= 1'b0; SLTI <= 1'b0; SLTIU <= 1'b0; XORI <= 1'b0; ORI <= 1'b0; ANDI <= 1'b0; SLLI <= 1'b0; SRLI <= 1'b0; SRAI <= 1'b0; ADD <= 1'b0; SUB <= 1'b0; SLL <= 1'b0; SLT <= 1'b0; SLTU <= 1'b0; XOR <= 1'b0; SRL <= 1'b0; SRA <= 1'b0; OR <= 1'b0; AND <= 1'b0; FENCE <= 1'b0; ECALL <= 1'b0; EBREAK <= 1'b0; CSRRW <= 1'b0; CSRRS <= 1'b0; CSRRC <= 1'b0; CSRRWI <= 1'b0; CSRRSI <= 1'b0; CSRRCI <= 1'b0; OTHER <= 1'b0; casez(i_ibus_rdt) // 3322222_22222 11111_111 11 // 1098765_43210 98765_432 10987_65432_10 32'b???????_?????_?????_???_?????_01101_11 : LUI <= 1'b1; 32'b???????_?????_?????_???_?????_00101_11 : AUIPC <= 1'b1; 32'b???????_?????_?????_???_?????_11011_11 : JAL <= 1'b1; 32'b???????_?????_?????_000_?????_11001_11 : JALR <= 1'b1; 32'b???????_?????_?????_000_?????_11000_11 : BEQ <= 1'b1; 32'b???????_?????_?????_001_?????_11000_11 : BNE <= 1'b1; 32'b???????_?????_?????_100_?????_11000_11 : BLT <= 1'b1; 32'b???????_?????_?????_101_?????_11000_11 : BGE <= 1'b1; 32'b???????_?????_?????_110_?????_11000_11 : BLTU <= 1'b1; 32'b???????_?????_?????_111_?????_11000_11 : BGEU <= 1'b1; 32'b???????_?????_?????_000_?????_00000_11 : LB <= 1'b1; 32'b???????_?????_?????_001_?????_00000_11 : LH <= 1'b1; 32'b???????_?????_?????_010_?????_00000_11 : LW <= 1'b1; 32'b???????_?????_?????_100_?????_00000_11 : LBU <= 1'b1; 32'b???????_?????_?????_101_?????_00000_11 : LHU <= 1'b1; 32'b???????_?????_?????_000_?????_01000_11 : SB <= 1'b1; 32'b???????_?????_?????_001_?????_01000_11 : SH <= 1'b1; 32'b???????_?????_?????_010_?????_01000_11 : SW <= 1'b1; 32'b???????_?????_?????_000_?????_00100_11 : ADDI <= 1'b1; 32'b???????_?????_?????_010_?????_00100_11 : SLTI <= 1'b1; 32'b???????_?????_?????_011_?????_00100_11 : SLTIU <= 1'b1; 32'b???????_?????_?????_100_?????_00100_11 : XORI <= 1'b1; 32'b???????_?????_?????_110_?????_00100_11 : ORI <= 1'b1; 32'b???????_?????_?????_111_?????_00100_11 : ANDI <= 1'b1; 32'b0000000_?????_?????_001_?????_00100_11 : SLLI <= 1'b1; 32'b0000000_?????_?????_101_?????_00100_11 : SRLI <= 1'b1; 32'b0100000_?????_?????_101_?????_00100_11 : SRAI <= 1'b1; 32'b0000000_?????_?????_000_?????_01100_11 : ADD <= 1'b1; 32'b0100000_?????_?????_000_?????_01100_11 : SUB <= 1'b1; 32'b0000000_?????_?????_001_?????_01100_11 : SLL <= 1'b1; 32'b0000000_?????_?????_010_?????_01100_11 : SLT <= 1'b1; 32'b0000000_?????_?????_011_?????_01100_11 : SLTU <= 1'b1; 32'b???????_?????_?????_100_?????_01100_11 : XOR <= 1'b1; 32'b0000000_?????_?????_101_?????_01100_11 : SRL <= 1'b1; 32'b0100000_?????_?????_101_?????_01100_11 : SRA <= 1'b1; 32'b???????_?????_?????_110_?????_01100_11 : OR <= 1'b1; 32'b???????_?????_?????_111_?????_01100_11 : AND <= 1'b1; 32'b???????_?????_?????_000_?????_00011_11 : FENCE <= 1'b1; 32'b0000000_00000_00000_000_00000_11100_11 : ECALL <= 1'b1; 32'b0000000_00001_00000_000_00000_11100_11 : EBREAK <= 1'b1; 32'b???????_?????_?????_001_?????_11100_11 : CSRRW <= 1'b1; 32'b???????_?????_?????_010_?????_11100_11 : CSRRS <= 1'b1; 32'b???????_?????_?????_011_?????_11100_11 : CSRRC <= 1'b1; 32'b???????_?????_?????_101_?????_11100_11 : CSRRWI <= 1'b1; 32'b???????_?????_?????_110_?????_11100_11 : CSRRSI <= 1'b1; 32'b???????_?????_?????_111_?????_11100_11 : CSRRCI <= 1'b1; default : OTHER <= 1'b1; endcase end end `ifdef RISCV_FORMAL reg [31:0] pc = RESET_PC; wire rs_en = two_stage_op ? init : i_ctrl_pc_en; assign rvfi_rd_wdata = update_rd ? dbg_rd : 32'd0; always @(posedge i_clk) begin /* End of instruction */ rvfi_valid <= i_cnt_done & i_ctrl_pc_en & !i_rst; rvfi_order <= rvfi_order + {63'd0,rvfi_valid}; /* Get instruction word when it's fetched from ibus */ if (i_ibus_cyc & i_ibus_ack) rvfi_insn <= i_ibus_rdt; if (i_cnt_done & i_ctrl_pc_en) begin rvfi_pc_rdata <= pc; if (!(rd_en & (|i_rd_addr))) begin rvfi_rd_addr <= 5'd0; end end rvfi_trap <= trap; if (rvfi_valid) begin rvfi_trap <= 1'b0; pc <= rvfi_pc_wdata; end /* RS1 not valid during J, U instructions (immdec_en[1]) */ /* RS2 not valid during I, J, U instructions (immdec_en[2]) */ if (i_rf_ready) begin rvfi_rs1_addr <= !immdec_en[1] ? rs1_addr : 5'd0; rvfi_rs2_addr <= !immdec_en[2] /*rs2_valid*/ ? rs2_addr : 5'd0; rvfi_rd_addr <= i_rd_addr; end if (rs_en) begin rvfi_rs1_rdata <= {(!immdec_en[1] ? rs1 : {W{1'b0}}),rvfi_rs1_rdata[31:W]}; rvfi_rs2_rdata <= {(!immdec_en[2] ? rs2 : {W{1'b0}}),rvfi_rs2_rdata[31:W]}; end if (i_dbus_ack) begin rvfi_mem_addr <= i_dbus_adr; rvfi_mem_rmask <= i_dbus_we ? 4'b0000 : i_dbus_sel; rvfi_mem_wmask <= i_dbus_we ? i_dbus_sel : 4'b0000; rvfi_mem_rdata <= i_dbus_rdt; rvfi_mem_wdata <= i_dbus_dat; end if (i_ibus_ack) begin rvfi_mem_rmask <= 4'b0000; rvfi_mem_wmask <= 4'b0000; end end assign rvfi_pc_wdata = i_ibus_adr; `endif endmodule