parent
9322b595bc
commit
c070f0b49d
89
rtl.flist
89
rtl.flist
|
@ -1,44 +1,45 @@
|
||||||
|
|
||||||
+incdir+../rtl/core
|
+incdir+../rtl/core
|
||||||
|
|
||||||
../rtl/core/clint.sv
|
../rtl/core/clint.sv
|
||||||
../rtl/core/csr_reg.sv
|
../rtl/core/csr_reg.sv
|
||||||
../rtl/core/defines.sv
|
../rtl/core/defines.sv
|
||||||
../rtl/core/divider.sv
|
../rtl/core/divider.sv
|
||||||
../rtl/core/exu.sv
|
../rtl/core/exu.sv
|
||||||
../rtl/core/exu_alu_datapath.sv
|
../rtl/core/exu_alu_datapath.sv
|
||||||
../rtl/core/exu_commit.sv
|
../rtl/core/exu_commit.sv
|
||||||
../rtl/core/exu_dispatch.sv
|
../rtl/core/exu_dispatch.sv
|
||||||
../rtl/core/exu_mem.sv
|
../rtl/core/exu_mem.sv
|
||||||
../rtl/core/exu_muldiv.sv
|
../rtl/core/exu_muldiv.sv
|
||||||
../rtl/core/gpr_reg.sv
|
../rtl/core/gpr_reg.sv
|
||||||
../rtl/core/idu.sv
|
../rtl/core/idu.sv
|
||||||
../rtl/core/idu_exu.sv
|
../rtl/core/idu_exu.sv
|
||||||
../rtl/core/ifu.sv
|
../rtl/core/ifu.sv
|
||||||
../rtl/core/ifu_idu.sv
|
../rtl/core/ifu_idu.sv
|
||||||
../rtl/core/pipe_ctrl.sv
|
../rtl/core/pipe_ctrl.sv
|
||||||
../rtl/core/rst_ctrl.sv
|
../rtl/core/rst_ctrl.sv
|
||||||
../rtl/core/tinyriscv_core.sv
|
../rtl/core/tinyriscv_core.sv
|
||||||
|
../rtl/core/tracer.sv
|
||||||
../rtl/debug/jtag_dm.sv
|
|
||||||
../rtl/debug/jtag_driver.sv
|
../rtl/debug/jtag_dm.sv
|
||||||
../rtl/debug/jtag_top.sv
|
../rtl/debug/jtag_driver.sv
|
||||||
|
../rtl/debug/jtag_top.sv
|
||||||
../rtl/perips/gpio.sv
|
|
||||||
../rtl/perips/ram.sv
|
../rtl/perips/gpio.sv
|
||||||
../rtl/perips/rom.sv
|
../rtl/perips/ram.sv
|
||||||
../rtl/perips/timer.sv
|
../rtl/perips/rom.sv
|
||||||
../rtl/perips/uart.sv
|
../rtl/perips/timer.sv
|
||||||
|
../rtl/perips/uart.sv
|
||||||
../rtl/sys_bus/rib.sv
|
|
||||||
|
../rtl/sys_bus/rib.sv
|
||||||
../rtl/top/tinyriscv_soc_top.sv
|
|
||||||
|
../rtl/top/tinyriscv_soc_top.sv
|
||||||
../rtl/utils/full_handshake_rx.sv
|
|
||||||
../rtl/utils/full_handshake_tx.sv
|
../rtl/utils/full_handshake_rx.sv
|
||||||
../rtl/utils/gen_buf.sv
|
../rtl/utils/full_handshake_tx.sv
|
||||||
../rtl/utils/gen_dff.sv
|
../rtl/utils/gen_buf.sv
|
||||||
../rtl/utils/gen_ram.sv
|
../rtl/utils/gen_dff.sv
|
||||||
../rtl/utils/vld_rdy.sv
|
../rtl/utils/gen_ram.sv
|
||||||
|
../rtl/utils/vld_rdy.sv
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,318 +1,324 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2019 Blue Liang, liangkangnan@163.com
|
Copyright 2019 Blue Liang, liangkangnan@163.com
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
`include "defines.sv"
|
`include "defines.sv"
|
||||||
|
|
||||||
// tinyriscv处理器核顶层模块
|
// tinyriscv处理器核顶层模块
|
||||||
module tinyriscv_core(
|
module tinyriscv_core(
|
||||||
|
|
||||||
input wire clk,
|
input wire clk,
|
||||||
input wire rst_n,
|
input wire rst_n,
|
||||||
|
|
||||||
output wire[31:0] dbus_addr_o,
|
output wire[31:0] dbus_addr_o,
|
||||||
input wire[31:0] dbus_data_i,
|
input wire[31:0] dbus_data_i,
|
||||||
output wire[31:0] dbus_data_o,
|
output wire[31:0] dbus_data_o,
|
||||||
output wire[3:0] dbus_sel_o,
|
output wire[3:0] dbus_sel_o,
|
||||||
output wire dbus_we_o,
|
output wire dbus_we_o,
|
||||||
output wire dbus_req_valid_o,
|
output wire dbus_req_valid_o,
|
||||||
input wire dbus_req_ready_i,
|
input wire dbus_req_ready_i,
|
||||||
input wire dbus_rsp_valid_i,
|
input wire dbus_rsp_valid_i,
|
||||||
output wire dbus_rsp_ready_o,
|
output wire dbus_rsp_ready_o,
|
||||||
|
|
||||||
output wire[31:0] ibus_addr_o, // 取指地址
|
output wire[31:0] ibus_addr_o, // 取指地址
|
||||||
input wire[31:0] ibus_data_i, // 取到的指令内容
|
input wire[31:0] ibus_data_i, // 取到的指令内容
|
||||||
output wire[31:0] ibus_data_o,
|
output wire[31:0] ibus_data_o,
|
||||||
output wire[3:0] ibus_sel_o,
|
output wire[3:0] ibus_sel_o,
|
||||||
output wire ibus_we_o,
|
output wire ibus_we_o,
|
||||||
output wire ibus_req_valid_o,
|
output wire ibus_req_valid_o,
|
||||||
input wire ibus_req_ready_i,
|
input wire ibus_req_ready_i,
|
||||||
input wire ibus_rsp_valid_i,
|
input wire ibus_rsp_valid_i,
|
||||||
output wire ibus_rsp_ready_o,
|
output wire ibus_rsp_ready_o,
|
||||||
|
|
||||||
input wire jtag_halt_i,
|
input wire jtag_halt_i,
|
||||||
input wire[`INT_WIDTH-1:0] int_i // 中断输入信号
|
input wire[`INT_WIDTH-1:0] int_i // 中断输入信号
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// ifu模块输出信号
|
// ifu模块输出信号
|
||||||
wire[31:0] ifetch_inst_o;
|
wire[31:0] ifetch_inst_o;
|
||||||
wire[31:0] ifetch_pc_o;
|
wire[31:0] ifetch_pc_o;
|
||||||
wire ifetch_inst_valid_o;
|
wire ifetch_inst_valid_o;
|
||||||
|
|
||||||
// ifu_idu模块输出信号
|
// ifu_idu模块输出信号
|
||||||
wire[31:0] if_inst_o;
|
wire[31:0] if_inst_o;
|
||||||
wire[31:0] if_inst_addr_o;
|
wire[31:0] if_inst_addr_o;
|
||||||
wire[`INT_WIDTH-1:0] if_int_flag_o;
|
wire[`INT_WIDTH-1:0] if_int_flag_o;
|
||||||
|
|
||||||
// idu模块输出信号
|
// idu模块输出信号
|
||||||
wire[31:0] id_inst_o;
|
wire[31:0] id_inst_o;
|
||||||
wire[31:0] id_inst_addr_o;
|
wire[31:0] id_inst_addr_o;
|
||||||
wire[`DECINFO_WIDTH-1:0] id_dec_info_bus_o;
|
wire[`DECINFO_WIDTH-1:0] id_dec_info_bus_o;
|
||||||
wire[31:0] id_dec_imm_o;
|
wire[31:0] id_dec_imm_o;
|
||||||
wire[31:0] id_dec_pc_o;
|
wire[31:0] id_dec_pc_o;
|
||||||
wire[4:0] id_rs1_raddr_o;
|
wire[4:0] id_rs1_raddr_o;
|
||||||
wire[4:0] id_rs2_raddr_o;
|
wire[4:0] id_rs2_raddr_o;
|
||||||
wire[4:0] id_rd_waddr_o;
|
wire[4:0] id_rd_waddr_o;
|
||||||
wire id_rd_we_o;
|
wire id_rd_we_o;
|
||||||
wire id_stall_o;
|
wire id_stall_o;
|
||||||
wire[31:0] id_rs1_rdata_o;
|
wire[31:0] id_rs1_rdata_o;
|
||||||
wire[31:0] id_rs2_rdata_o;
|
wire[31:0] id_rs2_rdata_o;
|
||||||
|
|
||||||
// idu_exu模块输出信号
|
// idu_exu模块输出信号
|
||||||
wire[31:0] ie_inst_o;
|
wire[31:0] ie_inst_o;
|
||||||
wire[31:0] ie_inst_addr_o;
|
wire[31:0] ie_inst_addr_o;
|
||||||
wire[`DECINFO_WIDTH-1:0] ie_dec_info_bus_o;
|
wire[`DECINFO_WIDTH-1:0] ie_dec_info_bus_o;
|
||||||
wire[31:0] ie_dec_imm_o;
|
wire[31:0] ie_dec_imm_o;
|
||||||
wire[31:0] ie_dec_pc_o;
|
wire[31:0] ie_dec_pc_o;
|
||||||
wire[31:0] ie_rs1_rdata_o;
|
wire[31:0] ie_rs1_rdata_o;
|
||||||
wire[31:0] ie_rs2_rdata_o;
|
wire[31:0] ie_rs2_rdata_o;
|
||||||
wire[4:0] ie_rd_waddr_o;
|
wire[4:0] ie_rd_waddr_o;
|
||||||
wire ie_rd_we_o;
|
wire ie_rd_we_o;
|
||||||
|
|
||||||
// exu模块输出信号
|
// exu模块输出信号
|
||||||
wire[31:0] ex_mem_wdata_o;
|
wire[31:0] ex_mem_wdata_o;
|
||||||
wire[31:0] ex_mem_addr_o;
|
wire[31:0] ex_mem_addr_o;
|
||||||
wire ex_mem_we_o;
|
wire ex_mem_we_o;
|
||||||
wire[3:0] ex_mem_sel_o;
|
wire[3:0] ex_mem_sel_o;
|
||||||
wire ex_mem_req_valid_o;
|
wire ex_mem_req_valid_o;
|
||||||
wire ex_mem_rsp_ready_o;
|
wire ex_mem_rsp_ready_o;
|
||||||
wire ex_mem_access_misaligned_o;
|
wire ex_mem_access_misaligned_o;
|
||||||
wire[31:0] ex_reg_wdata_o;
|
wire[31:0] ex_reg_wdata_o;
|
||||||
wire ex_reg_we_o;
|
wire ex_reg_we_o;
|
||||||
wire[4:0] ex_reg_waddr_o;
|
wire[4:0] ex_reg_waddr_o;
|
||||||
wire ex_hold_flag_o;
|
wire ex_hold_flag_o;
|
||||||
wire ex_jump_flag_o;
|
wire ex_jump_flag_o;
|
||||||
wire[31:0] ex_jump_addr_o;
|
wire[31:0] ex_jump_addr_o;
|
||||||
wire[31:0] ex_csr_wdata_o;
|
wire[31:0] ex_csr_wdata_o;
|
||||||
wire ex_csr_we_o;
|
wire ex_csr_we_o;
|
||||||
wire[31:0] ex_csr_waddr_o;
|
wire[31:0] ex_csr_waddr_o;
|
||||||
wire[31:0] ex_csr_raddr_o;
|
wire[31:0] ex_csr_raddr_o;
|
||||||
wire ex_inst_ecall_o;
|
wire ex_inst_ecall_o;
|
||||||
wire ex_inst_ebreak_o;
|
wire ex_inst_ebreak_o;
|
||||||
wire ex_inst_mret_o;
|
wire ex_inst_mret_o;
|
||||||
|
|
||||||
// gpr_reg模块输出信号
|
// gpr_reg模块输出信号
|
||||||
wire[31:0] regs_rdata1_o;
|
wire[31:0] regs_rdata1_o;
|
||||||
wire[31:0] regs_rdata2_o;
|
wire[31:0] regs_rdata2_o;
|
||||||
|
|
||||||
// csr_reg模块输出信号
|
// csr_reg模块输出信号
|
||||||
wire[31:0] csr_ex_data_o;
|
wire[31:0] csr_ex_data_o;
|
||||||
wire[31:0] csr_clint_data_o;
|
wire[31:0] csr_clint_data_o;
|
||||||
wire[31:0] csr_mtvec_o;
|
wire[31:0] csr_mtvec_o;
|
||||||
wire[31:0] csr_mepc_o;
|
wire[31:0] csr_mepc_o;
|
||||||
wire[31:0] csr_mstatus_o;
|
wire[31:0] csr_mstatus_o;
|
||||||
|
|
||||||
// pipe_ctrl模块输出信号
|
// pipe_ctrl模块输出信号
|
||||||
wire[31:0] ctrl_flush_addr_o;
|
wire[31:0] ctrl_flush_addr_o;
|
||||||
wire ctrl_flush_o;
|
wire ctrl_flush_o;
|
||||||
wire[`STALL_WIDTH-1:0] ctrl_stall_o;
|
wire[`STALL_WIDTH-1:0] ctrl_stall_o;
|
||||||
|
|
||||||
// clint模块输出信号
|
// clint模块输出信号
|
||||||
wire clint_csr_we_o;
|
wire clint_csr_we_o;
|
||||||
wire[31:0] clint_csr_waddr_o;
|
wire[31:0] clint_csr_waddr_o;
|
||||||
wire[31:0] clint_csr_wdata_o;
|
wire[31:0] clint_csr_wdata_o;
|
||||||
wire clint_stall_flag_o;
|
wire clint_stall_flag_o;
|
||||||
wire[31:0] clint_int_addr_o;
|
wire[31:0] clint_int_addr_o;
|
||||||
wire clint_int_assert_o;
|
wire clint_int_assert_o;
|
||||||
|
|
||||||
assign dbus_addr_o = ex_mem_addr_o;
|
assign dbus_addr_o = ex_mem_addr_o;
|
||||||
assign dbus_data_o = ex_mem_wdata_o;
|
assign dbus_data_o = ex_mem_wdata_o;
|
||||||
assign dbus_we_o = ex_mem_we_o;
|
assign dbus_we_o = ex_mem_we_o;
|
||||||
assign dbus_sel_o = ex_mem_sel_o;
|
assign dbus_sel_o = ex_mem_sel_o;
|
||||||
assign dbus_req_valid_o = ex_mem_req_valid_o;
|
assign dbus_req_valid_o = ex_mem_req_valid_o;
|
||||||
assign dbus_rsp_ready_o = ex_mem_rsp_ready_o;
|
assign dbus_rsp_ready_o = ex_mem_rsp_ready_o;
|
||||||
|
|
||||||
|
|
||||||
ifu u_ifu(
|
ifu u_ifu(
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.rst_n(rst_n),
|
.rst_n(rst_n),
|
||||||
.flush_addr_i(ctrl_flush_addr_o),
|
.flush_addr_i(ctrl_flush_addr_o),
|
||||||
.stall_i(ctrl_stall_o),
|
.stall_i(ctrl_stall_o),
|
||||||
.flush_i(ctrl_flush_o),
|
.flush_i(ctrl_flush_o),
|
||||||
.jtag_halt_i(jtag_halt_i),
|
.jtag_halt_i(jtag_halt_i),
|
||||||
.inst_o(ifetch_inst_o),
|
.inst_o(ifetch_inst_o),
|
||||||
.pc_o(ifetch_pc_o),
|
.pc_o(ifetch_pc_o),
|
||||||
.inst_valid_o(ifetch_inst_valid_o),
|
.inst_valid_o(ifetch_inst_valid_o),
|
||||||
.ibus_addr_o(ibus_addr_o),
|
.ibus_addr_o(ibus_addr_o),
|
||||||
.ibus_data_i(ibus_data_i),
|
.ibus_data_i(ibus_data_i),
|
||||||
.ibus_data_o(ibus_data_o),
|
.ibus_data_o(ibus_data_o),
|
||||||
.ibus_sel_o(ibus_sel_o),
|
.ibus_sel_o(ibus_sel_o),
|
||||||
.ibus_we_o(ibus_we_o),
|
.ibus_we_o(ibus_we_o),
|
||||||
.req_valid_o(ibus_req_valid_o),
|
.req_valid_o(ibus_req_valid_o),
|
||||||
.req_ready_i(ibus_req_ready_i),
|
.req_ready_i(ibus_req_ready_i),
|
||||||
.rsp_valid_i(ibus_rsp_valid_i),
|
.rsp_valid_i(ibus_rsp_valid_i),
|
||||||
.rsp_ready_o(ibus_rsp_ready_o)
|
.rsp_ready_o(ibus_rsp_ready_o)
|
||||||
);
|
);
|
||||||
|
|
||||||
pipe_ctrl u_pipe_ctrl(
|
pipe_ctrl u_pipe_ctrl(
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.rst_n(rst_n),
|
.rst_n(rst_n),
|
||||||
.stall_from_id_i(id_stall_o),
|
.stall_from_id_i(id_stall_o),
|
||||||
.stall_from_ex_i(ex_hold_flag_o),
|
.stall_from_ex_i(ex_hold_flag_o),
|
||||||
.stall_from_jtag_i(1'b0),
|
.stall_from_jtag_i(1'b0),
|
||||||
.stall_from_clint_i(clint_stall_flag_o),
|
.stall_from_clint_i(clint_stall_flag_o),
|
||||||
.jump_assert_i(ex_jump_flag_o),
|
.jump_assert_i(ex_jump_flag_o),
|
||||||
.jump_addr_i(ex_jump_addr_o),
|
.jump_addr_i(ex_jump_addr_o),
|
||||||
.flush_o(ctrl_flush_o),
|
.flush_o(ctrl_flush_o),
|
||||||
.stall_o(ctrl_stall_o),
|
.stall_o(ctrl_stall_o),
|
||||||
.flush_addr_o(ctrl_flush_addr_o)
|
.flush_addr_o(ctrl_flush_addr_o)
|
||||||
);
|
);
|
||||||
|
|
||||||
gpr_reg u_gpr_reg(
|
gpr_reg u_gpr_reg(
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.rst_n(rst_n),
|
.rst_n(rst_n),
|
||||||
.we_i(ex_reg_we_o),
|
.we_i(ex_reg_we_o),
|
||||||
.waddr_i(ex_reg_waddr_o),
|
.waddr_i(ex_reg_waddr_o),
|
||||||
.wdata_i(ex_reg_wdata_o),
|
.wdata_i(ex_reg_wdata_o),
|
||||||
.raddr1_i(id_rs1_raddr_o),
|
.raddr1_i(id_rs1_raddr_o),
|
||||||
.rdata1_o(regs_rdata1_o),
|
.rdata1_o(regs_rdata1_o),
|
||||||
.raddr2_i(id_rs2_raddr_o),
|
.raddr2_i(id_rs2_raddr_o),
|
||||||
.rdata2_o(regs_rdata2_o)
|
.rdata2_o(regs_rdata2_o)
|
||||||
);
|
);
|
||||||
|
|
||||||
csr_reg u_csr_reg(
|
csr_reg u_csr_reg(
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.rst_n(rst_n),
|
.rst_n(rst_n),
|
||||||
.exu_we_i(ex_csr_we_o),
|
.exu_we_i(ex_csr_we_o),
|
||||||
.exu_raddr_i(ex_csr_raddr_o),
|
.exu_raddr_i(ex_csr_raddr_o),
|
||||||
.exu_waddr_i(ex_csr_waddr_o),
|
.exu_waddr_i(ex_csr_waddr_o),
|
||||||
.exu_wdata_i(ex_csr_wdata_o),
|
.exu_wdata_i(ex_csr_wdata_o),
|
||||||
.exu_rdata_o(csr_ex_data_o),
|
.exu_rdata_o(csr_ex_data_o),
|
||||||
.clint_we_i(clint_csr_we_o),
|
.clint_we_i(clint_csr_we_o),
|
||||||
.clint_waddr_i(clint_csr_waddr_o),
|
.clint_waddr_i(clint_csr_waddr_o),
|
||||||
.clint_wdata_i(clint_csr_wdata_o),
|
.clint_wdata_i(clint_csr_wdata_o),
|
||||||
.mtvec_o(csr_mtvec_o),
|
.mtvec_o(csr_mtvec_o),
|
||||||
.mepc_o(csr_mepc_o),
|
.mepc_o(csr_mepc_o),
|
||||||
.mstatus_o(csr_mstatus_o)
|
.mstatus_o(csr_mstatus_o)
|
||||||
);
|
);
|
||||||
|
|
||||||
ifu_idu u_ifu_idu(
|
ifu_idu u_ifu_idu(
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.rst_n(rst_n),
|
.rst_n(rst_n),
|
||||||
.inst_i(ifetch_inst_o),
|
.inst_i(ifetch_inst_o),
|
||||||
.inst_addr_i(ifetch_pc_o),
|
.inst_addr_i(ifetch_pc_o),
|
||||||
.stall_i(ctrl_stall_o),
|
.stall_i(ctrl_stall_o),
|
||||||
.flush_i(ctrl_flush_o),
|
.flush_i(ctrl_flush_o),
|
||||||
.inst_valid_i(ifetch_inst_valid_o),
|
.inst_valid_i(ifetch_inst_valid_o),
|
||||||
.inst_o(if_inst_o),
|
.inst_o(if_inst_o),
|
||||||
.inst_addr_o(if_inst_addr_o)
|
.inst_addr_o(if_inst_addr_o)
|
||||||
);
|
);
|
||||||
|
|
||||||
idu u_idu(
|
idu u_idu(
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.rst_n(rst_n),
|
.rst_n(rst_n),
|
||||||
.inst_i(if_inst_o),
|
.inst_i(if_inst_o),
|
||||||
.rs1_rdata_i(regs_rdata1_o),
|
.rs1_rdata_i(regs_rdata1_o),
|
||||||
.rs2_rdata_i(regs_rdata2_o),
|
.rs2_rdata_i(regs_rdata2_o),
|
||||||
.inst_o(id_inst_o),
|
.inst_o(id_inst_o),
|
||||||
.inst_addr_i(if_inst_addr_o),
|
.inst_addr_i(if_inst_addr_o),
|
||||||
.rs1_rdata_o(id_rs1_rdata_o),
|
.rs1_rdata_o(id_rs1_rdata_o),
|
||||||
.rs2_rdata_o(id_rs2_rdata_o),
|
.rs2_rdata_o(id_rs2_rdata_o),
|
||||||
.stall_o(id_stall_o),
|
.stall_o(id_stall_o),
|
||||||
.dec_info_bus_o(id_dec_info_bus_o),
|
.dec_info_bus_o(id_dec_info_bus_o),
|
||||||
.dec_imm_o(id_dec_imm_o),
|
.dec_imm_o(id_dec_imm_o),
|
||||||
.dec_pc_o(id_dec_pc_o),
|
.dec_pc_o(id_dec_pc_o),
|
||||||
.rs1_raddr_o(id_rs1_raddr_o),
|
.rs1_raddr_o(id_rs1_raddr_o),
|
||||||
.rs2_raddr_o(id_rs2_raddr_o),
|
.rs2_raddr_o(id_rs2_raddr_o),
|
||||||
.rd_waddr_o(id_rd_waddr_o),
|
.rd_waddr_o(id_rd_waddr_o),
|
||||||
.rd_we_o(id_rd_we_o)
|
.rd_we_o(id_rd_we_o)
|
||||||
);
|
);
|
||||||
|
|
||||||
idu_exu u_idu_exu(
|
idu_exu u_idu_exu(
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.rst_n(rst_n),
|
.rst_n(rst_n),
|
||||||
.inst_i(id_inst_o),
|
.inst_i(id_inst_o),
|
||||||
.stall_i(ctrl_stall_o),
|
.stall_i(ctrl_stall_o),
|
||||||
.flush_i(ctrl_flush_o),
|
.flush_i(ctrl_flush_o),
|
||||||
.dec_info_bus_i(id_dec_info_bus_o),
|
.dec_info_bus_i(id_dec_info_bus_o),
|
||||||
.dec_imm_i(id_dec_imm_o),
|
.dec_imm_i(id_dec_imm_o),
|
||||||
.dec_pc_i(id_dec_pc_o),
|
.dec_pc_i(id_dec_pc_o),
|
||||||
.rs1_rdata_i(id_rs1_rdata_o),
|
.rs1_rdata_i(id_rs1_rdata_o),
|
||||||
.rs2_rdata_i(id_rs2_rdata_o),
|
.rs2_rdata_i(id_rs2_rdata_o),
|
||||||
.rd_waddr_i(id_rd_waddr_o),
|
.rd_waddr_i(id_rd_waddr_o),
|
||||||
.rd_we_i(id_rd_we_o),
|
.rd_we_i(id_rd_we_o),
|
||||||
.inst_o(ie_inst_o),
|
.inst_o(ie_inst_o),
|
||||||
.dec_info_bus_o(ie_dec_info_bus_o),
|
.dec_info_bus_o(ie_dec_info_bus_o),
|
||||||
.dec_imm_o(ie_dec_imm_o),
|
.dec_imm_o(ie_dec_imm_o),
|
||||||
.dec_pc_o(ie_dec_pc_o),
|
.dec_pc_o(ie_dec_pc_o),
|
||||||
.rs1_rdata_o(ie_rs1_rdata_o),
|
.rs1_rdata_o(ie_rs1_rdata_o),
|
||||||
.rs2_rdata_o(ie_rs2_rdata_o),
|
.rs2_rdata_o(ie_rs2_rdata_o),
|
||||||
.rd_waddr_o(ie_rd_waddr_o),
|
.rd_waddr_o(ie_rd_waddr_o),
|
||||||
.rd_we_o(ie_rd_we_o)
|
.rd_we_o(ie_rd_we_o)
|
||||||
);
|
);
|
||||||
|
|
||||||
exu u_exu(
|
exu u_exu(
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.rst_n(rst_n),
|
.rst_n(rst_n),
|
||||||
.reg1_rdata_i(ie_rs1_rdata_o),
|
.reg1_rdata_i(ie_rs1_rdata_o),
|
||||||
.reg2_rdata_i(ie_rs2_rdata_o),
|
.reg2_rdata_i(ie_rs2_rdata_o),
|
||||||
.mem_rdata_i(dbus_data_i),
|
.mem_rdata_i(dbus_data_i),
|
||||||
.mem_req_ready_i(dbus_req_ready_i),
|
.mem_req_ready_i(dbus_req_ready_i),
|
||||||
.mem_rsp_valid_i(dbus_rsp_valid_i),
|
.mem_rsp_valid_i(dbus_rsp_valid_i),
|
||||||
.mem_wdata_o(ex_mem_wdata_o),
|
.mem_wdata_o(ex_mem_wdata_o),
|
||||||
.mem_addr_o(ex_mem_addr_o),
|
.mem_addr_o(ex_mem_addr_o),
|
||||||
.mem_we_o(ex_mem_we_o),
|
.mem_we_o(ex_mem_we_o),
|
||||||
.mem_sel_o(ex_mem_sel_o),
|
.mem_sel_o(ex_mem_sel_o),
|
||||||
.mem_req_valid_o(ex_mem_req_valid_o),
|
.mem_req_valid_o(ex_mem_req_valid_o),
|
||||||
.mem_rsp_ready_o(ex_mem_rsp_ready_o),
|
.mem_rsp_ready_o(ex_mem_rsp_ready_o),
|
||||||
.mem_access_misaligned_o(ex_mem_access_misaligned_o),
|
.mem_access_misaligned_o(ex_mem_access_misaligned_o),
|
||||||
.reg_wdata_o(ex_reg_wdata_o),
|
.reg_wdata_o(ex_reg_wdata_o),
|
||||||
.reg_we_o(ex_reg_we_o),
|
.reg_we_o(ex_reg_we_o),
|
||||||
.reg_waddr_o(ex_reg_waddr_o),
|
.reg_waddr_o(ex_reg_waddr_o),
|
||||||
.hold_flag_o(ex_hold_flag_o),
|
.hold_flag_o(ex_hold_flag_o),
|
||||||
.jump_flag_o(ex_jump_flag_o),
|
.jump_flag_o(ex_jump_flag_o),
|
||||||
.jump_addr_o(ex_jump_addr_o),
|
.jump_addr_o(ex_jump_addr_o),
|
||||||
.int_assert_i(clint_int_assert_o),
|
.int_assert_i(clint_int_assert_o),
|
||||||
.int_addr_i(clint_int_addr_o),
|
.int_addr_i(clint_int_addr_o),
|
||||||
.inst_ecall_o(ex_inst_ecall_o),
|
.inst_ecall_o(ex_inst_ecall_o),
|
||||||
.inst_ebreak_o(ex_inst_ebreak_o),
|
.inst_ebreak_o(ex_inst_ebreak_o),
|
||||||
.inst_mret_o(ex_inst_mret_o),
|
.inst_mret_o(ex_inst_mret_o),
|
||||||
.int_stall_i(clint_stall_flag_o),
|
.int_stall_i(clint_stall_flag_o),
|
||||||
.csr_raddr_o(ex_csr_raddr_o),
|
.csr_raddr_o(ex_csr_raddr_o),
|
||||||
.csr_rdata_i(csr_ex_data_o),
|
.csr_rdata_i(csr_ex_data_o),
|
||||||
.csr_wdata_o(ex_csr_wdata_o),
|
.csr_wdata_o(ex_csr_wdata_o),
|
||||||
.csr_we_o(ex_csr_we_o),
|
.csr_we_o(ex_csr_we_o),
|
||||||
.csr_waddr_o(ex_csr_waddr_o),
|
.csr_waddr_o(ex_csr_waddr_o),
|
||||||
.dec_info_bus_i(ie_dec_info_bus_o),
|
.dec_info_bus_i(ie_dec_info_bus_o),
|
||||||
.dec_imm_i(ie_dec_imm_o),
|
.dec_imm_i(ie_dec_imm_o),
|
||||||
.dec_pc_i(ie_dec_pc_o),
|
.dec_pc_i(ie_dec_pc_o),
|
||||||
.next_pc_i(if_inst_addr_o),
|
.next_pc_i(if_inst_addr_o),
|
||||||
.rd_waddr_i(ie_rd_waddr_o),
|
.rd_waddr_i(ie_rd_waddr_o),
|
||||||
.rd_we_i(ie_rd_we_o)
|
.rd_we_i(ie_rd_we_o)
|
||||||
);
|
);
|
||||||
|
|
||||||
clint u_clint(
|
clint u_clint(
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.rst_n(rst_n),
|
.rst_n(rst_n),
|
||||||
.int_flag_i(int_i),
|
.int_flag_i(int_i),
|
||||||
.inst_ecall_i(ex_inst_ecall_o),
|
.inst_ecall_i(ex_inst_ecall_o),
|
||||||
.inst_ebreak_i(ex_inst_ebreak_o),
|
.inst_ebreak_i(ex_inst_ebreak_o),
|
||||||
.inst_mret_i(ex_inst_mret_o),
|
.inst_mret_i(ex_inst_mret_o),
|
||||||
.inst_addr_i(ie_dec_pc_o),
|
.inst_addr_i(ie_dec_pc_o),
|
||||||
.jump_flag_i(ex_jump_flag_o),
|
.jump_flag_i(ex_jump_flag_o),
|
||||||
.mem_access_misaligned_i(ex_mem_access_misaligned_o),
|
.mem_access_misaligned_i(ex_mem_access_misaligned_o),
|
||||||
.csr_mtvec_i(csr_mtvec_o),
|
.csr_mtvec_i(csr_mtvec_o),
|
||||||
.csr_mepc_i(csr_mepc_o),
|
.csr_mepc_i(csr_mepc_o),
|
||||||
.csr_mstatus_i(csr_mstatus_o),
|
.csr_mstatus_i(csr_mstatus_o),
|
||||||
.csr_we_o(clint_csr_we_o),
|
.csr_we_o(clint_csr_we_o),
|
||||||
.csr_waddr_o(clint_csr_waddr_o),
|
.csr_waddr_o(clint_csr_waddr_o),
|
||||||
.csr_wdata_o(clint_csr_wdata_o),
|
.csr_wdata_o(clint_csr_wdata_o),
|
||||||
.stall_flag_o(clint_stall_flag_o),
|
.stall_flag_o(clint_stall_flag_o),
|
||||||
.int_addr_o(clint_int_addr_o),
|
.int_addr_o(clint_int_addr_o),
|
||||||
.int_assert_o(clint_int_assert_o)
|
.int_assert_o(clint_int_assert_o)
|
||||||
);
|
);
|
||||||
|
|
||||||
endmodule
|
`ifdef TRACE_ENABLED
|
||||||
|
tracer u_tracer(
|
||||||
|
|
||||||
|
);
|
||||||
|
`endif
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
|
@ -0,0 +1,612 @@
|
||||||
|
/*
|
||||||
|
Copyright 2021 Blue Liang, liangkangnan@163.com
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module tracer(
|
||||||
|
input logic clk,
|
||||||
|
input logic rst_n,
|
||||||
|
|
||||||
|
input logic[31:0] inst_i,
|
||||||
|
input logic[31:0] pc_i,
|
||||||
|
input logic inst_valid_i
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum logic [6:0] {
|
||||||
|
OPCODE_LOAD = 7'h03,
|
||||||
|
OPCODE_MISC_MEM = 7'h0f,
|
||||||
|
OPCODE_OP_IMM = 7'h13,
|
||||||
|
OPCODE_AUIPC = 7'h17,
|
||||||
|
OPCODE_STORE = 7'h23,
|
||||||
|
OPCODE_OP = 7'h33,
|
||||||
|
OPCODE_LUI = 7'h37,
|
||||||
|
OPCODE_BRANCH = 7'h63,
|
||||||
|
OPCODE_JALR = 7'h67,
|
||||||
|
OPCODE_JAL = 7'h6f,
|
||||||
|
OPCODE_SYSTEM = 7'h73
|
||||||
|
} opcode_e;
|
||||||
|
|
||||||
|
|
||||||
|
// instruction masks (for tracer)
|
||||||
|
parameter logic [31:0] INSN_LUI = { 25'h?, {OPCODE_LUI } };
|
||||||
|
parameter logic [31:0] INSN_AUIPC = { 25'h?, {OPCODE_AUIPC} };
|
||||||
|
parameter logic [31:0] INSN_JAL = { 25'h?, {OPCODE_JAL } };
|
||||||
|
parameter logic [31:0] INSN_JALR = { 17'h?, 3'b000, 5'h?, {OPCODE_JALR } };
|
||||||
|
|
||||||
|
// BRANCH
|
||||||
|
parameter logic [31:0] INSN_BEQ = { 17'h?, 3'b000, 5'h?, {OPCODE_BRANCH} };
|
||||||
|
parameter logic [31:0] INSN_BNE = { 17'h?, 3'b001, 5'h?, {OPCODE_BRANCH} };
|
||||||
|
parameter logic [31:0] INSN_BLT = { 17'h?, 3'b100, 5'h?, {OPCODE_BRANCH} };
|
||||||
|
parameter logic [31:0] INSN_BGE = { 17'h?, 3'b101, 5'h?, {OPCODE_BRANCH} };
|
||||||
|
parameter logic [31:0] INSN_BLTU = { 17'h?, 3'b110, 5'h?, {OPCODE_BRANCH} };
|
||||||
|
parameter logic [31:0] INSN_BGEU = { 17'h?, 3'b111, 5'h?, {OPCODE_BRANCH} };
|
||||||
|
|
||||||
|
// OPIMM
|
||||||
|
parameter logic [31:0] INSN_ADDI = { 17'h?, 3'b000, 5'h?, {OPCODE_OP_IMM} };
|
||||||
|
parameter logic [31:0] INSN_SLTI = { 17'h?, 3'b010, 5'h?, {OPCODE_OP_IMM} };
|
||||||
|
parameter logic [31:0] INSN_SLTIU = { 17'h?, 3'b011, 5'h?, {OPCODE_OP_IMM} };
|
||||||
|
parameter logic [31:0] INSN_XORI = { 17'h?, 3'b100, 5'h?, {OPCODE_OP_IMM} };
|
||||||
|
parameter logic [31:0] INSN_ORI = { 17'h?, 3'b110, 5'h?, {OPCODE_OP_IMM} };
|
||||||
|
parameter logic [31:0] INSN_ANDI = { 17'h?, 3'b111, 5'h?, {OPCODE_OP_IMM} };
|
||||||
|
parameter logic [31:0] INSN_SLLI = { 7'b0000000, 10'h?, 3'b001, 5'h?, {OPCODE_OP_IMM} };
|
||||||
|
parameter logic [31:0] INSN_SRLI = { 7'b0000000, 10'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} };
|
||||||
|
parameter logic [31:0] INSN_SRAI = { 7'b0100000, 10'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} };
|
||||||
|
|
||||||
|
// OP
|
||||||
|
parameter logic [31:0] INSN_ADD = { 7'b0000000, 10'h?, 3'b000, 5'h?, {OPCODE_OP} };
|
||||||
|
parameter logic [31:0] INSN_SUB = { 7'b0100000, 10'h?, 3'b000, 5'h?, {OPCODE_OP} };
|
||||||
|
parameter logic [31:0] INSN_SLL = { 7'b0000000, 10'h?, 3'b001, 5'h?, {OPCODE_OP} };
|
||||||
|
parameter logic [31:0] INSN_SLT = { 7'b0000000, 10'h?, 3'b010, 5'h?, {OPCODE_OP} };
|
||||||
|
parameter logic [31:0] INSN_SLTU = { 7'b0000000, 10'h?, 3'b011, 5'h?, {OPCODE_OP} };
|
||||||
|
parameter logic [31:0] INSN_XOR = { 7'b0000000, 10'h?, 3'b100, 5'h?, {OPCODE_OP} };
|
||||||
|
parameter logic [31:0] INSN_SRL = { 7'b0000000, 10'h?, 3'b101, 5'h?, {OPCODE_OP} };
|
||||||
|
parameter logic [31:0] INSN_SRA = { 7'b0100000, 10'h?, 3'b101, 5'h?, {OPCODE_OP} };
|
||||||
|
parameter logic [31:0] INSN_OR = { 7'b0000000, 10'h?, 3'b110, 5'h?, {OPCODE_OP} };
|
||||||
|
parameter logic [31:0] INSN_AND = { 7'b0000000, 10'h?, 3'b111, 5'h?, {OPCODE_OP} };
|
||||||
|
|
||||||
|
// SYSTEM
|
||||||
|
parameter logic [31:0] INSN_CSRRW = { 17'h?, 3'b001, 5'h?, {OPCODE_SYSTEM} };
|
||||||
|
parameter logic [31:0] INSN_CSRRS = { 17'h?, 3'b010, 5'h?, {OPCODE_SYSTEM} };
|
||||||
|
parameter logic [31:0] INSN_CSRRC = { 17'h?, 3'b011, 5'h?, {OPCODE_SYSTEM} };
|
||||||
|
parameter logic [31:0] INSN_CSRRWI = { 17'h?, 3'b101, 5'h?, {OPCODE_SYSTEM} };
|
||||||
|
parameter logic [31:0] INSN_CSRRSI = { 17'h?, 3'b110, 5'h?, {OPCODE_SYSTEM} };
|
||||||
|
parameter logic [31:0] INSN_CSRRCI = { 17'h?, 3'b111, 5'h?, {OPCODE_SYSTEM} };
|
||||||
|
parameter logic [31:0] INSN_ECALL = { 12'b000000000000, 13'b0, {OPCODE_SYSTEM} };
|
||||||
|
parameter logic [31:0] INSN_EBREAK = { 12'b000000000001, 13'b0, {OPCODE_SYSTEM} };
|
||||||
|
parameter logic [31:0] INSN_MRET = { 12'b001100000010, 13'b0, {OPCODE_SYSTEM} };
|
||||||
|
parameter logic [31:0] INSN_DRET = { 12'b011110110010, 13'b0, {OPCODE_SYSTEM} };
|
||||||
|
parameter logic [31:0] INSN_WFI = { 12'b000100000101, 13'b0, {OPCODE_SYSTEM} };
|
||||||
|
|
||||||
|
// RV32M
|
||||||
|
parameter logic [31:0] INSN_MUL = { 7'b0000001, 10'h?, 3'b000, 5'h?, {OPCODE_OP} };
|
||||||
|
parameter logic [31:0] INSN_MULH = { 7'b0000001, 10'h?, 3'b001, 5'h?, {OPCODE_OP} };
|
||||||
|
parameter logic [31:0] INSN_MULHSU = { 7'b0000001, 10'h?, 3'b010, 5'h?, {OPCODE_OP} };
|
||||||
|
parameter logic [31:0] INSN_MULHU = { 7'b0000001, 10'h?, 3'b011, 5'h?, {OPCODE_OP} };
|
||||||
|
parameter logic [31:0] INSN_DIV = { 7'b0000001, 10'h?, 3'b100, 5'h?, {OPCODE_OP} };
|
||||||
|
parameter logic [31:0] INSN_DIVU = { 7'b0000001, 10'h?, 3'b101, 5'h?, {OPCODE_OP} };
|
||||||
|
parameter logic [31:0] INSN_REM = { 7'b0000001, 10'h?, 3'b110, 5'h?, {OPCODE_OP} };
|
||||||
|
parameter logic [31:0] INSN_REMU = { 7'b0000001, 10'h?, 3'b111, 5'h?, {OPCODE_OP} };
|
||||||
|
|
||||||
|
// LOAD & STORE
|
||||||
|
parameter logic [31:0] INSN_LOAD = {25'h?, {OPCODE_LOAD } };
|
||||||
|
parameter logic [31:0] INSN_STORE = {25'h?, {OPCODE_STORE} };
|
||||||
|
|
||||||
|
// MISC-MEM
|
||||||
|
parameter logic [31:0] INSN_FENCE = { 17'h?, 3'b000, 5'h?, {OPCODE_MISC_MEM} };
|
||||||
|
parameter logic [31:0] INSN_FENCEI = { 17'h0, 3'b001, 5'h0, {OPCODE_MISC_MEM} };
|
||||||
|
|
||||||
|
// Get a CSR name for a CSR address.
|
||||||
|
function automatic string get_csr_name(input logic [11:0] csr_addr);
|
||||||
|
unique case (csr_addr)
|
||||||
|
12'd0: return "ustatus";
|
||||||
|
12'd4: return "uie";
|
||||||
|
12'd5: return "utvec";
|
||||||
|
12'd64: return "uscratch";
|
||||||
|
12'd65: return "uepc";
|
||||||
|
12'd66: return "ucause";
|
||||||
|
12'd67: return "utval";
|
||||||
|
12'd68: return "uip";
|
||||||
|
12'd1: return "fflags";
|
||||||
|
12'd2: return "frm";
|
||||||
|
12'd3: return "fcsr";
|
||||||
|
12'd3072: return "cycle";
|
||||||
|
12'd3073: return "time";
|
||||||
|
12'd3074: return "instret";
|
||||||
|
12'd3075: return "hpmcounter3";
|
||||||
|
12'd3076: return "hpmcounter4";
|
||||||
|
12'd3077: return "hpmcounter5";
|
||||||
|
12'd3078: return "hpmcounter6";
|
||||||
|
12'd3079: return "hpmcounter7";
|
||||||
|
12'd3080: return "hpmcounter8";
|
||||||
|
12'd3081: return "hpmcounter9";
|
||||||
|
12'd3082: return "hpmcounter10";
|
||||||
|
12'd3083: return "hpmcounter11";
|
||||||
|
12'd3084: return "hpmcounter12";
|
||||||
|
12'd3085: return "hpmcounter13";
|
||||||
|
12'd3086: return "hpmcounter14";
|
||||||
|
12'd3087: return "hpmcounter15";
|
||||||
|
12'd3088: return "hpmcounter16";
|
||||||
|
12'd3089: return "hpmcounter17";
|
||||||
|
12'd3090: return "hpmcounter18";
|
||||||
|
12'd3091: return "hpmcounter19";
|
||||||
|
12'd3092: return "hpmcounter20";
|
||||||
|
12'd3093: return "hpmcounter21";
|
||||||
|
12'd3094: return "hpmcounter22";
|
||||||
|
12'd3095: return "hpmcounter23";
|
||||||
|
12'd3096: return "hpmcounter24";
|
||||||
|
12'd3097: return "hpmcounter25";
|
||||||
|
12'd3098: return "hpmcounter26";
|
||||||
|
12'd3099: return "hpmcounter27";
|
||||||
|
12'd3100: return "hpmcounter28";
|
||||||
|
12'd3101: return "hpmcounter29";
|
||||||
|
12'd3102: return "hpmcounter30";
|
||||||
|
12'd3103: return "hpmcounter31";
|
||||||
|
12'd3200: return "cycleh";
|
||||||
|
12'd3201: return "timeh";
|
||||||
|
12'd3202: return "instreth";
|
||||||
|
12'd3203: return "hpmcounter3h";
|
||||||
|
12'd3204: return "hpmcounter4h";
|
||||||
|
12'd3205: return "hpmcounter5h";
|
||||||
|
12'd3206: return "hpmcounter6h";
|
||||||
|
12'd3207: return "hpmcounter7h";
|
||||||
|
12'd3208: return "hpmcounter8h";
|
||||||
|
12'd3209: return "hpmcounter9h";
|
||||||
|
12'd3210: return "hpmcounter10h";
|
||||||
|
12'd3211: return "hpmcounter11h";
|
||||||
|
12'd3212: return "hpmcounter12h";
|
||||||
|
12'd3213: return "hpmcounter13h";
|
||||||
|
12'd3214: return "hpmcounter14h";
|
||||||
|
12'd3215: return "hpmcounter15h";
|
||||||
|
12'd3216: return "hpmcounter16h";
|
||||||
|
12'd3217: return "hpmcounter17h";
|
||||||
|
12'd3218: return "hpmcounter18h";
|
||||||
|
12'd3219: return "hpmcounter19h";
|
||||||
|
12'd3220: return "hpmcounter20h";
|
||||||
|
12'd3221: return "hpmcounter21h";
|
||||||
|
12'd3222: return "hpmcounter22h";
|
||||||
|
12'd3223: return "hpmcounter23h";
|
||||||
|
12'd3224: return "hpmcounter24h";
|
||||||
|
12'd3225: return "hpmcounter25h";
|
||||||
|
12'd3226: return "hpmcounter26h";
|
||||||
|
12'd3227: return "hpmcounter27h";
|
||||||
|
12'd3228: return "hpmcounter28h";
|
||||||
|
12'd3229: return "hpmcounter29h";
|
||||||
|
12'd3230: return "hpmcounter30h";
|
||||||
|
12'd3231: return "hpmcounter31h";
|
||||||
|
12'd256: return "sstatus";
|
||||||
|
12'd258: return "sedeleg";
|
||||||
|
12'd259: return "sideleg";
|
||||||
|
12'd260: return "sie";
|
||||||
|
12'd261: return "stvec";
|
||||||
|
12'd262: return "scounteren";
|
||||||
|
12'd320: return "sscratch";
|
||||||
|
12'd321: return "sepc";
|
||||||
|
12'd322: return "scause";
|
||||||
|
12'd323: return "stval";
|
||||||
|
12'd324: return "sip";
|
||||||
|
12'd384: return "satp";
|
||||||
|
12'd3857: return "mvendorid";
|
||||||
|
12'd3858: return "marchid";
|
||||||
|
12'd3859: return "mimpid";
|
||||||
|
12'd3860: return "mhartid";
|
||||||
|
12'd768: return "mstatus";
|
||||||
|
12'd769: return "misa";
|
||||||
|
12'd770: return "medeleg";
|
||||||
|
12'd771: return "mideleg";
|
||||||
|
12'd772: return "mie";
|
||||||
|
12'd773: return "mtvec";
|
||||||
|
12'd774: return "mcounteren";
|
||||||
|
12'd832: return "mscratch";
|
||||||
|
12'd833: return "mepc";
|
||||||
|
12'd834: return "mcause";
|
||||||
|
12'd835: return "mtval";
|
||||||
|
12'd836: return "mip";
|
||||||
|
12'd928: return "pmpcfg0";
|
||||||
|
12'd929: return "pmpcfg1";
|
||||||
|
12'd930: return "pmpcfg2";
|
||||||
|
12'd931: return "pmpcfg3";
|
||||||
|
12'd944: return "pmpaddr0";
|
||||||
|
12'd945: return "pmpaddr1";
|
||||||
|
12'd946: return "pmpaddr2";
|
||||||
|
12'd947: return "pmpaddr3";
|
||||||
|
12'd948: return "pmpaddr4";
|
||||||
|
12'd949: return "pmpaddr5";
|
||||||
|
12'd950: return "pmpaddr6";
|
||||||
|
12'd951: return "pmpaddr7";
|
||||||
|
12'd952: return "pmpaddr8";
|
||||||
|
12'd953: return "pmpaddr9";
|
||||||
|
12'd954: return "pmpaddr10";
|
||||||
|
12'd955: return "pmpaddr11";
|
||||||
|
12'd956: return "pmpaddr12";
|
||||||
|
12'd957: return "pmpaddr13";
|
||||||
|
12'd958: return "pmpaddr14";
|
||||||
|
12'd959: return "pmpaddr15";
|
||||||
|
12'd2816: return "mcycle";
|
||||||
|
12'd2818: return "minstret";
|
||||||
|
12'd2819: return "mhpmcounter3";
|
||||||
|
12'd2820: return "mhpmcounter4";
|
||||||
|
12'd2821: return "mhpmcounter5";
|
||||||
|
12'd2822: return "mhpmcounter6";
|
||||||
|
12'd2823: return "mhpmcounter7";
|
||||||
|
12'd2824: return "mhpmcounter8";
|
||||||
|
12'd2825: return "mhpmcounter9";
|
||||||
|
12'd2826: return "mhpmcounter10";
|
||||||
|
12'd2827: return "mhpmcounter11";
|
||||||
|
12'd2828: return "mhpmcounter12";
|
||||||
|
12'd2829: return "mhpmcounter13";
|
||||||
|
12'd2830: return "mhpmcounter14";
|
||||||
|
12'd2831: return "mhpmcounter15";
|
||||||
|
12'd2832: return "mhpmcounter16";
|
||||||
|
12'd2833: return "mhpmcounter17";
|
||||||
|
12'd2834: return "mhpmcounter18";
|
||||||
|
12'd2835: return "mhpmcounter19";
|
||||||
|
12'd2836: return "mhpmcounter20";
|
||||||
|
12'd2837: return "mhpmcounter21";
|
||||||
|
12'd2838: return "mhpmcounter22";
|
||||||
|
12'd2839: return "mhpmcounter23";
|
||||||
|
12'd2840: return "mhpmcounter24";
|
||||||
|
12'd2841: return "mhpmcounter25";
|
||||||
|
12'd2842: return "mhpmcounter26";
|
||||||
|
12'd2843: return "mhpmcounter27";
|
||||||
|
12'd2844: return "mhpmcounter28";
|
||||||
|
12'd2845: return "mhpmcounter29";
|
||||||
|
12'd2846: return "mhpmcounter30";
|
||||||
|
12'd2847: return "mhpmcounter31";
|
||||||
|
12'd2944: return "mcycleh";
|
||||||
|
12'd2946: return "minstreth";
|
||||||
|
12'd2947: return "mhpmcounter3h";
|
||||||
|
12'd2948: return "mhpmcounter4h";
|
||||||
|
12'd2949: return "mhpmcounter5h";
|
||||||
|
12'd2950: return "mhpmcounter6h";
|
||||||
|
12'd2951: return "mhpmcounter7h";
|
||||||
|
12'd2952: return "mhpmcounter8h";
|
||||||
|
12'd2953: return "mhpmcounter9h";
|
||||||
|
12'd2954: return "mhpmcounter10h";
|
||||||
|
12'd2955: return "mhpmcounter11h";
|
||||||
|
12'd2956: return "mhpmcounter12h";
|
||||||
|
12'd2957: return "mhpmcounter13h";
|
||||||
|
12'd2958: return "mhpmcounter14h";
|
||||||
|
12'd2959: return "mhpmcounter15h";
|
||||||
|
12'd2960: return "mhpmcounter16h";
|
||||||
|
12'd2961: return "mhpmcounter17h";
|
||||||
|
12'd2962: return "mhpmcounter18h";
|
||||||
|
12'd2963: return "mhpmcounter19h";
|
||||||
|
12'd2964: return "mhpmcounter20h";
|
||||||
|
12'd2965: return "mhpmcounter21h";
|
||||||
|
12'd2966: return "mhpmcounter22h";
|
||||||
|
12'd2967: return "mhpmcounter23h";
|
||||||
|
12'd2968: return "mhpmcounter24h";
|
||||||
|
12'd2969: return "mhpmcounter25h";
|
||||||
|
12'd2970: return "mhpmcounter26h";
|
||||||
|
12'd2971: return "mhpmcounter27h";
|
||||||
|
12'd2972: return "mhpmcounter28h";
|
||||||
|
12'd2973: return "mhpmcounter29h";
|
||||||
|
12'd2974: return "mhpmcounter30h";
|
||||||
|
12'd2975: return "mhpmcounter31h";
|
||||||
|
12'd803: return "mhpmevent3";
|
||||||
|
12'd804: return "mhpmevent4";
|
||||||
|
12'd805: return "mhpmevent5";
|
||||||
|
12'd806: return "mhpmevent6";
|
||||||
|
12'd807: return "mhpmevent7";
|
||||||
|
12'd808: return "mhpmevent8";
|
||||||
|
12'd809: return "mhpmevent9";
|
||||||
|
12'd810: return "mhpmevent10";
|
||||||
|
12'd811: return "mhpmevent11";
|
||||||
|
12'd812: return "mhpmevent12";
|
||||||
|
12'd813: return "mhpmevent13";
|
||||||
|
12'd814: return "mhpmevent14";
|
||||||
|
12'd815: return "mhpmevent15";
|
||||||
|
12'd816: return "mhpmevent16";
|
||||||
|
12'd817: return "mhpmevent17";
|
||||||
|
12'd818: return "mhpmevent18";
|
||||||
|
12'd819: return "mhpmevent19";
|
||||||
|
12'd820: return "mhpmevent20";
|
||||||
|
12'd821: return "mhpmevent21";
|
||||||
|
12'd822: return "mhpmevent22";
|
||||||
|
12'd823: return "mhpmevent23";
|
||||||
|
12'd824: return "mhpmevent24";
|
||||||
|
12'd825: return "mhpmevent25";
|
||||||
|
12'd826: return "mhpmevent26";
|
||||||
|
12'd827: return "mhpmevent27";
|
||||||
|
12'd828: return "mhpmevent28";
|
||||||
|
12'd829: return "mhpmevent29";
|
||||||
|
12'd830: return "mhpmevent30";
|
||||||
|
12'd831: return "mhpmevent31";
|
||||||
|
12'd1952: return "tselect";
|
||||||
|
12'd1953: return "tdata1";
|
||||||
|
12'd1954: return "tdata2";
|
||||||
|
12'd1955: return "tdata3";
|
||||||
|
12'd1968: return "dcsr";
|
||||||
|
12'd1969: return "dpc";
|
||||||
|
12'd1970: return "dscratch";
|
||||||
|
12'd512: return "hstatus";
|
||||||
|
12'd514: return "hedeleg";
|
||||||
|
12'd515: return "hideleg";
|
||||||
|
12'd516: return "hie";
|
||||||
|
12'd517: return "htvec";
|
||||||
|
12'd576: return "hscratch";
|
||||||
|
12'd577: return "hepc";
|
||||||
|
12'd578: return "hcause";
|
||||||
|
12'd579: return "hbadaddr";
|
||||||
|
12'd580: return "hip";
|
||||||
|
12'd896: return "mbase";
|
||||||
|
12'd897: return "mbound";
|
||||||
|
12'd898: return "mibase";
|
||||||
|
12'd899: return "mibound";
|
||||||
|
12'd900: return "mdbase";
|
||||||
|
12'd901: return "mdbound";
|
||||||
|
12'd800: return "mcountinhibit";
|
||||||
|
default: return $sformatf("0x%x", csr_addr);
|
||||||
|
endcase
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
int unsigned cycle;
|
||||||
|
string decoded_str;
|
||||||
|
int file_handle;
|
||||||
|
string file_name;
|
||||||
|
|
||||||
|
logic[4:0] rd_addr = inst_i[11:7];
|
||||||
|
logic[4:0] rs1_addr = inst_i[19:15];
|
||||||
|
logic[4:0] rs2_addr = inst_i[24:20];
|
||||||
|
|
||||||
|
|
||||||
|
function automatic void decode_u_insn(input string mnemonic);
|
||||||
|
decoded_str = $sformatf("%s\tx%0d,0x%0x", mnemonic, rd_addr, {inst_i[31:12]});
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function automatic void decode_j_insn(input string mnemonic);
|
||||||
|
decoded_str = $sformatf("%s\tx%0d,%0x", mnemonic, rd_addr,
|
||||||
|
{{12{inst_i[31]}}, inst_i[19:12], inst_i[20], inst_i[30:21], 1'b0});
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function automatic void decode_i_jalr_insn(input string mnemonic);
|
||||||
|
decoded_str = $sformatf("%s\tx%0d,%0d(x%0d)", mnemonic, rd_addr,
|
||||||
|
$signed({{20 {inst_i[31]}}, inst_i[31:20]}), rs1_addr);
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function automatic void decode_b_insn(input string mnemonic);
|
||||||
|
logic [31:0] branch_target;
|
||||||
|
logic [31:0] imm;
|
||||||
|
|
||||||
|
// We cannot use rvfi_pc_wdata for conditional jumps.
|
||||||
|
imm = $signed({ {19 {inst_i[31]}}, inst_i[31], inst_i[7],
|
||||||
|
inst_i[30:25], inst_i[11:8], 1'b0 });
|
||||||
|
branch_target = pc_i + imm;
|
||||||
|
|
||||||
|
decoded_str = $sformatf("%s\tx%0d,x%0d,%0x", mnemonic, rs1_addr, rs2_addr, branch_target);
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function automatic void decode_i_insn(input string mnemonic);
|
||||||
|
decoded_str = $sformatf("%s\tx%0d,x%0d,%0d", mnemonic, rd_addr, rs1_addr,
|
||||||
|
$signed({{20 {inst_i[31]}}, inst_i[31:20]}));
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function automatic void decode_i_shift_insn(input string mnemonic);
|
||||||
|
logic [4:0] shamt;
|
||||||
|
|
||||||
|
shamt = {inst_i[24:20]};
|
||||||
|
decoded_str = $sformatf("%s\tx%0d,x%0d,0x%0x", mnemonic, rd_addr, rs1_addr, shamt);
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function automatic void decode_r_insn(input string mnemonic);
|
||||||
|
decoded_str = $sformatf("%s\tx%0d,x%0d,x%0d", mnemonic, rd_addr, rs1_addr, rs2_addr);
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function automatic void decode_csr_insn(input string mnemonic);
|
||||||
|
logic [11:0] csr;
|
||||||
|
string csr_name;
|
||||||
|
|
||||||
|
csr = inst_i[31:20];
|
||||||
|
csr_name = get_csr_name(csr);
|
||||||
|
|
||||||
|
if (!inst_i[14]) begin
|
||||||
|
decoded_str = $sformatf("%s\tx%0d,%s,x%0d", mnemonic, rd_addr, csr_name, rs1_addr);
|
||||||
|
end else begin
|
||||||
|
decoded_str = $sformatf("%s\tx%0d,%s,%0d", mnemonic, rd_addr, csr_name, { 27'b0, inst_i[19:15]});
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function automatic void decode_mnemonic(input string mnemonic);
|
||||||
|
decoded_str = mnemonic;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function automatic void decode_load_insn();
|
||||||
|
string mnemonic;
|
||||||
|
|
||||||
|
logic [2:0] size;
|
||||||
|
size = inst_i[14:12];
|
||||||
|
if (size == 3'b000) begin
|
||||||
|
mnemonic = "lb";
|
||||||
|
end else if (size == 3'b001) begin
|
||||||
|
mnemonic = "lh";
|
||||||
|
end else if (size == 3'b010) begin
|
||||||
|
mnemonic = "lw";
|
||||||
|
end else if (size == 3'b100) begin
|
||||||
|
mnemonic = "lbu";
|
||||||
|
end else if (size == 3'b101) begin
|
||||||
|
mnemonic = "lhu";
|
||||||
|
end else begin
|
||||||
|
decode_mnemonic("INVALID");
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
decoded_str = $sformatf("%s\tx%0d,%0d(x%0d)", mnemonic, rd_addr,
|
||||||
|
$signed({{20 {inst_i[31]}}, inst_i[31:20]}), rs1_addr);
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function automatic void decode_store_insn();
|
||||||
|
string mnemonic;
|
||||||
|
|
||||||
|
if (inst_i[13:12] == 2'b00) begin
|
||||||
|
mnemonic = "sb";
|
||||||
|
end else if (inst_i[13:12] == 2'b01) begin
|
||||||
|
mnemonic = "sh";
|
||||||
|
end else if (inst_i[13:12] == 2'b10) begin
|
||||||
|
mnemonic = "sw";
|
||||||
|
end else begin
|
||||||
|
decode_mnemonic("INVALID");
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (!inst_i[14]) begin
|
||||||
|
decoded_str = $sformatf("%s\tx%0d,%0d(x%0d)", mnemonic, rs2_addr,
|
||||||
|
$signed({ {20 {inst_i[31]}}, inst_i[31:25], inst_i[11:7] }), rs1_addr);
|
||||||
|
end else begin
|
||||||
|
decode_mnemonic("INVALID");
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function automatic string get_fence_description(logic [3:0] bits);
|
||||||
|
string desc = "";
|
||||||
|
|
||||||
|
if (bits[3]) begin
|
||||||
|
desc = {desc, "i"};
|
||||||
|
end
|
||||||
|
if (bits[2]) begin
|
||||||
|
desc = {desc, "o"};
|
||||||
|
end
|
||||||
|
if (bits[1]) begin
|
||||||
|
desc = {desc, "r"};
|
||||||
|
end
|
||||||
|
if (bits[0]) begin
|
||||||
|
desc = {desc, "w"};
|
||||||
|
end
|
||||||
|
return desc;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function automatic void decode_fence();
|
||||||
|
string predecessor;
|
||||||
|
string successor;
|
||||||
|
|
||||||
|
predecessor = get_fence_description(inst_i[27:24]);
|
||||||
|
successor = get_fence_description(inst_i[23:20]);
|
||||||
|
decoded_str = $sformatf("fence\t%s,%s", predecessor, successor);
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
decoded_str = "";
|
||||||
|
|
||||||
|
unique casez (inst_i)
|
||||||
|
INSN_LUI: decode_u_insn("lui");
|
||||||
|
INSN_AUIPC: decode_u_insn("auipc");
|
||||||
|
INSN_JAL: decode_j_insn("jal");
|
||||||
|
INSN_JALR: decode_i_jalr_insn("jalr");
|
||||||
|
// BRANCH
|
||||||
|
INSN_BEQ: decode_b_insn("beq");
|
||||||
|
INSN_BNE: decode_b_insn("bne");
|
||||||
|
INSN_BLT: decode_b_insn("blt");
|
||||||
|
INSN_BGE: decode_b_insn("bge");
|
||||||
|
INSN_BLTU: decode_b_insn("bltu");
|
||||||
|
INSN_BGEU: decode_b_insn("bgeu");
|
||||||
|
// OPIMM
|
||||||
|
INSN_ADDI: begin
|
||||||
|
if (inst_i == 32'h00_00_00_13) begin
|
||||||
|
// TODO: objdump doesn't decode this as nop currently, even though it would be helpful
|
||||||
|
// Decide what to do here: diverge from objdump, or make the trace less readable to
|
||||||
|
// users.
|
||||||
|
//decode_mnemonic("nop");
|
||||||
|
decode_i_insn("addi");
|
||||||
|
end else begin
|
||||||
|
decode_i_insn("addi");
|
||||||
|
end
|
||||||
|
end
|
||||||
|
INSN_SLTI: decode_i_insn("slti");
|
||||||
|
INSN_SLTIU: decode_i_insn("sltiu");
|
||||||
|
INSN_XORI: decode_i_insn("xori");
|
||||||
|
INSN_ORI: decode_i_insn("ori");
|
||||||
|
INSN_ANDI: decode_i_insn("andi");
|
||||||
|
INSN_SLLI: decode_i_shift_insn("slli");
|
||||||
|
INSN_SRLI: decode_i_shift_insn("srli");
|
||||||
|
INSN_SRAI: decode_i_shift_insn("srai");
|
||||||
|
// OP
|
||||||
|
INSN_ADD: decode_r_insn("add");
|
||||||
|
INSN_SUB: decode_r_insn("sub");
|
||||||
|
INSN_SLL: decode_r_insn("sll");
|
||||||
|
INSN_SLT: decode_r_insn("slt");
|
||||||
|
INSN_SLTU: decode_r_insn("sltu");
|
||||||
|
INSN_XOR: decode_r_insn("xor");
|
||||||
|
INSN_SRL: decode_r_insn("srl");
|
||||||
|
INSN_SRA: decode_r_insn("sra");
|
||||||
|
INSN_OR: decode_r_insn("or");
|
||||||
|
INSN_AND: decode_r_insn("and");
|
||||||
|
// SYSTEM (CSR manipulation)
|
||||||
|
INSN_CSRRW: decode_csr_insn("csrrw");
|
||||||
|
INSN_CSRRS: decode_csr_insn("csrrs");
|
||||||
|
INSN_CSRRC: decode_csr_insn("csrrc");
|
||||||
|
INSN_CSRRWI: decode_csr_insn("csrrwi");
|
||||||
|
INSN_CSRRSI: decode_csr_insn("csrrsi");
|
||||||
|
INSN_CSRRCI: decode_csr_insn("csrrci");
|
||||||
|
// SYSTEM (others)
|
||||||
|
INSN_ECALL: decode_mnemonic("ecall");
|
||||||
|
INSN_EBREAK: decode_mnemonic("ebreak");
|
||||||
|
INSN_MRET: decode_mnemonic("mret");
|
||||||
|
INSN_DRET: decode_mnemonic("dret");
|
||||||
|
INSN_WFI: decode_mnemonic("wfi");
|
||||||
|
// RV32M
|
||||||
|
INSN_MUL: decode_r_insn("mul");
|
||||||
|
INSN_MULH: decode_r_insn("mulh");
|
||||||
|
INSN_MULHSU: decode_r_insn("mulhsu");
|
||||||
|
INSN_MULHU: decode_r_insn("mulhu");
|
||||||
|
INSN_DIV: decode_r_insn("div");
|
||||||
|
INSN_DIVU: decode_r_insn("divu");
|
||||||
|
INSN_REM: decode_r_insn("rem");
|
||||||
|
INSN_REMU: decode_r_insn("remu");
|
||||||
|
// LOAD & STORE
|
||||||
|
INSN_LOAD: decode_load_insn();
|
||||||
|
INSN_STORE: decode_store_insn();
|
||||||
|
// MISC-MEM
|
||||||
|
INSN_FENCE: decode_fence();
|
||||||
|
INSN_FENCEI: decode_mnemonic("fence.i");
|
||||||
|
default: decode_mnemonic("INVALID");
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
string file_name_base = "trace_core";
|
||||||
|
$sformat(file_name, "%s.log", file_name_base);
|
||||||
|
|
||||||
|
$display("Writing execution trace to %s", file_name);
|
||||||
|
file_handle = $fopen(file_name, "w");
|
||||||
|
$fwrite(file_handle, "Time\tCycle\tPC\tInsn\tDecoded instruction\n");
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function automatic void printbuffer_dumpline();
|
||||||
|
$fwrite(file_handle, "%15t\t%d\t%h\t%s\t%s", $time, cycle, pc_i, inst_i, decoded_str);
|
||||||
|
$fwrite(file_handle, "\n");
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
// log execution
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (inst_valid_i) begin
|
||||||
|
printbuffer_dumpline();
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// cycle counter
|
||||||
|
always @(posedge clk or negedge rst_n) begin
|
||||||
|
if (!rst_n) begin
|
||||||
|
cycle <= 0;
|
||||||
|
end else begin
|
||||||
|
cycle <= cycle + 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
178
sim/Makefile
178
sim/Makefile
|
@ -1,90 +1,88 @@
|
||||||
|
|
||||||
PROG := ../sdk/examples/simple/simple.mem
|
PROG := ../sdk/examples/simple/simple.mem
|
||||||
PROG_DIR := $(shell dirname $(PROG))
|
PROG_DIR := $(shell dirname $(PROG))
|
||||||
|
|
||||||
MAKE := make
|
MAKE := make
|
||||||
VERILATOR := verilator
|
VERILATOR := verilator
|
||||||
|
|
||||||
VERI_FLAGS += +vcd
|
VERI_FLAGS += +vcd
|
||||||
VERI_CFLAGS +=
|
VERI_CFLAGS +=
|
||||||
|
|
||||||
VERI_VFLAGS += -DRVFI
|
VERI_VFLAGS += -DTRACE_ENABLED
|
||||||
|
|
||||||
TRACE_ENABLE := 1
|
RTL_FILES = ../rtl.flist
|
||||||
|
|
||||||
RTL_FILES = ../rtl.flist
|
VERI_OBJ_DIR := cobj_dir
|
||||||
|
|
||||||
VERI_OBJ_DIR := cobj_dir
|
ifeq ($(findstring +vcd,$(VERI_FLAGS)),+vcd)
|
||||||
|
VERI_TRACE = "--trace"
|
||||||
ifeq ($(findstring +vcd,$(VERI_FLAGS)),+vcd)
|
VERI_CFLAGS += "-DVCD_TRACE"
|
||||||
VERI_TRACE = "--trace"
|
else
|
||||||
VERI_CFLAGS += "-DVCD_TRACE"
|
VERI_TRACE =
|
||||||
else
|
endif
|
||||||
VERI_TRACE =
|
|
||||||
endif
|
SIM_SRC := sim_jtag.sv
|
||||||
|
|
||||||
SIM_SRC := sim_jtag.sv
|
SIM_SRC += tb_top_verilator.sv \
|
||||||
|
tb_top_verilator.cpp
|
||||||
SIM_SRC += tb_top_verilator.sv \
|
|
||||||
tb_top_verilator.cpp
|
SIM_TOP_MODULE := tb_top_verilator
|
||||||
|
|
||||||
SIM_TOP_MODULE := tb_top_verilator
|
.DEFAULT_GOAL := sim
|
||||||
|
all: sim
|
||||||
.DEFAULT_GOAL := sim
|
|
||||||
all: sim
|
.PHONY: recompile
|
||||||
|
recompile:
|
||||||
.PHONY: recompile
|
rm -rf $(VERI_OBJ_DIR) testbench_verilator
|
||||||
recompile:
|
$(MAKE) -C ./remote_bitbang clean
|
||||||
rm -rf $(VERI_OBJ_DIR) testbench_verilator
|
$(MAKE) -C $(PROG_DIR) clean
|
||||||
$(MAKE) -C ./remote_bitbang clean
|
$(MAKE) compile
|
||||||
$(MAKE) -C $(PROG_DIR) clean
|
|
||||||
$(MAKE) compile
|
.PHONY: compile
|
||||||
|
compile: remote_bitbang/librbs.so $(PROG) testbench_verilator
|
||||||
.PHONY: compile
|
|
||||||
compile: remote_bitbang/librbs.so $(PROG) testbench_verilator
|
testbench_verilator:
|
||||||
|
$(VERILATOR) --cc --sv --exe \
|
||||||
testbench_verilator:
|
$(VERI_TRACE) \
|
||||||
$(VERILATOR) --cc --sv --exe \
|
--Wno-lint --Wno-UNOPTFLAT \
|
||||||
$(VERI_TRACE) \
|
--Wno-MODDUP --top-module \
|
||||||
--Wno-lint --Wno-UNOPTFLAT \
|
$(SIM_TOP_MODULE) \
|
||||||
--Wno-MODDUP --top-module \
|
-f $(RTL_FILES) \
|
||||||
$(SIM_TOP_MODULE) \
|
$(SIM_SRC) \
|
||||||
-f $(RTL_FILES) \
|
--Mdir $(VERI_OBJ_DIR) \
|
||||||
$(SIM_SRC) \
|
$(VERI_VFLAGS) \
|
||||||
--Mdir $(VERI_OBJ_DIR) \
|
-LDFLAGS "-L../remote_bitbang \
|
||||||
$(VERI_VFLAGS) \
|
-Wl,--enable-new-dtags -Wl,-rpath,remote_bitbang -lrbs" \
|
||||||
-LDFLAGS "-L../remote_bitbang \
|
-CFLAGS "-std=gnu++11 $(VERI_CFLAGS)"
|
||||||
-Wl,--enable-new-dtags -Wl,-rpath,remote_bitbang -lrbs" \
|
$(MAKE) -C $(VERI_OBJ_DIR) -f V$(SIM_TOP_MODULE).mk
|
||||||
-CFLAGS "-std=gnu++11 $(VERI_CFLAGS)"
|
cp $(VERI_OBJ_DIR)/V$(SIM_TOP_MODULE) testbench_verilator
|
||||||
$(MAKE) -C $(VERI_OBJ_DIR) -f V$(SIM_TOP_MODULE).mk
|
|
||||||
cp $(VERI_OBJ_DIR)/V$(SIM_TOP_MODULE) testbench_verilator
|
remote_bitbang/librbs.so:
|
||||||
|
$(MAKE) -C ./remote_bitbang all
|
||||||
remote_bitbang/librbs.so:
|
|
||||||
$(MAKE) -C ./remote_bitbang all
|
$(PROG):
|
||||||
|
$(MAKE) -C $(PROG_DIR)
|
||||||
$(PROG):
|
|
||||||
$(MAKE) -C $(PROG_DIR)
|
.PHONY: run
|
||||||
|
run:
|
||||||
.PHONY: run
|
./testbench_verilator "+firmware=$(PROG)"
|
||||||
run:
|
|
||||||
./testbench_verilator "+firmware=$(PROG)"
|
.PHONY: sim
|
||||||
|
sim: recompile run
|
||||||
.PHONY: sim
|
|
||||||
sim: recompile run
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
.PHONY: clean
|
rm -rf $(VERI_OBJ_DIR) testbench_verilator *.log *.vcd
|
||||||
clean:
|
$(MAKE) -C ./remote_bitbang clean
|
||||||
rm -rf $(VERI_OBJ_DIR) testbench_verilator *.log *.vcd
|
$(MAKE) -C $(PROG_DIR) clean
|
||||||
$(MAKE) -C ./remote_bitbang clean
|
|
||||||
$(MAKE) -C $(PROG_DIR) clean
|
.PHONY: help
|
||||||
|
help:
|
||||||
.PHONY: help
|
@echo 'rebuild all:'
|
||||||
help:
|
@echo 'make PROG=/path/file.mem recompile'
|
||||||
@echo 'rebuild all:'
|
@echo 'run directly:'
|
||||||
@echo 'make PROG=/path/file.mem recompile'
|
@echo 'make PROG=/path/file.mem run'
|
||||||
@echo 'run directly:'
|
@echo 'rebuild & run:'
|
||||||
@echo 'make PROG=/path/file.mem run'
|
@echo 'make PROG=/path/file.mem sim'
|
||||||
@echo 'rebuild & run:'
|
@echo 'clean obj files:'
|
||||||
@echo 'make PROG=/path/file.mem sim'
|
@echo 'make PROG=/path/file.mem clean'
|
||||||
@echo 'clean obj files:'
|
|
||||||
@echo 'make PROG=/path/file.mem clean'
|
|
||||||
|
|
|
@ -1,108 +1,107 @@
|
||||||
// Copyright 2018 Robert Balas <balasr@student.ethz.ch>
|
// Copyright 2018 Robert Balas <balasr@student.ethz.ch>
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
|
||||||
// Top level wrapper for a verilator RI5CY testbench
|
// Top level wrapper for a verilator RI5CY testbench
|
||||||
// Contributor: Robert Balas <balasr@student.ethz.ch>
|
// Contributor: Robert Balas <balasr@student.ethz.ch>
|
||||||
|
|
||||||
#include "svdpi.h"
|
#include "svdpi.h"
|
||||||
#include "Vtb_top_verilator__Dpi.h"
|
#include "Vtb_top_verilator__Dpi.h"
|
||||||
#include "Vtb_top_verilator.h"
|
#include "Vtb_top_verilator.h"
|
||||||
#include "verilated_vcd_c.h"
|
#include "verilated_vcd_c.h"
|
||||||
#include "verilated.h"
|
#include "verilated.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
|
|
||||||
//void dump_memory();
|
//void dump_memory();
|
||||||
double sc_time_stamp();
|
double sc_time_stamp();
|
||||||
|
|
||||||
static vluint64_t t = 0;
|
static vluint64_t t = 0;
|
||||||
Vtb_top_verilator *top;
|
Vtb_top_verilator *top;
|
||||||
|
|
||||||
int main(int argc, char **argv, char **env)
|
int main(int argc, char **argv, char **env)
|
||||||
{
|
{
|
||||||
Verilated::commandArgs(argc, argv);
|
Verilated::commandArgs(argc, argv);
|
||||||
Verilated::traceEverOn(true);
|
Verilated::traceEverOn(true);
|
||||||
top = new Vtb_top_verilator();
|
top = new Vtb_top_verilator();
|
||||||
|
|
||||||
//svSetScope(svGetScopeFromName(
|
//svSetScope(svGetScopeFromName(
|
||||||
// "TOP.tb_top_verilator.u_ram.ram"));
|
// "TOP.tb_top_verilator.u_ram.ram"));
|
||||||
//Verilated::scopesDump();
|
//Verilated::scopesDump();
|
||||||
|
|
||||||
#ifdef VCD_TRACE
|
#ifdef VCD_TRACE
|
||||||
VerilatedVcdC *tfp = new VerilatedVcdC;
|
VerilatedVcdC *tfp = new VerilatedVcdC;
|
||||||
top->trace(tfp, 99);
|
top->trace(tfp, 99);
|
||||||
tfp->open("verilator_tb.vcd");
|
tfp->open("verilator_tb.vcd");
|
||||||
#endif
|
#endif
|
||||||
top->fetch_enable_i = 1;
|
top->clk_i = 0;
|
||||||
top->clk_i = 0;
|
top->rst_ni = 0;
|
||||||
top->rst_ni = 0;
|
|
||||||
|
top->eval();
|
||||||
top->eval();
|
//dump_memory();
|
||||||
//dump_memory();
|
|
||||||
|
while (!Verilated::gotFinish()) {
|
||||||
while (!Verilated::gotFinish()) {
|
if (t > 40)
|
||||||
if (t > 40)
|
top->rst_ni = 1;
|
||||||
top->rst_ni = 1;
|
top->clk_i = !top->clk_i;
|
||||||
top->clk_i = !top->clk_i;
|
top->eval();
|
||||||
top->eval();
|
#ifdef VCD_TRACE
|
||||||
#ifdef VCD_TRACE
|
tfp->dump(t);
|
||||||
tfp->dump(t);
|
#endif
|
||||||
#endif
|
t += 5;
|
||||||
t += 5;
|
//if (t > 5000)
|
||||||
if (t > 1000)
|
// break;
|
||||||
break;
|
}
|
||||||
}
|
#ifdef VCD_TRACE
|
||||||
#ifdef VCD_TRACE
|
tfp->close();
|
||||||
tfp->close();
|
#endif
|
||||||
#endif
|
delete top;
|
||||||
delete top;
|
exit(0);
|
||||||
exit(0);
|
}
|
||||||
}
|
|
||||||
|
double sc_time_stamp()
|
||||||
double sc_time_stamp()
|
{
|
||||||
{
|
return t;
|
||||||
return t;
|
}
|
||||||
}
|
/*
|
||||||
/*
|
void dump_memory()
|
||||||
void dump_memory()
|
{
|
||||||
{
|
errno = 0;
|
||||||
errno = 0;
|
std::ofstream mem_file;
|
||||||
std::ofstream mem_file;
|
svLogicVecVal addr = {0};
|
||||||
svLogicVecVal addr = {0};
|
|
||||||
|
mem_file.exceptions(std::ofstream::failbit | std::ofstream::badbit);
|
||||||
mem_file.exceptions(std::ofstream::failbit | std::ofstream::badbit);
|
try {
|
||||||
try {
|
mem_file.open("memory_dump.bin");
|
||||||
mem_file.open("memory_dump.bin");
|
for (size_t i = 0; i < 1048576; i++) {
|
||||||
for (size_t i = 0; i < 1048576; i++) {
|
addr.aval = i;
|
||||||
addr.aval = i;
|
uint32_t val = read_byte(&addr);
|
||||||
uint32_t val = read_byte(&addr);
|
mem_file << std::setfill('0') << std::setw(2) << std::hex << val
|
||||||
mem_file << std::setfill('0') << std::setw(2) << std::hex << val
|
<< std::endl;
|
||||||
<< std::endl;
|
}
|
||||||
}
|
mem_file.close();
|
||||||
mem_file.close();
|
|
||||||
|
std::cout << "finished dumping memory" << std::endl;
|
||||||
std::cout << "finished dumping memory" << std::endl;
|
|
||||||
|
} catch (std::ofstream::failure e) {
|
||||||
} catch (std::ofstream::failure e) {
|
std::cerr << "exception opening/reading/closing file memory_dump.bin\n";
|
||||||
std::cerr << "exception opening/reading/closing file memory_dump.bin\n";
|
}
|
||||||
}
|
}
|
||||||
}
|
*/
|
||||||
*/
|
|
||||||
|
|
|
@ -1,48 +1,74 @@
|
||||||
// Copyright 2018 Robert Balas <balasr@student.ethz.ch>
|
// Copyright 2018 Robert Balas <balasr@student.ethz.ch>
|
||||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||||
// compliance with the License. You may obtain a copy of the License at
|
// compliance with the License. You may obtain a copy of the License at
|
||||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||||
// or agreed to in writing, software, hardware and materials distributed under
|
// or agreed to in writing, software, hardware and materials distributed under
|
||||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
// Top level wrapper for a verilator RI5CY testbench
|
// Top level wrapper for a verilator RI5CY testbench
|
||||||
// Contributor: Robert Balas <balasr@student.ethz.ch>
|
// Contributor: Robert Balas <balasr@student.ethz.ch>
|
||||||
|
|
||||||
|
|
||||||
module tb_top_verilator #(
|
module tb_top_verilator #(
|
||||||
|
|
||||||
) (
|
) (
|
||||||
input clk_i,
|
input clk_i,
|
||||||
input rst_ni,
|
input rst_ni
|
||||||
input fetch_enable_i
|
);
|
||||||
);
|
|
||||||
|
wire[31:0] x26 = u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.regs[26];
|
||||||
|
wire[31:0] x27 = u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.regs[27];
|
||||||
|
|
||||||
|
initial begin: load_prog
|
||||||
|
automatic logic [1023:0] firmware;
|
||||||
initial begin: load_prog
|
|
||||||
automatic logic [1023:0] firmware;
|
if($value$plusargs("firmware=%s", firmware)) begin
|
||||||
|
//if($test$plusargs("verbose"))
|
||||||
if($value$plusargs("firmware=%s", firmware)) begin
|
$display("[TESTBENCH] %t: loading firmware %0s ...",
|
||||||
//if($test$plusargs("verbose"))
|
$time, firmware);
|
||||||
$display("[TESTBENCH] %t: loading firmware %0s ...",
|
$readmemh (firmware, u_tinyriscv_soc_top.u_rom.u_gen_ram.ram);
|
||||||
$time, firmware);
|
end else begin
|
||||||
$readmemh (firmware, u_tinyriscv_soc_top.u_rom.u_gen_ram.ram);
|
$display("No firmware specified");
|
||||||
//$display("mem[0x80]=0x%x", u_ram.ram.mem[32]);
|
end
|
||||||
//$display("mem[0x84]=0x%x", u_ram.ram.mem[33]);
|
end
|
||||||
end else begin
|
|
||||||
$display("No firmware specified");
|
always @(posedge clk_i or negedge rst_ni) begin
|
||||||
end
|
if (!rst_ni) begin
|
||||||
end
|
|
||||||
|
end else begin
|
||||||
|
if (x26 == 32'b1) begin
|
||||||
tinyriscv_soc_top u_tinyriscv_soc_top(
|
if (x27 == 32'b1) begin
|
||||||
.clk(clk_i),
|
$display("~~~~~~~~~~~~~~~~~~~ TEST_PASS ~~~~~~~~~~~~~~~~~~~");
|
||||||
.rst_ext_i(rst_ni)
|
$display("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
||||||
);
|
$display("~~~~~~~~~ ##### ## #### #### ~~~~~~~~~");
|
||||||
|
$display("~~~~~~~~~ # # # # # # ~~~~~~~~~");
|
||||||
endmodule // tb_top_verilator
|
$display("~~~~~~~~~ # # # # #### #### ~~~~~~~~~");
|
||||||
|
$display("~~~~~~~~~ ##### ###### # #~~~~~~~~~");
|
||||||
|
$display("~~~~~~~~~ # # # # # # #~~~~~~~~~");
|
||||||
|
$display("~~~~~~~~~ # # # #### #### ~~~~~~~~~");
|
||||||
|
$display("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
||||||
|
end else begin
|
||||||
|
$display("~~~~~~~~~~~~~~~~~~~ TEST_FAIL ~~~~~~~~~~~~~~~~~~~~");
|
||||||
|
$display("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
||||||
|
$display("~~~~~~~~~~###### ## # # ~~~~~~~~~~");
|
||||||
|
$display("~~~~~~~~~~# # # # # ~~~~~~~~~~");
|
||||||
|
$display("~~~~~~~~~~##### # # # # ~~~~~~~~~~");
|
||||||
|
$display("~~~~~~~~~~# ###### # # ~~~~~~~~~~");
|
||||||
|
$display("~~~~~~~~~~# # # # # ~~~~~~~~~~");
|
||||||
|
$display("~~~~~~~~~~# # # # ######~~~~~~~~~~");
|
||||||
|
$display("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
||||||
|
end
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
tinyriscv_soc_top u_tinyriscv_soc_top(
|
||||||
|
.clk(clk_i),
|
||||||
|
.rst_ext_i(rst_ni)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule // tb_top_verilator
|
||||||
|
|
Loading…
Reference in New Issue