// Copyright 2018 ETH Zurich and University of Bologna. // Copyright and related rights are licensed under the Solderpad Hardware // 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 // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law // or agreed to in writing, software, hardware and materials distributed under // 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 // specific language governing permissions and limitations under the License. // // Author: Florian Zaruba, ETH Zurich // Date: 19.03.2017 // Description: Ariane Top-level module import ariane_pkg::*; //pragma translate_off `ifndef VERILATOR import instruction_tracer_pkg::*; `endif //pragma translate_on // default to AXI64 cache ports if not using the // serpent PULP extension `ifndef PITON_ARIANE `ifndef AXI64_CACHE_PORTS `define AXI64_CACHE_PORTS `endif `endif module ariane #( parameter logic [63:0] DmBaseAddress = 64'h0, // debug module base address `ifdef PITON_ARIANE parameter bit SwapEndianess = 0, // swap endianess in l15 adapter parameter logic [63:0] CachedAddrEnd = 64'h80_0000_0000, // end of cached region `endif parameter logic [63:0] CachedAddrBeg = 64'h00_8000_0000 // begin of cached region ) ( input logic clk_i, input logic rst_ni, // Core ID, Cluster ID and boot address are considered more or less static input logic [63:0] boot_addr_i, // reset boot address input logic [63:0] hart_id_i, // hart id in a multicore environment (reflected in a CSR) // Interrupt inputs input logic [1:0] irq_i, // level sensitive IR lines, mip & sip (async) input logic ipi_i, // inter-processor interrupts (async) // Timer facilities input logic time_irq_i, // timer interrupt in (async) input logic debug_req_i, // debug request (async) `ifdef AXI64_CACHE_PORTS // memory side, AXI Master output ariane_axi::req_t axi_req_o, input ariane_axi::resp_t axi_resp_i `else // L15 (memory side) output serpent_cache_pkg::l15_req_t l15_req_o, input serpent_cache_pkg::l15_rtrn_t l15_rtrn_i `endif ); // ------------------------------------------ // Global Signals // Signals connecting more than one module // ------------------------------------------ riscv::priv_lvl_t priv_lvl; exception_t ex_commit; // exception from commit stage branchpredict_t resolved_branch; logic [63:0] pc_commit; logic eret; logic [NR_COMMIT_PORTS-1:0] commit_ack; // -------------- // PCGEN <-> CSR // -------------- logic [63:0] trap_vector_base_commit_pcgen; logic [63:0] epc_commit_pcgen; // -------------- // IF <-> ID // -------------- frontend_fetch_t fetch_entry_if_id; logic fetch_valid_if_id; logic decode_ack_id_if; // -------------- // ID <-> ISSUE // -------------- scoreboard_entry_t issue_entry_id_issue; logic issue_entry_valid_id_issue; logic is_ctrl_fow_id_issue; logic issue_instr_issue_id; // -------------- // ISSUE <-> EX // -------------- fu_data_t fu_data_id_ex; logic [63:0] pc_id_ex; logic is_compressed_instr_id_ex; // fixed latency units logic flu_ready_ex_id; logic [TRANS_ID_BITS-1:0] flu_trans_id_ex_id; logic flu_valid_ex_id; logic [63:0] flu_result_ex_id; exception_t flu_exception_ex_id; // ALU logic alu_valid_id_ex; // Branches and Jumps logic branch_valid_id_ex; branchpredict_sbe_t branch_predict_id_ex; logic resolve_branch_ex_id; // LSU logic lsu_valid_id_ex; logic lsu_ready_ex_id; logic [TRANS_ID_BITS-1:0] load_trans_id_ex_id; logic [63:0] load_result_ex_id; logic load_valid_ex_id; exception_t load_exception_ex_id; logic [63:0] store_result_ex_id; logic [TRANS_ID_BITS-1:0] store_trans_id_ex_id; logic store_valid_ex_id; exception_t store_exception_ex_id; // MULT logic mult_valid_id_ex; // FPU logic fpu_ready_ex_id; logic fpu_valid_id_ex; logic [1:0] fpu_fmt_id_ex; logic [2:0] fpu_rm_id_ex; logic [TRANS_ID_BITS-1:0] fpu_trans_id_ex_id; logic [63:0] fpu_result_ex_id; logic fpu_valid_ex_id; exception_t fpu_exception_ex_id; // CSR logic csr_valid_id_ex; // -------------- // EX <-> COMMIT // -------------- // CSR Commit logic csr_commit_commit_ex; logic dirty_fp_state; // LSU Commit logic lsu_commit_commit_ex; logic lsu_commit_ready_ex_commit; logic no_st_pending_ex; logic no_st_pending_commit; logic amo_valid_commit; // -------------- // ID <-> COMMIT // -------------- scoreboard_entry_t [NR_COMMIT_PORTS-1:0] commit_instr_id_commit; // -------------- // COMMIT <-> ID // -------------- logic [NR_COMMIT_PORTS-1:0][4:0] waddr_commit_id; logic [NR_COMMIT_PORTS-1:0][63:0] wdata_commit_id; logic [NR_COMMIT_PORTS-1:0] we_gpr_commit_id; logic [NR_COMMIT_PORTS-1:0] we_fpr_commit_id; // -------------- // CSR <-> * // -------------- logic [4:0] fflags_csr_commit; riscv::xs_t fs; logic [2:0] frm_csr_id_issue_ex; logic [6:0] fprec_csr_ex; logic enable_translation_csr_ex; logic en_ld_st_translation_csr_ex; riscv::priv_lvl_t ld_st_priv_lvl_csr_ex; logic sum_csr_ex; logic mxr_csr_ex; logic [43:0] satp_ppn_csr_ex; logic [0:0] asid_csr_ex; logic [11:0] csr_addr_ex_csr; fu_op csr_op_commit_csr; logic [63:0] csr_wdata_commit_csr; logic [63:0] csr_rdata_csr_commit; exception_t csr_exception_csr_commit; logic tvm_csr_id; logic tw_csr_id; logic tsr_csr_id; logic dcache_en_csr_nbdcache; logic csr_write_fflags_commit_cs; logic icache_en_csr; logic debug_mode; logic single_step_csr_commit; // ---------------------------- // Performance Counters <-> * // ---------------------------- logic [4:0] addr_csr_perf; logic [63:0] data_csr_perf, data_perf_csr; logic we_csr_perf; logic icache_flush_ctrl_cache; logic itlb_miss_ex_perf; logic dtlb_miss_ex_perf; logic dcache_miss_cache_perf; logic icache_miss_cache_perf; // -------------- // CTRL <-> * // -------------- logic set_pc_ctrl_pcgen; logic flush_csr_ctrl; logic flush_unissued_instr_ctrl_id; logic flush_ctrl_if; logic flush_ctrl_id; logic flush_ctrl_ex; logic flush_tlb_ctrl_ex; logic fence_i_commit_controller; logic fence_commit_controller; logic sfence_vma_commit_controller; logic halt_ctrl; logic halt_csr_ctrl; logic dcache_flush_ctrl_cache; logic dcache_flush_ack_cache_ctrl; logic set_debug_pc; logic flush_commit; icache_areq_i_t icache_areq_ex_cache; icache_areq_o_t icache_areq_cache_ex; icache_dreq_i_t icache_dreq_if_cache; icache_dreq_o_t icache_dreq_cache_if; amo_req_t amo_req; amo_resp_t amo_resp; logic sb_full; logic debug_req; // Disable debug during AMO commit assign debug_req = debug_req_i & ~amo_valid_commit; // ---------------- // DCache <-> * // ---------------- dcache_req_i_t [2:0] dcache_req_ports_ex_cache; dcache_req_o_t [2:0] dcache_req_ports_cache_ex; logic dcache_commit_wbuffer_empty; // -------------- // Frontend // -------------- frontend #( .DmBaseAddress ( DmBaseAddress ) ) i_frontend ( .flush_i ( flush_ctrl_if ), // not entirely correct .flush_bp_i ( 1'b0 ), .debug_mode_i ( debug_mode ), .boot_addr_i ( boot_addr_i ), .icache_dreq_i ( icache_dreq_cache_if ), .icache_dreq_o ( icache_dreq_if_cache ), .resolved_branch_i ( resolved_branch ), .pc_commit_i ( pc_commit ), .set_pc_commit_i ( set_pc_ctrl_pcgen ), .set_debug_pc_i ( set_debug_pc ), .epc_i ( epc_commit_pcgen ), .eret_i ( eret ), .trap_vector_base_i ( trap_vector_base_commit_pcgen ), .ex_valid_i ( ex_commit.valid ), .fetch_entry_o ( fetch_entry_if_id ), .fetch_entry_valid_o ( fetch_valid_if_id ), .fetch_ack_i ( decode_ack_id_if ), .* ); // --------- // ID // --------- id_stage id_stage_i ( .flush_i ( flush_ctrl_if ), .fetch_entry_i ( fetch_entry_if_id ), .fetch_entry_valid_i ( fetch_valid_if_id ), .decoded_instr_ack_o ( decode_ack_id_if ), .issue_entry_o ( issue_entry_id_issue ), .issue_entry_valid_o ( issue_entry_valid_id_issue ), .is_ctrl_flow_o ( is_ctrl_fow_id_issue ), .issue_instr_ack_i ( issue_instr_issue_id ), .priv_lvl_i ( priv_lvl ), .fs_i ( fs ), .frm_i ( frm_csr_id_issue_ex ), .debug_mode_i ( debug_mode ), .tvm_i ( tvm_csr_id ), .tw_i ( tw_csr_id ), .tsr_i ( tsr_csr_id ), .* ); // --------- // Issue // --------- issue_stage #( .NR_ENTRIES ( NR_SB_ENTRIES ), .NR_WB_PORTS ( NR_WB_PORTS ) ) issue_stage_i ( .clk_i, .rst_ni, .sb_full_o ( sb_full ), .flush_unissued_instr_i ( flush_unissued_instr_ctrl_id ), .flush_i ( flush_ctrl_id ), // ID Stage .decoded_instr_i ( issue_entry_id_issue ), .decoded_instr_valid_i ( issue_entry_valid_id_issue ), .is_ctrl_flow_i ( is_ctrl_fow_id_issue ), .decoded_instr_ack_o ( issue_instr_issue_id ), // Functional Units .fu_data_o ( fu_data_id_ex ), .pc_o ( pc_id_ex ), .is_compressed_instr_o ( is_compressed_instr_id_ex ), // fixed latency unit ready .flu_ready_i ( flu_ready_ex_id ), // ALU .alu_valid_o ( alu_valid_id_ex ), // Branches and Jumps .branch_valid_o ( branch_valid_id_ex ), // branch is valid .branch_predict_o ( branch_predict_id_ex ), // branch predict to ex .resolve_branch_i ( resolve_branch_ex_id ), // in order to resolve the branch // LSU .lsu_ready_i ( lsu_ready_ex_id ), .lsu_valid_o ( lsu_valid_id_ex ), // Multiplier .mult_valid_o ( mult_valid_id_ex ), // FPU .fpu_ready_i ( fpu_ready_ex_id ), .fpu_valid_o ( fpu_valid_id_ex ), .fpu_fmt_o ( fpu_fmt_id_ex ), .fpu_rm_o ( fpu_rm_id_ex ), // CSR .csr_valid_o ( csr_valid_id_ex ), // Commit .resolved_branch_i ( resolved_branch ), .trans_id_i ( {flu_trans_id_ex_id, load_trans_id_ex_id, store_trans_id_ex_id, fpu_trans_id_ex_id }), .wbdata_i ( {flu_result_ex_id, load_result_ex_id, store_result_ex_id, fpu_result_ex_id }), .ex_ex_i ( {flu_exception_ex_id, load_exception_ex_id, store_exception_ex_id, fpu_exception_ex_id }), .wb_valid_i ( {flu_valid_ex_id, load_valid_ex_id, store_valid_ex_id, fpu_valid_ex_id }), .waddr_i ( waddr_commit_id ), .wdata_i ( wdata_commit_id ), .we_gpr_i ( we_gpr_commit_id ), .we_fpr_i ( we_fpr_commit_id ), .commit_instr_o ( commit_instr_id_commit ), .commit_ack_i ( commit_ack ), .* ); // --------- // EX // --------- ex_stage ex_stage_i ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), .flush_i ( flush_ctrl_ex ), .fu_data_i ( fu_data_id_ex ), .pc_i ( pc_id_ex ), .is_compressed_instr_i ( is_compressed_instr_id_ex ), // fixed latency units .flu_result_o ( flu_result_ex_id ), .flu_trans_id_o ( flu_trans_id_ex_id ), .flu_valid_o ( flu_valid_ex_id ), .flu_exception_o ( flu_exception_ex_id ), .flu_ready_o ( flu_ready_ex_id ), // ALU .alu_valid_i ( alu_valid_id_ex ), // Branches and Jumps .branch_valid_i ( branch_valid_id_ex ), .branch_predict_i ( branch_predict_id_ex ), // branch predict to ex .resolved_branch_o ( resolved_branch ), .resolve_branch_o ( resolve_branch_ex_id ), // CSR .csr_valid_i ( csr_valid_id_ex ), .csr_addr_o ( csr_addr_ex_csr ), .csr_commit_i ( csr_commit_commit_ex ), // from commit // MULT .mult_valid_i ( mult_valid_id_ex ), // LSU .lsu_ready_o ( lsu_ready_ex_id ), .lsu_valid_i ( lsu_valid_id_ex ), .load_result_o ( load_result_ex_id ), .load_trans_id_o ( load_trans_id_ex_id ), .load_valid_o ( load_valid_ex_id ), .load_exception_o ( load_exception_ex_id ), .store_result_o ( store_result_ex_id ), .store_trans_id_o ( store_trans_id_ex_id ), .store_valid_o ( store_valid_ex_id ), .store_exception_o ( store_exception_ex_id ), .lsu_commit_i ( lsu_commit_commit_ex ), // from commit .lsu_commit_ready_o ( lsu_commit_ready_ex_commit ), // to commit .no_st_pending_o ( no_st_pending_ex ), // FPU .fpu_ready_o ( fpu_ready_ex_id ), .fpu_valid_i ( fpu_valid_id_ex ), .fpu_fmt_i ( fpu_fmt_id_ex ), .fpu_rm_i ( fpu_rm_id_ex ), .fpu_frm_i ( frm_csr_id_issue_ex ), .fpu_prec_i ( fprec_csr_ex ), .fpu_trans_id_o ( fpu_trans_id_ex_id ), .fpu_result_o ( fpu_result_ex_id ), .fpu_valid_o ( fpu_valid_ex_id ), .fpu_exception_o ( fpu_exception_ex_id ), .amo_valid_commit_i ( amo_valid_commit ), .amo_req_o ( amo_req ), .amo_resp_i ( amo_resp ), // Performance counters .itlb_miss_o ( itlb_miss_ex_perf ), .dtlb_miss_o ( dtlb_miss_ex_perf ), // Memory Management .enable_translation_i ( enable_translation_csr_ex ), // from CSR .en_ld_st_translation_i ( en_ld_st_translation_csr_ex ), .flush_tlb_i ( flush_tlb_ctrl_ex ), .priv_lvl_i ( priv_lvl ), // from CSR .ld_st_priv_lvl_i ( ld_st_priv_lvl_csr_ex ), // from CSR .sum_i ( sum_csr_ex ), // from CSR .mxr_i ( mxr_csr_ex ), // from CSR .satp_ppn_i ( satp_ppn_csr_ex ), // from CSR .asid_i ( asid_csr_ex ), // from CSR .icache_areq_i ( icache_areq_cache_ex ), .icache_areq_o ( icache_areq_ex_cache ), // DCACHE interfaces .dcache_req_ports_i ( dcache_req_ports_cache_ex ), .dcache_req_ports_o ( dcache_req_ports_ex_cache ) ); // --------- // Commit // --------- // we have to make sure that the whole write buffer path is empty before // used e.g. for fence instructions. assign no_st_pending_commit = no_st_pending_ex & dcache_commit_wbuffer_empty; commit_stage commit_stage_i ( .clk_i, .rst_ni, .halt_i ( halt_ctrl ), .flush_dcache_i ( dcache_flush_ctrl_cache ), .exception_o ( ex_commit ), .dirty_fp_state_o ( dirty_fp_state ), .debug_mode_i ( debug_mode ), .debug_req_i ( debug_req ), .single_step_i ( single_step_csr_commit ), .commit_instr_i ( commit_instr_id_commit ), .commit_ack_o ( commit_ack ), .no_st_pending_i ( no_st_pending_commit ), .waddr_o ( waddr_commit_id ), .wdata_o ( wdata_commit_id ), .we_gpr_o ( we_gpr_commit_id ), .we_fpr_o ( we_fpr_commit_id ), .commit_lsu_o ( lsu_commit_commit_ex ), .commit_lsu_ready_i ( lsu_commit_ready_ex_commit ), .amo_valid_commit_o ( amo_valid_commit ), .amo_resp_i ( amo_resp ), .commit_csr_o ( csr_commit_commit_ex ), .pc_o ( pc_commit ), .csr_op_o ( csr_op_commit_csr ), .csr_wdata_o ( csr_wdata_commit_csr ), .csr_rdata_i ( csr_rdata_csr_commit ), .csr_write_fflags_o ( csr_write_fflags_commit_cs ), .csr_exception_i ( csr_exception_csr_commit ), .fence_i_o ( fence_i_commit_controller ), .fence_o ( fence_commit_controller ), .sfence_vma_o ( sfence_vma_commit_controller ), .flush_commit_o ( flush_commit ), .* ); // --------- // CSR // --------- csr_regfile #( .AsidWidth ( ASID_WIDTH ), .DmBaseAddress ( DmBaseAddress ) ) csr_regfile_i ( .flush_o ( flush_csr_ctrl ), .halt_csr_o ( halt_csr_ctrl ), .commit_instr_i ( commit_instr_id_commit ), .commit_ack_i ( commit_ack ), .ex_i ( ex_commit ), .csr_op_i ( csr_op_commit_csr ), .csr_write_fflags_i ( csr_write_fflags_commit_cs ), .dirty_fp_state_i ( dirty_fp_state ), .csr_addr_i ( csr_addr_ex_csr ), .csr_wdata_i ( csr_wdata_commit_csr ), .csr_rdata_o ( csr_rdata_csr_commit ), .pc_i ( pc_commit ), .csr_exception_o ( csr_exception_csr_commit ), .epc_o ( epc_commit_pcgen ), .eret_o ( eret ), .set_debug_pc_o ( set_debug_pc ), .trap_vector_base_o ( trap_vector_base_commit_pcgen ), .priv_lvl_o ( priv_lvl ), .fs_o ( fs ), .fflags_o ( fflags_csr_commit ), .frm_o ( frm_csr_id_issue_ex ), .fprec_o ( fprec_csr_ex ), .ld_st_priv_lvl_o ( ld_st_priv_lvl_csr_ex ), .en_translation_o ( enable_translation_csr_ex ), .en_ld_st_translation_o ( en_ld_st_translation_csr_ex ), .sum_o ( sum_csr_ex ), .mxr_o ( mxr_csr_ex ), .satp_ppn_o ( satp_ppn_csr_ex ), .asid_o ( asid_csr_ex ), .tvm_o ( tvm_csr_id ), .tw_o ( tw_csr_id ), .tsr_o ( tsr_csr_id ), .debug_mode_o ( debug_mode ), .single_step_o ( single_step_csr_commit ), .dcache_en_o ( dcache_en_csr_nbdcache ), .icache_en_o ( icache_en_csr ), .perf_addr_o ( addr_csr_perf ), .perf_data_o ( data_csr_perf ), .perf_data_i ( data_perf_csr ), .perf_we_o ( we_csr_perf ), .debug_req_i ( debug_req ), .ipi_i, .irq_i, .time_irq_i, .* ); // ------------------------ // Performance Counters // ------------------------ perf_counters i_perf_counters ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), .debug_mode_i ( debug_mode ), .addr_i ( addr_csr_perf ), .we_i ( we_csr_perf ), .data_i ( data_csr_perf ), .data_o ( data_perf_csr ), .commit_instr_i ( commit_instr_id_commit ), .commit_ack_i ( commit_ack ), .l1_icache_miss_i ( icache_miss_cache_perf ), .l1_dcache_miss_i ( dcache_miss_cache_perf ), .itlb_miss_i ( itlb_miss_ex_perf ), .dtlb_miss_i ( dtlb_miss_ex_perf ), .sb_full_i ( sb_full ), .if_empty_i ( ~fetch_valid_if_id ), .ex_i ( ex_commit ), .eret_i ( eret ), .resolved_branch_i ( resolved_branch ) ); // ------------ // Controller // ------------ controller controller_i ( // flush ports .set_pc_commit_o ( set_pc_ctrl_pcgen ), .flush_unissued_instr_o ( flush_unissued_instr_ctrl_id ), .flush_if_o ( flush_ctrl_if ), .flush_id_o ( flush_ctrl_id ), .flush_ex_o ( flush_ctrl_ex ), .flush_tlb_o ( flush_tlb_ctrl_ex ), .flush_dcache_o ( dcache_flush_ctrl_cache ), .flush_dcache_ack_i ( dcache_flush_ack_cache_ctrl ), .halt_csr_i ( halt_csr_ctrl ), .halt_o ( halt_ctrl ), // control ports .eret_i ( eret ), .ex_valid_i ( ex_commit.valid ), .set_debug_pc_i ( set_debug_pc ), .flush_csr_i ( flush_csr_ctrl ), .resolved_branch_i ( resolved_branch ), .fence_i_i ( fence_i_commit_controller ), .fence_i ( fence_commit_controller ), .sfence_vma_i ( sfence_vma_commit_controller ), .flush_commit_i ( flush_commit ), .flush_icache_o ( icache_flush_ctrl_cache ), .* ); // ------------------- // Cache Subsystem // ------------------- `ifdef PITON_ARIANE // this is a cache subsystem that is compatible with OpenPiton serpent_cache_subsystem #( .CachedAddrBeg ( CachedAddrBeg ), .CachedAddrEnd ( CachedAddrEnd ), .SwapEndianess ( SwapEndianess ) ) i_cache_subsystem ( // to D$ .clk_i ( clk_i ), .rst_ni ( rst_ni ), // I$ .icache_en_i ( icache_en_csr ), .icache_flush_i ( icache_flush_ctrl_cache ), .icache_miss_o ( icache_miss_cache_perf ), .icache_areq_i ( icache_areq_ex_cache ), .icache_areq_o ( icache_areq_cache_ex ), .icache_dreq_i ( icache_dreq_if_cache ), .icache_dreq_o ( icache_dreq_cache_if ), // D$ .dcache_enable_i ( dcache_en_csr_nbdcache ), .dcache_flush_i ( dcache_flush_ctrl_cache ), .dcache_flush_ack_o ( dcache_flush_ack_cache_ctrl ), // to commit stage .dcache_amo_req_i ( amo_req ), .dcache_amo_resp_o ( amo_resp ), // from PTW, Load Unit and Store Unit .dcache_miss_o ( dcache_miss_cache_perf ), .dcache_req_ports_i ( dcache_req_ports_ex_cache ), .dcache_req_ports_o ( dcache_req_ports_cache_ex ), // write buffer status .wbuffer_empty_o ( dcache_commit_wbuffer_empty ), `ifdef AXI64_CACHE_PORTS // memory side .axi_req_o ( axi_req_o ), .axi_resp_i ( axi_resp_i ) `else .l15_req_o ( l15_req_o ), .l15_rtrn_i ( l15_rtrn_i ) `endif ); `else std_cache_subsystem #( .CACHE_START_ADDR ( CachedAddrBeg ) ) i_cache_subsystem ( // to D$ .clk_i ( clk_i ), .rst_ni ( rst_ni ), .priv_lvl_i ( priv_lvl ), // I$ .icache_en_i ( icache_en_csr ), .icache_flush_i ( icache_flush_ctrl_cache ), .icache_miss_o ( icache_miss_cache_perf ), .icache_areq_i ( icache_areq_ex_cache ), .icache_areq_o ( icache_areq_cache_ex ), .icache_dreq_i ( icache_dreq_if_cache ), .icache_dreq_o ( icache_dreq_cache_if ), // D$ .dcache_enable_i ( dcache_en_csr_nbdcache ), .dcache_flush_i ( dcache_flush_ctrl_cache ), .dcache_flush_ack_o ( dcache_flush_ack_cache_ctrl ), // to commit stage .amo_req_i ( amo_req ), .amo_resp_o ( amo_resp ), .dcache_miss_o ( dcache_miss_cache_perf ), // this is statically set to 1 as the std_cache does not have a wbuffer .wbuffer_empty_o ( dcache_commit_wbuffer_empty ), // from PTW, Load Unit and Store Unit .dcache_req_ports_i ( dcache_req_ports_ex_cache ), .dcache_req_ports_o ( dcache_req_ports_cache_ex ), // memory side .axi_req_o ( axi_req_o ), .axi_resp_i ( axi_resp_i ) ); `endif // ------------------- // Instruction Tracer // ------------------- //pragma translate_off `ifndef VERILATOR instruction_tracer_if tracer_if (clk_i); // assign instruction tracer interface // control signals assign tracer_if.rstn = rst_ni; assign tracer_if.flush_unissued = flush_unissued_instr_ctrl_id; assign tracer_if.flush = flush_ctrl_ex; // fetch assign tracer_if.instruction = id_stage_i.compressed_decoder_i.instr_o; assign tracer_if.fetch_valid = id_stage_i.instr_realigner_i.fetch_entry_valid_o; assign tracer_if.fetch_ack = id_stage_i.instr_realigner_i.fetch_ack_i; // Issue assign tracer_if.issue_ack = issue_stage_i.i_scoreboard.issue_ack_i; assign tracer_if.issue_sbe = issue_stage_i.i_scoreboard.issue_instr_o; // write-back assign tracer_if.waddr = waddr_commit_id; assign tracer_if.wdata = wdata_commit_id; assign tracer_if.we_gpr = we_gpr_commit_id; assign tracer_if.we_fpr = we_fpr_commit_id; // commit assign tracer_if.commit_instr = commit_instr_id_commit; assign tracer_if.commit_ack = commit_ack; // branch predict assign tracer_if.resolve_branch = resolved_branch; // address translation // stores assign tracer_if.st_valid = ex_stage_i.lsu_i.i_store_unit.store_buffer_i.valid_i; assign tracer_if.st_paddr = ex_stage_i.lsu_i.i_store_unit.store_buffer_i.paddr_i; // loads assign tracer_if.ld_valid = ex_stage_i.lsu_i.i_load_unit.req_port_o.tag_valid; assign tracer_if.ld_kill = ex_stage_i.lsu_i.i_load_unit.req_port_o.kill_req; assign tracer_if.ld_paddr = ex_stage_i.lsu_i.i_load_unit.paddr_i; // exceptions assign tracer_if.exception = commit_stage_i.exception_o; // assign current privilege level assign tracer_if.priv_lvl = priv_lvl; assign tracer_if.debug_mode = debug_mode; instr_tracer instr_tracer_i (tracer_if, hart_id_i); program instr_tracer ( instruction_tracer_if tracer_if, input logic [63:0] hart_id_i ); instruction_tracer it = new (tracer_if, 1'b0); initial begin #15ns; it.create_file(hart_id_i); it.trace(); end final begin it.close(); end endprogram `ifdef PITON_ARIANE logic piton_pc_vld; logic [63:0] piton_pc; // expose retired PCs to OpenPiton verification environment // note: this only works with single issue, need to adapt this in case of dual issue always_ff @(posedge clk_i or negedge rst_ni) begin logic [63:0] pc_queue [$]; if (~rst_ni) begin pc_queue.delete(); piton_pc_vld <= 1'b0; piton_pc <= '0; end else begin // serialize retired PCs via queue construct for (int i = 0; i < NR_COMMIT_PORTS; i++) begin if (commit_ack[i] && !commit_instr_id_commit[i].ex.valid) begin pc_queue.push_back(commit_instr_id_commit[i].pc); end end if (pc_queue.size()>0) begin piton_pc_vld <= 1'b1; piton_pc <= pc_queue.pop_front(); end else begin piton_pc_vld <= 1'b0; piton_pc <= '0; end end end `endif // PITON_ARIANE // mock tracer for Verilator, to be used with spike-dasm `else int f; logic [63:0] cycles; initial begin f = $fopen("trace_hart_00.dasm", "w"); end always_ff @(posedge clk_i or negedge rst_ni) begin if (~rst_ni) begin cycles <= 0; end else begin string mode = ""; if (debug_mode) mode = "D"; else begin case (priv_lvl) riscv::PRIV_LVL_M: mode = "M"; riscv::PRIV_LVL_S: mode = "S"; riscv::PRIV_LVL_U: mode = "U"; endcase end for (int i = 0; i < NR_COMMIT_PORTS; i++) begin if (commit_ack[i] && !commit_instr_id_commit[i].ex.valid) begin $fwrite(f, "%d 0x%0h %s (0x%h) DASM(%h)\n", cycles, commit_instr_id_commit[i].pc, mode, commit_instr_id_commit[i].ex.tval[31:0], commit_instr_id_commit[i].ex.tval[31:0]); end else if (commit_ack[i] && commit_instr_id_commit[i].ex.valid) begin if (commit_instr_id_commit[i].ex.cause == 2) begin $fwrite(f, "Exception Cause: Illegal Instructions, DASM(%h) PC=%h\n", commit_instr_id_commit[i].ex.tval[31:0], commit_instr_id_commit[i].pc); end else begin if (debug_mode) begin $fwrite(f, "%d 0x%0h %s (0x%h) DASM(%h)\n", cycles, commit_instr_id_commit[i].pc, mode, commit_instr_id_commit[i].ex.tval[31:0], commit_instr_id_commit[i].ex.tval[31:0]); end else begin $fwrite(f, "Exception Cause: %5d, DASM(%h) PC=%h\n", commit_instr_id_commit[i].ex.cause, commit_instr_id_commit[i].ex.tval[31:0], commit_instr_id_commit[i].pc); end end end end cycles <= cycles + 1; end end final begin $fclose(f); end `endif // VERILATOR //pragma translate_on endmodule // ariane