serv/rtl/serv_debug.v
Olof Kindgren cd60abe837
Some checks failed
Run compliance test suite / RISC-V Compliance Test (push) Has been cancelled
Formal verification / Run RISCV-formal verification suite (push) Has been cancelled
Run linter / Linter (push) Has been cancelled
Build GDS using OpenLANE and sky130 PDK / build-openlane-sky130 (push) Has been cancelled
Fix CSR width issues in debug module
2024-10-17 14:34:08 +02:00

335 lines
11 KiB
Verilog

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 [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
if (i_cnt_en)
dbg_csr <= {i_csr_in, dbg_csr[31:W]};
if (update_rd)
if (i_csr_mstatus_en)
dbg_mstatus <= dbg_csr;
else if (i_csr_mie_en)
dbg_mie <= dbg_csr;
else if (i_csr_mcause_en)
dbg_mcause <= dbg_csr;
else if (i_csr_en)
case (i_csr_addr)
2'b00 : dbg_mscratch <= dbg_csr;
2'b01 : dbg_mtvec <= dbg_csr;
2'b10 : dbg_mepc <= dbg_csr;
2'b11 : dbg_mtval <= dbg_csr;
endcase
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