| ////////////////////////////////////////////////////////////////////////////// |
| // SPDX-FileCopyrightText: Syntacore LLC © 2016-2021 |
| // |
| // 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. |
| // SPDX-License-Identifier: Apache-2.0 |
| // SPDX-FileContributor: Syntacore LLC |
| // ////////////////////////////////////////////////////////////////////////// |
| /// @file <scr1_pipe_top.sv> |
| /// @brief SCR1 pipeline top |
| /// |
| |
| //---------------------------------------------------------------------------------- |
| // project : YiFive |
| // Rev: June 10, 2021, Dinesh A |
| // Bugfix- reset correction for scr1_pipe_tdu when debug is not enabled |
| // Note: previously reset rst_n is floating at simulation is failing |
| // when SCR1_DBG_EN is disabled |
| //--------------------------------------------------------------------------------- |
| |
| `include "scr1_arch_description.svh" |
| `include "scr1_memif.svh" |
| `include "scr1_riscv_isa_decoding.svh" |
| `include "scr1_csr.svh" |
| |
| `ifdef SCR1_IPIC_EN |
| `include "scr1_ipic.svh" |
| `endif // SCR1_IPIC_EN |
| |
| `ifdef SCR1_DBG_EN |
| `include "scr1_hdu.svh" |
| `endif // SCR1_DBG_EN |
| |
| `ifdef SCR1_TDU_EN |
| `include "scr1_tdu.svh" |
| `endif // SCR1_TDU_EN |
| |
| module scr1_pipe_top ( |
| // Common |
| input logic pipe_rst_n, // Pipe reset |
| output logic [48:0] pipe_debug, |
| `ifdef SCR1_DBG_EN |
| input logic pipe2hdu_rdc_qlfy_i, // Pipe RDC qualifier |
| input logic dbg_rst_n, // Debug reset |
| `endif // SCR1_DBG_EN |
| input logic clk, // Pipe clock |
| |
| // Instruction Memory Interface |
| output logic pipe2imem_req_o, // IMEM request |
| output logic pipe2imem_cmd_o, // IMEM command |
| output logic [`SCR1_IMEM_AWIDTH-1:0] pipe2imem_addr_o, // IMEM address |
| input logic imem2pipe_req_ack_i, // IMEM request acknowledge |
| input logic [`SCR1_IMEM_DWIDTH-1:0] imem2pipe_rdata_i, // IMEM read data |
| input logic [1:0] imem2pipe_resp_i, // IMEM response |
| |
| // Data Memory Interface |
| output logic pipe2dmem_req_o, // DMEM request |
| output logic pipe2dmem_cmd_o, // DMEM command |
| output logic [1:0] pipe2dmem_width_o, // DMEM data width |
| output logic [`SCR1_DMEM_AWIDTH-1:0] pipe2dmem_addr_o, // DMEM address |
| output logic [`SCR1_DMEM_DWIDTH-1:0] pipe2dmem_wdata_o, // DMEM write data |
| input logic dmem2pipe_req_ack_i, // DMEM request acknowledge |
| input logic [`SCR1_DMEM_DWIDTH-1:0] dmem2pipe_rdata_i, // DMEM read data |
| input logic [1:0] dmem2pipe_resp_i, // DMEM response |
| |
| `ifdef SCR1_DBG_EN |
| // Debug interface: |
| input logic dbg_en, // 1 - debug operations enabled |
| // DM <-> Pipeline: HART Run Control i/f |
| input logic dm2pipe_active_i, // Debug Module active flag |
| input logic dm2pipe_cmd_req_i, // Request from Debug Module |
| input type_scr1_hdu_dbgstates_e dm2pipe_cmd_i, // Command from Debug Module |
| output logic pipe2dm_cmd_resp_o, // Response to Debug Module |
| output logic pipe2dm_cmd_rcode_o, // Debug Module return code: 0 - Ok; 1 - Error |
| output logic pipe2dm_hart_event_o, // HART event flag |
| output type_scr1_hdu_hartstatus_s pipe2dm_hart_status_o, // HART status |
| |
| // DM <-> Pipeline: Program Buffer - HART instruction execution i/f |
| output logic [SCR1_HDU_PBUF_ADDR_WIDTH-1:0] pipe2dm_pbuf_addr_o, // Program Buffer address |
| input logic [SCR1_HDU_CORE_INSTR_WIDTH-1:0] dm2pipe_pbuf_instr_i, // Program Buffer instruction |
| |
| // DM <-> Pipeline: HART Abstract Data regs i/f |
| output logic pipe2dm_dreg_req_o, // Abstract Data Register request |
| output logic pipe2dm_dreg_wr_o, // Abstract Data Register write |
| output logic [`SCR1_XLEN-1:0] pipe2dm_dreg_wdata_o, // Abstract Data Register write data |
| input logic dm2pipe_dreg_resp_i, // Abstract Data Register response |
| input logic dm2pipe_dreg_fail_i, // Abstract Data Register fail - possibly not needed? |
| input logic [`SCR1_XLEN-1:0] dm2pipe_dreg_rdata_i, // Abstract Data Register read data |
| |
| // DM <-> Pipeling: PC i/f |
| output logic [`SCR1_XLEN-1:0] pipe2dm_pc_sample_o, // Current PC for sampling |
| `endif // SCR1_DBG_EN |
| |
| // IRQ |
| `ifdef SCR1_IPIC_EN |
| input logic [SCR1_IRQ_LINES_NUM-1:0] soc2pipe_irq_lines_i, // External interrupt request lines |
| `else // SCR1_IPIC_EN |
| input logic soc2pipe_irq_ext_i, // External interrupt request |
| `endif // SCR1_IPIC_EN |
| input logic soc2pipe_irq_soft_i, // Software generated interrupt request |
| input logic soc2pipe_irq_mtimer_i, // Machine timer interrupt request |
| |
| // Memory-mapped external timer |
| input logic [63:0] soc2pipe_mtimer_val_i, // Machine timer value |
| |
| `ifdef SCR1_CLKCTRL_EN |
| // CLK_CTRL interface |
| output logic pipe2clkctl_sleep_req_o, // CLK disable request to CLK gating circuit |
| output logic pipe2clkctl_wake_req_o, // CLK enable request to CLK gating circuit |
| input logic clkctl2pipe_clk_alw_on_i, // Not gated CLK |
| input logic clkctl2pipe_clk_dbgc_i, // CLK for HDU (not gated for now) |
| input logic clkctl2pipe_clk_en_i, // CLK enabled flag |
| `endif // SCR1_CLKCTRL_EN |
| |
| // Fuse |
| input logic [`SCR1_XLEN-1:0] soc2pipe_fuse_mhartid_i // Fuse MHARTID value |
| ); |
| |
| //------------------------------------------------------------------------------- |
| // Local signals declaration |
| //------------------------------------------------------------------------------- |
| |
| // Pipeline control |
| logic [`SCR1_XLEN-1:0] curr_pc; // Current PC |
| logic [`SCR1_XLEN-1:0] next_pc; // Is written to MEPC on interrupt trap |
| logic new_pc_req; // New PC request (jumps, branches, traps etc) |
| logic [`SCR1_XLEN-1:0] new_pc; // New PC |
| |
| logic stop_fetch; // Stop IFU |
| logic exu_exc_req; // Exception request |
| logic brkpt; // Breakpoint (sw) on current instruction |
| logic exu_init_pc; // Reset exit |
| logic wfi_run2halt; // Transition to WFI halted state |
| logic instret; // Instruction retirement (with or without exception) |
| logic instret_nexc; // Instruction retirement (without exception) |
| `ifdef SCR1_IPIC_EN |
| logic ipic2csr_irq; // IRQ request from IPIC |
| `endif // SCR1_IPIC_EN |
| `ifdef SCR1_TDU_EN |
| logic brkpt_hw; // Hardware breakpoint on current instruction |
| `endif // SCR1_TDU_EN |
| `ifdef SCR1_CLKCTRL_EN |
| logic imem_txns_pending; // There are pending imem transactions |
| logic wfi_halted; // WFI halted state |
| `endif // SCR1_CLKCTRL_EN |
| |
| // IFU <-> IDU |
| logic ifu2idu_vd; // IFU request |
| logic [`SCR1_IMEM_DWIDTH-1:0] ifu2idu_instr; // IFU instruction |
| logic ifu2idu_imem_err; // IFU instruction access fault |
| logic ifu2idu_err_rvi_hi; // 1 - imem fault when trying to fetch second half of an unaligned RVI instruction |
| logic idu2ifu_rdy; // IDU ready for new data |
| |
| // IDU <-> EXU |
| logic idu2exu_req; // IDU request |
| type_scr1_exu_cmd_s idu2exu_cmd; // IDU command (see scr1_riscv_isa_decoding.svh) |
| logic idu2exu_use_rs1; // Instruction uses rs1 |
| logic idu2exu_use_rs2; // Instruction uses rs2 |
| logic idu2exu_use_rd; // Instruction uses rd |
| logic idu2exu_use_imm; // Instruction uses immediate |
| logic exu2idu_rdy; // EXU ready for new data |
| |
| // EXU <-> MPRF |
| logic [`SCR1_MPRF_AWIDTH-1:0] exu2mprf_rs1_addr; // MPRF rs1 read address |
| logic [`SCR1_XLEN-1:0] mprf2exu_rs1_data; // MPRF rs1 read data |
| logic [`SCR1_MPRF_AWIDTH-1:0] exu2mprf_rs2_addr; // MPRF rs2 read address |
| logic [`SCR1_XLEN-1:0] mprf2exu_rs2_data; // MPRF rs2 read data |
| logic exu2mprf_w_req; // MPRF write request |
| logic [`SCR1_MPRF_AWIDTH-1:0] exu2mprf_rd_addr; // MPRF rd write address |
| logic [`SCR1_XLEN-1:0] exu2mprf_rd_data; // MPRF rd write data |
| |
| // EXU <-> CSR |
| logic [SCR1_CSR_ADDR_WIDTH-1:0] exu2csr_rw_addr; // CSR read/write address |
| logic exu2csr_r_req; // CSR read request |
| logic [`SCR1_XLEN-1:0] csr2exu_r_data; // CSR read data |
| logic exu2csr_w_req; // CSR write request |
| type_scr1_csr_cmd_sel_e exu2csr_w_cmd; // CSR write command |
| logic [`SCR1_XLEN-1:0] exu2csr_w_data; // CSR write data |
| logic csr2exu_rw_exc; // CSR read/write access exception |
| |
| // EXU <-> CSR event interface |
| logic exu2csr_take_irq; // Take IRQ trap |
| logic exu2csr_take_exc; // Take exception trap |
| logic exu2csr_mret_update; // MRET update CSR |
| logic exu2csr_mret_instr; // MRET instruction |
| logic [SCR1_EXC_CODE_WIDTH_E-1:0] exu2csr_exc_code; // Exception code (see scr1_arch_types.svh) |
| logic [`SCR1_XLEN-1:0] exu2csr_trap_val; // Trap value |
| logic [`SCR1_XLEN-1:0] csr2exu_new_pc; // Exception/IRQ/MRET new PC |
| logic csr2exu_irq; // IRQ request |
| logic csr2exu_ip_ie; // Some IRQ pending and locally enabled |
| logic csr2exu_mstatus_mie_up; // MSTATUS or MIE update in the current cycle |
| |
| `ifdef SCR1_IPIC_EN |
| // CSR <-> IPIC |
| logic csr2ipic_r_req; // IPIC read request |
| logic csr2ipic_w_req; // IPIC write request |
| logic [2:0] csr2ipic_addr; // IPIC address |
| logic [`SCR1_XLEN-1:0] csr2ipic_wdata; // IPIC write data |
| logic [`SCR1_XLEN-1:0] ipic2csr_rdata; // IPIC read data |
| `endif // SCR1_IPIC_EN |
| |
| `ifdef SCR1_TDU_EN |
| // CSR <-> TDU |
| logic csr2tdu_req; // Request to TDU |
| type_scr1_csr_cmd_sel_e csr2tdu_cmd; // TDU command |
| logic [SCR1_CSR_ADDR_TDU_OFFS_W-1:0] csr2tdu_addr; // TDU address |
| logic [`SCR1_XLEN-1:0] csr2tdu_wdata; // TDU write data |
| logic [`SCR1_XLEN-1:0] tdu2csr_rdata; // TDU read data |
| type_scr1_csr_resp_e tdu2csr_resp; // TDU response |
| `ifdef SCR1_DBG_EN |
| // Qualified TDU input signals from pipe_rst_n |
| // reset domain: |
| logic csr2tdu_req_qlfy; // Request to TDU |
| `endif // SCR1_DBG_EN |
| |
| // EXU/LSU <-> TDU |
| type_scr1_brkm_instr_mon_s exu2tdu_i_mon; // Instruction monitor |
| type_scr1_brkm_lsu_mon_s lsu2tdu_d_mon; // Data monitor |
| logic [SCR1_TDU_ALLTRIG_NUM-1:0] tdu2exu_i_match; // Instruction breakpoint(s) match |
| logic [SCR1_TDU_MTRIG_NUM-1:0] tdu2lsu_d_match; // Data breakpoint(s) match |
| logic tdu2exu_i_x_req; // Instruction breakpoint exception |
| logic tdu2lsu_i_x_req; // Instruction breakpoint exception |
| logic tdu2lsu_d_x_req; // Data breakpoint exception |
| logic [SCR1_TDU_ALLTRIG_NUM-1:0] exu2tdu_bp_retire; // Instruction with breakpoint flag retire |
| `ifdef SCR1_DBG_EN |
| // Qualified TDU input signals from pipe_rst_n |
| // reset domain: |
| type_scr1_brkm_instr_mon_s exu2tdu_i_mon_qlfy; // Instruction monitor |
| type_scr1_brkm_lsu_mon_s lsu2tdu_d_mon_qlfy; // Data monitor |
| logic [SCR1_TDU_ALLTRIG_NUM-1:0] exu2tdu_bp_retire_qlfy; // Instruction with breakpoint flag retire |
| `endif // SCR1_DBG_EN |
| `endif // SCR1_TDU_EN |
| |
| `ifdef SCR1_DBG_EN |
| // Debug signals: |
| logic fetch_pbuf; // Fetch instructions provided by Program Buffer (via HDU) |
| logic csr2hdu_req; // Request to HDU |
| type_scr1_csr_cmd_sel_e csr2hdu_cmd; // HDU command |
| logic [SCR1_HDU_DEBUGCSR_ADDR_WIDTH-1:0] csr2hdu_addr; // HDU address |
| logic [`SCR1_XLEN-1:0] csr2hdu_wdata; // HDU write data |
| logic [`SCR1_XLEN-1:0] hdu2csr_rdata; // HDU read data |
| type_scr1_csr_resp_e hdu2csr_resp; // HDU response |
| // Qualified HDU input signals from pipe_rst_n |
| // reset domain: |
| logic csr2hdu_req_qlfy; // Request to HDU |
| |
| logic hwbrk_dsbl; // Disables TDU |
| logic hdu_hwbrk_dsbl; // Disables TDU |
| logic tdu2hdu_dmode_req; // TDU requests transition to debug mode |
| |
| logic exu_no_commit; // Forbid instruction commitment |
| logic exu_irq_dsbl; // Disable IRQ |
| logic exu_pc_advmt_dsbl; // Forbid PC advancement |
| logic exu_dmode_sstep_en; // Enable single-step |
| |
| logic dbg_halted; // Debug halted state |
| logic dbg_run2halt; // Transition to debug halted state |
| logic dbg_halt2run; // Transition to run state |
| logic dbg_run_start; // First cycle of run state |
| logic [`SCR1_XLEN-1:0] dbg_new_pc; // New PC as starting point for HART Resume |
| |
| logic ifu2hdu_pbuf_rdy; |
| logic hdu2ifu_pbuf_vd; |
| logic hdu2ifu_pbuf_err; |
| logic [SCR1_HDU_CORE_INSTR_WIDTH-1:0] hdu2ifu_pbuf_instr; |
| |
| // Qualified HDU input signals from pipe_rst_n reset domain: |
| logic ifu2hdu_pbuf_rdy_qlfy; |
| logic exu_busy_qlfy; |
| logic instret_qlfy; |
| logic exu_init_pc_qlfy; |
| logic exu_exc_req_qlfy; |
| logic brkpt_qlfy; |
| |
| `endif // SCR1_DBG_EN |
| |
| logic exu_busy; |
| |
| |
| `ifndef SCR1_CLKCTRL_EN |
| logic pipe2clkctl_wake_req_o; |
| `endif // SCR1_CLKCTRL_EN |
| |
| |
| assign pipe_debug = {curr_pc[31:0],new_pc_req,stop_fetch, exu_exc_req,brkpt,exu_init_pc,wfi_run2halt,instret, |
| ifu2idu_vd,idu2ifu_rdy,idu2exu_req,exu2idu_rdy,exu2mprf_w_req,exu2csr_r_req,csr2exu_rw_exc, |
| exu2csr_mret_update,csr2exu_irq,csr2exu_mstatus_mie_up}; |
| //------------------------------------------------------------------------------- |
| // Pipeline logic |
| //------------------------------------------------------------------------------- |
| assign stop_fetch = wfi_run2halt |
| `ifdef SCR1_DBG_EN |
| | fetch_pbuf |
| `endif // SCR1_DBG_EN |
| ; |
| |
| `ifdef SCR1_CLKCTRL_EN |
| assign pipe2clkctl_sleep_req_o = wfi_halted & ~imem_txns_pending; |
| assign pipe2clkctl_wake_req_o = csr2exu_ip_ie |
| `ifdef SCR1_DBG_EN |
| | dm2pipe_active_i |
| `endif // SCR1_DBG_EN |
| ; |
| `endif // SCR1_CLKCTRL_EN |
| |
| `ifdef SCR1_DBG_EN |
| assign pipe2dm_pc_sample_o = curr_pc; |
| `endif // SCR1_DBG_EN |
| |
| //------------------------------------------------------------------------------- |
| // Instruction fetch unit |
| //------------------------------------------------------------------------------- |
| scr1_pipe_ifu i_pipe_ifu ( |
| .rst_n (pipe_rst_n ), |
| .clk (clk ), |
| |
| // Instruction memory interface |
| .imem2ifu_req_ack_i (imem2pipe_req_ack_i), |
| .ifu2imem_req_o (pipe2imem_req_o ), |
| .ifu2imem_cmd_o (pipe2imem_cmd_o ), |
| .ifu2imem_addr_o (pipe2imem_addr_o ), |
| .imem2ifu_rdata_i (imem2pipe_rdata_i ), |
| .imem2ifu_resp_i (imem2pipe_resp_i ), |
| |
| // New PC interface |
| .exu2ifu_pc_new_req_i (new_pc_req ), |
| .exu2ifu_pc_new_i (new_pc ), |
| .pipe2ifu_stop_fetch_i (stop_fetch ), |
| |
| `ifdef SCR1_DBG_EN |
| // IFU <-> HDU Program Buffer interface |
| .hdu2ifu_pbuf_fetch_i (fetch_pbuf ), |
| .ifu2hdu_pbuf_rdy_o (ifu2hdu_pbuf_rdy ), |
| .hdu2ifu_pbuf_vd_i (hdu2ifu_pbuf_vd ), |
| .hdu2ifu_pbuf_err_i (hdu2ifu_pbuf_err ), |
| .hdu2ifu_pbuf_instr_i (hdu2ifu_pbuf_instr ), |
| `endif // SCR1_DBG_EN |
| `ifdef SCR1_CLKCTRL_EN |
| .ifu2pipe_imem_txns_pnd_o (imem_txns_pending ), |
| `endif // SCR1_CLKCTRL_EN |
| |
| // IFU <-> IDU interface |
| .idu2ifu_rdy_i (idu2ifu_rdy ), |
| .ifu2idu_instr_o (ifu2idu_instr ), |
| .ifu2idu_imem_err_o (ifu2idu_imem_err ), |
| .ifu2idu_err_rvi_hi_o (ifu2idu_err_rvi_hi ), |
| .ifu2idu_vd_o (ifu2idu_vd ) |
| ); |
| |
| //------------------------------------------------------------------------------- |
| // Instruction decode unit |
| //------------------------------------------------------------------------------- |
| scr1_pipe_idu i_pipe_idu ( |
| `ifdef SCR1_TRGT_SIMULATION |
| .rst_n (pipe_rst_n ), |
| .clk (clk ), |
| `endif // SCR1_TRGT_SIMULATION |
| .idu2ifu_rdy_o (idu2ifu_rdy ), |
| .ifu2idu_instr_i (ifu2idu_instr ), |
| .ifu2idu_imem_err_i (ifu2idu_imem_err ), |
| .ifu2idu_err_rvi_hi_i (ifu2idu_err_rvi_hi), |
| .ifu2idu_vd_i (ifu2idu_vd ), |
| |
| .idu2exu_req_o (idu2exu_req ), |
| .idu2exu_cmd_o (idu2exu_cmd ), |
| .idu2exu_use_rs1_o (idu2exu_use_rs1 ), |
| .idu2exu_use_rs2_o (idu2exu_use_rs2 ), |
| .idu2exu_use_rd_o (idu2exu_use_rd ), |
| .idu2exu_use_imm_o (idu2exu_use_imm ), |
| .exu2idu_rdy_i (exu2idu_rdy ) |
| ); |
| |
| //------------------------------------------------------------------------------- |
| // Execution unit |
| //------------------------------------------------------------------------------- |
| scr1_pipe_exu i_pipe_exu ( |
| .rst_n (pipe_rst_n ), |
| .clk (clk ), |
| `ifdef SCR1_CLKCTRL_EN |
| .clk_alw_on (clkctl2pipe_clk_alw_on_i), |
| .clk_pipe_en (clkctl2pipe_clk_en_i), |
| `endif // SCR1_CLKCTRL_EN |
| |
| // IDU <-> EXU interface |
| .idu2exu_req_i (idu2exu_req ), |
| .exu2idu_rdy_o (exu2idu_rdy ), |
| .idu2exu_cmd_i (idu2exu_cmd ), |
| .idu2exu_use_rs1_i (idu2exu_use_rs1 ), |
| .idu2exu_use_rs2_i (idu2exu_use_rs2 ), |
| `ifndef SCR1_NO_EXE_STAGE |
| .idu2exu_use_rd_i (idu2exu_use_rd ), |
| .idu2exu_use_imm_i (idu2exu_use_imm ), |
| `endif // SCR1_NO_EXE_STAGE |
| |
| // EXU <-> MPRF interface |
| .exu2mprf_rs1_addr_o (exu2mprf_rs1_addr ), |
| .mprf2exu_rs1_data_i (mprf2exu_rs1_data ), |
| .exu2mprf_rs2_addr_o (exu2mprf_rs2_addr ), |
| .mprf2exu_rs2_data_i (mprf2exu_rs2_data ), |
| .exu2mprf_w_req_o (exu2mprf_w_req ), |
| .exu2mprf_rd_addr_o (exu2mprf_rd_addr ), |
| .exu2mprf_rd_data_o (exu2mprf_rd_data ), |
| |
| // EXU <-> CSR read/write interface |
| .exu2csr_rw_addr_o (exu2csr_rw_addr ), |
| .exu2csr_r_req_o (exu2csr_r_req ), |
| .csr2exu_r_data_i (csr2exu_r_data ), |
| .exu2csr_w_req_o (exu2csr_w_req ), |
| .exu2csr_w_cmd_o (exu2csr_w_cmd ), |
| .exu2csr_w_data_o (exu2csr_w_data ), |
| .csr2exu_rw_exc_i (csr2exu_rw_exc ), |
| |
| // EXU <-> CSR event interface |
| .exu2csr_take_irq_o (exu2csr_take_irq ), |
| .exu2csr_take_exc_o (exu2csr_take_exc ), |
| .exu2csr_mret_update_o (exu2csr_mret_update ), |
| .exu2csr_mret_instr_o (exu2csr_mret_instr ), |
| .exu2csr_exc_code_o (exu2csr_exc_code ), |
| .exu2csr_trap_val_o (exu2csr_trap_val ), |
| .csr2exu_new_pc_i (csr2exu_new_pc ), |
| .csr2exu_irq_i (csr2exu_irq ), |
| .csr2exu_ip_ie_i (csr2exu_ip_ie ), |
| .csr2exu_mstatus_mie_up_i (csr2exu_mstatus_mie_up ), |
| |
| // EXU <-> DMEM interface |
| .exu2dmem_req_o (pipe2dmem_req_o ), |
| .exu2dmem_cmd_o (pipe2dmem_cmd_o ), |
| .exu2dmem_width_o (pipe2dmem_width_o ), |
| .exu2dmem_addr_o (pipe2dmem_addr_o ), |
| .exu2dmem_wdata_o (pipe2dmem_wdata_o ), |
| .dmem2exu_req_ack_i (dmem2pipe_req_ack_i ), |
| .dmem2exu_rdata_i (dmem2pipe_rdata_i ), |
| .dmem2exu_resp_i (dmem2pipe_resp_i ), |
| |
| `ifdef SCR1_DBG_EN |
| // EXU <-> HDU interface |
| .hdu2exu_no_commit_i (exu_no_commit ), |
| .hdu2exu_irq_dsbl_i (exu_irq_dsbl ), |
| .hdu2exu_pc_advmt_dsbl_i (exu_pc_advmt_dsbl ), |
| .hdu2exu_dmode_sstep_en_i (exu_dmode_sstep_en ), |
| .hdu2exu_pbuf_fetch_i (fetch_pbuf ), |
| .hdu2exu_dbg_halted_i (dbg_halted ), |
| .hdu2exu_dbg_run2halt_i (dbg_run2halt ), |
| .hdu2exu_dbg_halt2run_i (dbg_halt2run ), |
| .hdu2exu_dbg_run_start_i (dbg_run_start ), |
| .hdu2exu_dbg_new_pc_i (dbg_new_pc ), |
| `endif // SCR1_DBG_EN |
| |
| `ifdef SCR1_TDU_EN |
| // EXU <-> TDU interface |
| .exu2tdu_imon_o (exu2tdu_i_mon ), |
| .tdu2exu_ibrkpt_match_i (tdu2exu_i_match ), |
| .tdu2exu_ibrkpt_exc_req_i (tdu2exu_i_x_req ), |
| .lsu2tdu_dmon_o (lsu2tdu_d_mon ), |
| .tdu2lsu_ibrkpt_exc_req_i (tdu2lsu_i_x_req ), |
| .tdu2lsu_dbrkpt_match_i (tdu2lsu_d_match ), |
| .tdu2lsu_dbrkpt_exc_req_i (tdu2lsu_d_x_req ), |
| .exu2tdu_ibrkpt_ret_o (exu2tdu_bp_retire ), |
| .exu2hdu_ibrkpt_hw_o (brkpt_hw ), |
| `endif // SCR1_TDU_EN |
| |
| // EXU control |
| .exu2pipe_exc_req_o (exu_exc_req ), |
| .exu2pipe_brkpt_o (brkpt ), |
| .exu2pipe_init_pc_o (exu_init_pc ), |
| .exu2pipe_wfi_run2halt_o (wfi_run2halt ), |
| .exu2pipe_instret_o (instret ), |
| .exu2csr_instret_no_exc_o (instret_nexc ), |
| .exu2pipe_exu_busy_o (exu_busy ), |
| |
| // PC interface |
| `ifdef SCR1_CLKCTRL_EN |
| .exu2pipe_wfi_halted_o (wfi_halted ), |
| `endif // SCR1_CLKCTRL_EN |
| .exu2pipe_pc_curr_o (curr_pc ), |
| .exu2csr_pc_next_o (next_pc ), |
| .exu2ifu_pc_new_req_o (new_pc_req ), |
| .exu2ifu_pc_new_o (new_pc ) |
| ); |
| |
| //------------------------------------------------------------------------------- |
| // Multi-port register file |
| //------------------------------------------------------------------------------- |
| scr1_pipe_mprf i_pipe_mprf ( |
| `ifdef SCR1_MPRF_RST_EN |
| .rst_n (pipe_rst_n ), |
| `endif // SCR1_MPRF_RST_EN |
| .clk (clk ), |
| |
| // EXU <-> MPRF interface |
| .exu2mprf_rs1_addr_i (exu2mprf_rs1_addr), |
| .mprf2exu_rs1_data_o (mprf2exu_rs1_data), |
| .exu2mprf_rs2_addr_i (exu2mprf_rs2_addr), |
| .mprf2exu_rs2_data_o (mprf2exu_rs2_data), |
| .exu2mprf_w_req_i (exu2mprf_w_req ), |
| .exu2mprf_rd_addr_i (exu2mprf_rd_addr ), |
| .exu2mprf_rd_data_i (exu2mprf_rd_data ) |
| ); |
| |
| //------------------------------------------------------------------------------- |
| // Control and status registers |
| //------------------------------------------------------------------------------- |
| scr1_pipe_csr i_pipe_csr ( |
| .rst_n (pipe_rst_n ), |
| .clk (clk ), |
| `ifdef SCR1_CLKCTRL_EN |
| .clk_alw_on (clkctl2pipe_clk_alw_on_i), |
| `endif // SCR1_CLKCTRL_EN |
| |
| // EXU <-> CSR read/write interface |
| .exu2csr_r_req_i (exu2csr_r_req ), |
| .exu2csr_rw_addr_i (exu2csr_rw_addr ), |
| .csr2exu_r_data_o (csr2exu_r_data ), |
| .exu2csr_w_req_i (exu2csr_w_req ), |
| .exu2csr_w_cmd_i (exu2csr_w_cmd ), |
| .exu2csr_w_data_i (exu2csr_w_data ), |
| .csr2exu_rw_exc_o (csr2exu_rw_exc ), |
| |
| // EXU <-> CSR event interface |
| .exu2csr_take_irq_i (exu2csr_take_irq ), |
| .exu2csr_take_exc_i (exu2csr_take_exc ), |
| .exu2csr_mret_update_i (exu2csr_mret_update ), |
| .exu2csr_mret_instr_i (exu2csr_mret_instr ), |
| .exu2csr_exc_code_i (exu2csr_exc_code ), |
| .exu2csr_trap_val_i (exu2csr_trap_val ), |
| .csr2exu_new_pc_o (csr2exu_new_pc ), |
| .csr2exu_irq_o (csr2exu_irq ), |
| .csr2exu_ip_ie_o (csr2exu_ip_ie ), |
| .csr2exu_mstatus_mie_up_o (csr2exu_mstatus_mie_up ), |
| |
| `ifdef SCR1_IPIC_EN |
| // CSR <-> IPIC interface |
| .csr2ipic_r_req_o (csr2ipic_r_req ), |
| .csr2ipic_w_req_o (csr2ipic_w_req ), |
| .csr2ipic_addr_o (csr2ipic_addr ), |
| .csr2ipic_wdata_o (csr2ipic_wdata ), |
| .ipic2csr_rdata_i (ipic2csr_rdata ), |
| `endif // SCR1_IPIC_EN |
| |
| // CSR <-> PC interface |
| .exu2csr_pc_curr_i (curr_pc ), |
| .exu2csr_pc_next_i (next_pc ), |
| `ifndef SCR1_CSR_REDUCED_CNT |
| .exu2csr_instret_no_exc_i (instret_nexc ), |
| `endif // SCR1_CSR_REDUCED_CNT |
| |
| // IRQ |
| `ifdef SCR1_IPIC_EN |
| .soc2csr_irq_ext_i (ipic2csr_irq ), |
| `else // SCR1_IPIC_EN |
| .soc2csr_irq_ext_i (soc2pipe_irq_ext_i ), |
| `endif // SCR1_IPIC_EN |
| .soc2csr_irq_soft_i (soc2pipe_irq_soft_i ), |
| .soc2csr_irq_mtimer_i (soc2pipe_irq_mtimer_i ), |
| |
| // Memory-mapped external timer |
| .soc2csr_mtimer_val_i (soc2pipe_mtimer_val_i ), |
| |
| `ifdef SCR1_DBG_EN |
| // CSR <-> HDU interface |
| .csr2hdu_req_o (csr2hdu_req ), |
| .csr2hdu_cmd_o (csr2hdu_cmd ), |
| .csr2hdu_addr_o (csr2hdu_addr ), |
| .csr2hdu_wdata_o (csr2hdu_wdata ), |
| .hdu2csr_rdata_i (hdu2csr_rdata ), |
| .hdu2csr_resp_i (hdu2csr_resp ), |
| .hdu2csr_no_commit_i (exu_no_commit ), |
| `endif // SCR1_DBG_EN |
| |
| `ifdef SCR1_TDU_EN |
| // CSR <-> TDU interface |
| .csr2tdu_req_o (csr2tdu_req ), |
| .csr2tdu_cmd_o (csr2tdu_cmd ), |
| .csr2tdu_addr_o (csr2tdu_addr ), |
| .csr2tdu_wdata_o (csr2tdu_wdata ), |
| .tdu2csr_rdata_i (tdu2csr_rdata ), |
| .tdu2csr_resp_i (tdu2csr_resp ), |
| `endif // SCR1_TDU_EN |
| .soc2csr_fuse_mhartid_i (soc2pipe_fuse_mhartid_i ) |
| ); |
| |
| //------------------------------------------------------------------------------- |
| // Integrated programmable interrupt controller |
| //------------------------------------------------------------------------------- |
| `ifdef SCR1_IPIC_EN |
| scr1_ipic i_pipe_ipic ( |
| .rst_n (pipe_rst_n ), |
| `ifdef SCR1_CLKCTRL_EN |
| .clk (clkctl2pipe_clk_alw_on_i), |
| `else // SCR1_CLKCTRL_EN |
| .clk (clk ), |
| `endif // SCR1_CLKCTRL_EN |
| .soc2ipic_irq_lines_i (soc2pipe_irq_lines_i ), |
| .csr2ipic_r_req_i (csr2ipic_r_req ), |
| .csr2ipic_w_req_i (csr2ipic_w_req ), |
| .csr2ipic_addr_i (csr2ipic_addr ), |
| .csr2ipic_wdata_i (csr2ipic_wdata ), |
| .ipic2csr_rdata_o (ipic2csr_rdata ), |
| .ipic2csr_irq_m_req_o (ipic2csr_irq ) |
| ); |
| `endif // SCR1_IPIC_EN |
| |
| //------------------------------------------------------------------------------- |
| // Breakpoint module |
| //------------------------------------------------------------------------------- |
| `ifdef SCR1_TDU_EN |
| scr1_pipe_tdu i_pipe_tdu ( |
| // Common signals |
| `ifdef SCR1_DBG_EN |
| .rst_n (dbg_rst_n ), |
| `else |
| .rst_n (pipe_rst_n ), |
| `endif // SCR1_DBG_EN |
| .clk (clk ), |
| .clk_en (1'b1 ), |
| `ifdef SCR1_DBG_EN |
| .tdu_dsbl_i (hwbrk_dsbl ), |
| `else // SCR1_DBG_EN |
| .tdu_dsbl_i (1'b0 ), |
| `endif // SCR1_DBG_EN |
| |
| // TDU <-> CSR interface |
| `ifdef SCR1_DBG_EN |
| .csr2tdu_req_i (csr2tdu_req_qlfy ), |
| .csr2tdu_cmd_i (csr2tdu_cmd ), |
| .csr2tdu_addr_i (csr2tdu_addr ), |
| .csr2tdu_wdata_i (csr2tdu_wdata ), |
| `else // SCR1_DBG_EN |
| .csr2tdu_req_i (csr2tdu_req ), |
| .csr2tdu_cmd_i (csr2tdu_cmd ), |
| .csr2tdu_addr_i (csr2tdu_addr ), |
| .csr2tdu_wdata_i (csr2tdu_wdata ), |
| `endif // SCR1_DBG_EN |
| .tdu2csr_rdata_o (tdu2csr_rdata ), |
| .tdu2csr_resp_o (tdu2csr_resp ), |
| |
| // TDU <-> EXU interface |
| `ifdef SCR1_DBG_EN |
| .exu2tdu_imon_i (exu2tdu_i_mon_qlfy ), |
| `else // SCR1_DBG_EN |
| .exu2tdu_imon_i (exu2tdu_i_mon ), |
| `endif // SCR1_DBG_EN |
| .tdu2exu_ibrkpt_match_o (tdu2exu_i_match ), |
| .tdu2exu_ibrkpt_exc_req_o (tdu2exu_i_x_req ), |
| `ifdef SCR1_DBG_EN |
| .exu2tdu_bp_retire_i (exu2tdu_bp_retire_qlfy), |
| `else // SCR1_DBG_EN |
| .exu2tdu_bp_retire_i (exu2tdu_bp_retire ), |
| `endif // SCR1_DBG_EN |
| |
| // TDU <-> LSU interface |
| .tdu2lsu_ibrkpt_exc_req_o (tdu2lsu_i_x_req ), |
| `ifdef SCR1_DBG_EN |
| .lsu2tdu_dmon_i (lsu2tdu_d_mon_qlfy ), |
| `else // SCR1_DBG_EN |
| .lsu2tdu_dmon_i (lsu2tdu_d_mon ), |
| `endif // SCR1_DBG_EN |
| .tdu2lsu_dbrkpt_match_o (tdu2lsu_d_match ), |
| .tdu2lsu_dbrkpt_exc_req_o (tdu2lsu_d_x_req ), |
| // EPU I/F |
| `ifdef SCR1_DBG_EN |
| .tdu2hdu_dmode_req_o (tdu2hdu_dmode_req ) |
| `else // SCR1_DBG_EN |
| .tdu2hdu_dmode_req_o ( ) |
| `endif // SCR1_DBG_EN |
| ); |
| |
| `ifdef SCR1_DBG_EN |
| assign hwbrk_dsbl = (~dbg_en) | hdu_hwbrk_dsbl; |
| // |
| assign csr2tdu_req_qlfy = dbg_en & csr2tdu_req & pipe2hdu_rdc_qlfy_i; |
| // |
| assign exu2tdu_i_mon_qlfy.vd = exu2tdu_i_mon.vd & pipe2hdu_rdc_qlfy_i; |
| assign exu2tdu_i_mon_qlfy.req = exu2tdu_i_mon.req; |
| assign exu2tdu_i_mon_qlfy.addr = exu2tdu_i_mon.addr; |
| assign lsu2tdu_d_mon_qlfy.vd = lsu2tdu_d_mon.vd & pipe2hdu_rdc_qlfy_i; |
| assign lsu2tdu_d_mon_qlfy.load = lsu2tdu_d_mon.load; |
| assign lsu2tdu_d_mon_qlfy.store = lsu2tdu_d_mon.store; |
| assign lsu2tdu_d_mon_qlfy.addr = lsu2tdu_d_mon.addr; |
| assign exu2tdu_bp_retire_qlfy = exu2tdu_bp_retire & {$bits(exu2tdu_bp_retire){pipe2hdu_rdc_qlfy_i}}; |
| `endif // SCR1_DBG_EN |
| |
| `endif // SCR1_TDU_EN |
| |
| //------------------------------------------------------------------------------- |
| // HART Debug Unit (HDU) |
| //------------------------------------------------------------------------------- |
| `ifdef SCR1_DBG_EN |
| scr1_pipe_hdu i_pipe_hdu ( |
| // Common signals |
| .rst_n (dbg_rst_n ), |
| .clk_en (dm2pipe_active_i ), |
| `ifdef SCR1_CLKCTRL_EN |
| .clk_pipe_en (clkctl2pipe_clk_en_i ), |
| .clk (clkctl2pipe_clk_dbgc_i), |
| `else |
| .clk (clk ), |
| `endif // SCR1_CLKCTRL_EN |
| |
| // Control/status registers i/f |
| .csr2hdu_req_i (csr2hdu_req_qlfy ), |
| .csr2hdu_cmd_i (csr2hdu_cmd ), |
| .csr2hdu_addr_i (csr2hdu_addr ), |
| .csr2hdu_wdata_i (csr2hdu_wdata ), |
| .hdu2csr_resp_o (hdu2csr_resp ), |
| .hdu2csr_rdata_o (hdu2csr_rdata ), |
| |
| // HART Run Control i/f |
| .pipe2hdu_rdc_qlfy_i (pipe2hdu_rdc_qlfy_i ), |
| .dm2hdu_cmd_req_i (dm2pipe_cmd_req_i ), |
| .dm2hdu_cmd_i (dm2pipe_cmd_i ), |
| .hdu2dm_cmd_resp_o (pipe2dm_cmd_resp_o ), |
| .hdu2dm_cmd_rcode_o (pipe2dm_cmd_rcode_o ), |
| .hdu2dm_hart_event_o (pipe2dm_hart_event_o ), |
| .hdu2dm_hart_status_o (pipe2dm_hart_status_o ), |
| |
| // Program Buffer - HART instruction execution i/f |
| .hdu2dm_pbuf_addr_o (pipe2dm_pbuf_addr_o ), |
| .dm2hdu_pbuf_instr_i (dm2pipe_pbuf_instr_i ), |
| |
| // HART Abstract Data regs i/f |
| .hdu2dm_dreg_req_o (pipe2dm_dreg_req_o ), |
| .hdu2dm_dreg_wr_o (pipe2dm_dreg_wr_o ), |
| .hdu2dm_dreg_wdata_o (pipe2dm_dreg_wdata_o ), |
| .dm2hdu_dreg_resp_i (dm2pipe_dreg_resp_i ), |
| .dm2hdu_dreg_fail_i (dm2pipe_dreg_fail_i ), |
| .dm2hdu_dreg_rdata_i (dm2pipe_dreg_rdata_i ), |
| // |
| `ifdef SCR1_TDU_EN |
| // HDU <-> TDU interface |
| .hdu2tdu_hwbrk_dsbl_o (hdu_hwbrk_dsbl ), |
| .tdu2hdu_dmode_req_i (tdu2hdu_dmode_req ), |
| .exu2hdu_ibrkpt_hw_i (brkpt_hw ), |
| `endif // SCR1_TDU_EN |
| |
| // HART Run Status |
| .pipe2hdu_exu_busy_i (exu_busy_qlfy ), |
| .pipe2hdu_instret_i (instret_qlfy ), |
| .pipe2hdu_init_pc_i (exu_init_pc_qlfy ), |
| |
| // HART Halt Status |
| .pipe2hdu_exu_exc_req_i (exu_exc_req_qlfy ), |
| .pipe2hdu_brkpt_i (brkpt_qlfy ), |
| |
| // HART Run Control |
| .hdu2exu_pbuf_fetch_o (fetch_pbuf ), |
| .hdu2exu_no_commit_o (exu_no_commit ), |
| .hdu2exu_irq_dsbl_o (exu_irq_dsbl ), |
| .hdu2exu_pc_advmt_dsbl_o (exu_pc_advmt_dsbl ), |
| .hdu2exu_dmode_sstep_en_o (exu_dmode_sstep_en ), |
| |
| // HART state |
| .hdu2exu_dbg_halted_o (dbg_halted ), |
| .hdu2exu_dbg_run2halt_o (dbg_run2halt ), |
| .hdu2exu_dbg_halt2run_o (dbg_halt2run ), |
| .hdu2exu_dbg_run_start_o (dbg_run_start ), |
| |
| // PC interface |
| .pipe2hdu_pc_curr_i (curr_pc ), |
| .hdu2exu_dbg_new_pc_o (dbg_new_pc ), |
| |
| // Prgram Buffer Instruction interface |
| .ifu2hdu_pbuf_instr_rdy_i (ifu2hdu_pbuf_rdy_qlfy ), |
| .hdu2ifu_pbuf_instr_vd_o (hdu2ifu_pbuf_vd ), |
| .hdu2ifu_pbuf_instr_err_o (hdu2ifu_pbuf_err ), |
| .hdu2ifu_pbuf_instr_o (hdu2ifu_pbuf_instr ) |
| ); |
| |
| assign csr2hdu_req_qlfy = csr2hdu_req & dbg_en & pipe2hdu_rdc_qlfy_i; |
| // |
| assign exu_busy_qlfy = exu_busy & {$bits(exu_busy){pipe2hdu_rdc_qlfy_i}}; |
| assign instret_qlfy = instret & {$bits(instret){pipe2hdu_rdc_qlfy_i}}; |
| assign exu_init_pc_qlfy = exu_init_pc & {$bits(exu_init_pc){pipe2hdu_rdc_qlfy_i}}; |
| assign exu_exc_req_qlfy = exu_exc_req & {$bits(exu_exc_req){pipe2hdu_rdc_qlfy_i}}; |
| assign brkpt_qlfy = brkpt & {$bits(brkpt){pipe2hdu_rdc_qlfy_i}}; |
| assign ifu2hdu_pbuf_rdy_qlfy = ifu2hdu_pbuf_rdy & {$bits(ifu2hdu_pbuf_rdy){pipe2hdu_rdc_qlfy_i}}; |
| |
| `endif // SCR1_DBG_EN |
| |
| `ifdef SCR1_TRGT_SIMULATION |
| //------------------------------------------------------------------------------- |
| // Tracelog |
| //------------------------------------------------------------------------------- |
| |
| scr1_tracelog i_tracelog ( |
| .rst_n (pipe_rst_n ), |
| .clk (clk ), |
| .soc2pipe_fuse_mhartid_i (soc2pipe_fuse_mhartid_i ), |
| |
| // MPRF |
| .mprf2trace_int_i (i_pipe_mprf.mprf_int ), |
| .mprf2trace_wr_en_i (i_pipe_mprf.exu2mprf_w_req_i ), |
| .mprf2trace_wr_addr_i (i_pipe_mprf.exu2mprf_rd_addr_i ), |
| .mprf2trace_wr_data_i (i_pipe_mprf.exu2mprf_rd_data_i ), |
| |
| // EXU |
| .exu2trace_update_pc_en_i (i_pipe_exu.update_pc_en ), |
| .exu2trace_update_pc_i (i_pipe_exu.update_pc ), |
| |
| // IFU |
| .ifu2trace_instr_i (i_pipe_ifu.ifu2idu_instr_o ), |
| |
| // CSR |
| .csr2trace_mstatus_mie_i (i_pipe_csr.csr_mstatus_mie_ff ), |
| .csr2trace_mstatus_mpie_i (i_pipe_csr.csr_mstatus_mpie_ff ), |
| .csr2trace_mtvec_base_i (i_pipe_csr.csr_mtvec_base ), |
| .csr2trace_mtvec_mode_i (i_pipe_csr.csr_mtvec_mode ), |
| .csr2trace_mie_meie_i (i_pipe_csr.csr_mie_meie_ff ), |
| .csr2trace_mie_mtie_i (i_pipe_csr.csr_mie_mtie_ff ), |
| .csr2trace_mie_msie_i (i_pipe_csr.csr_mie_msie_ff ), |
| .csr2trace_mip_meip_i (i_pipe_csr.csr_mip_meip ), |
| .csr2trace_mip_mtip_i (i_pipe_csr.csr_mip_mtip ), |
| .csr2trace_mip_msip_i (i_pipe_csr.csr_mip_msip ), |
| .csr2trace_mepc_i (i_pipe_csr.csr_mepc_ff ), |
| .csr2trace_mcause_irq_i (i_pipe_csr.csr_mcause_i_ff ), |
| .csr2trace_mcause_ec_i (i_pipe_csr.csr_mcause_ec_ff ), |
| .csr2trace_mtval_i (i_pipe_csr.csr_mtval_ff ), |
| .csr2trace_mstatus_mie_up_i (i_pipe_csr.csr2exu_mstatus_mie_up_o), |
| |
| // Events |
| .csr2trace_e_exc_i (i_pipe_csr.e_exc ), |
| .csr2trace_e_irq_i (i_pipe_csr.e_irq ), |
| .pipe2trace_e_wake_i (pipe2clkctl_wake_req_o ), |
| .csr2trace_e_mret_i (i_pipe_csr.e_mret ) |
| ); |
| |
| `endif // SCR1_TRGT_SIMULATION |
| |
| endmodule : scr1_pipe_top |