mirror of
https://github.com/olofk/serv.git
synced 2025-04-24 22:07:20 -04:00
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
335 lines
11 KiB
Verilog
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
|