Format sv and v code.
This commit is contained in:
parent
2f8715aeb6
commit
6bf845bb46
File diff suppressed because it is too large
Load Diff
|
@ -28,419 +28,430 @@
|
|||
//********************************************************************************
|
||||
|
||||
module el2_dec
|
||||
import el2_pkg::*;
|
||||
import el2_pkg::*;
|
||||
#(
|
||||
`include "el2_param.vh"
|
||||
)
|
||||
(
|
||||
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
|
||||
input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in.
|
||||
input logic free_clk, // Clock always. Through two clock headers. For flops without second clock header built in.
|
||||
input logic free_l2clk, // Clock always. Through one clock header. For flops with second header built in.
|
||||
|
||||
input logic lsu_fastint_stall_any, // needed by lsu for 2nd pass of dma with ecc correction, stall next cycle
|
||||
|
||||
output logic dec_extint_stall, // Stall on external interrupt
|
||||
|
||||
output logic dec_i0_decode_d, // Valid instruction at D-stage and not blocked
|
||||
output logic dec_pause_state_cg, // to top for active state clock gating
|
||||
`include "el2_param.vh"
|
||||
) (
|
||||
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
|
||||
input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in.
|
||||
input logic free_clk, // Clock always. Through two clock headers. For flops without second clock header built in.
|
||||
input logic free_l2clk, // Clock always. Through one clock header. For flops with second header built in.
|
||||
|
||||
input logic lsu_fastint_stall_any, // needed by lsu for 2nd pass of dma with ecc correction, stall next cycle
|
||||
|
||||
output logic dec_extint_stall, // Stall on external interrupt
|
||||
|
||||
output logic dec_i0_decode_d, // Valid instruction at D-stage and not blocked
|
||||
output logic dec_pause_state_cg, // to top for active state clock gating
|
||||
|
||||
output logic dec_tlu_core_empty,
|
||||
|
||||
input logic rst_l, // reset, active low
|
||||
input logic [31:1] rst_vec, // reset vector, from core pins
|
||||
|
||||
input logic nmi_int, // NMI pin
|
||||
input logic [31:1] nmi_vec, // NMI vector, from pins
|
||||
output logic dec_tlu_core_empty,
|
||||
|
||||
input logic rst_l, // reset, active low
|
||||
input logic [31:1] rst_vec, // reset vector, from core pins
|
||||
|
||||
input logic i_cpu_halt_req, // Asynchronous Halt request to CPU
|
||||
input logic i_cpu_run_req, // Asynchronous Restart request to CPU
|
||||
input logic nmi_int, // NMI pin
|
||||
input logic [31:1] nmi_vec, // NMI vector, from pins
|
||||
|
||||
output logic o_cpu_halt_status, // Halt status of core (pmu/fw)
|
||||
output logic o_cpu_halt_ack, // Halt request ack
|
||||
output logic o_cpu_run_ack, // Run request ack
|
||||
output logic o_debug_mode_status, // Core to the PMU that core is in debug mode. When core is in debug mode, the PMU should refrain from sendng a halt or run request
|
||||
input logic i_cpu_halt_req, // Asynchronous Halt request to CPU
|
||||
input logic i_cpu_run_req, // Asynchronous Restart request to CPU
|
||||
|
||||
input logic [31:4] core_id, // CORE ID
|
||||
output logic o_cpu_halt_status, // Halt status of core (pmu/fw)
|
||||
output logic o_cpu_halt_ack, // Halt request ack
|
||||
output logic o_cpu_run_ack, // Run request ack
|
||||
output logic o_debug_mode_status, // Core to the PMU that core is in debug mode. When core is in debug mode, the PMU should refrain from sendng a halt or run request
|
||||
|
||||
// external MPC halt/run interface
|
||||
input logic mpc_debug_halt_req, // Async halt request
|
||||
input logic mpc_debug_run_req, // Async run request
|
||||
input logic mpc_reset_run_req, // Run/halt after reset
|
||||
output logic mpc_debug_halt_ack, // Halt ack
|
||||
output logic mpc_debug_run_ack, // Run ack
|
||||
output logic debug_brkpt_status, // debug breakpoint
|
||||
input logic [31:4] core_id, // CORE ID
|
||||
|
||||
input logic exu_pmu_i0_br_misp, // slot 0 branch misp
|
||||
input logic exu_pmu_i0_br_ataken, // slot 0 branch actual taken
|
||||
input logic exu_pmu_i0_pc4, // slot 0 4 byte branch
|
||||
// external MPC halt/run interface
|
||||
input logic mpc_debug_halt_req, // Async halt request
|
||||
input logic mpc_debug_run_req, // Async run request
|
||||
input logic mpc_reset_run_req, // Run/halt after reset
|
||||
output logic mpc_debug_halt_ack, // Halt ack
|
||||
output logic mpc_debug_run_ack, // Run ack
|
||||
output logic debug_brkpt_status, // debug breakpoint
|
||||
|
||||
input logic exu_pmu_i0_br_misp, // slot 0 branch misp
|
||||
input logic exu_pmu_i0_br_ataken, // slot 0 branch actual taken
|
||||
input logic exu_pmu_i0_pc4, // slot 0 4 byte branch
|
||||
|
||||
input logic lsu_nonblock_load_valid_m, // valid nonblock load at m
|
||||
input logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_m, // -> corresponding tag
|
||||
input logic lsu_nonblock_load_inv_r, // invalidate request for nonblock load r
|
||||
input logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_r, // -> corresponding tag
|
||||
input logic lsu_nonblock_load_data_valid, // valid nonblock load data back
|
||||
input logic lsu_nonblock_load_data_error, // nonblock load bus error
|
||||
input logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // -> corresponding tag
|
||||
input logic [31:0] lsu_nonblock_load_data, // nonblock load data
|
||||
|
||||
input logic lsu_pmu_bus_trxn, // D side bus transaction
|
||||
input logic lsu_pmu_bus_misaligned, // D side bus misaligned
|
||||
input logic lsu_pmu_bus_error, // D side bus error
|
||||
input logic lsu_pmu_bus_busy, // D side bus busy
|
||||
input logic lsu_pmu_misaligned_m, // D side load or store misaligned
|
||||
input logic lsu_pmu_load_external_m, // D side bus load
|
||||
input logic lsu_pmu_store_external_m, // D side bus store
|
||||
input logic dma_pmu_dccm_read, // DMA DCCM read
|
||||
input logic dma_pmu_dccm_write, // DMA DCCM write
|
||||
input logic dma_pmu_any_read, // DMA read
|
||||
input logic dma_pmu_any_write, // DMA write
|
||||
input logic lsu_nonblock_load_valid_m, // valid nonblock load at m
|
||||
input logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_m, // -> corresponding tag
|
||||
input logic lsu_nonblock_load_inv_r, // invalidate request for nonblock load r
|
||||
input logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_r, // -> corresponding tag
|
||||
input logic lsu_nonblock_load_data_valid, // valid nonblock load data back
|
||||
input logic lsu_nonblock_load_data_error, // nonblock load bus error
|
||||
input logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // -> corresponding tag
|
||||
input logic [31:0] lsu_nonblock_load_data, // nonblock load data
|
||||
|
||||
input logic [31:1] lsu_fir_addr, // Fast int address
|
||||
input logic [1:0] lsu_fir_error, // Fast int lookup error
|
||||
input logic lsu_pmu_bus_trxn, // D side bus transaction
|
||||
input logic lsu_pmu_bus_misaligned, // D side bus misaligned
|
||||
input logic lsu_pmu_bus_error, // D side bus error
|
||||
input logic lsu_pmu_bus_busy, // D side bus busy
|
||||
input logic lsu_pmu_misaligned_m, // D side load or store misaligned
|
||||
input logic lsu_pmu_load_external_m, // D side bus load
|
||||
input logic lsu_pmu_store_external_m, // D side bus store
|
||||
input logic dma_pmu_dccm_read, // DMA DCCM read
|
||||
input logic dma_pmu_dccm_write, // DMA DCCM write
|
||||
input logic dma_pmu_any_read, // DMA read
|
||||
input logic dma_pmu_any_write, // DMA write
|
||||
|
||||
input logic ifu_pmu_instr_aligned, // aligned instructions
|
||||
input logic ifu_pmu_fetch_stall, // fetch unit stalled
|
||||
input logic ifu_pmu_ic_miss, // icache miss
|
||||
input logic ifu_pmu_ic_hit, // icache hit
|
||||
input logic ifu_pmu_bus_error, // Instruction side bus error
|
||||
input logic ifu_pmu_bus_busy, // Instruction side bus busy
|
||||
input logic ifu_pmu_bus_trxn, // Instruction side bus transaction
|
||||
input logic [31:1] lsu_fir_addr, // Fast int address
|
||||
input logic [ 1:0] lsu_fir_error, // Fast int lookup error
|
||||
|
||||
input logic ifu_ic_error_start, // IC single bit error
|
||||
input logic ifu_iccm_rd_ecc_single_err, // ICCM single bit error
|
||||
input logic ifu_pmu_instr_aligned, // aligned instructions
|
||||
input logic ifu_pmu_fetch_stall, // fetch unit stalled
|
||||
input logic ifu_pmu_ic_miss, // icache miss
|
||||
input logic ifu_pmu_ic_hit, // icache hit
|
||||
input logic ifu_pmu_bus_error, // Instruction side bus error
|
||||
input logic ifu_pmu_bus_busy, // Instruction side bus busy
|
||||
input logic ifu_pmu_bus_trxn, // Instruction side bus transaction
|
||||
|
||||
input logic [3:0] lsu_trigger_match_m,
|
||||
input logic dbg_cmd_valid, // debugger abstract command valid
|
||||
input logic dbg_cmd_write, // command is a write
|
||||
input logic [1:0] dbg_cmd_type, // command type
|
||||
input logic [31:0] dbg_cmd_addr, // command address
|
||||
input logic [1:0] dbg_cmd_wrdata, // command write data, for fence/fence_i
|
||||
input logic ifu_ic_error_start, // IC single bit error
|
||||
input logic ifu_iccm_rd_ecc_single_err, // ICCM single bit error
|
||||
|
||||
input logic [ 3:0] lsu_trigger_match_m,
|
||||
input logic dbg_cmd_valid, // debugger abstract command valid
|
||||
input logic dbg_cmd_write, // command is a write
|
||||
input logic [ 1:0] dbg_cmd_type, // command type
|
||||
input logic [31:0] dbg_cmd_addr, // command address
|
||||
input logic [ 1:0] dbg_cmd_wrdata, // command write data, for fence/fence_i
|
||||
|
||||
input logic ifu_i0_icaf, // icache access fault
|
||||
input logic [1:0] ifu_i0_icaf_type, // icache access fault type
|
||||
|
||||
input logic ifu_i0_icaf_second, // i0 has access fault on second 2B of 4B inst
|
||||
input logic ifu_i0_dbecc, // icache/iccm double-bit error
|
||||
input logic ifu_i0_icaf, // icache access fault
|
||||
input logic [1:0] ifu_i0_icaf_type, // icache access fault type
|
||||
|
||||
input logic lsu_idle_any, // lsu idle for halting
|
||||
input logic ifu_i0_icaf_second, // i0 has access fault on second 2B of 4B inst
|
||||
input logic ifu_i0_dbecc, // icache/iccm double-bit error
|
||||
|
||||
input el2_br_pkt_t i0_brp, // branch packet
|
||||
input logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] ifu_i0_bp_index, // BP index
|
||||
input logic [pt.BHT_GHR_SIZE-1:0] ifu_i0_bp_fghr, // BP FGHR
|
||||
input logic [pt.BTB_BTAG_SIZE-1:0] ifu_i0_bp_btag, // BP tag
|
||||
input logic [$clog2(pt.BTB_SIZE)-1:0] ifu_i0_fa_index, // Fully associt btb index
|
||||
input logic lsu_idle_any, // lsu idle for halting
|
||||
|
||||
input el2_lsu_error_pkt_t lsu_error_pkt_r, // LSU exception/error packet
|
||||
input logic lsu_single_ecc_error_incr, // LSU inc SB error counter
|
||||
input el2_br_pkt_t i0_brp, // branch packet
|
||||
input logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] ifu_i0_bp_index, // BP index
|
||||
input logic [ pt.BHT_GHR_SIZE-1:0] ifu_i0_bp_fghr, // BP FGHR
|
||||
input logic [ pt.BTB_BTAG_SIZE-1:0] ifu_i0_bp_btag, // BP tag
|
||||
input logic [ $clog2(pt.BTB_SIZE)-1:0] ifu_i0_fa_index, // Fully associt btb index
|
||||
|
||||
input logic lsu_imprecise_error_load_any, // LSU imprecise load bus error
|
||||
input logic lsu_imprecise_error_store_any, // LSU imprecise store bus error
|
||||
input logic [31:0] lsu_imprecise_error_addr_any, // LSU imprecise bus error address
|
||||
input el2_lsu_error_pkt_t lsu_error_pkt_r, // LSU exception/error packet
|
||||
input logic lsu_single_ecc_error_incr, // LSU inc SB error counter
|
||||
|
||||
input logic [31:0] exu_div_result, // final div result
|
||||
input logic exu_div_wren, // Divide write enable to GPR
|
||||
input logic lsu_imprecise_error_load_any, // LSU imprecise load bus error
|
||||
input logic lsu_imprecise_error_store_any, // LSU imprecise store bus error
|
||||
input logic [31:0] lsu_imprecise_error_addr_any, // LSU imprecise bus error address
|
||||
|
||||
input logic [31:0] exu_csr_rs1_x, // rs1 for csr instruction
|
||||
input logic [31:0] exu_div_result, // final div result
|
||||
input logic exu_div_wren, // Divide write enable to GPR
|
||||
|
||||
input logic [31:0] lsu_result_m, // load result
|
||||
input logic [31:0] lsu_result_corr_r, // load result - corrected load data
|
||||
input logic [31:0] exu_csr_rs1_x, // rs1 for csr instruction
|
||||
|
||||
input logic lsu_load_stall_any, // This is for blocking loads
|
||||
input logic lsu_store_stall_any, // This is for blocking stores
|
||||
input logic dma_dccm_stall_any, // stall any load/store at decode, pmu event
|
||||
input logic dma_iccm_stall_any, // iccm stalled, pmu event
|
||||
input logic [31:0] lsu_result_m, // load result
|
||||
input logic [31:0] lsu_result_corr_r, // load result - corrected load data
|
||||
|
||||
input logic iccm_dma_sb_error, // ICCM DMA single bit error
|
||||
input logic lsu_load_stall_any, // This is for blocking loads
|
||||
input logic lsu_store_stall_any, // This is for blocking stores
|
||||
input logic dma_dccm_stall_any, // stall any load/store at decode, pmu event
|
||||
input logic dma_iccm_stall_any, // iccm stalled, pmu event
|
||||
|
||||
input logic exu_flush_final, // slot0 flush
|
||||
input logic iccm_dma_sb_error, // ICCM DMA single bit error
|
||||
|
||||
input logic [31:1] exu_npc_r, // next PC
|
||||
input logic exu_flush_final, // slot0 flush
|
||||
|
||||
input logic [31:0] exu_i0_result_x, // alu result x
|
||||
input logic [31:1] exu_npc_r, // next PC
|
||||
|
||||
input logic [31:0] exu_i0_result_x, // alu result x
|
||||
|
||||
input logic ifu_i0_valid, // fetch valids to instruction buffer
|
||||
input logic [31:0] ifu_i0_instr, // fetch inst's to instruction buffer
|
||||
input logic [31:1] ifu_i0_pc, // pc's for instruction buffer
|
||||
input logic ifu_i0_pc4, // indication of 4B or 2B for corresponding inst
|
||||
input logic [31:1] exu_i0_pc_x, // pc's for e1 from the alu's
|
||||
|
||||
input logic mexintpend, // External interrupt pending
|
||||
input logic timer_int, // Timer interrupt pending (from pin)
|
||||
input logic soft_int, // Software interrupt pending (from pin)
|
||||
input logic ifu_i0_valid, // fetch valids to instruction buffer
|
||||
input logic [31:0] ifu_i0_instr, // fetch inst's to instruction buffer
|
||||
input logic [31:1] ifu_i0_pc, // pc's for instruction buffer
|
||||
input logic ifu_i0_pc4, // indication of 4B or 2B for corresponding inst
|
||||
input logic [31:1] exu_i0_pc_x, // pc's for e1 from the alu's
|
||||
|
||||
input logic [7:0] pic_claimid, // PIC claimid
|
||||
input logic [3:0] pic_pl, // PIC priv level
|
||||
input logic mhwakeup, // High priority wakeup
|
||||
input logic mexintpend, // External interrupt pending
|
||||
input logic timer_int, // Timer interrupt pending (from pin)
|
||||
input logic soft_int, // Software interrupt pending (from pin)
|
||||
|
||||
output logic [3:0] dec_tlu_meicurpl, // to PIC, Current priv level
|
||||
output logic [3:0] dec_tlu_meipt, // to PIC
|
||||
input logic [7:0] pic_claimid, // PIC claimid
|
||||
input logic [3:0] pic_pl, // PIC priv level
|
||||
input logic mhwakeup, // High priority wakeup
|
||||
|
||||
input logic [70:0] ifu_ic_debug_rd_data, // diagnostic icache read data
|
||||
input logic ifu_ic_debug_rd_data_valid, // diagnostic icache read data valid
|
||||
output el2_cache_debug_pkt_t dec_tlu_ic_diag_pkt, // packet of DICAWICS, DICAD0/1, DICAGO info for icache diagnostics
|
||||
output logic [3:0] dec_tlu_meicurpl, // to PIC, Current priv level
|
||||
output logic [3:0] dec_tlu_meipt, // to PIC
|
||||
|
||||
input logic [70:0] ifu_ic_debug_rd_data, // diagnostic icache read data
|
||||
input logic ifu_ic_debug_rd_data_valid, // diagnostic icache read data valid
|
||||
output el2_cache_debug_pkt_t dec_tlu_ic_diag_pkt, // packet of DICAWICS, DICAD0/1, DICAGO info for icache diagnostics
|
||||
|
||||
// Debug start
|
||||
input logic dbg_halt_req, // DM requests a halt
|
||||
input logic dbg_resume_req, // DM requests a resume
|
||||
input logic ifu_miss_state_idle, // I-side miss buffer empty
|
||||
|
||||
output logic dec_tlu_dbg_halted, // Core is halted and ready for debug command
|
||||
output logic dec_tlu_debug_mode, // Core is in debug mode
|
||||
output logic dec_tlu_resume_ack, // Resume acknowledge
|
||||
output logic dec_tlu_flush_noredir_r, // Tell fetch to idle on this flush
|
||||
output logic dec_tlu_mpc_halted_only, // Core is halted only due to MPC
|
||||
output logic dec_tlu_flush_leak_one_r, // single step
|
||||
output logic dec_tlu_flush_err_r, // iside perr/ecc rfpc
|
||||
output logic [31:2] dec_tlu_meihap, // Fast ext int base
|
||||
// Debug start
|
||||
input logic dbg_halt_req, // DM requests a halt
|
||||
input logic dbg_resume_req, // DM requests a resume
|
||||
input logic ifu_miss_state_idle, // I-side miss buffer empty
|
||||
|
||||
output logic dec_debug_wdata_rs1_d, // insert debug write data into rs1 at decode
|
||||
output logic dec_tlu_dbg_halted, // Core is halted and ready for debug command
|
||||
output logic dec_tlu_debug_mode, // Core is in debug mode
|
||||
output logic dec_tlu_resume_ack, // Resume acknowledge
|
||||
output logic dec_tlu_flush_noredir_r, // Tell fetch to idle on this flush
|
||||
output logic dec_tlu_mpc_halted_only, // Core is halted only due to MPC
|
||||
output logic dec_tlu_flush_leak_one_r, // single step
|
||||
output logic dec_tlu_flush_err_r, // iside perr/ecc rfpc
|
||||
output logic [31:2] dec_tlu_meihap, // Fast ext int base
|
||||
|
||||
output logic [31:0] dec_dbg_rddata, // debug command read data
|
||||
output logic dec_debug_wdata_rs1_d, // insert debug write data into rs1 at decode
|
||||
|
||||
output logic dec_dbg_cmd_done, // abstract command is done
|
||||
output logic dec_dbg_cmd_fail, // abstract command failed (illegal reg address)
|
||||
output logic [31:0] dec_dbg_rddata, // debug command read data
|
||||
|
||||
output el2_trigger_pkt_t [3:0] trigger_pkt_any, // info needed by debug trigger blocks
|
||||
output logic dec_dbg_cmd_done, // abstract command is done
|
||||
output logic dec_dbg_cmd_fail, // abstract command failed (illegal reg address)
|
||||
|
||||
output logic dec_tlu_force_halt, // halt has been forced
|
||||
// Debug end
|
||||
// branch info from pipe0 for errors or counter updates
|
||||
input logic [1:0] exu_i0_br_hist_r, // history
|
||||
input logic exu_i0_br_error_r, // error
|
||||
input logic exu_i0_br_start_error_r, // start error
|
||||
input logic exu_i0_br_valid_r, // valid
|
||||
input logic exu_i0_br_mp_r, // mispredict
|
||||
input logic exu_i0_br_middle_r, // middle of bank
|
||||
output el2_trigger_pkt_t [3:0] trigger_pkt_any, // info needed by debug trigger blocks
|
||||
|
||||
// branch info from pipe1 for errors or counter updates
|
||||
output logic dec_tlu_force_halt, // halt has been forced
|
||||
// Debug end
|
||||
// branch info from pipe0 for errors or counter updates
|
||||
input logic [1:0] exu_i0_br_hist_r, // history
|
||||
input logic exu_i0_br_error_r, // error
|
||||
input logic exu_i0_br_start_error_r, // start error
|
||||
input logic exu_i0_br_valid_r, // valid
|
||||
input logic exu_i0_br_mp_r, // mispredict
|
||||
input logic exu_i0_br_middle_r, // middle of bank
|
||||
|
||||
input logic exu_i0_br_way_r, // way hit or repl
|
||||
// branch info from pipe1 for errors or counter updates
|
||||
|
||||
output logic dec_i0_rs1_en_d, // Qualify GPR RS1 data
|
||||
output logic dec_i0_rs2_en_d, // Qualify GPR RS2 data
|
||||
output logic [31:0] gpr_i0_rs1_d, // gpr rs1 data
|
||||
output logic [31:0] gpr_i0_rs2_d, // gpr rs2 data
|
||||
input logic exu_i0_br_way_r, // way hit or repl
|
||||
|
||||
output logic [31:0] dec_i0_immed_d, // immediate data
|
||||
output logic [12:1] dec_i0_br_immed_d, // br immediate data
|
||||
output logic dec_i0_rs1_en_d, // Qualify GPR RS1 data
|
||||
output logic dec_i0_rs2_en_d, // Qualify GPR RS2 data
|
||||
output logic [31:0] gpr_i0_rs1_d, // gpr rs1 data
|
||||
output logic [31:0] gpr_i0_rs2_d, // gpr rs2 data
|
||||
|
||||
output el2_alu_pkt_t i0_ap, // alu packet
|
||||
output logic [31:0] dec_i0_immed_d, // immediate data
|
||||
output logic [12:1] dec_i0_br_immed_d, // br immediate data
|
||||
|
||||
output logic dec_i0_alu_decode_d, // schedule on D-stage alu
|
||||
output logic dec_i0_branch_d, // Branch in D-stage
|
||||
output el2_alu_pkt_t i0_ap, // alu packet
|
||||
|
||||
output logic dec_i0_select_pc_d, // select pc onto rs1 for jal's
|
||||
output logic dec_i0_alu_decode_d, // schedule on D-stage alu
|
||||
output logic dec_i0_branch_d, // Branch in D-stage
|
||||
|
||||
output logic [31:1] dec_i0_pc_d, // pc's at decode
|
||||
output logic [3:0] dec_i0_rs1_bypass_en_d, // rs1 bypass enable
|
||||
output logic [3:0] dec_i0_rs2_bypass_en_d, // rs2 bypass enable
|
||||
output logic dec_i0_select_pc_d, // select pc onto rs1 for jal's
|
||||
|
||||
output logic [31:0] dec_i0_result_r, // Result R-stage
|
||||
output logic [31:1] dec_i0_pc_d, // pc's at decode
|
||||
output logic [ 3:0] dec_i0_rs1_bypass_en_d, // rs1 bypass enable
|
||||
output logic [ 3:0] dec_i0_rs2_bypass_en_d, // rs2 bypass enable
|
||||
|
||||
output el2_lsu_pkt_t lsu_p, // lsu packet
|
||||
output logic dec_qual_lsu_d, // LSU instruction at D. Use to quiet LSU operands
|
||||
output el2_mul_pkt_t mul_p, // mul packet
|
||||
output el2_div_pkt_t div_p, // div packet
|
||||
output logic dec_div_cancel, // cancel divide operation
|
||||
output logic [31:0] dec_i0_result_r, // Result R-stage
|
||||
|
||||
output logic [11:0] dec_lsu_offset_d, // 12b offset for load/store addresses
|
||||
output el2_lsu_pkt_t lsu_p, // lsu packet
|
||||
output logic dec_qual_lsu_d, // LSU instruction at D. Use to quiet LSU operands
|
||||
output el2_mul_pkt_t mul_p, // mul packet
|
||||
output el2_div_pkt_t div_p, // div packet
|
||||
output logic dec_div_cancel, // cancel divide operation
|
||||
|
||||
output logic dec_csr_ren_d, // CSR read enable
|
||||
output logic [31:0] dec_csr_rddata_d, // CSR read data
|
||||
output logic [11:0] dec_lsu_offset_d, // 12b offset for load/store addresses
|
||||
|
||||
output logic dec_tlu_flush_lower_r, // tlu flush due to late mp, exception, rfpc, or int
|
||||
output logic dec_tlu_flush_lower_wb,
|
||||
output logic [31:1] dec_tlu_flush_path_r, // tlu flush target
|
||||
output logic dec_tlu_i0_kill_writeb_r, // I0 is flushed, don't writeback any results to arch state
|
||||
output logic dec_tlu_fence_i_r, // flush is a fence_i rfnpc, flush icache
|
||||
output logic dec_csr_ren_d, // CSR read enable
|
||||
output logic [31:0] dec_csr_rddata_d, // CSR read data
|
||||
|
||||
output logic [31:1] pred_correct_npc_x, // npc if prediction is correct at e2 stage
|
||||
output logic dec_tlu_flush_lower_r, // tlu flush due to late mp, exception, rfpc, or int
|
||||
output logic dec_tlu_flush_lower_wb,
|
||||
output logic [31:1] dec_tlu_flush_path_r, // tlu flush target
|
||||
output logic dec_tlu_i0_kill_writeb_r, // I0 is flushed, don't writeback any results to arch state
|
||||
output logic dec_tlu_fence_i_r, // flush is a fence_i rfnpc, flush icache
|
||||
|
||||
output el2_br_tlu_pkt_t dec_tlu_br0_r_pkt, // slot 0 branch predictor update packet
|
||||
output logic [31:1] pred_correct_npc_x, // npc if prediction is correct at e2 stage
|
||||
|
||||
output logic dec_tlu_perfcnt0, // toggles when slot0 perf counter 0 has an event inc
|
||||
output logic dec_tlu_perfcnt1, // toggles when slot0 perf counter 1 has an event inc
|
||||
output logic dec_tlu_perfcnt2, // toggles when slot0 perf counter 2 has an event inc
|
||||
output logic dec_tlu_perfcnt3, // toggles when slot0 perf counter 3 has an event inc
|
||||
output el2_br_tlu_pkt_t dec_tlu_br0_r_pkt, // slot 0 branch predictor update packet
|
||||
|
||||
output el2_predict_pkt_t dec_i0_predict_p_d, // prediction packet to alus
|
||||
output logic [pt.BHT_GHR_SIZE-1:0] i0_predict_fghr_d, // DEC predict fghr
|
||||
output logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] i0_predict_index_d, // DEC predict index
|
||||
output logic [pt.BTB_BTAG_SIZE-1:0] i0_predict_btag_d, // DEC predict branch tag
|
||||
output logic dec_tlu_perfcnt0, // toggles when slot0 perf counter 0 has an event inc
|
||||
output logic dec_tlu_perfcnt1, // toggles when slot0 perf counter 1 has an event inc
|
||||
output logic dec_tlu_perfcnt2, // toggles when slot0 perf counter 2 has an event inc
|
||||
output logic dec_tlu_perfcnt3, // toggles when slot0 perf counter 3 has an event inc
|
||||
|
||||
output logic [$clog2(pt.BTB_SIZE)-1:0] dec_fa_error_index, // Fully associt btb error index
|
||||
output el2_predict_pkt_t dec_i0_predict_p_d, // prediction packet to alus
|
||||
output logic [pt.BHT_GHR_SIZE-1:0] i0_predict_fghr_d, // DEC predict fghr
|
||||
output logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] i0_predict_index_d, // DEC predict index
|
||||
output logic [pt.BTB_BTAG_SIZE-1:0] i0_predict_btag_d, // DEC predict branch tag
|
||||
|
||||
output logic dec_lsu_valid_raw_d,
|
||||
output logic [$clog2(
|
||||
pt.BTB_SIZE
|
||||
)-1:0] dec_fa_error_index, // Fully associt btb error index
|
||||
|
||||
output logic [31:0] dec_tlu_mrac_ff, // CSR for memory region control
|
||||
output logic dec_lsu_valid_raw_d,
|
||||
|
||||
output logic [1:0] dec_data_en, // clock-gate control logic
|
||||
output logic [1:0] dec_ctl_en,
|
||||
output logic [31:0] dec_tlu_mrac_ff, // CSR for memory region control
|
||||
|
||||
input logic [15:0] ifu_i0_cinst, // 16b compressed instruction
|
||||
output logic [1:0] dec_data_en, // clock-gate control logic
|
||||
output logic [1:0] dec_ctl_en,
|
||||
|
||||
output el2_trace_pkt_t trace_rv_trace_pkt, // trace packet
|
||||
input logic [15:0] ifu_i0_cinst, // 16b compressed instruction
|
||||
|
||||
// feature disable from mfdc
|
||||
output logic dec_tlu_external_ldfwd_disable, // disable external load forwarding
|
||||
output logic dec_tlu_sideeffect_posted_disable, // disable posted stores to side-effect address
|
||||
output logic dec_tlu_core_ecc_disable, // disable core ECC
|
||||
output logic dec_tlu_bpred_disable, // disable branch prediction
|
||||
output logic dec_tlu_wb_coalescing_disable, // disable writebuffer coalescing
|
||||
output logic [2:0] dec_tlu_dma_qos_prty, // DMA QoS priority coming from MFDC [18:16]
|
||||
output el2_trace_pkt_t trace_rv_trace_pkt, // trace packet
|
||||
|
||||
// clock gating overrides from mcgc
|
||||
output logic dec_tlu_misc_clk_override, // override misc clock domain gating
|
||||
output logic dec_tlu_ifu_clk_override, // override fetch clock domain gating
|
||||
output logic dec_tlu_lsu_clk_override, // override load/store clock domain gating
|
||||
output logic dec_tlu_bus_clk_override, // override bus clock domain gating
|
||||
output logic dec_tlu_pic_clk_override, // override PIC clock domain gating
|
||||
output logic dec_tlu_picio_clk_override, // override PICIO clock domain gating
|
||||
output logic dec_tlu_dccm_clk_override, // override DCCM clock domain gating
|
||||
output logic dec_tlu_icm_clk_override, // override ICCM clock domain gating
|
||||
// feature disable from mfdc
|
||||
output logic dec_tlu_external_ldfwd_disable, // disable external load forwarding
|
||||
output logic dec_tlu_sideeffect_posted_disable, // disable posted stores to side-effect address
|
||||
output logic dec_tlu_core_ecc_disable, // disable core ECC
|
||||
output logic dec_tlu_bpred_disable, // disable branch prediction
|
||||
output logic dec_tlu_wb_coalescing_disable, // disable writebuffer coalescing
|
||||
output logic [2:0] dec_tlu_dma_qos_prty, // DMA QoS priority coming from MFDC [18:16]
|
||||
|
||||
output logic dec_tlu_i0_commit_cmt, // committed i0 instruction
|
||||
input logic scan_mode // Flop scan mode control
|
||||
// clock gating overrides from mcgc
|
||||
output logic dec_tlu_misc_clk_override, // override misc clock domain gating
|
||||
output logic dec_tlu_ifu_clk_override, // override fetch clock domain gating
|
||||
output logic dec_tlu_lsu_clk_override, // override load/store clock domain gating
|
||||
output logic dec_tlu_bus_clk_override, // override bus clock domain gating
|
||||
output logic dec_tlu_pic_clk_override, // override PIC clock domain gating
|
||||
output logic dec_tlu_picio_clk_override, // override PICIO clock domain gating
|
||||
output logic dec_tlu_dccm_clk_override, // override DCCM clock domain gating
|
||||
output logic dec_tlu_icm_clk_override, // override ICCM clock domain gating
|
||||
|
||||
);
|
||||
output logic dec_tlu_i0_commit_cmt, // committed i0 instruction
|
||||
input logic scan_mode // Flop scan mode control
|
||||
|
||||
);
|
||||
|
||||
logic dec_tlu_dec_clk_override; // to and from dec blocks
|
||||
logic clk_override;
|
||||
|
||||
logic dec_ib0_valid_d;
|
||||
logic dec_tlu_dec_clk_override; // to and from dec blocks
|
||||
logic clk_override;
|
||||
|
||||
logic dec_pmu_instr_decoded;
|
||||
logic dec_pmu_decode_stall;
|
||||
logic dec_pmu_presync_stall;
|
||||
logic dec_pmu_postsync_stall;
|
||||
logic dec_ib0_valid_d;
|
||||
|
||||
logic dec_tlu_wr_pause_r; // CSR write to pause reg is at R.
|
||||
logic dec_pmu_instr_decoded;
|
||||
logic dec_pmu_decode_stall;
|
||||
logic dec_pmu_presync_stall;
|
||||
logic dec_pmu_postsync_stall;
|
||||
|
||||
logic [4:0] dec_i0_rs1_d;
|
||||
logic [4:0] dec_i0_rs2_d;
|
||||
logic dec_tlu_wr_pause_r; // CSR write to pause reg is at R.
|
||||
|
||||
logic [31:0] dec_i0_instr_d;
|
||||
logic [4:0] dec_i0_rs1_d;
|
||||
logic [4:0] dec_i0_rs2_d;
|
||||
|
||||
logic dec_tlu_trace_disable;
|
||||
logic dec_tlu_pipelining_disable;
|
||||
logic [31:0] dec_i0_instr_d;
|
||||
|
||||
logic dec_tlu_trace_disable;
|
||||
logic dec_tlu_pipelining_disable;
|
||||
|
||||
logic [4:0] dec_i0_waddr_r;
|
||||
logic dec_i0_wen_r;
|
||||
logic [31:0] dec_i0_wdata_r;
|
||||
logic dec_csr_wen_r; // csr write enable at wb
|
||||
logic [11:0] dec_csr_wraddr_r; // write address for csryes
|
||||
logic [31:0] dec_csr_wrdata_r; // csr write data at wb
|
||||
|
||||
logic [11:0] dec_csr_rdaddr_d; // read address for csr
|
||||
logic dec_csr_legal_d; // csr indicates legal operation
|
||||
logic [4:0] dec_i0_waddr_r;
|
||||
logic dec_i0_wen_r;
|
||||
logic [31:0] dec_i0_wdata_r;
|
||||
logic dec_csr_wen_r; // csr write enable at wb
|
||||
logic [11:0] dec_csr_wraddr_r; // write address for csryes
|
||||
logic [31:0] dec_csr_wrdata_r; // csr write data at wb
|
||||
|
||||
logic dec_csr_wen_unq_d; // valid csr with write - for csr legal
|
||||
logic dec_csr_any_unq_d; // valid csr - for csr legal
|
||||
logic dec_csr_stall_int_ff; // csr is mie/mstatus
|
||||
logic [11:0] dec_csr_rdaddr_d; // read address for csr
|
||||
logic dec_csr_legal_d; // csr indicates legal operation
|
||||
|
||||
el2_trap_pkt_t dec_tlu_packet_r;
|
||||
logic dec_csr_wen_unq_d; // valid csr with write - for csr legal
|
||||
logic dec_csr_any_unq_d; // valid csr - for csr legal
|
||||
logic dec_csr_stall_int_ff; // csr is mie/mstatus
|
||||
|
||||
logic dec_i0_pc4_d;
|
||||
logic dec_tlu_presync_d;
|
||||
logic dec_tlu_postsync_d;
|
||||
logic dec_tlu_debug_stall;
|
||||
el2_trap_pkt_t dec_tlu_packet_r;
|
||||
|
||||
logic [31:0] dec_illegal_inst;
|
||||
logic dec_i0_pc4_d;
|
||||
logic dec_tlu_presync_d;
|
||||
logic dec_tlu_postsync_d;
|
||||
logic dec_tlu_debug_stall;
|
||||
|
||||
logic dec_i0_icaf_d;
|
||||
logic [31:0] dec_illegal_inst;
|
||||
|
||||
logic dec_i0_dbecc_d;
|
||||
logic dec_i0_icaf_second_d;
|
||||
logic [3:0] dec_i0_trigger_match_d;
|
||||
logic dec_debug_fence_d;
|
||||
logic dec_nonblock_load_wen;
|
||||
logic [4:0] dec_nonblock_load_waddr;
|
||||
logic dec_tlu_flush_pause_r;
|
||||
el2_br_pkt_t dec_i0_brp;
|
||||
logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] dec_i0_bp_index;
|
||||
logic [pt.BHT_GHR_SIZE-1:0] dec_i0_bp_fghr;
|
||||
logic [pt.BTB_BTAG_SIZE-1:0] dec_i0_bp_btag;
|
||||
logic [$clog2(pt.BTB_SIZE)-1:0] dec_i0_bp_fa_index; // Fully associt btb index
|
||||
logic dec_i0_icaf_d;
|
||||
|
||||
logic [31:1] dec_tlu_i0_pc_r;
|
||||
logic dec_tlu_i0_kill_writeb_wb;
|
||||
logic dec_tlu_i0_valid_r;
|
||||
logic dec_i0_dbecc_d;
|
||||
logic dec_i0_icaf_second_d;
|
||||
logic [3:0] dec_i0_trigger_match_d;
|
||||
logic dec_debug_fence_d;
|
||||
logic dec_nonblock_load_wen;
|
||||
logic [4:0] dec_nonblock_load_waddr;
|
||||
logic dec_tlu_flush_pause_r;
|
||||
el2_br_pkt_t dec_i0_brp;
|
||||
logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] dec_i0_bp_index;
|
||||
logic [pt.BHT_GHR_SIZE-1:0] dec_i0_bp_fghr;
|
||||
logic [pt.BTB_BTAG_SIZE-1:0] dec_i0_bp_btag;
|
||||
logic [$clog2(pt.BTB_SIZE)-1:0] dec_i0_bp_fa_index; // Fully associt btb index
|
||||
|
||||
logic dec_pause_state;
|
||||
logic [31:1] dec_tlu_i0_pc_r;
|
||||
logic dec_tlu_i0_kill_writeb_wb;
|
||||
logic dec_tlu_i0_valid_r;
|
||||
|
||||
logic [1:0] dec_i0_icaf_type_d; // i0 instruction access fault type
|
||||
logic dec_pause_state;
|
||||
|
||||
logic dec_tlu_flush_extint; // Fast ext int started
|
||||
logic [1:0] dec_i0_icaf_type_d; // i0 instruction access fault type
|
||||
|
||||
logic [31:0] dec_i0_inst_wb;
|
||||
logic [31:1] dec_i0_pc_wb;
|
||||
logic dec_tlu_i0_valid_wb1, dec_tlu_int_valid_wb1;
|
||||
logic [4:0] dec_tlu_exc_cause_wb1;
|
||||
logic [31:0] dec_tlu_mtval_wb1;
|
||||
logic dec_tlu_i0_exc_valid_wb1;
|
||||
logic dec_tlu_flush_extint; // Fast ext int started
|
||||
|
||||
logic [4:0] div_waddr_wb;
|
||||
logic dec_div_active;
|
||||
logic [31:0] dec_i0_inst_wb;
|
||||
logic [31:1] dec_i0_pc_wb;
|
||||
logic dec_tlu_i0_valid_wb1, dec_tlu_int_valid_wb1;
|
||||
logic [ 4:0] dec_tlu_exc_cause_wb1;
|
||||
logic [31:0] dec_tlu_mtval_wb1;
|
||||
logic dec_tlu_i0_exc_valid_wb1;
|
||||
|
||||
logic dec_debug_valid_d;
|
||||
logic [ 4:0] div_waddr_wb;
|
||||
logic dec_div_active;
|
||||
|
||||
assign clk_override = dec_tlu_dec_clk_override;
|
||||
logic dec_debug_valid_d;
|
||||
|
||||
assign clk_override = dec_tlu_dec_clk_override;
|
||||
|
||||
assign dec_dbg_rddata[31:0] = dec_i0_wdata_r[31:0];
|
||||
|
||||
assign dec_dbg_rddata[31:0] = dec_i0_wdata_r[31:0];
|
||||
|
||||
el2_dec_ib_ctl #(.pt(pt)) instbuff (.*);
|
||||
|
||||
el2_dec_ib_ctl #(.pt(pt)) instbuff (.*);
|
||||
|
||||
el2_dec_decode_ctl #(.pt(pt)) decode (.*);
|
||||
|
||||
el2_dec_decode_ctl #(.pt(pt)) decode (.*);
|
||||
|
||||
el2_dec_tlu_ctl #(.pt(pt)) tlu (.*);
|
||||
|
||||
el2_dec_tlu_ctl #(.pt(pt)) tlu (.*);
|
||||
|
||||
el2_dec_gpr_ctl #(.pt(pt)) arf (.*,
|
||||
// inputs
|
||||
.raddr0(dec_i0_rs1_d[4:0]),
|
||||
.raddr1(dec_i0_rs2_d[4:0]),
|
||||
|
||||
.wen0(dec_i0_wen_r), .waddr0(dec_i0_waddr_r[4:0]), .wd0(dec_i0_wdata_r[31:0]),
|
||||
.wen1(dec_nonblock_load_wen), .waddr1(dec_nonblock_load_waddr[4:0]), .wd1(lsu_nonblock_load_data[31:0]),
|
||||
.wen2(exu_div_wren), .waddr2(div_waddr_wb), .wd2(exu_div_result[31:0]),
|
||||
el2_dec_gpr_ctl #(
|
||||
.pt(pt)
|
||||
) arf (
|
||||
.*,
|
||||
// inputs
|
||||
.raddr0(dec_i0_rs1_d[4:0]),
|
||||
.raddr1(dec_i0_rs2_d[4:0]),
|
||||
|
||||
// outputs
|
||||
.rd0(gpr_i0_rs1_d[31:0]), .rd1(gpr_i0_rs2_d[31:0])
|
||||
);
|
||||
.wen0(dec_i0_wen_r),
|
||||
.waddr0(dec_i0_waddr_r[4:0]),
|
||||
.wd0(dec_i0_wdata_r[31:0]),
|
||||
.wen1(dec_nonblock_load_wen),
|
||||
.waddr1(dec_nonblock_load_waddr[4:0]),
|
||||
.wd1(lsu_nonblock_load_data[31:0]),
|
||||
.wen2(exu_div_wren),
|
||||
.waddr2(div_waddr_wb),
|
||||
.wd2(exu_div_result[31:0]),
|
||||
|
||||
// outputs
|
||||
.rd0(gpr_i0_rs1_d[31:0]),
|
||||
.rd1(gpr_i0_rs2_d[31:0])
|
||||
);
|
||||
|
||||
// Trigger
|
||||
|
||||
el2_dec_trigger #(.pt(pt)) dec_trigger (.*);
|
||||
// Trigger
|
||||
|
||||
el2_dec_trigger #(.pt(pt)) dec_trigger (.*);
|
||||
|
||||
|
||||
|
||||
// trace
|
||||
assign trace_rv_trace_pkt.trace_rv_i_insn_ip = dec_i0_inst_wb[31:0];
|
||||
assign trace_rv_trace_pkt.trace_rv_i_address_ip = { dec_i0_pc_wb[31:1], 1'b0};
|
||||
|
||||
assign trace_rv_trace_pkt.trace_rv_i_valid_ip = dec_tlu_int_valid_wb1 | dec_tlu_i0_valid_wb1 | dec_tlu_i0_exc_valid_wb1;
|
||||
assign trace_rv_trace_pkt.trace_rv_i_exception_ip = dec_tlu_int_valid_wb1 | dec_tlu_i0_exc_valid_wb1;
|
||||
assign trace_rv_trace_pkt.trace_rv_i_ecause_ip = dec_tlu_exc_cause_wb1[4:0]; // replicate across ports
|
||||
assign trace_rv_trace_pkt.trace_rv_i_interrupt_ip = dec_tlu_int_valid_wb1;
|
||||
assign trace_rv_trace_pkt.trace_rv_i_tval_ip = dec_tlu_mtval_wb1[31:0]; // replicate across ports
|
||||
// trace
|
||||
assign trace_rv_trace_pkt.trace_rv_i_insn_ip = dec_i0_inst_wb[31:0];
|
||||
assign trace_rv_trace_pkt.trace_rv_i_address_ip = {dec_i0_pc_wb[31:1], 1'b0};
|
||||
|
||||
assign trace_rv_trace_pkt.trace_rv_i_valid_ip = dec_tlu_int_valid_wb1 | dec_tlu_i0_valid_wb1 | dec_tlu_i0_exc_valid_wb1;
|
||||
assign trace_rv_trace_pkt.trace_rv_i_exception_ip = dec_tlu_int_valid_wb1 | dec_tlu_i0_exc_valid_wb1;
|
||||
assign trace_rv_trace_pkt.trace_rv_i_ecause_ip = dec_tlu_exc_cause_wb1[4:0]; // replicate across ports
|
||||
assign trace_rv_trace_pkt.trace_rv_i_interrupt_ip = dec_tlu_int_valid_wb1;
|
||||
assign trace_rv_trace_pkt.trace_rv_i_tval_ip = dec_tlu_mtval_wb1[31:0]; // replicate across ports
|
||||
|
||||
|
||||
// end trace
|
||||
|
||||
// end trace
|
||||
|
||||
endmodule // el2_dec
|
||||
|
||||
endmodule // el2_dec
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -14,69 +14,74 @@
|
|||
// limitations under the License.
|
||||
|
||||
module el2_dec_gpr_ctl
|
||||
import el2_pkg::*;
|
||||
import el2_pkg::*;
|
||||
#(
|
||||
`include "el2_param.vh"
|
||||
) (
|
||||
input logic [4:0] raddr0, // logical read addresses
|
||||
input logic [4:0] raddr1,
|
||||
`include "el2_param.vh"
|
||||
) (
|
||||
input logic [4:0] raddr0, // logical read addresses
|
||||
input logic [4:0] raddr1,
|
||||
|
||||
input logic wen0, // write enable
|
||||
input logic [4:0] waddr0, // write address
|
||||
input logic [31:0] wd0, // write data
|
||||
input logic wen0, // write enable
|
||||
input logic [ 4:0] waddr0, // write address
|
||||
input logic [31:0] wd0, // write data
|
||||
|
||||
input logic wen1, // write enable
|
||||
input logic [4:0] waddr1, // write address
|
||||
input logic [31:0] wd1, // write data
|
||||
input logic wen1, // write enable
|
||||
input logic [ 4:0] waddr1, // write address
|
||||
input logic [31:0] wd1, // write data
|
||||
|
||||
input logic wen2, // write enable
|
||||
input logic [4:0] waddr2, // write address
|
||||
input logic [31:0] wd2, // write data
|
||||
input logic wen2, // write enable
|
||||
input logic [ 4:0] waddr2, // write address
|
||||
input logic [31:0] wd2, // write data
|
||||
|
||||
input logic clk,
|
||||
input logic rst_l,
|
||||
input logic clk,
|
||||
input logic rst_l,
|
||||
|
||||
output logic [31:0] rd0, // read data
|
||||
output logic [31:0] rd0, // read data
|
||||
output logic [31:0] rd1,
|
||||
|
||||
input logic scan_mode
|
||||
input logic scan_mode
|
||||
);
|
||||
|
||||
logic [31:1] [31:0] gpr_out; // 31 x 32 bit GPRs
|
||||
logic [31:1] [31:0] gpr_in;
|
||||
logic [31:1] w0v,w1v,w2v;
|
||||
logic [31:1] gpr_wr_en;
|
||||
logic [31:1][31:0] gpr_out; // 31 x 32 bit GPRs
|
||||
logic [31:1][31:0] gpr_in;
|
||||
logic [31:1] w0v, w1v, w2v;
|
||||
logic [31:1] gpr_wr_en;
|
||||
|
||||
// GPR Write Enables
|
||||
assign gpr_wr_en[31:1] = (w0v[31:1] | w1v[31:1] | w2v[31:1]);
|
||||
for ( genvar j=1; j<32; j++ ) begin : gpr
|
||||
rvdffe #(32) gprff (.*, .en(gpr_wr_en[j]), .din(gpr_in[j][31:0]), .dout(gpr_out[j][31:0]));
|
||||
end : gpr
|
||||
// GPR Write Enables
|
||||
assign gpr_wr_en[31:1] = (w0v[31:1] | w1v[31:1] | w2v[31:1]);
|
||||
for (genvar j = 1; j < 32; j++) begin : gpr
|
||||
rvdffe #(32) gprff (
|
||||
.*,
|
||||
.en (gpr_wr_en[j]),
|
||||
.din (gpr_in[j][31:0]),
|
||||
.dout(gpr_out[j][31:0])
|
||||
);
|
||||
end : gpr
|
||||
|
||||
// the read out
|
||||
always_comb begin
|
||||
rd0[31:0] = 32'b0;
|
||||
rd1[31:0] = 32'b0;
|
||||
w0v[31:1] = 31'b0;
|
||||
w1v[31:1] = 31'b0;
|
||||
w2v[31:1] = 31'b0;
|
||||
gpr_in[31:1] = '0;
|
||||
// the read out
|
||||
always_comb begin
|
||||
rd0[31:0] = 32'b0;
|
||||
rd1[31:0] = 32'b0;
|
||||
w0v[31:1] = 31'b0;
|
||||
w1v[31:1] = 31'b0;
|
||||
w2v[31:1] = 31'b0;
|
||||
gpr_in[31:1] = '0;
|
||||
|
||||
// GPR Read logic
|
||||
for (int j=1; j<32; j++ ) begin
|
||||
rd0[31:0] |= ({32{(raddr0[4:0]== 5'(j))}} & gpr_out[j][31:0]);
|
||||
rd1[31:0] |= ({32{(raddr1[4:0]== 5'(j))}} & gpr_out[j][31:0]);
|
||||
end
|
||||
// GPR Read logic
|
||||
for (int j = 1; j < 32; j++) begin
|
||||
rd0[31:0] |= ({32{(raddr0[4:0] == 5'(j))}} & gpr_out[j][31:0]);
|
||||
rd1[31:0] |= ({32{(raddr1[4:0] == 5'(j))}} & gpr_out[j][31:0]);
|
||||
end
|
||||
|
||||
// GPR Write logic
|
||||
for (int j=1; j<32; j++ ) begin
|
||||
w0v[j] = wen0 & (waddr0[4:0]== 5'(j) );
|
||||
w1v[j] = wen1 & (waddr1[4:0]== 5'(j) );
|
||||
w2v[j] = wen2 & (waddr2[4:0]== 5'(j) );
|
||||
gpr_in[j] = ({32{w0v[j]}} & wd0[31:0]) |
|
||||
// GPR Write logic
|
||||
for (int j = 1; j < 32; j++) begin
|
||||
w0v[j] = wen0 & (waddr0[4:0] == 5'(j));
|
||||
w1v[j] = wen1 & (waddr1[4:0] == 5'(j));
|
||||
w2v[j] = wen2 & (waddr2[4:0] == 5'(j));
|
||||
gpr_in[j] = ({32{w0v[j]}} & wd0[31:0]) |
|
||||
({32{w1v[j]}} & wd1[31:0]) |
|
||||
({32{w2v[j]}} & wd2[31:0]);
|
||||
end
|
||||
end // always_comb begin
|
||||
end
|
||||
end // always_comb begin
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -14,151 +14,151 @@
|
|||
// limitations under the License.
|
||||
|
||||
module el2_dec_ib_ctl
|
||||
import el2_pkg::*;
|
||||
import el2_pkg::*;
|
||||
#(
|
||||
`include "el2_param.vh"
|
||||
)
|
||||
(
|
||||
input logic dbg_cmd_valid, // valid dbg cmd
|
||||
`include "el2_param.vh"
|
||||
) (
|
||||
input logic dbg_cmd_valid, // valid dbg cmd
|
||||
|
||||
input logic dbg_cmd_write, // dbg cmd is write
|
||||
input logic [1:0] dbg_cmd_type, // dbg type
|
||||
input logic [31:0] dbg_cmd_addr, // expand to 31:0
|
||||
input logic dbg_cmd_write, // dbg cmd is write
|
||||
input logic [ 1:0] dbg_cmd_type, // dbg type
|
||||
input logic [31:0] dbg_cmd_addr, // expand to 31:0
|
||||
|
||||
input el2_br_pkt_t i0_brp, // i0 branch packet from aligner
|
||||
input logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] ifu_i0_bp_index, // BP index
|
||||
input logic [pt.BHT_GHR_SIZE-1:0] ifu_i0_bp_fghr, // BP FGHR
|
||||
input logic [pt.BTB_BTAG_SIZE-1:0] ifu_i0_bp_btag, // BP tag
|
||||
input logic [$clog2(pt.BTB_SIZE)-1:0] ifu_i0_fa_index, // Fully associt btb index
|
||||
input el2_br_pkt_t i0_brp, // i0 branch packet from aligner
|
||||
input logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] ifu_i0_bp_index, // BP index
|
||||
input logic [pt.BHT_GHR_SIZE-1:0] ifu_i0_bp_fghr, // BP FGHR
|
||||
input logic [pt.BTB_BTAG_SIZE-1:0] ifu_i0_bp_btag, // BP tag
|
||||
input logic [$clog2(pt.BTB_SIZE)-1:0] ifu_i0_fa_index, // Fully associt btb index
|
||||
|
||||
input logic ifu_i0_pc4, // i0 is 4B inst else 2B
|
||||
input logic ifu_i0_valid, // i0 valid from ifu
|
||||
input logic ifu_i0_icaf, // i0 instruction access fault
|
||||
input logic [1:0] ifu_i0_icaf_type, // i0 instruction access fault type
|
||||
input logic ifu_i0_pc4, // i0 is 4B inst else 2B
|
||||
input logic ifu_i0_valid, // i0 valid from ifu
|
||||
input logic ifu_i0_icaf, // i0 instruction access fault
|
||||
input logic [1:0] ifu_i0_icaf_type, // i0 instruction access fault type
|
||||
|
||||
input logic ifu_i0_icaf_second, // i0 has access fault on second 2B of 4B inst
|
||||
input logic ifu_i0_dbecc, // i0 double-bit error
|
||||
input logic [31:0] ifu_i0_instr, // i0 instruction from the aligner
|
||||
input logic [31:1] ifu_i0_pc, // i0 pc from the aligner
|
||||
input logic ifu_i0_icaf_second, // i0 has access fault on second 2B of 4B inst
|
||||
input logic ifu_i0_dbecc, // i0 double-bit error
|
||||
input logic [31:0] ifu_i0_instr, // i0 instruction from the aligner
|
||||
input logic [31:1] ifu_i0_pc, // i0 pc from the aligner
|
||||
|
||||
|
||||
output logic dec_ib0_valid_d, // ib0 valid
|
||||
output logic dec_debug_valid_d, // Debug read or write at D-stage
|
||||
output logic dec_ib0_valid_d, // ib0 valid
|
||||
output logic dec_debug_valid_d, // Debug read or write at D-stage
|
||||
|
||||
|
||||
output logic [31:0] dec_i0_instr_d, // i0 inst at decode
|
||||
output logic [31:0] dec_i0_instr_d, // i0 inst at decode
|
||||
|
||||
output logic [31:1] dec_i0_pc_d, // i0 pc at decode
|
||||
output logic [31:1] dec_i0_pc_d, // i0 pc at decode
|
||||
|
||||
output logic dec_i0_pc4_d, // i0 is 4B inst else 2B
|
||||
output logic dec_i0_pc4_d, // i0 is 4B inst else 2B
|
||||
|
||||
output el2_br_pkt_t dec_i0_brp, // i0 branch packet at decode
|
||||
output logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] dec_i0_bp_index, // i0 branch index
|
||||
output logic [pt.BHT_GHR_SIZE-1:0] dec_i0_bp_fghr, // BP FGHR
|
||||
output logic [pt.BTB_BTAG_SIZE-1:0] dec_i0_bp_btag, // BP tag
|
||||
output logic [$clog2(pt.BTB_SIZE)-1:0] dec_i0_bp_fa_index, // Fully associt btb index
|
||||
output el2_br_pkt_t dec_i0_brp, // i0 branch packet at decode
|
||||
output logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] dec_i0_bp_index, // i0 branch index
|
||||
output logic [pt.BHT_GHR_SIZE-1:0] dec_i0_bp_fghr, // BP FGHR
|
||||
output logic [pt.BTB_BTAG_SIZE-1:0] dec_i0_bp_btag, // BP tag
|
||||
output logic [$clog2(pt.BTB_SIZE)-1:0] dec_i0_bp_fa_index, // Fully associt btb index
|
||||
|
||||
output logic dec_i0_icaf_d, // i0 instruction access fault at decode
|
||||
output logic dec_i0_icaf_second_d, // i0 instruction access fault on second 2B of 4B inst
|
||||
output logic [1:0] dec_i0_icaf_type_d, // i0 instruction access fault type
|
||||
output logic dec_i0_dbecc_d, // i0 double-bit error at decode
|
||||
output logic dec_debug_wdata_rs1_d, // put debug write data onto rs1 source: machine is halted
|
||||
output logic dec_i0_icaf_d, // i0 instruction access fault at decode
|
||||
output logic dec_i0_icaf_second_d, // i0 instruction access fault on second 2B of 4B inst
|
||||
output logic [1:0] dec_i0_icaf_type_d, // i0 instruction access fault type
|
||||
output logic dec_i0_dbecc_d, // i0 double-bit error at decode
|
||||
output logic dec_debug_wdata_rs1_d, // put debug write data onto rs1 source: machine is halted
|
||||
|
||||
output logic dec_debug_fence_d // debug fence inst
|
||||
output logic dec_debug_fence_d // debug fence inst
|
||||
|
||||
);
|
||||
);
|
||||
|
||||
|
||||
logic debug_valid;
|
||||
logic [4:0] dreg;
|
||||
logic [11:0] dcsr;
|
||||
logic [31:0] ib0, ib0_debug_in;
|
||||
logic debug_valid;
|
||||
logic [ 4:0] dreg;
|
||||
logic [11:0] dcsr;
|
||||
logic [31:0] ib0, ib0_debug_in;
|
||||
|
||||
logic debug_read;
|
||||
logic debug_write;
|
||||
logic debug_read_gpr;
|
||||
logic debug_write_gpr;
|
||||
logic debug_read_csr;
|
||||
logic debug_write_csr;
|
||||
logic debug_read;
|
||||
logic debug_write;
|
||||
logic debug_read_gpr;
|
||||
logic debug_write_gpr;
|
||||
logic debug_read_csr;
|
||||
logic debug_write_csr;
|
||||
|
||||
logic [34:0] ifu_i0_pcdata, pc0;
|
||||
logic [34:0] ifu_i0_pcdata, pc0;
|
||||
|
||||
assign ifu_i0_pcdata[34:0] = { ifu_i0_icaf_second, ifu_i0_dbecc, ifu_i0_icaf,
|
||||
ifu_i0_pc[31:1], ifu_i0_pc4 };
|
||||
assign ifu_i0_pcdata[34:0] = {
|
||||
ifu_i0_icaf_second, ifu_i0_dbecc, ifu_i0_icaf, ifu_i0_pc[31:1], ifu_i0_pc4
|
||||
};
|
||||
|
||||
assign pc0[34:0] = ifu_i0_pcdata[34:0];
|
||||
assign pc0[34:0] = ifu_i0_pcdata[34:0];
|
||||
|
||||
assign dec_i0_icaf_second_d = pc0[34]; // icaf's can only decode as i0
|
||||
assign dec_i0_icaf_second_d = pc0[34]; // icaf's can only decode as i0
|
||||
|
||||
assign dec_i0_dbecc_d = pc0[33];
|
||||
assign dec_i0_dbecc_d = pc0[33];
|
||||
|
||||
assign dec_i0_icaf_d = pc0[32];
|
||||
assign dec_i0_pc_d[31:1] = pc0[31:1];
|
||||
assign dec_i0_pc4_d = pc0[0];
|
||||
assign dec_i0_icaf_d = pc0[32];
|
||||
assign dec_i0_pc_d[31:1] = pc0[31:1];
|
||||
assign dec_i0_pc4_d = pc0[0];
|
||||
|
||||
assign dec_i0_icaf_type_d[1:0] = ifu_i0_icaf_type[1:0];
|
||||
assign dec_i0_icaf_type_d[1:0] = ifu_i0_icaf_type[1:0];
|
||||
|
||||
// GPR accesses
|
||||
// GPR accesses
|
||||
|
||||
// put reg to read on rs1
|
||||
// read -> or %x0, %reg,%x0 {000000000000,reg[4:0],110000000110011}
|
||||
// put reg to read on rs1
|
||||
// read -> or %x0, %reg,%x0 {000000000000,reg[4:0],110000000110011}
|
||||
|
||||
// put write date on rs1
|
||||
// write -> or %reg, %x0, %x0 {00000000000000000110,reg[4:0],0110011}
|
||||
// put write date on rs1
|
||||
// write -> or %reg, %x0, %x0 {00000000000000000110,reg[4:0],0110011}
|
||||
|
||||
|
||||
// CSR accesses
|
||||
// csr is of form rd, csr, rs1
|
||||
// CSR accesses
|
||||
// csr is of form rd, csr, rs1
|
||||
|
||||
// read -> csrrs %x0, %csr, %x0 {csr[11:0],00000010000001110011}
|
||||
// read -> csrrs %x0, %csr, %x0 {csr[11:0],00000010000001110011}
|
||||
|
||||
// put write data on rs1
|
||||
// write -> csrrw %x0, %csr, %x0 {csr[11:0],00000001000001110011}
|
||||
// put write data on rs1
|
||||
// write -> csrrw %x0, %csr, %x0 {csr[11:0],00000001000001110011}
|
||||
|
||||
// abstract memory command not done here
|
||||
assign debug_valid = dbg_cmd_valid & (dbg_cmd_type[1:0] != 2'h2);
|
||||
// abstract memory command not done here
|
||||
assign debug_valid = dbg_cmd_valid & (dbg_cmd_type[1:0] != 2'h2);
|
||||
|
||||
|
||||
assign debug_read = debug_valid & ~dbg_cmd_write;
|
||||
assign debug_write = debug_valid & dbg_cmd_write;
|
||||
assign debug_read = debug_valid & ~dbg_cmd_write;
|
||||
assign debug_write = debug_valid & dbg_cmd_write;
|
||||
|
||||
assign debug_read_gpr = debug_read & (dbg_cmd_type[1:0]==2'h0);
|
||||
assign debug_write_gpr = debug_write & (dbg_cmd_type[1:0]==2'h0);
|
||||
assign debug_read_csr = debug_read & (dbg_cmd_type[1:0]==2'h1);
|
||||
assign debug_write_csr = debug_write & (dbg_cmd_type[1:0]==2'h1);
|
||||
assign debug_read_gpr = debug_read & (dbg_cmd_type[1:0] == 2'h0);
|
||||
assign debug_write_gpr = debug_write & (dbg_cmd_type[1:0] == 2'h0);
|
||||
assign debug_read_csr = debug_read & (dbg_cmd_type[1:0] == 2'h1);
|
||||
assign debug_write_csr = debug_write & (dbg_cmd_type[1:0] == 2'h1);
|
||||
|
||||
assign dreg[4:0] = dbg_cmd_addr[4:0];
|
||||
assign dcsr[11:0] = dbg_cmd_addr[11:0];
|
||||
assign dreg[4:0] = dbg_cmd_addr[4:0];
|
||||
assign dcsr[11:0] = dbg_cmd_addr[11:0];
|
||||
|
||||
|
||||
assign ib0_debug_in[31:0] = ({32{debug_read_gpr}} & {12'b000000000000,dreg[4:0],15'b110000000110011}) |
|
||||
assign ib0_debug_in[31:0] = ({32{debug_read_gpr}} & {12'b000000000000,dreg[4:0],15'b110000000110011}) |
|
||||
({32{debug_write_gpr}} & {20'b00000000000000000110,dreg[4:0],7'b0110011}) |
|
||||
({32{debug_read_csr}} & {dcsr[11:0],20'b00000010000001110011}) |
|
||||
({32{debug_write_csr}} & {dcsr[11:0],20'b00000001000001110011});
|
||||
|
||||
|
||||
|
||||
// machine is in halted state, pipe empty, write will always happen next cycle
|
||||
// machine is in halted state, pipe empty, write will always happen next cycle
|
||||
|
||||
assign dec_debug_wdata_rs1_d = debug_write_gpr | debug_write_csr;
|
||||
assign dec_debug_wdata_rs1_d = debug_write_gpr | debug_write_csr;
|
||||
|
||||
|
||||
// special fence csr for use only in debug mode
|
||||
// special fence csr for use only in debug mode
|
||||
|
||||
assign dec_debug_fence_d = debug_write_csr & (dcsr[11:0] == 12'h7c4);
|
||||
assign dec_debug_fence_d = debug_write_csr & (dcsr[11:0] == 12'h7c4);
|
||||
|
||||
assign ib0[31:0] = (debug_valid) ? ib0_debug_in[31:0] : ifu_i0_instr[31:0];
|
||||
assign ib0[31:0] = (debug_valid) ? ib0_debug_in[31:0] : ifu_i0_instr[31:0];
|
||||
|
||||
assign dec_ib0_valid_d = ifu_i0_valid | debug_valid;
|
||||
assign dec_ib0_valid_d = ifu_i0_valid | debug_valid;
|
||||
|
||||
assign dec_debug_valid_d = debug_valid;
|
||||
assign dec_debug_valid_d = debug_valid;
|
||||
|
||||
assign dec_i0_instr_d[31:0] = ib0[31:0];
|
||||
assign dec_i0_instr_d[31:0] = ib0[31:0];
|
||||
|
||||
assign dec_i0_brp = i0_brp;
|
||||
assign dec_i0_bp_index = ifu_i0_bp_index;
|
||||
assign dec_i0_bp_fghr = ifu_i0_bp_fghr;
|
||||
assign dec_i0_bp_btag = ifu_i0_bp_btag;
|
||||
assign dec_i0_bp_fa_index = ifu_i0_fa_index;
|
||||
assign dec_i0_brp = i0_brp;
|
||||
assign dec_i0_bp_index = ifu_i0_bp_index;
|
||||
assign dec_i0_bp_fghr = ifu_i0_bp_fghr;
|
||||
assign dec_i0_bp_btag = ifu_i0_bp_btag;
|
||||
assign dec_i0_bp_fa_index = ifu_i0_fa_index;
|
||||
|
||||
endmodule
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -23,27 +23,32 @@
|
|||
//
|
||||
//********************************************************************************
|
||||
module el2_dec_trigger
|
||||
import el2_pkg::*;
|
||||
import el2_pkg::*;
|
||||
#(
|
||||
`include "el2_param.vh"
|
||||
)(
|
||||
`include "el2_param.vh"
|
||||
) (
|
||||
|
||||
input el2_trigger_pkt_t [3:0] trigger_pkt_any, // Packet from tlu. 'select':0-pc,1-Opcode 'Execute' needs to be set for dec triggers to fire. 'match'-1 do mask, 0: full match
|
||||
input logic [31:1] dec_i0_pc_d, // i0 pc
|
||||
input el2_trigger_pkt_t [3:0] trigger_pkt_any, // Packet from tlu. 'select':0-pc,1-Opcode 'Execute' needs to be set for dec triggers to fire. 'match'-1 do mask, 0: full match
|
||||
input logic [31:1] dec_i0_pc_d, // i0 pc
|
||||
|
||||
output logic [3:0] dec_i0_trigger_match_d // Trigger match
|
||||
output logic [3:0] dec_i0_trigger_match_d // Trigger match
|
||||
);
|
||||
|
||||
logic [3:0][31:0] dec_i0_match_data;
|
||||
logic [3:0] dec_i0_trigger_data_match;
|
||||
logic [3:0][31:0] dec_i0_match_data;
|
||||
logic [3:0] dec_i0_trigger_data_match;
|
||||
|
||||
for (genvar i=0; i<4; i++) begin
|
||||
assign dec_i0_match_data[i][31:0] = ({32{~trigger_pkt_any[i].select & trigger_pkt_any[i].execute}} & {dec_i0_pc_d[31:1], trigger_pkt_any[i].tdata2[0]}); // select=0; do a PC match
|
||||
for (genvar i = 0; i < 4; i++) begin
|
||||
assign dec_i0_match_data[i][31:0] = ({32{~trigger_pkt_any[i].select & trigger_pkt_any[i].execute}} & {dec_i0_pc_d[31:1], trigger_pkt_any[i].tdata2[0]}); // select=0; do a PC match
|
||||
|
||||
rvmaskandmatch trigger_i0_match (.mask(trigger_pkt_any[i].tdata2[31:0]), .data(dec_i0_match_data[i][31:0]), .masken(trigger_pkt_any[i].match), .match(dec_i0_trigger_data_match[i]));
|
||||
rvmaskandmatch trigger_i0_match (
|
||||
.mask (trigger_pkt_any[i].tdata2[31:0]),
|
||||
.data (dec_i0_match_data[i][31:0]),
|
||||
.masken(trigger_pkt_any[i].match),
|
||||
.match (dec_i0_trigger_data_match[i])
|
||||
);
|
||||
|
||||
assign dec_i0_trigger_match_d[i] = trigger_pkt_any[i].execute & trigger_pkt_any[i].m & dec_i0_trigger_data_match[i];
|
||||
end
|
||||
assign dec_i0_trigger_match_d[i] = trigger_pkt_any[i].execute & trigger_pkt_any[i].m & dec_i0_trigger_data_match[i];
|
||||
end
|
||||
|
||||
endmodule // el2_dec_trigger
|
||||
endmodule // el2_dec_trigger
|
||||
|
||||
|
|
|
@ -23,42 +23,41 @@
|
|||
//-------------------------------------------------------------------------------------
|
||||
|
||||
module dmi_jtag_to_core_sync (
|
||||
// JTAG signals
|
||||
input rd_en, // 1 bit Read Enable from JTAG
|
||||
input wr_en, // 1 bit Write enable from JTAG
|
||||
// JTAG signals
|
||||
input rd_en, // 1 bit Read Enable from JTAG
|
||||
input wr_en, // 1 bit Write enable from JTAG
|
||||
|
||||
// Processor Signals
|
||||
input rst_n, // Core reset
|
||||
input clk, // Core clock
|
||||
// Processor Signals
|
||||
input rst_n, // Core reset
|
||||
input clk, // Core clock
|
||||
|
||||
output reg_en, // 1 bit Write interface bit to Processor
|
||||
output reg_wr_en // 1 bit Write enable to Processor
|
||||
output reg_en, // 1 bit Write interface bit to Processor
|
||||
output reg_wr_en // 1 bit Write enable to Processor
|
||||
);
|
||||
|
||||
wire c_rd_en;
|
||||
wire c_wr_en;
|
||||
reg [2:0] rden, wren;
|
||||
|
||||
|
||||
// Outputs
|
||||
assign reg_en = c_wr_en | c_rd_en;
|
||||
assign reg_wr_en = c_wr_en;
|
||||
wire c_rd_en;
|
||||
wire c_wr_en;
|
||||
reg [2:0] rden, wren;
|
||||
|
||||
|
||||
// synchronizers
|
||||
always @ ( posedge clk or negedge rst_n) begin
|
||||
if(!rst_n) begin
|
||||
rden <= '0;
|
||||
wren <= '0;
|
||||
// Outputs
|
||||
assign reg_en = c_wr_en | c_rd_en;
|
||||
assign reg_wr_en = c_wr_en;
|
||||
|
||||
|
||||
// synchronizers
|
||||
always @(posedge clk or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
rden <= '0;
|
||||
wren <= '0;
|
||||
end else begin
|
||||
rden <= {rden[1:0], rd_en};
|
||||
wren <= {wren[1:0], wr_en};
|
||||
end
|
||||
else begin
|
||||
rden <= {rden[1:0], rd_en};
|
||||
wren <= {wren[1:0], wr_en};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign c_rd_en = rden[1] & ~rden[2];
|
||||
assign c_wr_en = wren[1] & ~wren[2];
|
||||
|
||||
assign c_rd_en = rden[1] & ~rden[2];
|
||||
assign c_wr_en = wren[1] & ~wren[2];
|
||||
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -21,70 +21,70 @@
|
|||
//
|
||||
//-------------------------------------------------------------------------------------
|
||||
|
||||
module dmi_wrapper(
|
||||
module dmi_wrapper (
|
||||
|
||||
// JTAG signals
|
||||
input trst_n, // JTAG reset
|
||||
input tck, // JTAG clock
|
||||
input tms, // Test mode select
|
||||
input tdi, // Test Data Input
|
||||
output tdo, // Test Data Output
|
||||
output tdoEnable, // Test Data Output enable
|
||||
// JTAG signals
|
||||
input trst_n, // JTAG reset
|
||||
input tck, // JTAG clock
|
||||
input tms, // Test mode select
|
||||
input tdi, // Test Data Input
|
||||
output tdo, // Test Data Output
|
||||
output tdoEnable, // Test Data Output enable
|
||||
|
||||
// Processor Signals
|
||||
input core_rst_n, // Core reset
|
||||
input core_clk, // Core clock
|
||||
input [31:1] jtag_id, // JTAG ID
|
||||
input [31:0] rd_data, // 32 bit Read data from Processor
|
||||
output [31:0] reg_wr_data, // 32 bit Write data to Processor
|
||||
output [6:0] reg_wr_addr, // 7 bit reg address to Processor
|
||||
output reg_en, // 1 bit Read enable to Processor
|
||||
output reg_wr_en, // 1 bit Write enable to Processor
|
||||
output dmi_hard_reset
|
||||
// Processor Signals
|
||||
input core_rst_n, // Core reset
|
||||
input core_clk, // Core clock
|
||||
input [31:1] jtag_id, // JTAG ID
|
||||
input [31:0] rd_data, // 32 bit Read data from Processor
|
||||
output [31:0] reg_wr_data, // 32 bit Write data to Processor
|
||||
output [6:0] reg_wr_addr, // 7 bit reg address to Processor
|
||||
output reg_en, // 1 bit Read enable to Processor
|
||||
output reg_wr_en, // 1 bit Write enable to Processor
|
||||
output dmi_hard_reset
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//Wire Declaration
|
||||
wire rd_en;
|
||||
wire wr_en;
|
||||
wire dmireset;
|
||||
wire rd_en;
|
||||
wire wr_en;
|
||||
wire dmireset;
|
||||
|
||||
|
||||
|
||||
//jtag_tap instantiation
|
||||
rvjtag_tap i_jtag_tap(
|
||||
.trst(trst_n), // dedicated JTAG TRST (active low) pad signal or asynchronous active low power on reset
|
||||
.tck(tck), // dedicated JTAG TCK pad signal
|
||||
.tms(tms), // dedicated JTAG TMS pad signal
|
||||
.tdi(tdi), // dedicated JTAG TDI pad signal
|
||||
.tdo(tdo), // dedicated JTAG TDO pad signal
|
||||
.tdoEnable(tdoEnable), // enable for TDO pad
|
||||
.wr_data(reg_wr_data), // 32 bit Write data
|
||||
.wr_addr(reg_wr_addr), // 7 bit Write address
|
||||
.rd_en(rd_en), // 1 bit read enable
|
||||
.wr_en(wr_en), // 1 bit Write enable
|
||||
.rd_data(rd_data), // 32 bit Read data
|
||||
.rd_status(2'b0),
|
||||
.idle(3'h0), // no need to wait to sample data
|
||||
.dmi_stat(2'b0), // no need to wait or error possible
|
||||
.version(4'h1), // debug spec 0.13 compliant
|
||||
.jtag_id(jtag_id),
|
||||
.dmi_hard_reset(dmi_hard_reset),
|
||||
.dmi_reset(dmireset)
|
||||
);
|
||||
rvjtag_tap i_jtag_tap (
|
||||
.trst(trst_n), // dedicated JTAG TRST (active low) pad signal or asynchronous active low power on reset
|
||||
.tck(tck), // dedicated JTAG TCK pad signal
|
||||
.tms(tms), // dedicated JTAG TMS pad signal
|
||||
.tdi(tdi), // dedicated JTAG TDI pad signal
|
||||
.tdo(tdo), // dedicated JTAG TDO pad signal
|
||||
.tdoEnable(tdoEnable), // enable for TDO pad
|
||||
.wr_data(reg_wr_data), // 32 bit Write data
|
||||
.wr_addr(reg_wr_addr), // 7 bit Write address
|
||||
.rd_en(rd_en), // 1 bit read enable
|
||||
.wr_en(wr_en), // 1 bit Write enable
|
||||
.rd_data(rd_data), // 32 bit Read data
|
||||
.rd_status(2'b0),
|
||||
.idle(3'h0), // no need to wait to sample data
|
||||
.dmi_stat(2'b0), // no need to wait or error possible
|
||||
.version(4'h1), // debug spec 0.13 compliant
|
||||
.jtag_id(jtag_id),
|
||||
.dmi_hard_reset(dmi_hard_reset),
|
||||
.dmi_reset(dmireset)
|
||||
);
|
||||
|
||||
|
||||
// dmi_jtag_to_core_sync instantiation
|
||||
dmi_jtag_to_core_sync i_dmi_jtag_to_core_sync(
|
||||
.wr_en(wr_en), // 1 bit Write enable
|
||||
.rd_en(rd_en), // 1 bit Read enable
|
||||
dmi_jtag_to_core_sync i_dmi_jtag_to_core_sync (
|
||||
.wr_en(wr_en), // 1 bit Write enable
|
||||
.rd_en(rd_en), // 1 bit Read enable
|
||||
|
||||
.rst_n(core_rst_n),
|
||||
.clk(core_clk),
|
||||
.reg_en(reg_en), // 1 bit Write interface bit
|
||||
.reg_wr_en(reg_wr_en) // 1 bit Write enable
|
||||
.rst_n (core_rst_n),
|
||||
.clk (core_clk),
|
||||
.reg_en (reg_en), // 1 bit Write interface bit
|
||||
.reg_wr_en(reg_wr_en) // 1 bit Write enable
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -14,209 +14,202 @@
|
|||
// limitations under the License
|
||||
|
||||
module rvjtag_tap #(
|
||||
parameter AWIDTH = 7
|
||||
)
|
||||
(
|
||||
input trst,
|
||||
input tck,
|
||||
input tms,
|
||||
input tdi,
|
||||
output reg tdo,
|
||||
output tdoEnable,
|
||||
parameter AWIDTH = 7
|
||||
) (
|
||||
input trst,
|
||||
input tck,
|
||||
input tms,
|
||||
input tdi,
|
||||
output reg tdo,
|
||||
output tdoEnable,
|
||||
|
||||
output [31:0] wr_data,
|
||||
output [AWIDTH-1:0] wr_addr,
|
||||
output wr_en,
|
||||
output rd_en,
|
||||
output [ 31:0] wr_data,
|
||||
output [AWIDTH-1:0] wr_addr,
|
||||
output wr_en,
|
||||
output rd_en,
|
||||
|
||||
input [31:0] rd_data,
|
||||
input [1:0] rd_status,
|
||||
input [31:0] rd_data,
|
||||
input [ 1:0] rd_status,
|
||||
|
||||
output reg dmi_reset,
|
||||
output reg dmi_hard_reset,
|
||||
output reg dmi_reset,
|
||||
output reg dmi_hard_reset,
|
||||
|
||||
input [2:0] idle,
|
||||
input [1:0] dmi_stat,
|
||||
/*
|
||||
input [ 2:0] idle,
|
||||
input [ 1:0] dmi_stat,
|
||||
/*
|
||||
-- revisionCode : 4'h0;
|
||||
-- manufacturersIdCode : 11'h45;
|
||||
-- deviceIdCode : 16'h0001;
|
||||
-- order MSB .. LSB -> [4 bit version or revision] [16 bit part number] [11 bit manufacturer id] [value of 1'b1 in LSB]
|
||||
*/
|
||||
input [31:1] jtag_id,
|
||||
input [3:0] version
|
||||
input [31:1] jtag_id,
|
||||
input [ 3:0] version
|
||||
);
|
||||
|
||||
localparam USER_DR_LENGTH = AWIDTH + 34;
|
||||
localparam USER_DR_LENGTH = AWIDTH + 34;
|
||||
|
||||
|
||||
reg [USER_DR_LENGTH-1:0] sr, nsr, dr;
|
||||
reg [USER_DR_LENGTH-1:0] sr, nsr, dr;
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// Tap controller
|
||||
///////////////////////////////////////////////////////
|
||||
logic[3:0] state, nstate;
|
||||
logic [4:0] ir;
|
||||
wire jtag_reset;
|
||||
wire shift_dr;
|
||||
wire pause_dr;
|
||||
wire update_dr;
|
||||
wire capture_dr;
|
||||
wire shift_ir;
|
||||
wire pause_ir ;
|
||||
wire update_ir ;
|
||||
wire capture_ir;
|
||||
wire[1:0] dr_en;
|
||||
wire devid_sel;
|
||||
wire [5:0] abits;
|
||||
///////////////////////////////////////////////////////
|
||||
// Tap controller
|
||||
///////////////////////////////////////////////////////
|
||||
logic [3:0] state, nstate;
|
||||
logic [4:0] ir;
|
||||
wire jtag_reset;
|
||||
wire shift_dr;
|
||||
wire pause_dr;
|
||||
wire update_dr;
|
||||
wire capture_dr;
|
||||
wire shift_ir;
|
||||
wire pause_ir;
|
||||
wire update_ir;
|
||||
wire capture_ir;
|
||||
wire [1:0] dr_en;
|
||||
wire devid_sel;
|
||||
wire [5:0] abits;
|
||||
|
||||
assign abits = AWIDTH[5:0];
|
||||
assign abits = AWIDTH[5:0];
|
||||
|
||||
|
||||
localparam TEST_LOGIC_RESET_STATE = 0;
|
||||
localparam RUN_TEST_IDLE_STATE = 1;
|
||||
localparam SELECT_DR_SCAN_STATE = 2;
|
||||
localparam CAPTURE_DR_STATE = 3;
|
||||
localparam SHIFT_DR_STATE = 4;
|
||||
localparam EXIT1_DR_STATE = 5;
|
||||
localparam PAUSE_DR_STATE = 6;
|
||||
localparam EXIT2_DR_STATE = 7;
|
||||
localparam UPDATE_DR_STATE = 8;
|
||||
localparam SELECT_IR_SCAN_STATE = 9;
|
||||
localparam CAPTURE_IR_STATE = 10;
|
||||
localparam SHIFT_IR_STATE = 11;
|
||||
localparam EXIT1_IR_STATE = 12;
|
||||
localparam PAUSE_IR_STATE = 13;
|
||||
localparam EXIT2_IR_STATE = 14;
|
||||
localparam UPDATE_IR_STATE = 15;
|
||||
localparam TEST_LOGIC_RESET_STATE = 0;
|
||||
localparam RUN_TEST_IDLE_STATE = 1;
|
||||
localparam SELECT_DR_SCAN_STATE = 2;
|
||||
localparam CAPTURE_DR_STATE = 3;
|
||||
localparam SHIFT_DR_STATE = 4;
|
||||
localparam EXIT1_DR_STATE = 5;
|
||||
localparam PAUSE_DR_STATE = 6;
|
||||
localparam EXIT2_DR_STATE = 7;
|
||||
localparam UPDATE_DR_STATE = 8;
|
||||
localparam SELECT_IR_SCAN_STATE = 9;
|
||||
localparam CAPTURE_IR_STATE = 10;
|
||||
localparam SHIFT_IR_STATE = 11;
|
||||
localparam EXIT1_IR_STATE = 12;
|
||||
localparam PAUSE_IR_STATE = 13;
|
||||
localparam EXIT2_IR_STATE = 14;
|
||||
localparam UPDATE_IR_STATE = 15;
|
||||
|
||||
always_comb begin
|
||||
always_comb begin
|
||||
nstate = state;
|
||||
case(state)
|
||||
TEST_LOGIC_RESET_STATE: nstate = tms ? TEST_LOGIC_RESET_STATE : RUN_TEST_IDLE_STATE;
|
||||
RUN_TEST_IDLE_STATE: nstate = tms ? SELECT_DR_SCAN_STATE : RUN_TEST_IDLE_STATE;
|
||||
SELECT_DR_SCAN_STATE: nstate = tms ? SELECT_IR_SCAN_STATE : CAPTURE_DR_STATE;
|
||||
CAPTURE_DR_STATE: nstate = tms ? EXIT1_DR_STATE : SHIFT_DR_STATE;
|
||||
SHIFT_DR_STATE: nstate = tms ? EXIT1_DR_STATE : SHIFT_DR_STATE;
|
||||
EXIT1_DR_STATE: nstate = tms ? UPDATE_DR_STATE : PAUSE_DR_STATE;
|
||||
PAUSE_DR_STATE: nstate = tms ? EXIT2_DR_STATE : PAUSE_DR_STATE;
|
||||
EXIT2_DR_STATE: nstate = tms ? UPDATE_DR_STATE : SHIFT_DR_STATE;
|
||||
UPDATE_DR_STATE: nstate = tms ? SELECT_DR_SCAN_STATE : RUN_TEST_IDLE_STATE;
|
||||
SELECT_IR_SCAN_STATE: nstate = tms ? TEST_LOGIC_RESET_STATE : CAPTURE_IR_STATE;
|
||||
CAPTURE_IR_STATE: nstate = tms ? EXIT1_IR_STATE : SHIFT_IR_STATE;
|
||||
SHIFT_IR_STATE: nstate = tms ? EXIT1_IR_STATE : SHIFT_IR_STATE;
|
||||
EXIT1_IR_STATE: nstate = tms ? UPDATE_IR_STATE : PAUSE_IR_STATE;
|
||||
PAUSE_IR_STATE: nstate = tms ? EXIT2_IR_STATE : PAUSE_IR_STATE;
|
||||
EXIT2_IR_STATE: nstate = tms ? UPDATE_IR_STATE : SHIFT_IR_STATE;
|
||||
UPDATE_IR_STATE: nstate = tms ? SELECT_DR_SCAN_STATE : RUN_TEST_IDLE_STATE;
|
||||
default: nstate = TEST_LOGIC_RESET_STATE;
|
||||
case (state)
|
||||
TEST_LOGIC_RESET_STATE: nstate = tms ? TEST_LOGIC_RESET_STATE : RUN_TEST_IDLE_STATE;
|
||||
RUN_TEST_IDLE_STATE: nstate = tms ? SELECT_DR_SCAN_STATE : RUN_TEST_IDLE_STATE;
|
||||
SELECT_DR_SCAN_STATE: nstate = tms ? SELECT_IR_SCAN_STATE : CAPTURE_DR_STATE;
|
||||
CAPTURE_DR_STATE: nstate = tms ? EXIT1_DR_STATE : SHIFT_DR_STATE;
|
||||
SHIFT_DR_STATE: nstate = tms ? EXIT1_DR_STATE : SHIFT_DR_STATE;
|
||||
EXIT1_DR_STATE: nstate = tms ? UPDATE_DR_STATE : PAUSE_DR_STATE;
|
||||
PAUSE_DR_STATE: nstate = tms ? EXIT2_DR_STATE : PAUSE_DR_STATE;
|
||||
EXIT2_DR_STATE: nstate = tms ? UPDATE_DR_STATE : SHIFT_DR_STATE;
|
||||
UPDATE_DR_STATE: nstate = tms ? SELECT_DR_SCAN_STATE : RUN_TEST_IDLE_STATE;
|
||||
SELECT_IR_SCAN_STATE: nstate = tms ? TEST_LOGIC_RESET_STATE : CAPTURE_IR_STATE;
|
||||
CAPTURE_IR_STATE: nstate = tms ? EXIT1_IR_STATE : SHIFT_IR_STATE;
|
||||
SHIFT_IR_STATE: nstate = tms ? EXIT1_IR_STATE : SHIFT_IR_STATE;
|
||||
EXIT1_IR_STATE: nstate = tms ? UPDATE_IR_STATE : PAUSE_IR_STATE;
|
||||
PAUSE_IR_STATE: nstate = tms ? EXIT2_IR_STATE : PAUSE_IR_STATE;
|
||||
EXIT2_IR_STATE: nstate = tms ? UPDATE_IR_STATE : SHIFT_IR_STATE;
|
||||
UPDATE_IR_STATE: nstate = tms ? SELECT_DR_SCAN_STATE : RUN_TEST_IDLE_STATE;
|
||||
default: nstate = TEST_LOGIC_RESET_STATE;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always @ (posedge tck or negedge trst) begin
|
||||
if(!trst) state <= TEST_LOGIC_RESET_STATE;
|
||||
always @(posedge tck or negedge trst) begin
|
||||
if (!trst) state <= TEST_LOGIC_RESET_STATE;
|
||||
else state <= nstate;
|
||||
end
|
||||
end
|
||||
|
||||
assign jtag_reset = state == TEST_LOGIC_RESET_STATE;
|
||||
assign shift_dr = state == SHIFT_DR_STATE;
|
||||
assign pause_dr = state == PAUSE_DR_STATE;
|
||||
assign update_dr = state == UPDATE_DR_STATE;
|
||||
assign capture_dr = state == CAPTURE_DR_STATE;
|
||||
assign shift_ir = state == SHIFT_IR_STATE;
|
||||
assign pause_ir = state == PAUSE_IR_STATE;
|
||||
assign update_ir = state == UPDATE_IR_STATE;
|
||||
assign capture_ir = state == CAPTURE_IR_STATE;
|
||||
assign jtag_reset = state == TEST_LOGIC_RESET_STATE;
|
||||
assign shift_dr = state == SHIFT_DR_STATE;
|
||||
assign pause_dr = state == PAUSE_DR_STATE;
|
||||
assign update_dr = state == UPDATE_DR_STATE;
|
||||
assign capture_dr = state == CAPTURE_DR_STATE;
|
||||
assign shift_ir = state == SHIFT_IR_STATE;
|
||||
assign pause_ir = state == PAUSE_IR_STATE;
|
||||
assign update_ir = state == UPDATE_IR_STATE;
|
||||
assign capture_ir = state == CAPTURE_IR_STATE;
|
||||
|
||||
assign tdoEnable = shift_dr | shift_ir;
|
||||
assign tdoEnable = shift_dr | shift_ir;
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// IR register
|
||||
///////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////
|
||||
// IR register
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
always @ (negedge tck or negedge trst) begin
|
||||
if (!trst) ir <= 5'b1;
|
||||
else begin
|
||||
always @(negedge tck or negedge trst) begin
|
||||
if (!trst) ir <= 5'b1;
|
||||
else begin
|
||||
if (jtag_reset) ir <= 5'b1;
|
||||
else if (update_ir) ir <= (sr[4:0] == '0) ? 5'h1f :sr[4:0];
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
assign devid_sel = ir == 5'b00001;
|
||||
assign dr_en[0] = ir == 5'b10000;
|
||||
assign dr_en[1] = ir == 5'b10001;
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// Shift register
|
||||
///////////////////////////////////////////////////////
|
||||
always @ (posedge tck or negedge trst) begin
|
||||
if(!trst)begin
|
||||
sr <= '0;
|
||||
else if (update_ir) ir <= (sr[4:0] == '0) ? 5'h1f : sr[4:0];
|
||||
end
|
||||
else begin
|
||||
sr <= nsr;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// SR next value
|
||||
always_comb begin
|
||||
|
||||
assign devid_sel = ir == 5'b00001;
|
||||
assign dr_en[0] = ir == 5'b10000;
|
||||
assign dr_en[1] = ir == 5'b10001;
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// Shift register
|
||||
///////////////////////////////////////////////////////
|
||||
always @(posedge tck or negedge trst) begin
|
||||
if (!trst) begin
|
||||
sr <= '0;
|
||||
end else begin
|
||||
sr <= nsr;
|
||||
end
|
||||
end
|
||||
|
||||
// SR next value
|
||||
always_comb begin
|
||||
nsr = sr;
|
||||
case(1)
|
||||
shift_dr: begin
|
||||
case(1)
|
||||
dr_en[1]: nsr = {tdi, sr[USER_DR_LENGTH-1:1]};
|
||||
case (1)
|
||||
shift_dr: begin
|
||||
case (1)
|
||||
dr_en[1]: nsr = {tdi, sr[USER_DR_LENGTH-1:1]};
|
||||
|
||||
dr_en[0],
|
||||
dr_en[0],
|
||||
devid_sel: nsr = {{USER_DR_LENGTH-32{1'b0}},tdi, sr[31:1]};
|
||||
default: nsr = {{USER_DR_LENGTH-1{1'b0}},tdi}; // bypass
|
||||
endcase
|
||||
end
|
||||
capture_dr: begin
|
||||
nsr[0] = 1'b0;
|
||||
case(1)
|
||||
dr_en[0]: nsr = {{USER_DR_LENGTH-15{1'b0}}, idle, dmi_stat, abits, version};
|
||||
dr_en[1]: nsr = {{AWIDTH{1'b0}}, rd_data, rd_status};
|
||||
devid_sel: nsr = {{USER_DR_LENGTH-32{1'b0}}, jtag_id, 1'b1};
|
||||
endcase
|
||||
end
|
||||
shift_ir: nsr = {{USER_DR_LENGTH-5{1'b0}},tdi, sr[4:1]};
|
||||
capture_ir: nsr = {{USER_DR_LENGTH-1{1'b0}},1'b1};
|
||||
default: nsr = {{USER_DR_LENGTH-1{1'b0}},tdi}; // bypass
|
||||
endcase
|
||||
end
|
||||
capture_dr: begin
|
||||
nsr[0] = 1'b0;
|
||||
case (1)
|
||||
dr_en[0]: nsr = {{USER_DR_LENGTH - 15{1'b0}}, idle, dmi_stat, abits, version};
|
||||
dr_en[1]: nsr = {{AWIDTH{1'b0}}, rd_data, rd_status};
|
||||
devid_sel: nsr = {{USER_DR_LENGTH - 32{1'b0}}, jtag_id, 1'b1};
|
||||
endcase
|
||||
end
|
||||
shift_ir: nsr = {{USER_DR_LENGTH - 5{1'b0}}, tdi, sr[4:1]};
|
||||
capture_ir: nsr = {{USER_DR_LENGTH - 1{1'b0}}, 1'b1};
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// TDO retiming
|
||||
always @ (negedge tck ) tdo <= sr[0];
|
||||
// TDO retiming
|
||||
always @(negedge tck) tdo <= sr[0];
|
||||
|
||||
// DMI CS register
|
||||
always @ (posedge tck or negedge trst) begin
|
||||
if(!trst) begin
|
||||
dmi_hard_reset <= 1'b0;
|
||||
dmi_reset <= 1'b0;
|
||||
end
|
||||
else if (update_dr & dr_en[0]) begin
|
||||
dmi_hard_reset <= sr[17];
|
||||
dmi_reset <= sr[16];
|
||||
// DMI CS register
|
||||
always @(posedge tck or negedge trst) begin
|
||||
if (!trst) begin
|
||||
dmi_hard_reset <= 1'b0;
|
||||
dmi_reset <= 1'b0;
|
||||
end else if (update_dr & dr_en[0]) begin
|
||||
dmi_hard_reset <= sr[17];
|
||||
dmi_reset <= sr[16];
|
||||
end else begin
|
||||
dmi_hard_reset <= 1'b0;
|
||||
dmi_reset <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// DR register
|
||||
always @(posedge tck or negedge trst) begin
|
||||
if (!trst) dr <= '0;
|
||||
else begin
|
||||
dmi_hard_reset <= 1'b0;
|
||||
dmi_reset <= 1'b0;
|
||||
if (update_dr & dr_en[1]) dr <= sr;
|
||||
else dr <= {dr[USER_DR_LENGTH-1:2], 2'b0};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// DR register
|
||||
always @ (posedge tck or negedge trst) begin
|
||||
if(!trst)
|
||||
dr <= '0;
|
||||
else begin
|
||||
if (update_dr & dr_en[1])
|
||||
dr <= sr;
|
||||
else
|
||||
dr <= {dr[USER_DR_LENGTH-1:2],2'b0};
|
||||
end
|
||||
end
|
||||
|
||||
assign {wr_addr, wr_data, wr_en, rd_en} = dr;
|
||||
assign {wr_addr, wr_data, wr_en, rd_en} = dr;
|
||||
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -16,124 +16,132 @@
|
|||
//********************************************************************************
|
||||
|
||||
module el2_mem
|
||||
import el2_pkg::*;
|
||||
import el2_pkg::*;
|
||||
#(
|
||||
`include "el2_param.vh"
|
||||
)
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst_l,
|
||||
input logic dccm_clk_override,
|
||||
input logic icm_clk_override,
|
||||
input logic dec_tlu_core_ecc_disable,
|
||||
`include "el2_param.vh"
|
||||
) (
|
||||
input logic clk,
|
||||
input logic rst_l,
|
||||
input logic dccm_clk_override,
|
||||
input logic icm_clk_override,
|
||||
input logic dec_tlu_core_ecc_disable,
|
||||
|
||||
//DCCM ports
|
||||
input logic dccm_wren,
|
||||
input logic dccm_rden,
|
||||
input logic [pt.DCCM_BITS-1:0] dccm_wr_addr_lo,
|
||||
input logic [pt.DCCM_BITS-1:0] dccm_wr_addr_hi,
|
||||
input logic [pt.DCCM_BITS-1:0] dccm_rd_addr_lo,
|
||||
input logic [pt.DCCM_BITS-1:0] dccm_rd_addr_hi,
|
||||
input logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_wr_data_lo,
|
||||
input logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_wr_data_hi,
|
||||
//DCCM ports
|
||||
input logic dccm_wren,
|
||||
input logic dccm_rden,
|
||||
input logic [ pt.DCCM_BITS-1:0] dccm_wr_addr_lo,
|
||||
input logic [ pt.DCCM_BITS-1:0] dccm_wr_addr_hi,
|
||||
input logic [ pt.DCCM_BITS-1:0] dccm_rd_addr_lo,
|
||||
input logic [ pt.DCCM_BITS-1:0] dccm_rd_addr_hi,
|
||||
input logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_wr_data_lo,
|
||||
input logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_wr_data_hi,
|
||||
|
||||
|
||||
output logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo,
|
||||
output logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi,
|
||||
output logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo,
|
||||
output logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi,
|
||||
|
||||
//`ifdef pt.DCCM_ENABLE
|
||||
input el2_dccm_ext_in_pkt_t [pt.DCCM_NUM_BANKS-1:0] dccm_ext_in_pkt,
|
||||
//`ifdef pt.DCCM_ENABLE
|
||||
input el2_dccm_ext_in_pkt_t [pt.DCCM_NUM_BANKS-1:0] dccm_ext_in_pkt,
|
||||
|
||||
//`endif
|
||||
//`endif
|
||||
|
||||
//ICCM ports
|
||||
input el2_ccm_ext_in_pkt_t [pt.ICCM_NUM_BANKS-1:0] iccm_ext_in_pkt,
|
||||
//ICCM ports
|
||||
input el2_ccm_ext_in_pkt_t [pt.ICCM_NUM_BANKS-1:0] iccm_ext_in_pkt,
|
||||
|
||||
input logic [pt.ICCM_BITS-1:1] iccm_rw_addr,
|
||||
input logic iccm_buf_correct_ecc, // ICCM is doing a single bit error correct cycle
|
||||
input logic iccm_correction_state, // ICCM is doing a single bit error correct cycle
|
||||
input logic iccm_wren,
|
||||
input logic iccm_rden,
|
||||
input logic [2:0] iccm_wr_size,
|
||||
input logic [77:0] iccm_wr_data,
|
||||
input logic [pt.ICCM_BITS-1:1] iccm_rw_addr,
|
||||
input logic iccm_buf_correct_ecc, // ICCM is doing a single bit error correct cycle
|
||||
input logic iccm_correction_state, // ICCM is doing a single bit error correct cycle
|
||||
input logic iccm_wren,
|
||||
input logic iccm_rden,
|
||||
input logic [2:0] iccm_wr_size,
|
||||
input logic [77:0] iccm_wr_data,
|
||||
|
||||
output logic [63:0] iccm_rd_data,
|
||||
output logic [77:0] iccm_rd_data_ecc,
|
||||
output logic [63:0] iccm_rd_data,
|
||||
output logic [77:0] iccm_rd_data_ecc,
|
||||
|
||||
// Icache and Itag Ports
|
||||
// Icache and Itag Ports
|
||||
|
||||
input logic [31:1] ic_rw_addr,
|
||||
input logic [pt.ICACHE_NUM_WAYS-1:0] ic_tag_valid,
|
||||
input logic [pt.ICACHE_NUM_WAYS-1:0] ic_wr_en,
|
||||
input logic ic_rd_en,
|
||||
input logic [63:0] ic_premux_data, // Premux data to be muxed with each way of the Icache.
|
||||
input logic ic_sel_premux_data, // Premux data sel
|
||||
input el2_ic_data_ext_in_pkt_t [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0] ic_data_ext_in_pkt,
|
||||
input el2_ic_tag_ext_in_pkt_t [pt.ICACHE_NUM_WAYS-1:0] ic_tag_ext_in_pkt,
|
||||
input logic [31:1] ic_rw_addr,
|
||||
input logic [pt.ICACHE_NUM_WAYS-1:0] ic_tag_valid,
|
||||
input logic [pt.ICACHE_NUM_WAYS-1:0] ic_wr_en,
|
||||
input logic ic_rd_en,
|
||||
input logic [63:0] ic_premux_data, // Premux data to be muxed with each way of the Icache.
|
||||
input logic ic_sel_premux_data, // Premux data sel
|
||||
input el2_ic_data_ext_in_pkt_t [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0] ic_data_ext_in_pkt,
|
||||
input el2_ic_tag_ext_in_pkt_t [pt.ICACHE_NUM_WAYS-1:0] ic_tag_ext_in_pkt,
|
||||
|
||||
input logic [pt.ICACHE_BANKS_WAY-1:0][70:0] ic_wr_data, // Data to fill to the Icache. With ECC
|
||||
input logic [70:0] ic_debug_wr_data, // Debug wr cache.
|
||||
output logic [70:0] ic_debug_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC
|
||||
input logic [pt.ICACHE_INDEX_HI:3] ic_debug_addr, // Read/Write addresss to the Icache.
|
||||
input logic ic_debug_rd_en, // Icache debug rd
|
||||
input logic ic_debug_wr_en, // Icache debug wr
|
||||
input logic ic_debug_tag_array, // Debug tag array
|
||||
input logic [pt.ICACHE_NUM_WAYS-1:0] ic_debug_way, // Debug way. Rd or Wr.
|
||||
input logic [pt.ICACHE_BANKS_WAY-1:0][70:0] ic_wr_data, // Data to fill to the Icache. With ECC
|
||||
input logic [70:0] ic_debug_wr_data, // Debug wr cache.
|
||||
output logic [70:0] ic_debug_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC
|
||||
input logic [pt.ICACHE_INDEX_HI:3] ic_debug_addr, // Read/Write addresss to the Icache.
|
||||
input logic ic_debug_rd_en, // Icache debug rd
|
||||
input logic ic_debug_wr_en, // Icache debug wr
|
||||
input logic ic_debug_tag_array, // Debug tag array
|
||||
input logic [pt.ICACHE_NUM_WAYS-1:0] ic_debug_way, // Debug way. Rd or Wr.
|
||||
|
||||
output logic [63:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC
|
||||
output logic [25:0] ictag_debug_rd_data,// Debug icache tag.
|
||||
output logic [63:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC
|
||||
output logic [25:0] ictag_debug_rd_data, // Debug icache tag.
|
||||
|
||||
|
||||
output logic [pt.ICACHE_BANKS_WAY-1:0] ic_eccerr, // ecc error per bank
|
||||
output logic [pt.ICACHE_BANKS_WAY-1:0] ic_parerr, // parity error per bank
|
||||
output logic [pt.ICACHE_NUM_WAYS-1:0] ic_rd_hit,
|
||||
output logic ic_tag_perr, // Icache Tag parity error
|
||||
output logic [pt.ICACHE_BANKS_WAY-1:0] ic_eccerr, // ecc error per bank
|
||||
output logic [pt.ICACHE_BANKS_WAY-1:0] ic_parerr, // parity error per bank
|
||||
output logic [ pt.ICACHE_NUM_WAYS-1:0] ic_rd_hit,
|
||||
output logic ic_tag_perr, // Icache Tag parity error
|
||||
|
||||
|
||||
input logic scan_mode
|
||||
input logic scan_mode
|
||||
|
||||
);
|
||||
|
||||
logic active_clk;
|
||||
rvoclkhdr active_cg ( .en(1'b1), .l1clk(active_clk), .* );
|
||||
|
||||
// DCCM Instantiation
|
||||
if (pt.DCCM_ENABLE == 1) begin: Gen_dccm_enable
|
||||
el2_lsu_dccm_mem #(.pt(pt)) dccm (
|
||||
.clk_override(dccm_clk_override),
|
||||
.*
|
||||
);
|
||||
end else begin: Gen_dccm_disable
|
||||
assign dccm_rd_data_lo = '0;
|
||||
assign dccm_rd_data_hi = '0;
|
||||
end
|
||||
|
||||
if ( pt.ICACHE_ENABLE ) begin: icache
|
||||
el2_ifu_ic_mem #(.pt(pt)) icm (
|
||||
.clk_override(icm_clk_override),
|
||||
logic active_clk;
|
||||
rvoclkhdr active_cg (
|
||||
.en(1'b1),
|
||||
.l1clk(active_clk),
|
||||
.*
|
||||
);
|
||||
end
|
||||
else begin
|
||||
assign ic_rd_hit[pt.ICACHE_NUM_WAYS-1:0] = '0;
|
||||
assign ic_tag_perr = '0 ;
|
||||
assign ic_rd_data = '0 ;
|
||||
assign ictag_debug_rd_data = '0 ;
|
||||
end // else: !if( pt.ICACHE_ENABLE )
|
||||
);
|
||||
|
||||
// DCCM Instantiation
|
||||
if (pt.DCCM_ENABLE == 1) begin : Gen_dccm_enable
|
||||
el2_lsu_dccm_mem #(
|
||||
.pt(pt)
|
||||
) dccm (
|
||||
.clk_override(dccm_clk_override),
|
||||
.*
|
||||
);
|
||||
end else begin : Gen_dccm_disable
|
||||
assign dccm_rd_data_lo = '0;
|
||||
assign dccm_rd_data_hi = '0;
|
||||
end
|
||||
|
||||
if (pt.ICACHE_ENABLE) begin : icache
|
||||
el2_ifu_ic_mem #(
|
||||
.pt(pt)
|
||||
) icm (
|
||||
.clk_override(icm_clk_override),
|
||||
.*
|
||||
);
|
||||
end else begin
|
||||
assign ic_rd_hit[pt.ICACHE_NUM_WAYS-1:0] = '0;
|
||||
assign ic_tag_perr = '0 ;
|
||||
assign ic_rd_data = '0 ;
|
||||
assign ictag_debug_rd_data = '0 ;
|
||||
end // else: !if( pt.ICACHE_ENABLE )
|
||||
|
||||
|
||||
|
||||
if (pt.ICCM_ENABLE) begin : iccm
|
||||
el2_ifu_iccm_mem #(.pt(pt)) iccm (.*,
|
||||
.clk_override(icm_clk_override),
|
||||
.iccm_rw_addr(iccm_rw_addr[pt.ICCM_BITS-1:1]),
|
||||
.iccm_rd_data(iccm_rd_data[63:0])
|
||||
);
|
||||
end
|
||||
else begin
|
||||
assign iccm_rd_data = '0 ;
|
||||
assign iccm_rd_data_ecc = '0 ;
|
||||
end
|
||||
if (pt.ICCM_ENABLE) begin : iccm
|
||||
el2_ifu_iccm_mem #(
|
||||
.pt(pt)
|
||||
) iccm (
|
||||
.*,
|
||||
.clk_override(icm_clk_override),
|
||||
.iccm_rw_addr(iccm_rw_addr[pt.ICCM_BITS-1:1]),
|
||||
.iccm_rd_data(iccm_rd_data[63:0])
|
||||
);
|
||||
end else begin
|
||||
assign iccm_rd_data = '0 ;
|
||||
assign iccm_rd_data_ecc = '0 ;
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -15,355 +15,437 @@
|
|||
|
||||
|
||||
module el2_exu
|
||||
import el2_pkg::*;
|
||||
import el2_pkg::*;
|
||||
#(
|
||||
`include "el2_param.vh"
|
||||
)
|
||||
(
|
||||
input logic clk, // Top level clock
|
||||
input logic rst_l, // Reset
|
||||
input logic scan_mode, // Scan control
|
||||
`include "el2_param.vh"
|
||||
) (
|
||||
input logic clk, // Top level clock
|
||||
input logic rst_l, // Reset
|
||||
input logic scan_mode, // Scan control
|
||||
|
||||
input logic [1:0] dec_data_en, // Clock enable {x,r}, one cycle pulse
|
||||
input logic [1:0] dec_ctl_en, // Clock enable {x,r}, two cycle pulse
|
||||
input logic [31:0] dbg_cmd_wrdata, // Debug data to primary I0 RS1
|
||||
input el2_alu_pkt_t i0_ap, // DEC alu {valid,predecodes}
|
||||
input logic [ 1:0] dec_data_en, // Clock enable {x,r}, one cycle pulse
|
||||
input logic [ 1:0] dec_ctl_en, // Clock enable {x,r}, two cycle pulse
|
||||
input logic [31:0] dbg_cmd_wrdata, // Debug data to primary I0 RS1
|
||||
input el2_alu_pkt_t i0_ap, // DEC alu {valid,predecodes}
|
||||
|
||||
input logic dec_debug_wdata_rs1_d, // Debug select to primary I0 RS1
|
||||
input logic dec_debug_wdata_rs1_d, // Debug select to primary I0 RS1
|
||||
|
||||
input el2_predict_pkt_t dec_i0_predict_p_d, // DEC branch predict packet
|
||||
input logic [pt.BHT_GHR_SIZE-1:0] i0_predict_fghr_d, // DEC predict fghr
|
||||
input logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] i0_predict_index_d, // DEC predict index
|
||||
input logic [pt.BTB_BTAG_SIZE-1:0] i0_predict_btag_d, // DEC predict branch tag
|
||||
input el2_predict_pkt_t dec_i0_predict_p_d, // DEC branch predict packet
|
||||
input logic [pt.BHT_GHR_SIZE-1:0] i0_predict_fghr_d, // DEC predict fghr
|
||||
input logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] i0_predict_index_d, // DEC predict index
|
||||
input logic [pt.BTB_BTAG_SIZE-1:0] i0_predict_btag_d, // DEC predict branch tag
|
||||
|
||||
input logic [31:0] lsu_result_m, // Load result M-stage
|
||||
input logic [31:0] lsu_nonblock_load_data, // nonblock load data
|
||||
input logic dec_i0_rs1_en_d, // Qualify GPR RS1 data
|
||||
input logic dec_i0_rs2_en_d, // Qualify GPR RS2 data
|
||||
input logic [31:0] gpr_i0_rs1_d, // DEC data gpr
|
||||
input logic [31:0] gpr_i0_rs2_d, // DEC data gpr
|
||||
input logic [31:0] dec_i0_immed_d, // DEC data immediate
|
||||
input logic [31:0] dec_i0_result_r, // DEC result in R-stage
|
||||
input logic [12:1] dec_i0_br_immed_d, // Branch immediate
|
||||
input logic dec_i0_alu_decode_d, // Valid to X-stage ALU
|
||||
input logic dec_i0_branch_d, // Branch in D-stage
|
||||
input logic dec_i0_select_pc_d, // PC select to RS1
|
||||
input logic [31:1] dec_i0_pc_d, // Instruction PC
|
||||
input logic [3:0] dec_i0_rs1_bypass_en_d, // DEC bypass select 1 - X-stage, 0 - dec bypass data
|
||||
input logic [3:0] dec_i0_rs2_bypass_en_d, // DEC bypass select 1 - X-stage, 0 - dec bypass data
|
||||
input logic dec_csr_ren_d, // CSR read select
|
||||
input logic [31:0] dec_csr_rddata_d, // CSR read data
|
||||
input logic [31:0] lsu_result_m, // Load result M-stage
|
||||
input logic [31:0] lsu_nonblock_load_data, // nonblock load data
|
||||
input logic dec_i0_rs1_en_d, // Qualify GPR RS1 data
|
||||
input logic dec_i0_rs2_en_d, // Qualify GPR RS2 data
|
||||
input logic [31:0] gpr_i0_rs1_d, // DEC data gpr
|
||||
input logic [31:0] gpr_i0_rs2_d, // DEC data gpr
|
||||
input logic [31:0] dec_i0_immed_d, // DEC data immediate
|
||||
input logic [31:0] dec_i0_result_r, // DEC result in R-stage
|
||||
input logic [12:1] dec_i0_br_immed_d, // Branch immediate
|
||||
input logic dec_i0_alu_decode_d, // Valid to X-stage ALU
|
||||
input logic dec_i0_branch_d, // Branch in D-stage
|
||||
input logic dec_i0_select_pc_d, // PC select to RS1
|
||||
input logic [31:1] dec_i0_pc_d, // Instruction PC
|
||||
input logic [3:0] dec_i0_rs1_bypass_en_d, // DEC bypass select 1 - X-stage, 0 - dec bypass data
|
||||
input logic [3:0] dec_i0_rs2_bypass_en_d, // DEC bypass select 1 - X-stage, 0 - dec bypass data
|
||||
input logic dec_csr_ren_d, // CSR read select
|
||||
input logic [31:0] dec_csr_rddata_d, // CSR read data
|
||||
|
||||
input logic dec_qual_lsu_d, // LSU instruction at D. Use to quiet LSU operands
|
||||
input el2_mul_pkt_t mul_p, // DEC {valid, operand signs, low, operand bypass}
|
||||
input el2_div_pkt_t div_p, // DEC {valid, unsigned, rem}
|
||||
input logic dec_div_cancel, // Cancel the divide operation
|
||||
input logic dec_qual_lsu_d, // LSU instruction at D. Use to quiet LSU operands
|
||||
input el2_mul_pkt_t mul_p, // DEC {valid, operand signs, low, operand bypass}
|
||||
input el2_div_pkt_t div_p, // DEC {valid, unsigned, rem}
|
||||
input logic dec_div_cancel, // Cancel the divide operation
|
||||
|
||||
input logic [31:1] pred_correct_npc_x, // DEC NPC for correctly predicted branch
|
||||
input logic [31:1] pred_correct_npc_x, // DEC NPC for correctly predicted branch
|
||||
|
||||
input logic dec_tlu_flush_lower_r, // Flush divide and secondary ALUs
|
||||
input logic [31:1] dec_tlu_flush_path_r, // Redirect target
|
||||
input logic dec_tlu_flush_lower_r, // Flush divide and secondary ALUs
|
||||
input logic [31:1] dec_tlu_flush_path_r, // Redirect target
|
||||
|
||||
|
||||
input logic dec_extint_stall, // External stall mux select
|
||||
input logic [31:2] dec_tlu_meihap, // External stall mux data
|
||||
input logic dec_extint_stall, // External stall mux select
|
||||
input logic [31:2] dec_tlu_meihap, // External stall mux data
|
||||
|
||||
|
||||
output logic [31:0] exu_lsu_rs1_d, // LSU operand
|
||||
output logic [31:0] exu_lsu_rs2_d, // LSU operand
|
||||
output logic [31:0] exu_lsu_rs1_d, // LSU operand
|
||||
output logic [31:0] exu_lsu_rs2_d, // LSU operand
|
||||
|
||||
output logic exu_flush_final, // Pipe is being flushed this cycle
|
||||
output logic [31:1] exu_flush_path_final, // Target for the oldest flush source
|
||||
output logic exu_flush_final, // Pipe is being flushed this cycle
|
||||
output logic [31:1] exu_flush_path_final, // Target for the oldest flush source
|
||||
|
||||
output logic [31:0] exu_i0_result_x, // Primary ALU result to DEC
|
||||
output logic [31:1] exu_i0_pc_x, // Primary PC result to DEC
|
||||
output logic [31:0] exu_csr_rs1_x, // RS1 source for a CSR instruction
|
||||
output logic [31:0] exu_i0_result_x, // Primary ALU result to DEC
|
||||
output logic [31:1] exu_i0_pc_x, // Primary PC result to DEC
|
||||
output logic [31:0] exu_csr_rs1_x, // RS1 source for a CSR instruction
|
||||
|
||||
output logic [31:1] exu_npc_r, // Divide NPC
|
||||
output logic [1:0] exu_i0_br_hist_r, // to DEC I0 branch history
|
||||
output logic exu_i0_br_error_r, // to DEC I0 branch error
|
||||
output logic exu_i0_br_start_error_r, // to DEC I0 branch start error
|
||||
output logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] exu_i0_br_index_r, // to DEC I0 branch index
|
||||
output logic exu_i0_br_valid_r, // to DEC I0 branch valid
|
||||
output logic exu_i0_br_mp_r, // to DEC I0 branch mispredict
|
||||
output logic exu_i0_br_middle_r, // to DEC I0 branch middle
|
||||
output logic [pt.BHT_GHR_SIZE-1:0] exu_i0_br_fghr_r, // to DEC I0 branch fghr
|
||||
output logic exu_i0_br_way_r, // to DEC I0 branch way
|
||||
output logic [31:1] exu_npc_r, // Divide NPC
|
||||
output logic [1:0] exu_i0_br_hist_r, // to DEC I0 branch history
|
||||
output logic exu_i0_br_error_r, // to DEC I0 branch error
|
||||
output logic exu_i0_br_start_error_r, // to DEC I0 branch start error
|
||||
output logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] exu_i0_br_index_r, // to DEC I0 branch index
|
||||
output logic exu_i0_br_valid_r, // to DEC I0 branch valid
|
||||
output logic exu_i0_br_mp_r, // to DEC I0 branch mispredict
|
||||
output logic exu_i0_br_middle_r, // to DEC I0 branch middle
|
||||
output logic [pt.BHT_GHR_SIZE-1:0] exu_i0_br_fghr_r, // to DEC I0 branch fghr
|
||||
output logic exu_i0_br_way_r, // to DEC I0 branch way
|
||||
|
||||
output el2_predict_pkt_t exu_mp_pkt, // Mispredict branch packet
|
||||
output logic [pt.BHT_GHR_SIZE-1:0] exu_mp_eghr, // Mispredict global history
|
||||
output logic [pt.BHT_GHR_SIZE-1:0] exu_mp_fghr, // Mispredict fghr
|
||||
output logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] exu_mp_index, // Mispredict index
|
||||
output logic [pt.BTB_BTAG_SIZE-1:0] exu_mp_btag, // Mispredict btag
|
||||
output el2_predict_pkt_t exu_mp_pkt, // Mispredict branch packet
|
||||
output logic [pt.BHT_GHR_SIZE-1:0] exu_mp_eghr, // Mispredict global history
|
||||
output logic [pt.BHT_GHR_SIZE-1:0] exu_mp_fghr, // Mispredict fghr
|
||||
output logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] exu_mp_index, // Mispredict index
|
||||
output logic [pt.BTB_BTAG_SIZE-1:0] exu_mp_btag, // Mispredict btag
|
||||
|
||||
|
||||
output logic exu_pmu_i0_br_misp, // to PMU - I0 E4 branch mispredict
|
||||
output logic exu_pmu_i0_br_ataken, // to PMU - I0 E4 taken
|
||||
output logic exu_pmu_i0_pc4, // to PMU - I0 E4 PC
|
||||
output logic exu_pmu_i0_br_misp, // to PMU - I0 E4 branch mispredict
|
||||
output logic exu_pmu_i0_br_ataken, // to PMU - I0 E4 taken
|
||||
output logic exu_pmu_i0_pc4, // to PMU - I0 E4 PC
|
||||
|
||||
|
||||
output logic [31:0] exu_div_result, // Divide result
|
||||
output logic exu_div_wren // Divide write enable to GPR
|
||||
output logic [31:0] exu_div_result, // Divide result
|
||||
output logic exu_div_wren // Divide write enable to GPR
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
logic [31:0] i0_rs1_bypass_data_d;
|
||||
logic [31:0] i0_rs2_bypass_data_d;
|
||||
logic i0_rs1_bypass_en_d;
|
||||
logic i0_rs2_bypass_en_d;
|
||||
logic [31:0] i0_rs1_d, i0_rs2_d;
|
||||
logic [31:0] muldiv_rs1_d;
|
||||
logic [31:1] pred_correct_npc_r;
|
||||
logic i0_pred_correct_upper_r;
|
||||
logic [31:1] i0_flush_path_upper_r;
|
||||
logic x_data_en, x_data_en_q1, x_data_en_q2, r_data_en, r_data_en_q2;
|
||||
logic x_ctl_en, r_ctl_en;
|
||||
|
||||
logic [pt.BHT_GHR_SIZE-1:0] ghr_d_ns, ghr_d;
|
||||
logic [pt.BHT_GHR_SIZE-1:0] ghr_x_ns, ghr_x;
|
||||
logic i0_taken_d;
|
||||
logic i0_taken_x;
|
||||
logic i0_valid_d;
|
||||
logic i0_valid_x;
|
||||
logic [pt.BHT_GHR_SIZE-1:0] after_flush_eghr;
|
||||
|
||||
el2_predict_pkt_t final_predict_mp;
|
||||
el2_predict_pkt_t i0_predict_newp_d;
|
||||
|
||||
logic flush_in_d;
|
||||
logic [ 31:0] alu_result_x;
|
||||
|
||||
logic mul_valid_x;
|
||||
logic [ 31:0] mul_result_x;
|
||||
|
||||
el2_predict_pkt_t i0_pp_r;
|
||||
|
||||
logic i0_flush_upper_d;
|
||||
logic [ 31:1] i0_flush_path_d;
|
||||
el2_predict_pkt_t i0_predict_p_d;
|
||||
logic i0_pred_correct_upper_d;
|
||||
|
||||
logic i0_flush_upper_x;
|
||||
logic [ 31:1] i0_flush_path_x;
|
||||
el2_predict_pkt_t i0_predict_p_x;
|
||||
logic i0_pred_correct_upper_x;
|
||||
logic i0_branch_x;
|
||||
|
||||
localparam PREDPIPESIZE = pt.BTB_ADDR_HI-pt.BTB_ADDR_LO+1+pt.BHT_GHR_SIZE+pt.BTB_BTAG_SIZE;
|
||||
logic [PREDPIPESIZE-1:0] predpipe_d, predpipe_x, predpipe_r, final_predpipe_mp;
|
||||
|
||||
|
||||
|
||||
|
||||
rvdffpcie #(31) i_flush_path_x_ff (
|
||||
.*,
|
||||
.clk (clk),
|
||||
.en (x_data_en),
|
||||
.din (i0_flush_path_d[31:1]),
|
||||
.dout(i0_flush_path_x[31:1])
|
||||
);
|
||||
rvdffe #(32) i_csr_rs1_x_ff (
|
||||
.*,
|
||||
.clk (clk),
|
||||
.en (x_data_en_q1),
|
||||
.din (i0_rs1_d[31:0]),
|
||||
.dout(exu_csr_rs1_x[31:0])
|
||||
);
|
||||
rvdffppe #($bits(
|
||||
el2_predict_pkt_t
|
||||
)) i_predictpacket_x_ff (
|
||||
.*,
|
||||
.clk (clk),
|
||||
.en (x_data_en),
|
||||
.din (i0_predict_p_d),
|
||||
.dout(i0_predict_p_x)
|
||||
);
|
||||
rvdffe #(PREDPIPESIZE) i_predpipe_x_ff (
|
||||
.*,
|
||||
.clk (clk),
|
||||
.en (x_data_en_q2),
|
||||
.din (predpipe_d),
|
||||
.dout(predpipe_x)
|
||||
);
|
||||
rvdffe #(PREDPIPESIZE) i_predpipe_r_ff (
|
||||
.*,
|
||||
.clk (clk),
|
||||
.en (r_data_en_q2),
|
||||
.din (predpipe_x),
|
||||
.dout(predpipe_r)
|
||||
);
|
||||
|
||||
rvdffe #(4 + pt.BHT_GHR_SIZE) i_x_ff (
|
||||
.*,
|
||||
.clk(clk),
|
||||
.en(x_ctl_en),
|
||||
.din({
|
||||
i0_valid_d,
|
||||
i0_taken_d,
|
||||
i0_flush_upper_d,
|
||||
i0_pred_correct_upper_d,
|
||||
ghr_x_ns[pt.BHT_GHR_SIZE-1:0]
|
||||
}),
|
||||
.dout({
|
||||
i0_valid_x,
|
||||
i0_taken_x,
|
||||
i0_flush_upper_x,
|
||||
i0_pred_correct_upper_x,
|
||||
ghr_x[pt.BHT_GHR_SIZE-1:0]
|
||||
})
|
||||
);
|
||||
|
||||
rvdffppe #($bits(
|
||||
el2_predict_pkt_t
|
||||
) + 1) i_r_ff0 (
|
||||
.*,
|
||||
.clk (clk),
|
||||
.en (r_ctl_en),
|
||||
.din ({i0_pred_correct_upper_x, i0_predict_p_x}),
|
||||
.dout({i0_pred_correct_upper_r, i0_pp_r})
|
||||
);
|
||||
|
||||
rvdffpcie #(31) i_flush_r_ff (
|
||||
.*,
|
||||
.clk (clk),
|
||||
.en (r_data_en),
|
||||
.din (i0_flush_path_x[31:1]),
|
||||
.dout(i0_flush_path_upper_r[31:1])
|
||||
);
|
||||
rvdffpcie #(31) i_npc_r_ff (
|
||||
.*,
|
||||
.clk (clk),
|
||||
.en (r_data_en),
|
||||
.din (pred_correct_npc_x[31:1]),
|
||||
.dout(pred_correct_npc_r[31:1])
|
||||
);
|
||||
|
||||
rvdffie #(pt.BHT_GHR_SIZE + 2, 1) i_misc_ff (
|
||||
.*,
|
||||
.clk (clk),
|
||||
.din ({ghr_d_ns[pt.BHT_GHR_SIZE-1:0], mul_p.valid, dec_i0_branch_d}),
|
||||
.dout({ghr_d[pt.BHT_GHR_SIZE-1:0], mul_valid_x, i0_branch_x})
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
logic [31:0] i0_rs1_bypass_data_d;
|
||||
logic [31:0] i0_rs2_bypass_data_d;
|
||||
logic i0_rs1_bypass_en_d;
|
||||
logic i0_rs2_bypass_en_d;
|
||||
logic [31:0] i0_rs1_d, i0_rs2_d;
|
||||
logic [31:0] muldiv_rs1_d;
|
||||
logic [31:1] pred_correct_npc_r;
|
||||
logic i0_pred_correct_upper_r;
|
||||
logic [31:1] i0_flush_path_upper_r;
|
||||
logic x_data_en, x_data_en_q1, x_data_en_q2, r_data_en, r_data_en_q2;
|
||||
logic x_ctl_en, r_ctl_en;
|
||||
|
||||
logic [pt.BHT_GHR_SIZE-1:0] ghr_d_ns, ghr_d;
|
||||
logic [pt.BHT_GHR_SIZE-1:0] ghr_x_ns, ghr_x;
|
||||
logic i0_taken_d;
|
||||
logic i0_taken_x;
|
||||
logic i0_valid_d;
|
||||
logic i0_valid_x;
|
||||
logic [pt.BHT_GHR_SIZE-1:0] after_flush_eghr;
|
||||
|
||||
el2_predict_pkt_t final_predict_mp;
|
||||
el2_predict_pkt_t i0_predict_newp_d;
|
||||
|
||||
logic flush_in_d;
|
||||
logic [31:0] alu_result_x;
|
||||
|
||||
logic mul_valid_x;
|
||||
logic [31:0] mul_result_x;
|
||||
|
||||
el2_predict_pkt_t i0_pp_r;
|
||||
|
||||
logic i0_flush_upper_d;
|
||||
logic [31:1] i0_flush_path_d;
|
||||
el2_predict_pkt_t i0_predict_p_d;
|
||||
logic i0_pred_correct_upper_d;
|
||||
|
||||
logic i0_flush_upper_x;
|
||||
logic [31:1] i0_flush_path_x;
|
||||
el2_predict_pkt_t i0_predict_p_x;
|
||||
logic i0_pred_correct_upper_x;
|
||||
logic i0_branch_x;
|
||||
|
||||
localparam PREDPIPESIZE = pt.BTB_ADDR_HI-pt.BTB_ADDR_LO+1+pt.BHT_GHR_SIZE+pt.BTB_BTAG_SIZE;
|
||||
logic [PREDPIPESIZE-1:0] predpipe_d, predpipe_x, predpipe_r, final_predpipe_mp;
|
||||
assign predpipe_d[PREDPIPESIZE-1:0] = {i0_predict_fghr_d, i0_predict_index_d, i0_predict_btag_d};
|
||||
|
||||
|
||||
assign i0_rs1_bypass_en_d = dec_i0_rs1_bypass_en_d[0] | dec_i0_rs1_bypass_en_d[1] | dec_i0_rs1_bypass_en_d[2] | dec_i0_rs1_bypass_en_d[3];
|
||||
assign i0_rs2_bypass_en_d = dec_i0_rs2_bypass_en_d[0] | dec_i0_rs2_bypass_en_d[1] | dec_i0_rs2_bypass_en_d[2] | dec_i0_rs2_bypass_en_d[3];
|
||||
|
||||
|
||||
rvdffpcie #(31) i_flush_path_x_ff (.*, .clk(clk), .en ( x_data_en ), .din ( i0_flush_path_d[31:1] ), .dout( i0_flush_path_x[31:1] ) );
|
||||
rvdffe #(32) i_csr_rs1_x_ff (.*, .clk(clk), .en ( x_data_en_q1 ), .din ( i0_rs1_d[31:0] ), .dout( exu_csr_rs1_x[31:0] ) );
|
||||
rvdffppe #($bits(el2_predict_pkt_t)) i_predictpacket_x_ff (.*, .clk(clk), .en ( x_data_en ), .din ( i0_predict_p_d ), .dout( i0_predict_p_x ) );
|
||||
rvdffe #(PREDPIPESIZE) i_predpipe_x_ff (.*, .clk(clk), .en ( x_data_en_q2 ), .din ( predpipe_d ), .dout( predpipe_x ) );
|
||||
rvdffe #(PREDPIPESIZE) i_predpipe_r_ff (.*, .clk(clk), .en ( r_data_en_q2 ), .din ( predpipe_x ), .dout( predpipe_r ) );
|
||||
|
||||
rvdffe #(4+pt.BHT_GHR_SIZE) i_x_ff (.*, .clk(clk), .en ( x_ctl_en ), .din ({i0_valid_d,i0_taken_d,i0_flush_upper_d,i0_pred_correct_upper_d,ghr_x_ns[pt.BHT_GHR_SIZE-1:0]} ),
|
||||
.dout({i0_valid_x,i0_taken_x,i0_flush_upper_x,i0_pred_correct_upper_x,ghr_x[pt.BHT_GHR_SIZE-1:0]} ) );
|
||||
|
||||
rvdffppe #($bits(el2_predict_pkt_t)+1) i_r_ff0 (.*, .clk(clk), .en ( r_ctl_en ), .din ({i0_pred_correct_upper_x, i0_predict_p_x}),
|
||||
.dout({i0_pred_correct_upper_r, i0_pp_r }) );
|
||||
|
||||
rvdffpcie #(31) i_flush_r_ff (.*, .clk(clk), .en ( r_data_en ), .din ( i0_flush_path_x[31:1] ), .dout( i0_flush_path_upper_r[31:1]) );
|
||||
rvdffpcie #(31) i_npc_r_ff (.*, .clk(clk), .en ( r_data_en ), .din ( pred_correct_npc_x[31:1] ), .dout( pred_correct_npc_r[31:1] ) );
|
||||
|
||||
rvdffie #(pt.BHT_GHR_SIZE+2,1) i_misc_ff (.*, .clk(clk), .din ({ghr_d_ns[pt.BHT_GHR_SIZE-1:0], mul_p.valid, dec_i0_branch_d}),
|
||||
.dout({ghr_d[pt.BHT_GHR_SIZE-1:0] , mul_valid_x, i0_branch_x}) );
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
assign predpipe_d[PREDPIPESIZE-1:0]
|
||||
= {i0_predict_fghr_d, i0_predict_index_d, i0_predict_btag_d};
|
||||
|
||||
|
||||
assign i0_rs1_bypass_en_d = dec_i0_rs1_bypass_en_d[0] | dec_i0_rs1_bypass_en_d[1] | dec_i0_rs1_bypass_en_d[2] | dec_i0_rs1_bypass_en_d[3];
|
||||
assign i0_rs2_bypass_en_d = dec_i0_rs2_bypass_en_d[0] | dec_i0_rs2_bypass_en_d[1] | dec_i0_rs2_bypass_en_d[2] | dec_i0_rs2_bypass_en_d[3];
|
||||
|
||||
assign i0_rs1_bypass_data_d[31:0]=({32{dec_i0_rs1_bypass_en_d[0]}} & dec_i0_result_r[31:0] ) |
|
||||
assign i0_rs1_bypass_data_d[31:0]=({32{dec_i0_rs1_bypass_en_d[0]}} & dec_i0_result_r[31:0] ) |
|
||||
({32{dec_i0_rs1_bypass_en_d[1]}} & lsu_result_m[31:0] ) |
|
||||
({32{dec_i0_rs1_bypass_en_d[2]}} & exu_i0_result_x[31:0] ) |
|
||||
({32{dec_i0_rs1_bypass_en_d[3]}} & lsu_nonblock_load_data[31:0]);
|
||||
|
||||
assign i0_rs2_bypass_data_d[31:0]=({32{dec_i0_rs2_bypass_en_d[0]}} & dec_i0_result_r[31:0] ) |
|
||||
assign i0_rs2_bypass_data_d[31:0]=({32{dec_i0_rs2_bypass_en_d[0]}} & dec_i0_result_r[31:0] ) |
|
||||
({32{dec_i0_rs2_bypass_en_d[1]}} & lsu_result_m[31:0] ) |
|
||||
({32{dec_i0_rs2_bypass_en_d[2]}} & exu_i0_result_x[31:0] ) |
|
||||
({32{dec_i0_rs2_bypass_en_d[3]}} & lsu_nonblock_load_data[31:0]);
|
||||
|
||||
|
||||
assign i0_rs1_d[31:0] = ({32{ i0_rs1_bypass_en_d }} & i0_rs1_bypass_data_d[31:0]) |
|
||||
assign i0_rs1_d[31:0] = ({32{ i0_rs1_bypass_en_d }} & i0_rs1_bypass_data_d[31:0]) |
|
||||
({32{~i0_rs1_bypass_en_d & dec_i0_select_pc_d }} & {dec_i0_pc_d[31:1],1'b0} ) | // for jal's
|
||||
({32{~i0_rs1_bypass_en_d & dec_debug_wdata_rs1_d }} & dbg_cmd_wrdata[31:0] ) |
|
||||
({32{~i0_rs1_bypass_en_d & ~dec_debug_wdata_rs1_d & dec_i0_rs1_en_d}} & gpr_i0_rs1_d[31:0] );
|
||||
|
||||
assign i0_rs2_d[31:0] = ({32{~i0_rs2_bypass_en_d & dec_i0_rs2_en_d}} & gpr_i0_rs2_d[31:0] ) |
|
||||
assign i0_rs2_d[31:0] = ({32{~i0_rs2_bypass_en_d & dec_i0_rs2_en_d}} & gpr_i0_rs2_d[31:0] ) |
|
||||
({32{~i0_rs2_bypass_en_d }} & dec_i0_immed_d[31:0] ) |
|
||||
({32{ i0_rs2_bypass_en_d }} & i0_rs2_bypass_data_d[31:0]);
|
||||
|
||||
|
||||
assign exu_lsu_rs1_d[31:0] = ({32{~i0_rs1_bypass_en_d & ~dec_extint_stall & dec_i0_rs1_en_d & dec_qual_lsu_d}} & gpr_i0_rs1_d[31:0] ) |
|
||||
assign exu_lsu_rs1_d[31:0] = ({32{~i0_rs1_bypass_en_d & ~dec_extint_stall & dec_i0_rs1_en_d & dec_qual_lsu_d}} & gpr_i0_rs1_d[31:0] ) |
|
||||
({32{ i0_rs1_bypass_en_d & ~dec_extint_stall & dec_qual_lsu_d}} & i0_rs1_bypass_data_d[31:0]) |
|
||||
({32{ dec_extint_stall & dec_qual_lsu_d}} & {dec_tlu_meihap[31:2],2'b0});
|
||||
|
||||
assign exu_lsu_rs2_d[31:0] = ({32{~i0_rs2_bypass_en_d & ~dec_extint_stall & dec_i0_rs2_en_d & dec_qual_lsu_d}} & gpr_i0_rs2_d[31:0] ) |
|
||||
assign exu_lsu_rs2_d[31:0] = ({32{~i0_rs2_bypass_en_d & ~dec_extint_stall & dec_i0_rs2_en_d & dec_qual_lsu_d}} & gpr_i0_rs2_d[31:0] ) |
|
||||
({32{ i0_rs2_bypass_en_d & ~dec_extint_stall & dec_qual_lsu_d}} & i0_rs2_bypass_data_d[31:0]);
|
||||
|
||||
|
||||
assign muldiv_rs1_d[31:0] = ({32{~i0_rs1_bypass_en_d & dec_i0_rs1_en_d}} & gpr_i0_rs1_d[31:0] ) |
|
||||
assign muldiv_rs1_d[31:0] = ({32{~i0_rs1_bypass_en_d & dec_i0_rs1_en_d}} & gpr_i0_rs1_d[31:0] ) |
|
||||
({32{ i0_rs1_bypass_en_d }} & i0_rs1_bypass_data_d[31:0]);
|
||||
|
||||
|
||||
assign x_data_en = dec_data_en[1];
|
||||
assign x_data_en_q1 = dec_data_en[1] & dec_csr_ren_d;
|
||||
assign x_data_en_q2 = dec_data_en[1] & dec_i0_branch_d;
|
||||
assign r_data_en = dec_data_en[0];
|
||||
assign r_data_en_q2 = dec_data_en[0] & i0_branch_x;
|
||||
assign x_ctl_en = dec_ctl_en[1];
|
||||
assign r_ctl_en = dec_ctl_en[0];
|
||||
assign x_data_en = dec_data_en[1];
|
||||
assign x_data_en_q1 = dec_data_en[1] & dec_csr_ren_d;
|
||||
assign x_data_en_q2 = dec_data_en[1] & dec_i0_branch_d;
|
||||
assign r_data_en = dec_data_en[0];
|
||||
assign r_data_en_q2 = dec_data_en[0] & i0_branch_x;
|
||||
assign x_ctl_en = dec_ctl_en[1];
|
||||
assign r_ctl_en = dec_ctl_en[0];
|
||||
|
||||
|
||||
|
||||
|
||||
el2_exu_alu_ctl #(.pt(pt)) i_alu (.*,
|
||||
.enable ( x_data_en ), // I
|
||||
.pp_in ( i0_predict_newp_d ), // I
|
||||
.valid_in ( dec_i0_alu_decode_d ), // I
|
||||
.flush_upper_x ( i0_flush_upper_x ), // I
|
||||
.flush_lower_r ( dec_tlu_flush_lower_r ), // I
|
||||
.a_in ( i0_rs1_d[31:0] ), // I
|
||||
.b_in ( i0_rs2_d[31:0] ), // I
|
||||
.pc_in ( dec_i0_pc_d[31:1] ), // I
|
||||
.brimm_in ( dec_i0_br_immed_d[12:1] ), // I
|
||||
.ap ( i0_ap ), // I
|
||||
.csr_ren_in ( dec_csr_ren_d ), // I
|
||||
.csr_rddata_in ( dec_csr_rddata_d[31:0] ), // I
|
||||
.result_ff ( alu_result_x[31:0] ), // O
|
||||
.flush_upper_out ( i0_flush_upper_d ), // O
|
||||
.flush_final_out ( exu_flush_final ), // O
|
||||
.flush_path_out ( i0_flush_path_d[31:1] ), // O
|
||||
.predict_p_out ( i0_predict_p_d ), // O
|
||||
.pred_correct_out ( i0_pred_correct_upper_d ), // O
|
||||
.pc_ff ( exu_i0_pc_x[31:1] )); // O
|
||||
el2_exu_alu_ctl #(
|
||||
.pt(pt)
|
||||
) i_alu (
|
||||
.*,
|
||||
.enable (x_data_en), // I
|
||||
.pp_in (i0_predict_newp_d), // I
|
||||
.valid_in (dec_i0_alu_decode_d), // I
|
||||
.flush_upper_x (i0_flush_upper_x), // I
|
||||
.flush_lower_r (dec_tlu_flush_lower_r), // I
|
||||
.a_in (i0_rs1_d[31:0]), // I
|
||||
.b_in (i0_rs2_d[31:0]), // I
|
||||
.pc_in (dec_i0_pc_d[31:1]), // I
|
||||
.brimm_in (dec_i0_br_immed_d[12:1]), // I
|
||||
.ap (i0_ap), // I
|
||||
.csr_ren_in (dec_csr_ren_d), // I
|
||||
.csr_rddata_in (dec_csr_rddata_d[31:0]), // I
|
||||
.result_ff (alu_result_x[31:0]), // O
|
||||
.flush_upper_out (i0_flush_upper_d), // O
|
||||
.flush_final_out (exu_flush_final), // O
|
||||
.flush_path_out (i0_flush_path_d[31:1]), // O
|
||||
.predict_p_out (i0_predict_p_d), // O
|
||||
.pred_correct_out(i0_pred_correct_upper_d), // O
|
||||
.pc_ff (exu_i0_pc_x[31:1])
|
||||
); // O
|
||||
|
||||
|
||||
|
||||
el2_exu_mul_ctl #(.pt(pt)) i_mul (.*,
|
||||
.mul_p ( mul_p & {$bits(el2_mul_pkt_t){mul_p.valid}} ), // I
|
||||
.rs1_in ( muldiv_rs1_d[31:0] & {32{mul_p.valid}} ), // I
|
||||
.rs2_in ( i0_rs2_d[31:0] & {32{mul_p.valid}} ), // I
|
||||
.result_x ( mul_result_x[31:0] )); // O
|
||||
el2_exu_mul_ctl #(
|
||||
.pt(pt)
|
||||
) i_mul (
|
||||
.*,
|
||||
.mul_p (mul_p & {$bits(el2_mul_pkt_t) {mul_p.valid}}), // I
|
||||
.rs1_in (muldiv_rs1_d[31:0] & {32{mul_p.valid}}), // I
|
||||
.rs2_in (i0_rs2_d[31:0] & {32{mul_p.valid}}), // I
|
||||
.result_x(mul_result_x[31:0])
|
||||
); // O
|
||||
|
||||
|
||||
|
||||
el2_exu_div_ctl #(.pt(pt)) i_div (.*,
|
||||
.cancel ( dec_div_cancel ), // I
|
||||
.dp ( div_p ), // I
|
||||
.dividend ( muldiv_rs1_d[31:0] ), // I
|
||||
.divisor ( i0_rs2_d[31:0] ), // I
|
||||
.finish_dly ( exu_div_wren ), // O
|
||||
.out ( exu_div_result[31:0] )); // O
|
||||
el2_exu_div_ctl #(
|
||||
.pt(pt)
|
||||
) i_div (
|
||||
.*,
|
||||
.cancel (dec_div_cancel), // I
|
||||
.dp (div_p), // I
|
||||
.dividend (muldiv_rs1_d[31:0]), // I
|
||||
.divisor (i0_rs2_d[31:0]), // I
|
||||
.finish_dly(exu_div_wren), // O
|
||||
.out (exu_div_result[31:0])
|
||||
); // O
|
||||
|
||||
|
||||
|
||||
assign exu_i0_result_x[31:0] = (mul_valid_x) ? mul_result_x[31:0] : alu_result_x[31:0];
|
||||
assign exu_i0_result_x[31:0] = (mul_valid_x) ? mul_result_x[31:0] : alu_result_x[31:0];
|
||||
|
||||
|
||||
|
||||
|
||||
always_comb begin
|
||||
i0_predict_newp_d = dec_i0_predict_p_d;
|
||||
i0_predict_newp_d.boffset = dec_i0_pc_d[1]; // from the start of inst
|
||||
end
|
||||
always_comb begin
|
||||
i0_predict_newp_d = dec_i0_predict_p_d;
|
||||
i0_predict_newp_d.boffset = dec_i0_pc_d[1]; // from the start of inst
|
||||
end
|
||||
|
||||
|
||||
assign exu_pmu_i0_br_misp = i0_pp_r.misp;
|
||||
assign exu_pmu_i0_br_ataken = i0_pp_r.ataken;
|
||||
assign exu_pmu_i0_pc4 = i0_pp_r.pc4;
|
||||
assign exu_pmu_i0_br_misp = i0_pp_r.misp;
|
||||
assign exu_pmu_i0_br_ataken = i0_pp_r.ataken;
|
||||
assign exu_pmu_i0_pc4 = i0_pp_r.pc4;
|
||||
|
||||
|
||||
assign i0_valid_d = i0_predict_p_d.valid & dec_i0_alu_decode_d & ~dec_tlu_flush_lower_r;
|
||||
assign i0_taken_d = (i0_predict_p_d.ataken & dec_i0_alu_decode_d);
|
||||
assign i0_valid_d = i0_predict_p_d.valid & dec_i0_alu_decode_d & ~dec_tlu_flush_lower_r;
|
||||
assign i0_taken_d = (i0_predict_p_d.ataken & dec_i0_alu_decode_d);
|
||||
|
||||
if(pt.BTB_ENABLE==1) begin
|
||||
// maintain GHR at D
|
||||
assign ghr_d_ns[pt.BHT_GHR_SIZE-1:0]
|
||||
if (pt.BTB_ENABLE == 1) begin
|
||||
// maintain GHR at D
|
||||
assign ghr_d_ns[pt.BHT_GHR_SIZE-1:0]
|
||||
= ({pt.BHT_GHR_SIZE{~dec_tlu_flush_lower_r & i0_valid_d}} & {ghr_d[pt.BHT_GHR_SIZE-2:0], i0_taken_d}) |
|
||||
({pt.BHT_GHR_SIZE{~dec_tlu_flush_lower_r & ~i0_valid_d}} & ghr_d[pt.BHT_GHR_SIZE-1:0] ) |
|
||||
({pt.BHT_GHR_SIZE{ dec_tlu_flush_lower_r }} & ghr_x[pt.BHT_GHR_SIZE-1:0] );
|
||||
|
||||
// maintain GHR at X
|
||||
assign ghr_x_ns[pt.BHT_GHR_SIZE-1:0]
|
||||
// maintain GHR at X
|
||||
assign ghr_x_ns[pt.BHT_GHR_SIZE-1:0]
|
||||
= ({pt.BHT_GHR_SIZE{ i0_valid_x}} & {ghr_x[pt.BHT_GHR_SIZE-2:0], i0_taken_x}) |
|
||||
({pt.BHT_GHR_SIZE{~i0_valid_x}} & ghr_x[pt.BHT_GHR_SIZE-1:0] ) ;
|
||||
|
||||
|
||||
assign exu_i0_br_valid_r = i0_pp_r.valid;
|
||||
assign exu_i0_br_mp_r = i0_pp_r.misp;
|
||||
assign exu_i0_br_way_r = i0_pp_r.way;
|
||||
assign exu_i0_br_hist_r[1:0] = {2{i0_pp_r.valid}} & i0_pp_r.hist[1:0];
|
||||
assign exu_i0_br_error_r = i0_pp_r.br_error;
|
||||
assign exu_i0_br_middle_r = i0_pp_r.pc4 ^ i0_pp_r.boffset;
|
||||
assign exu_i0_br_start_error_r = i0_pp_r.br_start_error;
|
||||
assign exu_i0_br_valid_r = i0_pp_r.valid;
|
||||
assign exu_i0_br_mp_r = i0_pp_r.misp;
|
||||
assign exu_i0_br_way_r = i0_pp_r.way;
|
||||
assign exu_i0_br_hist_r[1:0] = {2{i0_pp_r.valid}} & i0_pp_r.hist[1:0];
|
||||
assign exu_i0_br_error_r = i0_pp_r.br_error;
|
||||
assign exu_i0_br_middle_r = i0_pp_r.pc4 ^ i0_pp_r.boffset;
|
||||
assign exu_i0_br_start_error_r = i0_pp_r.br_start_error;
|
||||
|
||||
assign {exu_i0_br_fghr_r[pt.BHT_GHR_SIZE-1:0],
|
||||
assign {exu_i0_br_fghr_r[pt.BHT_GHR_SIZE-1:0],
|
||||
exu_i0_br_index_r[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]}= predpipe_r[PREDPIPESIZE-1:pt.BTB_BTAG_SIZE];
|
||||
|
||||
|
||||
assign final_predict_mp = (i0_flush_upper_x) ? i0_predict_p_x : '0;
|
||||
assign final_predict_mp = (i0_flush_upper_x) ? i0_predict_p_x : '0;
|
||||
|
||||
assign final_predpipe_mp[PREDPIPESIZE-1:0] = (i0_flush_upper_x) ? predpipe_x : '0;
|
||||
assign final_predpipe_mp[PREDPIPESIZE-1:0] = (i0_flush_upper_x) ? predpipe_x : '0;
|
||||
|
||||
assign after_flush_eghr[pt.BHT_GHR_SIZE-1:0] = (i0_flush_upper_x & ~dec_tlu_flush_lower_r) ? ghr_d[pt.BHT_GHR_SIZE-1:0] : ghr_x[pt.BHT_GHR_SIZE-1:0];
|
||||
assign after_flush_eghr[pt.BHT_GHR_SIZE-1:0] = (i0_flush_upper_x & ~dec_tlu_flush_lower_r) ? ghr_d[pt.BHT_GHR_SIZE-1:0] : ghr_x[pt.BHT_GHR_SIZE-1:0];
|
||||
|
||||
|
||||
assign exu_mp_pkt.valid = final_predict_mp.valid;
|
||||
assign exu_mp_pkt.way = final_predict_mp.way;
|
||||
assign exu_mp_pkt.misp = final_predict_mp.misp;
|
||||
assign exu_mp_pkt.pcall = final_predict_mp.pcall;
|
||||
assign exu_mp_pkt.pja = final_predict_mp.pja;
|
||||
assign exu_mp_pkt.pret = final_predict_mp.pret;
|
||||
assign exu_mp_pkt.ataken = final_predict_mp.ataken;
|
||||
assign exu_mp_pkt.boffset = final_predict_mp.boffset;
|
||||
assign exu_mp_pkt.pc4 = final_predict_mp.pc4;
|
||||
assign exu_mp_pkt.hist[1:0] = final_predict_mp.hist[1:0];
|
||||
assign exu_mp_pkt.toffset[11:0] = final_predict_mp.toffset[11:0];
|
||||
assign exu_mp_pkt.valid = final_predict_mp.valid;
|
||||
assign exu_mp_pkt.way = final_predict_mp.way;
|
||||
assign exu_mp_pkt.misp = final_predict_mp.misp;
|
||||
assign exu_mp_pkt.pcall = final_predict_mp.pcall;
|
||||
assign exu_mp_pkt.pja = final_predict_mp.pja;
|
||||
assign exu_mp_pkt.pret = final_predict_mp.pret;
|
||||
assign exu_mp_pkt.ataken = final_predict_mp.ataken;
|
||||
assign exu_mp_pkt.boffset = final_predict_mp.boffset;
|
||||
assign exu_mp_pkt.pc4 = final_predict_mp.pc4;
|
||||
assign exu_mp_pkt.hist[1:0] = final_predict_mp.hist[1:0];
|
||||
assign exu_mp_pkt.toffset[11:0] = final_predict_mp.toffset[11:0];
|
||||
|
||||
assign exu_mp_fghr[pt.BHT_GHR_SIZE-1:0] = after_flush_eghr[pt.BHT_GHR_SIZE-1:0];
|
||||
assign exu_mp_fghr[pt.BHT_GHR_SIZE-1:0] = after_flush_eghr[pt.BHT_GHR_SIZE-1:0];
|
||||
|
||||
assign {exu_mp_index[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO],
|
||||
assign {exu_mp_index[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO],
|
||||
exu_mp_btag[pt.BTB_BTAG_SIZE-1:0]} = final_predpipe_mp[PREDPIPESIZE-pt.BHT_GHR_SIZE-1:0];
|
||||
|
||||
assign exu_mp_eghr[pt.BHT_GHR_SIZE-1:0] = final_predpipe_mp[PREDPIPESIZE-1:pt.BTB_ADDR_HI-pt.BTB_ADDR_LO+pt.BTB_BTAG_SIZE+1]; // mp ghr for bht write
|
||||
end // if (pt.BTB_ENABLE==1)
|
||||
assign exu_mp_eghr[pt.BHT_GHR_SIZE-1:0] = final_predpipe_mp[PREDPIPESIZE-1:pt.BTB_ADDR_HI-pt.BTB_ADDR_LO+pt.BTB_BTAG_SIZE+1]; // mp ghr for bht write
|
||||
end // if (pt.BTB_ENABLE==1)
|
||||
else begin
|
||||
assign ghr_d_ns = '0;
|
||||
assign ghr_x_ns = '0;
|
||||
assign exu_mp_pkt = '0;
|
||||
assign exu_mp_eghr = '0;
|
||||
assign exu_mp_fghr = '0;
|
||||
assign exu_mp_index = '0;
|
||||
assign exu_mp_btag = '0;
|
||||
assign exu_i0_br_hist_r = '0;
|
||||
assign exu_i0_br_error_r = '0;
|
||||
assign exu_i0_br_start_error_r = '0;
|
||||
assign exu_i0_br_index_r = '0;
|
||||
assign exu_i0_br_valid_r = '0;
|
||||
assign exu_i0_br_mp_r = '0;
|
||||
assign exu_i0_br_middle_r = '0;
|
||||
assign exu_i0_br_fghr_r = '0;
|
||||
assign exu_i0_br_way_r = '0;
|
||||
end // else: !if(pt.BTB_ENABLE==1)
|
||||
assign ghr_d_ns = '0;
|
||||
assign ghr_x_ns = '0;
|
||||
assign exu_mp_pkt = '0;
|
||||
assign exu_mp_eghr = '0;
|
||||
assign exu_mp_fghr = '0;
|
||||
assign exu_mp_index = '0;
|
||||
assign exu_mp_btag = '0;
|
||||
assign exu_i0_br_hist_r = '0;
|
||||
assign exu_i0_br_error_r = '0;
|
||||
assign exu_i0_br_start_error_r = '0;
|
||||
assign exu_i0_br_index_r = '0;
|
||||
assign exu_i0_br_valid_r = '0;
|
||||
assign exu_i0_br_mp_r = '0;
|
||||
assign exu_i0_br_middle_r = '0;
|
||||
assign exu_i0_br_fghr_r = '0;
|
||||
assign exu_i0_br_way_r = '0;
|
||||
end // else: !if(pt.BTB_ENABLE==1)
|
||||
|
||||
assign exu_flush_path_final[31:1] = ( {31{ dec_tlu_flush_lower_r }} & dec_tlu_flush_path_r[31:1] ) |
|
||||
assign exu_flush_path_final[31:1] = ( {31{ dec_tlu_flush_lower_r }} & dec_tlu_flush_path_r[31:1] ) |
|
||||
( {31{~dec_tlu_flush_lower_r & i0_flush_upper_d}} & i0_flush_path_d[31:1] );
|
||||
|
||||
assign exu_npc_r[31:1] = (i0_pred_correct_upper_r) ? pred_correct_npc_r[31:1] : i0_flush_path_upper_r[31:1];
|
||||
assign exu_npc_r[31:1] = (i0_pred_correct_upper_r) ? pred_correct_npc_r[31:1] : i0_flush_path_upper_r[31:1];
|
||||
|
||||
|
||||
endmodule // el2_exu
|
||||
endmodule // el2_exu
|
||||
|
|
|
@ -15,255 +15,247 @@
|
|||
|
||||
|
||||
module el2_exu_alu_ctl
|
||||
import el2_pkg::*;
|
||||
import el2_pkg::*;
|
||||
#(
|
||||
`include "el2_param.vh"
|
||||
)
|
||||
(
|
||||
input logic clk, // Top level clock
|
||||
input logic rst_l, // Reset
|
||||
input logic scan_mode, // Scan control
|
||||
`include "el2_param.vh"
|
||||
) (
|
||||
input logic clk, // Top level clock
|
||||
input logic rst_l, // Reset
|
||||
input logic scan_mode, // Scan control
|
||||
|
||||
input logic flush_upper_x, // Branch flush from previous cycle
|
||||
input logic flush_lower_r, // Master flush of entire pipeline
|
||||
input logic enable, // Clock enable
|
||||
input logic valid_in, // Valid
|
||||
input el2_alu_pkt_t ap, // predecodes
|
||||
input logic csr_ren_in, // CSR select
|
||||
input logic [31:0] csr_rddata_in, // CSR data
|
||||
input logic signed [31:0] a_in, // A operand
|
||||
input logic [31:0] b_in, // B operand
|
||||
input logic [31:1] pc_in, // for pc=pc+2,4 calculations
|
||||
input el2_predict_pkt_t pp_in, // Predicted branch structure
|
||||
input logic [12:1] brimm_in, // Branch offset
|
||||
input logic flush_upper_x, // Branch flush from previous cycle
|
||||
input logic flush_lower_r, // Master flush of entire pipeline
|
||||
input logic enable, // Clock enable
|
||||
input logic valid_in, // Valid
|
||||
input el2_alu_pkt_t ap, // predecodes
|
||||
input logic csr_ren_in, // CSR select
|
||||
input logic [31:0] csr_rddata_in, // CSR data
|
||||
input logic signed [31:0] a_in, // A operand
|
||||
input logic [31:0] b_in, // B operand
|
||||
input logic [31:1] pc_in, // for pc=pc+2,4 calculations
|
||||
input el2_predict_pkt_t pp_in, // Predicted branch structure
|
||||
input logic [12:1] brimm_in, // Branch offset
|
||||
|
||||
|
||||
output logic [31:0] result_ff, // final result
|
||||
output logic flush_upper_out, // Branch flush
|
||||
output logic flush_final_out, // Branch flush or flush entire pipeline
|
||||
output logic [31:1] flush_path_out, // Branch flush PC
|
||||
output logic [31:1] pc_ff, // flopped PC
|
||||
output logic pred_correct_out, // NPC control
|
||||
output el2_predict_pkt_t predict_p_out // Predicted branch structure
|
||||
output logic [31:0] result_ff, // final result
|
||||
output logic flush_upper_out, // Branch flush
|
||||
output logic flush_final_out, // Branch flush or flush entire pipeline
|
||||
output logic [31:1] flush_path_out, // Branch flush PC
|
||||
output logic [31:1] pc_ff, // flopped PC
|
||||
output logic pred_correct_out, // NPC control
|
||||
output el2_predict_pkt_t predict_p_out // Predicted branch structure
|
||||
);
|
||||
|
||||
|
||||
logic [31:0] zba_a_in;
|
||||
logic [31:0] aout;
|
||||
logic cout, ov, neg;
|
||||
logic [31:0] lout;
|
||||
logic [31:0] sout;
|
||||
logic sel_shift;
|
||||
logic sel_adder;
|
||||
logic slt_one;
|
||||
logic actual_taken;
|
||||
logic [31:1] pcout;
|
||||
logic cond_mispredict;
|
||||
logic target_mispredict;
|
||||
logic eq, ne, lt, ge;
|
||||
logic any_jal;
|
||||
logic [ 1:0] newhist;
|
||||
logic sel_pc;
|
||||
logic [31:0] csr_write_data;
|
||||
logic [31:0] result;
|
||||
|
||||
|
||||
|
||||
|
||||
// *** Start - BitManip ***
|
||||
|
||||
// Zbb
|
||||
logic ap_clz;
|
||||
logic ap_ctz;
|
||||
logic ap_cpop;
|
||||
logic ap_sext_b;
|
||||
logic ap_sext_h;
|
||||
logic ap_min;
|
||||
logic ap_max;
|
||||
logic ap_rol;
|
||||
logic ap_ror;
|
||||
logic ap_rev8;
|
||||
logic ap_orc_b;
|
||||
logic ap_zbb;
|
||||
|
||||
// Zbs
|
||||
logic ap_bset;
|
||||
logic ap_bclr;
|
||||
logic ap_binv;
|
||||
logic ap_bext;
|
||||
|
||||
// Zbp
|
||||
logic ap_pack;
|
||||
logic ap_packu;
|
||||
logic ap_packh;
|
||||
|
||||
// Zba
|
||||
logic ap_sh1add;
|
||||
logic ap_sh2add;
|
||||
logic ap_sh3add;
|
||||
logic ap_zba;
|
||||
|
||||
|
||||
|
||||
if (pt.BITMANIP_ZBB == 1) begin
|
||||
assign ap_clz = ap.clz;
|
||||
assign ap_ctz = ap.ctz;
|
||||
assign ap_cpop = ap.cpop;
|
||||
assign ap_sext_b = ap.sext_b;
|
||||
assign ap_sext_h = ap.sext_h;
|
||||
assign ap_min = ap.min;
|
||||
assign ap_max = ap.max;
|
||||
end else begin
|
||||
assign ap_clz = 1'b0;
|
||||
assign ap_ctz = 1'b0;
|
||||
assign ap_cpop = 1'b0;
|
||||
assign ap_sext_b = 1'b0;
|
||||
assign ap_sext_h = 1'b0;
|
||||
assign ap_min = 1'b0;
|
||||
assign ap_max = 1'b0;
|
||||
end
|
||||
|
||||
|
||||
if ((pt.BITMANIP_ZBB == 1) | (pt.BITMANIP_ZBP == 1)) begin
|
||||
assign ap_rol = ap.rol;
|
||||
assign ap_ror = ap.ror;
|
||||
assign ap_rev8 = ap.grev & (b_in[4:0] == 5'b11000);
|
||||
assign ap_orc_b = ap.gorc & (b_in[4:0] == 5'b00111);
|
||||
assign ap_zbb = ap.zbb;
|
||||
end else begin
|
||||
assign ap_rol = 1'b0;
|
||||
assign ap_ror = 1'b0;
|
||||
assign ap_rev8 = 1'b0;
|
||||
assign ap_orc_b = 1'b0;
|
||||
assign ap_zbb = 1'b0;
|
||||
end
|
||||
|
||||
|
||||
if (pt.BITMANIP_ZBS == 1) begin
|
||||
assign ap_bset = ap.bset;
|
||||
assign ap_bclr = ap.bclr;
|
||||
assign ap_binv = ap.binv;
|
||||
assign ap_bext = ap.bext;
|
||||
end else begin
|
||||
assign ap_bset = 1'b0;
|
||||
assign ap_bclr = 1'b0;
|
||||
assign ap_binv = 1'b0;
|
||||
assign ap_bext = 1'b0;
|
||||
end
|
||||
|
||||
|
||||
if (pt.BITMANIP_ZBP == 1) begin
|
||||
assign ap_packu = ap.packu;
|
||||
end else begin
|
||||
assign ap_packu = 1'b0;
|
||||
end
|
||||
|
||||
|
||||
if ( (pt.BITMANIP_ZBB == 1) | (pt.BITMANIP_ZBP == 1) | (pt.BITMANIP_ZBE == 1) | (pt.BITMANIP_ZBF == 1) )
|
||||
begin
|
||||
assign ap_pack = ap.pack;
|
||||
assign ap_packh = ap.packh;
|
||||
end else begin
|
||||
assign ap_pack = 1'b0;
|
||||
assign ap_packh = 1'b0;
|
||||
end
|
||||
|
||||
|
||||
if (pt.BITMANIP_ZBA == 1) begin
|
||||
assign ap_sh1add = ap.sh1add;
|
||||
assign ap_sh2add = ap.sh2add;
|
||||
assign ap_sh3add = ap.sh3add;
|
||||
assign ap_zba = ap.zba;
|
||||
end else begin
|
||||
assign ap_sh1add = 1'b0;
|
||||
assign ap_sh2add = 1'b0;
|
||||
assign ap_sh3add = 1'b0;
|
||||
assign ap_zba = 1'b0;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
// *** End - BitManip ***
|
||||
|
||||
|
||||
|
||||
|
||||
rvdffpcie #(31) i_pc_ff (
|
||||
.*,
|
||||
.clk (clk),
|
||||
.en (enable),
|
||||
.din (pc_in[31:1]),
|
||||
.dout(pc_ff[31:1])
|
||||
); // any PC is run through here - doesn't have to be alu
|
||||
rvdffe #(32) i_result_ff (
|
||||
.*,
|
||||
.clk (clk),
|
||||
.en (enable & valid_in),
|
||||
.din (result[31:0]),
|
||||
.dout(result_ff[31:0])
|
||||
);
|
||||
|
||||
|
||||
logic [31:0] zba_a_in;
|
||||
logic [31:0] aout;
|
||||
logic cout,ov,neg;
|
||||
logic [31:0] lout;
|
||||
logic [31:0] sout;
|
||||
logic sel_shift;
|
||||
logic sel_adder;
|
||||
logic slt_one;
|
||||
logic actual_taken;
|
||||
logic [31:1] pcout;
|
||||
logic cond_mispredict;
|
||||
logic target_mispredict;
|
||||
logic eq, ne, lt, ge;
|
||||
logic any_jal;
|
||||
logic [1:0] newhist;
|
||||
logic sel_pc;
|
||||
logic [31:0] csr_write_data;
|
||||
logic [31:0] result;
|
||||
|
||||
// immediates are just muxed into rs2
|
||||
|
||||
// add => add=1;
|
||||
// sub => add=1; sub=1;
|
||||
|
||||
// and => lctl=3
|
||||
// or => lctl=2
|
||||
// xor => lctl=1
|
||||
|
||||
// sll => sctl=3
|
||||
// srl => sctl=2
|
||||
// sra => sctl=1
|
||||
|
||||
// slt => slt
|
||||
|
||||
// lui => lctl=2; or x0, imm20 previously << 12
|
||||
// auipc => add; add pc, imm20 previously << 12
|
||||
|
||||
// beq => bctl=4; add; add x0, pc, sext(offset[12:1])
|
||||
// bne => bctl=3; add; add x0, pc, sext(offset[12:1])
|
||||
// blt => bctl=2; add; add x0, pc, sext(offset[12:1])
|
||||
// bge => bctl=1; add; add x0, pc, sext(offset[12:1])
|
||||
|
||||
// jal => rs1=pc {pc[31:1],1'b0}, rs2=sext(offset20:1]); rd=pc+[2,4]
|
||||
// jalr => rs1=rs1, rs2=sext(offset20:1]); rd=pc+[2,4]
|
||||
|
||||
|
||||
|
||||
|
||||
// *** Start - BitManip ***
|
||||
|
||||
// Zbb
|
||||
logic ap_clz;
|
||||
logic ap_ctz;
|
||||
logic ap_cpop;
|
||||
logic ap_sext_b;
|
||||
logic ap_sext_h;
|
||||
logic ap_min;
|
||||
logic ap_max;
|
||||
logic ap_rol;
|
||||
logic ap_ror;
|
||||
logic ap_rev8;
|
||||
logic ap_orc_b;
|
||||
logic ap_zbb;
|
||||
|
||||
// Zbs
|
||||
logic ap_bset;
|
||||
logic ap_bclr;
|
||||
logic ap_binv;
|
||||
logic ap_bext;
|
||||
|
||||
// Zbp
|
||||
logic ap_pack;
|
||||
logic ap_packu;
|
||||
logic ap_packh;
|
||||
|
||||
// Zba
|
||||
logic ap_sh1add;
|
||||
logic ap_sh2add;
|
||||
logic ap_sh3add;
|
||||
logic ap_zba;
|
||||
|
||||
|
||||
|
||||
if (pt.BITMANIP_ZBB == 1)
|
||||
begin
|
||||
assign ap_clz = ap.clz;
|
||||
assign ap_ctz = ap.ctz;
|
||||
assign ap_cpop = ap.cpop;
|
||||
assign ap_sext_b = ap.sext_b;
|
||||
assign ap_sext_h = ap.sext_h;
|
||||
assign ap_min = ap.min;
|
||||
assign ap_max = ap.max;
|
||||
end
|
||||
else
|
||||
begin
|
||||
assign ap_clz = 1'b0;
|
||||
assign ap_ctz = 1'b0;
|
||||
assign ap_cpop = 1'b0;
|
||||
assign ap_sext_b = 1'b0;
|
||||
assign ap_sext_h = 1'b0;
|
||||
assign ap_min = 1'b0;
|
||||
assign ap_max = 1'b0;
|
||||
end
|
||||
|
||||
|
||||
if ( (pt.BITMANIP_ZBB == 1) | (pt.BITMANIP_ZBP == 1) )
|
||||
begin
|
||||
assign ap_rol = ap.rol;
|
||||
assign ap_ror = ap.ror;
|
||||
assign ap_rev8 = ap.grev & (b_in[4:0] == 5'b11000);
|
||||
assign ap_orc_b = ap.gorc & (b_in[4:0] == 5'b00111);
|
||||
assign ap_zbb = ap.zbb;
|
||||
end
|
||||
else
|
||||
begin
|
||||
assign ap_rol = 1'b0;
|
||||
assign ap_ror = 1'b0;
|
||||
assign ap_rev8 = 1'b0;
|
||||
assign ap_orc_b = 1'b0;
|
||||
assign ap_zbb = 1'b0;
|
||||
end
|
||||
|
||||
|
||||
if (pt.BITMANIP_ZBS == 1)
|
||||
begin
|
||||
assign ap_bset = ap.bset;
|
||||
assign ap_bclr = ap.bclr;
|
||||
assign ap_binv = ap.binv;
|
||||
assign ap_bext = ap.bext;
|
||||
end
|
||||
else
|
||||
begin
|
||||
assign ap_bset = 1'b0;
|
||||
assign ap_bclr = 1'b0;
|
||||
assign ap_binv = 1'b0;
|
||||
assign ap_bext = 1'b0;
|
||||
end
|
||||
|
||||
|
||||
if (pt.BITMANIP_ZBP == 1)
|
||||
begin
|
||||
assign ap_packu = ap.packu;
|
||||
end
|
||||
else
|
||||
begin
|
||||
assign ap_packu = 1'b0;
|
||||
end
|
||||
|
||||
|
||||
if ( (pt.BITMANIP_ZBB == 1) | (pt.BITMANIP_ZBP == 1) | (pt.BITMANIP_ZBE == 1) | (pt.BITMANIP_ZBF == 1) )
|
||||
begin
|
||||
assign ap_pack = ap.pack;
|
||||
assign ap_packh = ap.packh;
|
||||
end
|
||||
else
|
||||
begin
|
||||
assign ap_pack = 1'b0;
|
||||
assign ap_packh = 1'b0;
|
||||
end
|
||||
|
||||
|
||||
if (pt.BITMANIP_ZBA == 1)
|
||||
begin
|
||||
assign ap_sh1add = ap.sh1add;
|
||||
assign ap_sh2add = ap.sh2add;
|
||||
assign ap_sh3add = ap.sh3add;
|
||||
assign ap_zba = ap.zba;
|
||||
end
|
||||
else
|
||||
begin
|
||||
assign ap_sh1add = 1'b0;
|
||||
assign ap_sh2add = 1'b0;
|
||||
assign ap_sh3add = 1'b0;
|
||||
assign ap_zba = 1'b0;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
// *** End - BitManip ***
|
||||
|
||||
|
||||
|
||||
|
||||
rvdffpcie #(31) i_pc_ff (.*, .clk(clk), .en(enable), .din(pc_in[31:1]), .dout(pc_ff[31:1])); // any PC is run through here - doesn't have to be alu
|
||||
rvdffe #(32) i_result_ff (.*, .clk(clk), .en(enable & valid_in), .din(result[31:0]), .dout(result_ff[31:0]));
|
||||
|
||||
|
||||
|
||||
// immediates are just muxed into rs2
|
||||
|
||||
// add => add=1;
|
||||
// sub => add=1; sub=1;
|
||||
|
||||
// and => lctl=3
|
||||
// or => lctl=2
|
||||
// xor => lctl=1
|
||||
|
||||
// sll => sctl=3
|
||||
// srl => sctl=2
|
||||
// sra => sctl=1
|
||||
|
||||
// slt => slt
|
||||
|
||||
// lui => lctl=2; or x0, imm20 previously << 12
|
||||
// auipc => add; add pc, imm20 previously << 12
|
||||
|
||||
// beq => bctl=4; add; add x0, pc, sext(offset[12:1])
|
||||
// bne => bctl=3; add; add x0, pc, sext(offset[12:1])
|
||||
// blt => bctl=2; add; add x0, pc, sext(offset[12:1])
|
||||
// bge => bctl=1; add; add x0, pc, sext(offset[12:1])
|
||||
|
||||
// jal => rs1=pc {pc[31:1],1'b0}, rs2=sext(offset20:1]); rd=pc+[2,4]
|
||||
// jalr => rs1=rs1, rs2=sext(offset20:1]); rd=pc+[2,4]
|
||||
|
||||
|
||||
|
||||
assign zba_a_in[31:0] = ( {32{ ap_sh1add}} & {a_in[30:0],1'b0} ) |
|
||||
assign zba_a_in[31:0] = ( {32{ ap_sh1add}} & {a_in[30:0],1'b0} ) |
|
||||
( {32{ ap_sh2add}} & {a_in[29:0],2'b0} ) |
|
||||
( {32{ ap_sh3add}} & {a_in[28:0],3'b0} ) |
|
||||
( {32{~ap_zba }} & a_in[31:0] );
|
||||
|
||||
logic [31:0] bm;
|
||||
logic [31:0] bm;
|
||||
|
||||
assign bm[31:0] = ( ap.sub ) ? ~b_in[31:0] : b_in[31:0];
|
||||
assign bm[31:0] = (ap.sub) ? ~b_in[31:0] : b_in[31:0];
|
||||
|
||||
assign {cout, aout[31:0]} = {1'b0, zba_a_in[31:0]} + {1'b0, bm[31:0]} + {32'b0, ap.sub};
|
||||
assign {cout, aout[31:0]} = {1'b0, zba_a_in[31:0]} + {1'b0, bm[31:0]} + {32'b0, ap.sub};
|
||||
|
||||
assign ov = (~a_in[31] & ~bm[31] & aout[31]) |
|
||||
( a_in[31] & bm[31] & ~aout[31] );
|
||||
assign ov = (~a_in[31] & ~bm[31] & aout[31]) | (a_in[31] & bm[31] & ~aout[31]);
|
||||
|
||||
assign lt = (~ap.unsign & (neg ^ ov)) |
|
||||
( ap.unsign & ~cout);
|
||||
assign lt = (~ap.unsign & (neg ^ ov)) | (ap.unsign & ~cout);
|
||||
|
||||
assign eq = (a_in[31:0] == b_in[31:0]);
|
||||
assign ne = ~eq;
|
||||
assign neg = aout[31];
|
||||
assign ge = ~lt;
|
||||
assign eq = (a_in[31:0] == b_in[31:0]);
|
||||
assign ne = ~eq;
|
||||
assign neg = aout[31];
|
||||
assign ge = ~lt;
|
||||
|
||||
|
||||
|
||||
assign lout[31:0] = ( {32{csr_ren_in }} & csr_rddata_in[31:0] ) |
|
||||
assign lout[31:0] = ( {32{csr_ren_in }} & csr_rddata_in[31:0] ) |
|
||||
( {32{ap.land & ~ap_zbb}} & a_in[31:0] & b_in[31:0] ) |
|
||||
( {32{ap.lor & ~ap_zbb}} & (a_in[31:0] | b_in[31:0]) ) |
|
||||
( {32{ap.lxor & ~ap_zbb}} & (a_in[31:0] ^ b_in[31:0]) ) |
|
||||
|
@ -274,16 +266,16 @@ import el2_pkg::*;
|
|||
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : ROL,ROR * * * * * * * * * * * * * * * * * *
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : ZBEXT * * * * * * * * * * * * * * * * * *
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : ROL,ROR * * * * * * * * * * * * * * * * * *
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : ZBEXT * * * * * * * * * * * * * * * * * *
|
||||
|
||||
logic [5:0] shift_amount;
|
||||
logic [31:0] shift_mask;
|
||||
logic [62:0] shift_extend;
|
||||
logic [62:0] shift_long;
|
||||
logic [ 5:0] shift_amount;
|
||||
logic [31:0] shift_mask;
|
||||
logic [62:0] shift_extend;
|
||||
logic [62:0] shift_long;
|
||||
|
||||
|
||||
assign shift_amount[5:0] = ( { 6{ap.sll}} & (6'd32 - {1'b0,b_in[4:0]}) ) | // [5] unused
|
||||
assign shift_amount[5:0] = ( { 6{ap.sll}} & (6'd32 - {1'b0,b_in[4:0]}) ) | // [5] unused
|
||||
( { 6{ap.srl}} & {1'b0,b_in[4:0]} ) |
|
||||
( { 6{ap.sra}} & {1'b0,b_in[4:0]} ) |
|
||||
( { 6{ap_rol}} & (6'd32 - {1'b0,b_in[4:0]}) ) |
|
||||
|
@ -291,174 +283,199 @@ import el2_pkg::*;
|
|||
( { 6{ap_bext}} & {1'b0,b_in[4:0]} );
|
||||
|
||||
|
||||
assign shift_mask[31:0] = ( 32'hffffffff << ({5{ap.sll}} & b_in[4:0]) );
|
||||
assign shift_mask[31:0] = (32'hffffffff << ({5{ap.sll}} & b_in[4:0]));
|
||||
|
||||
|
||||
assign shift_extend[31:0] = a_in[31:0];
|
||||
assign shift_extend[31:0] = a_in[31:0];
|
||||
|
||||
assign shift_extend[62:32] = ( {31{ap.sra}} & {31{a_in[31]}} ) |
|
||||
assign shift_extend[62:32] = ( {31{ap.sra}} & {31{a_in[31]}} ) |
|
||||
( {31{ap.sll}} & a_in[30:0] ) |
|
||||
( {31{ap_rol}} & a_in[30:0] ) |
|
||||
( {31{ap_ror}} & a_in[30:0] );
|
||||
|
||||
|
||||
assign shift_long[62:0] = ( shift_extend[62:0] >> shift_amount[4:0] ); // 62-32 unused
|
||||
assign shift_long[62:0] = (shift_extend[62:0] >> shift_amount[4:0]); // 62-32 unused
|
||||
|
||||
assign sout[31:0] = shift_long[31:0] & shift_mask[31:0];
|
||||
assign sout[31:0] = shift_long[31:0] & shift_mask[31:0];
|
||||
|
||||
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : CLZ,CTZ * * * * * * * * * * * * * * * * * *
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : CLZ,CTZ * * * * * * * * * * * * * * * * * *
|
||||
|
||||
logic bitmanip_clz_ctz_sel;
|
||||
logic [31:0] bitmanip_a_reverse_ff;
|
||||
logic [31:0] bitmanip_lzd_in;
|
||||
logic [5:0] bitmanip_dw_lzd_enc;
|
||||
logic [5:0] bitmanip_clz_ctz_result;
|
||||
logic bitmanip_clz_ctz_sel;
|
||||
logic [31:0] bitmanip_a_reverse_ff;
|
||||
logic [31:0] bitmanip_lzd_in;
|
||||
logic [ 5:0] bitmanip_dw_lzd_enc;
|
||||
logic [ 5:0] bitmanip_clz_ctz_result;
|
||||
|
||||
assign bitmanip_clz_ctz_sel = ap_clz | ap_ctz;
|
||||
assign bitmanip_clz_ctz_sel = ap_clz | ap_ctz;
|
||||
|
||||
assign bitmanip_a_reverse_ff[31:0] = {a_in[0], a_in[1], a_in[2], a_in[3], a_in[4], a_in[5], a_in[6], a_in[7],
|
||||
a_in[8], a_in[9], a_in[10], a_in[11], a_in[12], a_in[13], a_in[14], a_in[15],
|
||||
a_in[16], a_in[17], a_in[18], a_in[19], a_in[20], a_in[21], a_in[22], a_in[23],
|
||||
a_in[24], a_in[25], a_in[26], a_in[27], a_in[28], a_in[29], a_in[30], a_in[31]};
|
||||
assign bitmanip_a_reverse_ff[31:0] = {
|
||||
a_in[0],
|
||||
a_in[1],
|
||||
a_in[2],
|
||||
a_in[3],
|
||||
a_in[4],
|
||||
a_in[5],
|
||||
a_in[6],
|
||||
a_in[7],
|
||||
a_in[8],
|
||||
a_in[9],
|
||||
a_in[10],
|
||||
a_in[11],
|
||||
a_in[12],
|
||||
a_in[13],
|
||||
a_in[14],
|
||||
a_in[15],
|
||||
a_in[16],
|
||||
a_in[17],
|
||||
a_in[18],
|
||||
a_in[19],
|
||||
a_in[20],
|
||||
a_in[21],
|
||||
a_in[22],
|
||||
a_in[23],
|
||||
a_in[24],
|
||||
a_in[25],
|
||||
a_in[26],
|
||||
a_in[27],
|
||||
a_in[28],
|
||||
a_in[29],
|
||||
a_in[30],
|
||||
a_in[31]
|
||||
};
|
||||
|
||||
assign bitmanip_lzd_in[31:0] = ( {32{ap_clz}} & a_in[31:0] ) |
|
||||
assign bitmanip_lzd_in[31:0] = ( {32{ap_clz}} & a_in[31:0] ) |
|
||||
( {32{ap_ctz}} & bitmanip_a_reverse_ff[31:0]);
|
||||
|
||||
logic [31:0] bitmanip_lzd_os;
|
||||
integer i;
|
||||
logic found;
|
||||
logic [31:0] bitmanip_lzd_os;
|
||||
integer i;
|
||||
logic found;
|
||||
|
||||
always_comb
|
||||
begin
|
||||
bitmanip_lzd_os[31:0] = bitmanip_lzd_in[31:0];
|
||||
bitmanip_dw_lzd_enc[5:0]= 6'b0;
|
||||
found = 1'b0;
|
||||
always_comb begin
|
||||
bitmanip_lzd_os[31:0] = bitmanip_lzd_in[31:0];
|
||||
bitmanip_dw_lzd_enc[5:0] = 6'b0;
|
||||
found = 1'b0;
|
||||
|
||||
for (int i=0; i<32 && found==0; i++) begin
|
||||
if (bitmanip_lzd_os[31] == 1'b0) begin
|
||||
bitmanip_dw_lzd_enc[5:0]= bitmanip_dw_lzd_enc[5:0] + 6'b00_0001;
|
||||
bitmanip_lzd_os[31:0] = bitmanip_lzd_os[31:0] << 1;
|
||||
end
|
||||
else
|
||||
found=1'b1;
|
||||
end
|
||||
end
|
||||
for (int i = 0; i < 32 && found == 0; i++) begin
|
||||
if (bitmanip_lzd_os[31] == 1'b0) begin
|
||||
bitmanip_dw_lzd_enc[5:0] = bitmanip_dw_lzd_enc[5:0] + 6'b00_0001;
|
||||
bitmanip_lzd_os[31:0] = bitmanip_lzd_os[31:0] << 1;
|
||||
end else found = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
assign bitmanip_clz_ctz_result[5:0] = {6{bitmanip_clz_ctz_sel}} & {bitmanip_dw_lzd_enc[5],( {5{~bitmanip_dw_lzd_enc[5]}} & bitmanip_dw_lzd_enc[4:0] )};
|
||||
assign bitmanip_clz_ctz_result[5:0] = {6{bitmanip_clz_ctz_sel}} & {bitmanip_dw_lzd_enc[5],( {5{~bitmanip_dw_lzd_enc[5]}} & bitmanip_dw_lzd_enc[4:0] )};
|
||||
|
||||
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : CPOP * * * * * * * * * * * * * * * * * *
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : CPOP * * * * * * * * * * * * * * * * * *
|
||||
|
||||
logic [5:0] bitmanip_cpop;
|
||||
logic [5:0] bitmanip_cpop_result;
|
||||
logic [5:0] bitmanip_cpop;
|
||||
logic [5:0] bitmanip_cpop_result;
|
||||
|
||||
|
||||
integer bitmanip_cpop_i;
|
||||
integer bitmanip_cpop_i;
|
||||
|
||||
always_comb
|
||||
begin
|
||||
bitmanip_cpop[5:0] = 6'b0;
|
||||
always_comb begin
|
||||
bitmanip_cpop[5:0] = 6'b0;
|
||||
|
||||
for (bitmanip_cpop_i=0; bitmanip_cpop_i<32; bitmanip_cpop_i++)
|
||||
begin
|
||||
bitmanip_cpop[5:0] = bitmanip_cpop[5:0] + {5'b0,a_in[bitmanip_cpop_i]};
|
||||
end // FOR bitmanip_cpop_i
|
||||
end // ALWAYS_COMB
|
||||
for (bitmanip_cpop_i = 0; bitmanip_cpop_i < 32; bitmanip_cpop_i++) begin
|
||||
bitmanip_cpop[5:0] = bitmanip_cpop[5:0] + {5'b0, a_in[bitmanip_cpop_i]};
|
||||
end // FOR bitmanip_cpop_i
|
||||
end // ALWAYS_COMB
|
||||
|
||||
|
||||
assign bitmanip_cpop_result[5:0] = {6{ap_cpop}} & bitmanip_cpop[5:0];
|
||||
assign bitmanip_cpop_result[5:0] = {6{ap_cpop}} & bitmanip_cpop[5:0];
|
||||
|
||||
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : SEXT_B,SEXT_H * * * * * * * * * * * * * * * * *
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : SEXT_B,SEXT_H * * * * * * * * * * * * * * * * *
|
||||
|
||||
logic [31:0] bitmanip_sext_result;
|
||||
logic [31:0] bitmanip_sext_result;
|
||||
|
||||
assign bitmanip_sext_result[31:0] = ( {32{ap_sext_b}} & { {24{a_in[7]}} ,a_in[7:0] } ) |
|
||||
assign bitmanip_sext_result[31:0] = ( {32{ap_sext_b}} & { {24{a_in[7]}} ,a_in[7:0] } ) |
|
||||
( {32{ap_sext_h}} & { {16{a_in[15]}},a_in[15:0] } );
|
||||
|
||||
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : MIN,MAX,MINU,MAXU * * * * * * * * * * * * * * *
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : MIN,MAX,MINU,MAXU * * * * * * * * * * * * * * *
|
||||
|
||||
logic bitmanip_minmax_sel;
|
||||
logic [31:0] bitmanip_minmax_result;
|
||||
logic bitmanip_minmax_sel;
|
||||
logic [31:0] bitmanip_minmax_result;
|
||||
|
||||
assign bitmanip_minmax_sel = ap_min | ap_max;
|
||||
assign bitmanip_minmax_sel = ap_min | ap_max;
|
||||
|
||||
logic bitmanip_minmax_sel_a;
|
||||
logic bitmanip_minmax_sel_a;
|
||||
|
||||
assign bitmanip_minmax_sel_a = ge ^ ap_min;
|
||||
assign bitmanip_minmax_sel_a = ge ^ ap_min;
|
||||
|
||||
assign bitmanip_minmax_result[31:0] = ({32{bitmanip_minmax_sel & bitmanip_minmax_sel_a}} & a_in[31:0]) |
|
||||
assign bitmanip_minmax_result[31:0] = ({32{bitmanip_minmax_sel & bitmanip_minmax_sel_a}} & a_in[31:0]) |
|
||||
({32{bitmanip_minmax_sel & ~bitmanip_minmax_sel_a}} & b_in[31:0]);
|
||||
|
||||
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : PACK, PACKU, PACKH * * * * * * * * * * * * * * *
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : PACK, PACKU, PACKH * * * * * * * * * * * * * * *
|
||||
|
||||
logic [31:0] bitmanip_pack_result;
|
||||
logic [31:0] bitmanip_packu_result;
|
||||
logic [31:0] bitmanip_packh_result;
|
||||
logic [31:0] bitmanip_pack_result;
|
||||
logic [31:0] bitmanip_packu_result;
|
||||
logic [31:0] bitmanip_packh_result;
|
||||
|
||||
assign bitmanip_pack_result[31:0] = {32{ap_pack}} & {b_in[15:0], a_in[15:0]};
|
||||
assign bitmanip_packu_result[31:0] = {32{ap_packu}} & {b_in[31:16],a_in[31:16]};
|
||||
assign bitmanip_packh_result[31:0] = {32{ap_packh}} & {16'b0,b_in[7:0],a_in[7:0]};
|
||||
assign bitmanip_pack_result[31:0] = {32{ap_pack}} & {b_in[15:0], a_in[15:0]};
|
||||
assign bitmanip_packu_result[31:0] = {32{ap_packu}} & {b_in[31:16], a_in[31:16]};
|
||||
assign bitmanip_packh_result[31:0] = {32{ap_packh}} & {16'b0, b_in[7:0], a_in[7:0]};
|
||||
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : REV, ORC_B * * * * * * * * * * * * * * * * * *
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : REV, ORC_B * * * * * * * * * * * * * * * * * *
|
||||
|
||||
logic [31:0] bitmanip_rev8_result;
|
||||
logic [31:0] bitmanip_orc_b_result;
|
||||
logic [31:0] bitmanip_rev8_result;
|
||||
logic [31:0] bitmanip_orc_b_result;
|
||||
|
||||
assign bitmanip_rev8_result[31:0] = {32{ap_rev8}} & {a_in[7:0],a_in[15:8],a_in[23:16],a_in[31:24]};
|
||||
assign bitmanip_rev8_result[31:0] = {32{ap_rev8}} & {a_in[7:0],a_in[15:8],a_in[23:16],a_in[31:24]};
|
||||
|
||||
|
||||
// uint32_t gorc32(uint32_t rs1, uint32_t rs2)
|
||||
// {
|
||||
// uint32_t x = rs1;
|
||||
// int shamt = rs2 & 31; ORC.B ORC16
|
||||
// if (shamt & 1) x |= ((x & 0x55555555) << 1) | ((x & 0xAAAAAAAA) >> 1); 1 0
|
||||
// if (shamt & 2) x |= ((x & 0x33333333) << 2) | ((x & 0xCCCCCCCC) >> 2); 1 0
|
||||
// if (shamt & 4) x |= ((x & 0x0F0F0F0F) << 4) | ((x & 0xF0F0F0F0) >> 4); 1 0
|
||||
// if (shamt & 8) x |= ((x & 0x00FF00FF) << 8) | ((x & 0xFF00FF00) >> 8); 0 0
|
||||
// if (shamt & 16) x |= ((x & 0x0000FFFF) << 16) | ((x & 0xFFFF0000) >> 16); 0 1
|
||||
// return x;
|
||||
// }
|
||||
// uint32_t gorc32(uint32_t rs1, uint32_t rs2)
|
||||
// {
|
||||
// uint32_t x = rs1;
|
||||
// int shamt = rs2 & 31; ORC.B ORC16
|
||||
// if (shamt & 1) x |= ((x & 0x55555555) << 1) | ((x & 0xAAAAAAAA) >> 1); 1 0
|
||||
// if (shamt & 2) x |= ((x & 0x33333333) << 2) | ((x & 0xCCCCCCCC) >> 2); 1 0
|
||||
// if (shamt & 4) x |= ((x & 0x0F0F0F0F) << 4) | ((x & 0xF0F0F0F0) >> 4); 1 0
|
||||
// if (shamt & 8) x |= ((x & 0x00FF00FF) << 8) | ((x & 0xFF00FF00) >> 8); 0 0
|
||||
// if (shamt & 16) x |= ((x & 0x0000FFFF) << 16) | ((x & 0xFFFF0000) >> 16); 0 1
|
||||
// return x;
|
||||
// }
|
||||
|
||||
|
||||
// BEFORE 31 , 30 , 29 , 28 , 27 , 26, 25, 24
|
||||
// shamt[0] b = a31|a30,a31|a30,a29|a28,a29|a28, a27|a26,a27|a26,a25|a24,a25|a24
|
||||
// shamt[1] c = b31|b29,b30|b28,b31|b29,b30|b28, b27|b25,b26|b24,b27|b25,b26|b24
|
||||
// shamt[2] d = c31|c27,c30|c26,c29|c25,c28|c24, c31|c27,c30|c26,c29|c25,c28|c24
|
||||
//
|
||||
// Expand d31 = c31 | c27;
|
||||
// = b31 | b29 | b27 | b25;
|
||||
// = a31|a30 | a29|a28 | a27|a26 | a25|a24
|
||||
// BEFORE 31 , 30 , 29 , 28 , 27 , 26, 25, 24
|
||||
// shamt[0] b = a31|a30,a31|a30,a29|a28,a29|a28, a27|a26,a27|a26,a25|a24,a25|a24
|
||||
// shamt[1] c = b31|b29,b30|b28,b31|b29,b30|b28, b27|b25,b26|b24,b27|b25,b26|b24
|
||||
// shamt[2] d = c31|c27,c30|c26,c29|c25,c28|c24, c31|c27,c30|c26,c29|c25,c28|c24
|
||||
//
|
||||
// Expand d31 = c31 | c27;
|
||||
// = b31 | b29 | b27 | b25;
|
||||
// = a31|a30 | a29|a28 | a27|a26 | a25|a24
|
||||
|
||||
assign bitmanip_orc_b_result[31:0] = {32{ap_orc_b}} & { {8{| a_in[31:24]}}, {8{| a_in[23:16]}}, {8{| a_in[15:8]}}, {8{| a_in[7:0]}} };
|
||||
assign bitmanip_orc_b_result[31:0] = {32{ap_orc_b}} & { {8{| a_in[31:24]}}, {8{| a_in[23:16]}}, {8{| a_in[15:8]}}, {8{| a_in[7:0]}} };
|
||||
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : ZBSET, ZBCLR, ZBINV * * * * * * * * * * * * * *
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : ZBSET, ZBCLR, ZBINV * * * * * * * * * * * * * *
|
||||
|
||||
logic [31:0] bitmanip_sb_1hot;
|
||||
logic [31:0] bitmanip_sb_data;
|
||||
logic [31:0] bitmanip_sb_1hot;
|
||||
logic [31:0] bitmanip_sb_data;
|
||||
|
||||
assign bitmanip_sb_1hot[31:0] = ( 32'h00000001 << b_in[4:0] );
|
||||
assign bitmanip_sb_1hot[31:0] = (32'h00000001 << b_in[4:0]);
|
||||
|
||||
assign bitmanip_sb_data[31:0] = ( {32{ap_bset}} & ( a_in[31:0] | bitmanip_sb_1hot[31:0]) ) |
|
||||
assign bitmanip_sb_data[31:0] = ( {32{ap_bset}} & ( a_in[31:0] | bitmanip_sb_1hot[31:0]) ) |
|
||||
( {32{ap_bclr}} & ( a_in[31:0] & ~bitmanip_sb_1hot[31:0]) ) |
|
||||
( {32{ap_binv}} & ( a_in[31:0] ^ bitmanip_sb_1hot[31:0]) );
|
||||
|
||||
|
@ -467,16 +484,16 @@ import el2_pkg::*;
|
|||
|
||||
|
||||
|
||||
assign sel_shift = ap.sll | ap.srl | ap.sra | ap_rol | ap_ror;
|
||||
assign sel_adder = (ap.add | ap.sub | ap_zba) & ~ap.slt & ~ap_min & ~ap_max;
|
||||
assign sel_pc = ap.jal | pp_in.pcall | pp_in.pja | pp_in.pret;
|
||||
assign csr_write_data[31:0]= (ap.csr_imm) ? b_in[31:0] : a_in[31:0];
|
||||
assign sel_shift = ap.sll | ap.srl | ap.sra | ap_rol | ap_ror;
|
||||
assign sel_adder = (ap.add | ap.sub | ap_zba) & ~ap.slt & ~ap_min & ~ap_max;
|
||||
assign sel_pc = ap.jal | pp_in.pcall | pp_in.pja | pp_in.pret;
|
||||
assign csr_write_data[31:0] = (ap.csr_imm) ? b_in[31:0] : a_in[31:0];
|
||||
|
||||
assign slt_one = ap.slt & lt;
|
||||
assign slt_one = ap.slt & lt;
|
||||
|
||||
|
||||
|
||||
assign result[31:0] = lout[31:0] |
|
||||
assign result[31:0] = lout[31:0] |
|
||||
({32{sel_shift}} & sout[31:0] ) |
|
||||
({32{sel_adder}} & aout[31:0] ) |
|
||||
({32{sel_pc}} & {pcout[31:1],1'b0} ) |
|
||||
|
@ -496,81 +513,74 @@ import el2_pkg::*;
|
|||
|
||||
|
||||
|
||||
// *** branch handling ***
|
||||
// *** branch handling ***
|
||||
|
||||
assign any_jal = ap.jal |
|
||||
pp_in.pcall |
|
||||
pp_in.pja |
|
||||
pp_in.pret;
|
||||
assign any_jal = ap.jal | pp_in.pcall | pp_in.pja | pp_in.pret;
|
||||
|
||||
assign actual_taken = (ap.beq & eq) |
|
||||
(ap.bne & ne) |
|
||||
(ap.blt & lt) |
|
||||
(ap.bge & ge) |
|
||||
any_jal;
|
||||
assign actual_taken = (ap.beq & eq) | (ap.bne & ne) | (ap.blt & lt) | (ap.bge & ge) | any_jal;
|
||||
|
||||
// for a conditional br pcout[] will be the opposite of the branch prediction
|
||||
// for jal or pcall, it will be the link address pc+2 or pc+4
|
||||
// for a conditional br pcout[] will be the opposite of the branch prediction
|
||||
// for jal or pcall, it will be the link address pc+2 or pc+4
|
||||
|
||||
rvbradder ibradder (
|
||||
.pc ( pc_in[31:1] ),
|
||||
.offset ( brimm_in[12:1] ),
|
||||
.dout ( pcout[31:1] ));
|
||||
rvbradder ibradder (
|
||||
.pc (pc_in[31:1]),
|
||||
.offset(brimm_in[12:1]),
|
||||
.dout (pcout[31:1])
|
||||
);
|
||||
|
||||
|
||||
// pred_correct is for the npc logic
|
||||
// pred_correct indicates not to use the flush_path
|
||||
// for any_jal pred_correct==0
|
||||
// pred_correct is for the npc logic
|
||||
// pred_correct indicates not to use the flush_path
|
||||
// for any_jal pred_correct==0
|
||||
|
||||
assign pred_correct_out = (valid_in & ap.predict_nt & ~actual_taken & ~any_jal) |
|
||||
assign pred_correct_out = (valid_in & ap.predict_nt & ~actual_taken & ~any_jal) |
|
||||
(valid_in & ap.predict_t & actual_taken & ~any_jal);
|
||||
|
||||
|
||||
// for any_jal adder output is the flush path
|
||||
assign flush_path_out[31:1]= (any_jal) ? aout[31:1] : pcout[31:1];
|
||||
// for any_jal adder output is the flush path
|
||||
assign flush_path_out[31:1] = (any_jal) ? aout[31:1] : pcout[31:1];
|
||||
|
||||
|
||||
// pcall and pret are included here
|
||||
assign cond_mispredict = (ap.predict_t & ~actual_taken) |
|
||||
(ap.predict_nt & actual_taken);
|
||||
// pcall and pret are included here
|
||||
assign cond_mispredict = (ap.predict_t & ~actual_taken) | (ap.predict_nt & actual_taken);
|
||||
|
||||
|
||||
// target mispredicts on ret's
|
||||
// target mispredicts on ret's
|
||||
|
||||
assign target_mispredict = pp_in.pret & (pp_in.prett[31:1] != aout[31:1]);
|
||||
assign target_mispredict = pp_in.pret & (pp_in.prett[31:1] != aout[31:1]);
|
||||
|
||||
assign flush_upper_out = (ap.jal | cond_mispredict | target_mispredict) & valid_in & ~flush_upper_x & ~flush_lower_r;
|
||||
assign flush_final_out = ( (ap.jal | cond_mispredict | target_mispredict) & valid_in & ~flush_upper_x ) | flush_lower_r;
|
||||
assign flush_upper_out = (ap.jal | cond_mispredict | target_mispredict) & valid_in & ~flush_upper_x & ~flush_lower_r;
|
||||
assign flush_final_out = ( (ap.jal | cond_mispredict | target_mispredict) & valid_in & ~flush_upper_x ) | flush_lower_r;
|
||||
|
||||
|
||||
// .i 3
|
||||
// .o 2
|
||||
// .ilb hist[1] hist[0] taken
|
||||
// .ob newhist[1] newhist[0]
|
||||
// .type fd
|
||||
//
|
||||
// 00 0 01
|
||||
// 01 0 01
|
||||
// 10 0 00
|
||||
// 11 0 10
|
||||
// 00 1 10
|
||||
// 01 1 00
|
||||
// 10 1 11
|
||||
// 11 1 11
|
||||
// .i 3
|
||||
// .o 2
|
||||
// .ilb hist[1] hist[0] taken
|
||||
// .ob newhist[1] newhist[0]
|
||||
// .type fd
|
||||
//
|
||||
// 00 0 01
|
||||
// 01 0 01
|
||||
// 10 0 00
|
||||
// 11 0 10
|
||||
// 00 1 10
|
||||
// 01 1 00
|
||||
// 10 1 11
|
||||
// 11 1 11
|
||||
|
||||
assign newhist[1] = ( pp_in.hist[1] & pp_in.hist[0]) | (~pp_in.hist[0] & actual_taken);
|
||||
assign newhist[0] = (~pp_in.hist[1] & ~actual_taken) | ( pp_in.hist[1] & actual_taken);
|
||||
assign newhist[1] = (pp_in.hist[1] & pp_in.hist[0]) | (~pp_in.hist[0] & actual_taken);
|
||||
assign newhist[0] = (~pp_in.hist[1] & ~actual_taken) | (pp_in.hist[1] & actual_taken);
|
||||
|
||||
always_comb begin
|
||||
predict_p_out = pp_in;
|
||||
always_comb begin
|
||||
predict_p_out = pp_in;
|
||||
|
||||
predict_p_out.misp = ~flush_upper_x & ~flush_lower_r & (cond_mispredict | target_mispredict);
|
||||
predict_p_out.ataken = actual_taken;
|
||||
predict_p_out.hist[1] = newhist[1];
|
||||
predict_p_out.hist[0] = newhist[0];
|
||||
predict_p_out.misp = ~flush_upper_x & ~flush_lower_r & (cond_mispredict | target_mispredict);
|
||||
predict_p_out.ataken = actual_taken;
|
||||
predict_p_out.hist[1] = newhist[1];
|
||||
predict_p_out.hist[0] = newhist[0];
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
endmodule // el2_exu_alu_ctl
|
||||
endmodule // el2_exu_alu_ctl
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -20,352 +20,411 @@
|
|||
//********************************************************************************
|
||||
|
||||
module el2_ifu
|
||||
import el2_pkg::*;
|
||||
import el2_pkg::*;
|
||||
#(
|
||||
`include "el2_param.vh"
|
||||
)
|
||||
(
|
||||
input logic free_l2clk, // Clock always. Through one clock header. For flops with second header built in.
|
||||
input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in.
|
||||
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
|
||||
input logic rst_l, // reset, active low
|
||||
`include "el2_param.vh"
|
||||
) (
|
||||
input logic free_l2clk, // Clock always. Through one clock header. For flops with second header built in.
|
||||
input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in.
|
||||
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
|
||||
input logic rst_l, // reset, active low
|
||||
|
||||
input logic dec_i0_decode_d, // Valid instruction at D and not blocked
|
||||
input logic dec_i0_decode_d, // Valid instruction at D and not blocked
|
||||
|
||||
input logic exu_flush_final, // flush, includes upper and lower
|
||||
input logic dec_tlu_i0_commit_cmt , // committed i0
|
||||
input logic dec_tlu_flush_err_wb , // flush due to parity error.
|
||||
input logic dec_tlu_flush_noredir_wb, // don't fetch, validated with exu_flush_final
|
||||
input logic [31:1] exu_flush_path_final, // flush fetch address
|
||||
input logic exu_flush_final, // flush, includes upper and lower
|
||||
input logic dec_tlu_i0_commit_cmt, // committed i0
|
||||
input logic dec_tlu_flush_err_wb, // flush due to parity error.
|
||||
input logic dec_tlu_flush_noredir_wb, // don't fetch, validated with exu_flush_final
|
||||
input logic [31:1] exu_flush_path_final, // flush fetch address
|
||||
|
||||
input logic [31:0] dec_tlu_mrac_ff ,// Side_effect , cacheable for each region
|
||||
input logic dec_tlu_fence_i_wb, // fence.i, invalidate icache, validated with exu_flush_final
|
||||
input logic dec_tlu_flush_leak_one_wb, // ignore bp for leak one fetches
|
||||
input logic [31:0] dec_tlu_mrac_ff, // Side_effect , cacheable for each region
|
||||
input logic dec_tlu_fence_i_wb, // fence.i, invalidate icache, validated with exu_flush_final
|
||||
input logic dec_tlu_flush_leak_one_wb, // ignore bp for leak one fetches
|
||||
|
||||
input logic dec_tlu_bpred_disable, // disable all branch prediction
|
||||
input logic dec_tlu_core_ecc_disable, // disable ecc checking and flagging
|
||||
input logic dec_tlu_force_halt, // force halt
|
||||
input logic dec_tlu_bpred_disable, // disable all branch prediction
|
||||
input logic dec_tlu_core_ecc_disable, // disable ecc checking and flagging
|
||||
input logic dec_tlu_force_halt, // force halt
|
||||
|
||||
//-------------------------- IFU AXI signals--------------------------
|
||||
// AXI Write Channels
|
||||
output logic ifu_axi_awvalid,
|
||||
output logic [pt.IFU_BUS_TAG-1:0] ifu_axi_awid,
|
||||
output logic [31:0] ifu_axi_awaddr,
|
||||
output logic [3:0] ifu_axi_awregion,
|
||||
output logic [7:0] ifu_axi_awlen,
|
||||
output logic [2:0] ifu_axi_awsize,
|
||||
output logic [1:0] ifu_axi_awburst,
|
||||
output logic ifu_axi_awlock,
|
||||
output logic [3:0] ifu_axi_awcache,
|
||||
output logic [2:0] ifu_axi_awprot,
|
||||
output logic [3:0] ifu_axi_awqos,
|
||||
//-------------------------- IFU AXI signals--------------------------
|
||||
// AXI Write Channels
|
||||
output logic ifu_axi_awvalid,
|
||||
output logic [pt.IFU_BUS_TAG-1:0] ifu_axi_awid,
|
||||
output logic [ 31:0] ifu_axi_awaddr,
|
||||
output logic [ 3:0] ifu_axi_awregion,
|
||||
output logic [ 7:0] ifu_axi_awlen,
|
||||
output logic [ 2:0] ifu_axi_awsize,
|
||||
output logic [ 1:0] ifu_axi_awburst,
|
||||
output logic ifu_axi_awlock,
|
||||
output logic [ 3:0] ifu_axi_awcache,
|
||||
output logic [ 2:0] ifu_axi_awprot,
|
||||
output logic [ 3:0] ifu_axi_awqos,
|
||||
|
||||
output logic ifu_axi_wvalid,
|
||||
output logic [63:0] ifu_axi_wdata,
|
||||
output logic [7:0] ifu_axi_wstrb,
|
||||
output logic ifu_axi_wlast,
|
||||
output logic ifu_axi_wvalid,
|
||||
output logic [63:0] ifu_axi_wdata,
|
||||
output logic [ 7:0] ifu_axi_wstrb,
|
||||
output logic ifu_axi_wlast,
|
||||
|
||||
output logic ifu_axi_bready,
|
||||
output logic ifu_axi_bready,
|
||||
|
||||
// AXI Read Channels
|
||||
output logic ifu_axi_arvalid,
|
||||
input logic ifu_axi_arready,
|
||||
output logic [pt.IFU_BUS_TAG-1:0] ifu_axi_arid,
|
||||
output logic [31:0] ifu_axi_araddr,
|
||||
output logic [3:0] ifu_axi_arregion,
|
||||
output logic [7:0] ifu_axi_arlen,
|
||||
output logic [2:0] ifu_axi_arsize,
|
||||
output logic [1:0] ifu_axi_arburst,
|
||||
output logic ifu_axi_arlock,
|
||||
output logic [3:0] ifu_axi_arcache,
|
||||
output logic [2:0] ifu_axi_arprot,
|
||||
output logic [3:0] ifu_axi_arqos,
|
||||
// AXI Read Channels
|
||||
output logic ifu_axi_arvalid,
|
||||
input logic ifu_axi_arready,
|
||||
output logic [pt.IFU_BUS_TAG-1:0] ifu_axi_arid,
|
||||
output logic [ 31:0] ifu_axi_araddr,
|
||||
output logic [ 3:0] ifu_axi_arregion,
|
||||
output logic [ 7:0] ifu_axi_arlen,
|
||||
output logic [ 2:0] ifu_axi_arsize,
|
||||
output logic [ 1:0] ifu_axi_arburst,
|
||||
output logic ifu_axi_arlock,
|
||||
output logic [ 3:0] ifu_axi_arcache,
|
||||
output logic [ 2:0] ifu_axi_arprot,
|
||||
output logic [ 3:0] ifu_axi_arqos,
|
||||
|
||||
input logic ifu_axi_rvalid,
|
||||
output logic ifu_axi_rready,
|
||||
input logic [pt.IFU_BUS_TAG-1:0] ifu_axi_rid,
|
||||
input logic [63:0] ifu_axi_rdata,
|
||||
input logic [1:0] ifu_axi_rresp,
|
||||
input logic ifu_axi_rvalid,
|
||||
output logic ifu_axi_rready,
|
||||
input logic [pt.IFU_BUS_TAG-1:0] ifu_axi_rid,
|
||||
input logic [ 63:0] ifu_axi_rdata,
|
||||
input logic [ 1:0] ifu_axi_rresp,
|
||||
|
||||
input logic ifu_bus_clk_en,
|
||||
input logic ifu_bus_clk_en,
|
||||
|
||||
input logic dma_iccm_req,
|
||||
input logic [31:0] dma_mem_addr,
|
||||
input logic [2:0] dma_mem_sz,
|
||||
input logic dma_mem_write,
|
||||
input logic [63:0] dma_mem_wdata,
|
||||
input logic [2:0] dma_mem_tag, // DMA Buffer entry number
|
||||
input logic dma_iccm_req,
|
||||
input logic [31:0] dma_mem_addr,
|
||||
input logic [ 2:0] dma_mem_sz,
|
||||
input logic dma_mem_write,
|
||||
input logic [63:0] dma_mem_wdata,
|
||||
input logic [ 2:0] dma_mem_tag, // DMA Buffer entry number
|
||||
|
||||
|
||||
input logic dma_iccm_stall_any,
|
||||
output logic iccm_dma_ecc_error,
|
||||
output logic iccm_dma_rvalid,
|
||||
output logic [63:0] iccm_dma_rdata,
|
||||
output logic [2:0] iccm_dma_rtag, // Tag of the DMA req
|
||||
output logic iccm_ready,
|
||||
input logic dma_iccm_stall_any,
|
||||
output logic iccm_dma_ecc_error,
|
||||
output logic iccm_dma_rvalid,
|
||||
output logic [63:0] iccm_dma_rdata,
|
||||
output logic [ 2:0] iccm_dma_rtag, // Tag of the DMA req
|
||||
output logic iccm_ready,
|
||||
|
||||
output logic ifu_pmu_instr_aligned,
|
||||
output logic ifu_pmu_fetch_stall,
|
||||
output logic ifu_ic_error_start, // has all of the I$ ecc/parity for data/tag
|
||||
output logic ifu_pmu_instr_aligned,
|
||||
output logic ifu_pmu_fetch_stall,
|
||||
output logic ifu_ic_error_start, // has all of the I$ ecc/parity for data/tag
|
||||
|
||||
// I$ & ITAG Ports
|
||||
output logic [31:1] ic_rw_addr, // Read/Write addresss to the Icache.
|
||||
output logic [pt.ICACHE_NUM_WAYS-1:0] ic_wr_en, // Icache write enable, when filling the Icache.
|
||||
output logic ic_rd_en, // Icache read enable.
|
||||
// I$ & ITAG Ports
|
||||
output logic [31:1] ic_rw_addr, // Read/Write addresss to the Icache.
|
||||
output logic [pt.ICACHE_NUM_WAYS-1:0] ic_wr_en, // Icache write enable, when filling the Icache.
|
||||
output logic ic_rd_en, // Icache read enable.
|
||||
|
||||
output logic [pt.ICACHE_BANKS_WAY-1:0][70:0] ic_wr_data, // Data to fill to the Icache. With ECC
|
||||
input logic [63:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC
|
||||
input logic [70:0] ic_debug_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC
|
||||
input logic [25:0] ictag_debug_rd_data,// Debug icache tag.
|
||||
output logic [70:0] ic_debug_wr_data, // Debug wr cache.
|
||||
output logic [pt.ICACHE_BANKS_WAY-1:0][70:0] ic_wr_data, // Data to fill to the Icache. With ECC
|
||||
input logic [63:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC
|
||||
input logic [70:0] ic_debug_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC
|
||||
input logic [25:0] ictag_debug_rd_data, // Debug icache tag.
|
||||
output logic [70:0] ic_debug_wr_data, // Debug wr cache.
|
||||
|
||||
output logic [70:0] ifu_ic_debug_rd_data,
|
||||
output logic [70:0] ifu_ic_debug_rd_data,
|
||||
|
||||
input logic [pt.ICACHE_BANKS_WAY-1:0] ic_eccerr, //
|
||||
input logic [pt.ICACHE_BANKS_WAY-1:0] ic_parerr,
|
||||
output logic [63:0] ic_premux_data, // Premux data to be muxed with each way of the Icache.
|
||||
output logic ic_sel_premux_data, // Select the premux data.
|
||||
input logic [pt.ICACHE_BANKS_WAY-1:0] ic_eccerr, //
|
||||
input logic [pt.ICACHE_BANKS_WAY-1:0] ic_parerr,
|
||||
output logic [63:0] ic_premux_data, // Premux data to be muxed with each way of the Icache.
|
||||
output logic ic_sel_premux_data, // Select the premux data.
|
||||
|
||||
output logic [pt.ICACHE_INDEX_HI:3] ic_debug_addr, // Read/Write addresss to the Icache.
|
||||
output logic ic_debug_rd_en, // Icache debug rd
|
||||
output logic ic_debug_wr_en, // Icache debug wr
|
||||
output logic ic_debug_tag_array, // Debug tag array
|
||||
output logic [pt.ICACHE_NUM_WAYS-1:0] ic_debug_way, // Debug way. Rd or Wr.
|
||||
output logic [ pt.ICACHE_INDEX_HI:3] ic_debug_addr, // Read/Write addresss to the Icache.
|
||||
output logic ic_debug_rd_en, // Icache debug rd
|
||||
output logic ic_debug_wr_en, // Icache debug wr
|
||||
output logic ic_debug_tag_array, // Debug tag array
|
||||
output logic [pt.ICACHE_NUM_WAYS-1:0] ic_debug_way, // Debug way. Rd or Wr.
|
||||
|
||||
|
||||
output logic [pt.ICACHE_NUM_WAYS-1:0] ic_tag_valid, // Valid bits when accessing the Icache. One valid bit per way. F2 stage
|
||||
output logic [pt.ICACHE_NUM_WAYS-1:0] ic_tag_valid, // Valid bits when accessing the Icache. One valid bit per way. F2 stage
|
||||
|
||||
input logic [pt.ICACHE_NUM_WAYS-1:0] ic_rd_hit, // Compare hits from Icache tags. Per way. F2 stage
|
||||
input logic ic_tag_perr, // Icache Tag parity error
|
||||
input logic [pt.ICACHE_NUM_WAYS-1:0] ic_rd_hit, // Compare hits from Icache tags. Per way. F2 stage
|
||||
input logic ic_tag_perr, // Icache Tag parity error
|
||||
|
||||
|
||||
// ICCM ports
|
||||
output logic [pt.ICCM_BITS-1:1] iccm_rw_addr, // ICCM read/write address.
|
||||
output logic iccm_wren, // ICCM write enable (through the DMA)
|
||||
output logic iccm_rden, // ICCM read enable.
|
||||
output logic [77:0] iccm_wr_data, // ICCM write data.
|
||||
output logic [2:0] iccm_wr_size, // ICCM write location within DW.
|
||||
// ICCM ports
|
||||
output logic [pt.ICCM_BITS-1:1] iccm_rw_addr, // ICCM read/write address.
|
||||
output logic iccm_wren, // ICCM write enable (through the DMA)
|
||||
output logic iccm_rden, // ICCM read enable.
|
||||
output logic [ 77:0] iccm_wr_data, // ICCM write data.
|
||||
output logic [ 2:0] iccm_wr_size, // ICCM write location within DW.
|
||||
|
||||
input logic [63:0] iccm_rd_data, // Data read from ICCM.
|
||||
input logic [77:0] iccm_rd_data_ecc, // Data + ECC read from ICCM.
|
||||
input logic [63:0] iccm_rd_data, // Data read from ICCM.
|
||||
input logic [77:0] iccm_rd_data_ecc, // Data + ECC read from ICCM.
|
||||
|
||||
output logic ifu_iccm_rd_ecc_single_err, // This fetch has a single ICCM ecc error.
|
||||
output logic ifu_iccm_rd_ecc_single_err, // This fetch has a single ICCM ecc error.
|
||||
|
||||
// Perf counter sigs
|
||||
output logic ifu_pmu_ic_miss, // ic miss
|
||||
output logic ifu_pmu_ic_hit, // ic hit
|
||||
output logic ifu_pmu_bus_error, // iside bus error
|
||||
output logic ifu_pmu_bus_busy, // iside bus busy
|
||||
output logic ifu_pmu_bus_trxn, // iside bus transactions
|
||||
// Perf counter sigs
|
||||
output logic ifu_pmu_ic_miss, // ic miss
|
||||
output logic ifu_pmu_ic_hit, // ic hit
|
||||
output logic ifu_pmu_bus_error, // iside bus error
|
||||
output logic ifu_pmu_bus_busy, // iside bus busy
|
||||
output logic ifu_pmu_bus_trxn, // iside bus transactions
|
||||
|
||||
|
||||
output logic ifu_i0_icaf, // Instruction 0 access fault. From Aligner to Decode
|
||||
output logic [1:0] ifu_i0_icaf_type, // Instruction 0 access fault type
|
||||
output logic ifu_i0_icaf, // Instruction 0 access fault. From Aligner to Decode
|
||||
output logic [1:0] ifu_i0_icaf_type, // Instruction 0 access fault type
|
||||
|
||||
output logic ifu_i0_valid, // Instruction 0 valid. From Aligner to Decode
|
||||
output logic ifu_i0_icaf_second, // Instruction 0 has access fault on second 2B of 4B inst
|
||||
output logic ifu_i0_dbecc, // Instruction 0 has double bit ecc error
|
||||
output logic iccm_dma_sb_error, // Single Bit ECC error from a DMA access
|
||||
output logic[31:0] ifu_i0_instr, // Instruction 0 . From Aligner to Decode
|
||||
output logic[31:1] ifu_i0_pc, // Instruction 0 pc. From Aligner to Decode
|
||||
output logic ifu_i0_pc4, // Instruction 0 is 4 byte. From Aligner to Decode
|
||||
output logic ifu_i0_valid, // Instruction 0 valid. From Aligner to Decode
|
||||
output logic ifu_i0_icaf_second, // Instruction 0 has access fault on second 2B of 4B inst
|
||||
output logic ifu_i0_dbecc, // Instruction 0 has double bit ecc error
|
||||
output logic iccm_dma_sb_error, // Single Bit ECC error from a DMA access
|
||||
output logic [31:0] ifu_i0_instr, // Instruction 0 . From Aligner to Decode
|
||||
output logic [31:1] ifu_i0_pc, // Instruction 0 pc. From Aligner to Decode
|
||||
output logic ifu_i0_pc4, // Instruction 0 is 4 byte. From Aligner to Decode
|
||||
|
||||
output logic ifu_miss_state_idle, // There is no outstanding miss. Cache miss state is idle.
|
||||
output logic ifu_miss_state_idle, // There is no outstanding miss. Cache miss state is idle.
|
||||
|
||||
output el2_br_pkt_t i0_brp, // Instruction 0 branch packet. From Aligner to Decode
|
||||
output logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] ifu_i0_bp_index, // BP index
|
||||
output logic [pt.BHT_GHR_SIZE-1:0] ifu_i0_bp_fghr, // BP FGHR
|
||||
output logic [pt.BTB_BTAG_SIZE-1:0] ifu_i0_bp_btag, // BP tag
|
||||
output logic [$clog2(pt.BTB_SIZE)-1:0] ifu_i0_fa_index, // Fully associt btb index
|
||||
output el2_br_pkt_t i0_brp, // Instruction 0 branch packet. From Aligner to Decode
|
||||
output logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] ifu_i0_bp_index, // BP index
|
||||
output logic [pt.BHT_GHR_SIZE-1:0] ifu_i0_bp_fghr, // BP FGHR
|
||||
output logic [pt.BTB_BTAG_SIZE-1:0] ifu_i0_bp_btag, // BP tag
|
||||
output logic [$clog2(pt.BTB_SIZE)-1:0] ifu_i0_fa_index, // Fully associt btb index
|
||||
|
||||
input el2_predict_pkt_t exu_mp_pkt, // mispredict packet
|
||||
input logic [pt.BHT_GHR_SIZE-1:0] exu_mp_eghr, // execute ghr
|
||||
input logic [pt.BHT_GHR_SIZE-1:0] exu_mp_fghr, // Mispredict fghr
|
||||
input logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] exu_mp_index, // Mispredict index
|
||||
input logic [pt.BTB_BTAG_SIZE-1:0] exu_mp_btag, // Mispredict btag
|
||||
input el2_predict_pkt_t exu_mp_pkt, // mispredict packet
|
||||
input logic [ pt.BHT_GHR_SIZE-1:0] exu_mp_eghr, // execute ghr
|
||||
input logic [ pt.BHT_GHR_SIZE-1:0] exu_mp_fghr, // Mispredict fghr
|
||||
input logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] exu_mp_index, // Mispredict index
|
||||
input logic [ pt.BTB_BTAG_SIZE-1:0] exu_mp_btag, // Mispredict btag
|
||||
|
||||
input el2_br_tlu_pkt_t dec_tlu_br0_r_pkt, // slot0 update/error pkt
|
||||
input logic [pt.BHT_GHR_SIZE-1:0] exu_i0_br_fghr_r, // fghr to bp
|
||||
input logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] exu_i0_br_index_r, // bp index
|
||||
input logic [$clog2(pt.BTB_SIZE)-1:0] dec_fa_error_index, // Fully associt btb error index
|
||||
input el2_br_tlu_pkt_t dec_tlu_br0_r_pkt, // slot0 update/error pkt
|
||||
input logic [pt.BHT_GHR_SIZE-1:0] exu_i0_br_fghr_r, // fghr to bp
|
||||
input logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] exu_i0_br_index_r, // bp index
|
||||
input logic [$clog2(pt.BTB_SIZE)-1:0] dec_fa_error_index, // Fully associt btb error index
|
||||
|
||||
input dec_tlu_flush_lower_wb,
|
||||
input dec_tlu_flush_lower_wb,
|
||||
|
||||
output logic [15:0] ifu_i0_cinst,
|
||||
output logic [15:0] ifu_i0_cinst,
|
||||
|
||||
|
||||
/// Icache debug
|
||||
input el2_cache_debug_pkt_t dec_tlu_ic_diag_pkt ,
|
||||
output logic ifu_ic_debug_rd_data_valid,
|
||||
output logic iccm_buf_correct_ecc,
|
||||
output logic iccm_correction_state,
|
||||
/// Icache debug
|
||||
input el2_cache_debug_pkt_t dec_tlu_ic_diag_pkt,
|
||||
output logic ifu_ic_debug_rd_data_valid,
|
||||
output logic iccm_buf_correct_ecc,
|
||||
output logic iccm_correction_state,
|
||||
|
||||
input logic scan_mode
|
||||
);
|
||||
input logic scan_mode
|
||||
);
|
||||
|
||||
localparam TAGWIDTH = 2 ;
|
||||
localparam IDWIDTH = 2 ;
|
||||
localparam TAGWIDTH = 2;
|
||||
localparam IDWIDTH = 2;
|
||||
|
||||
logic ifu_fb_consume1, ifu_fb_consume2;
|
||||
logic [31:1] ifc_fetch_addr_f;
|
||||
logic [31:1] ifc_fetch_addr_bf;
|
||||
logic ifu_fb_consume1, ifu_fb_consume2;
|
||||
logic [31:1] ifc_fetch_addr_f;
|
||||
logic [31:1] ifc_fetch_addr_bf;
|
||||
|
||||
logic [1:0] ifu_fetch_val; // valids on a 2B boundary, left justified [7] implies valid fetch
|
||||
logic [31:1] ifu_fetch_pc; // starting pc of fetch
|
||||
logic [ 1:0] ifu_fetch_val; // valids on a 2B boundary, left justified [7] implies valid fetch
|
||||
logic [31:1] ifu_fetch_pc; // starting pc of fetch
|
||||
|
||||
logic iccm_rd_ecc_single_err, ic_error_start;
|
||||
assign ifu_iccm_rd_ecc_single_err = iccm_rd_ecc_single_err;
|
||||
assign ifu_ic_error_start = ic_error_start;
|
||||
logic iccm_rd_ecc_single_err, ic_error_start;
|
||||
assign ifu_iccm_rd_ecc_single_err = iccm_rd_ecc_single_err;
|
||||
assign ifu_ic_error_start = ic_error_start;
|
||||
|
||||
|
||||
logic ic_write_stall;
|
||||
logic ic_dma_active;
|
||||
logic ifc_dma_access_ok;
|
||||
logic [1:0] ic_access_fault_f;
|
||||
logic [1:0] ic_access_fault_type_f;
|
||||
logic ifu_ic_mb_empty;
|
||||
logic ic_write_stall;
|
||||
logic ic_dma_active;
|
||||
logic ifc_dma_access_ok;
|
||||
logic [1:0] ic_access_fault_f;
|
||||
logic [1:0] ic_access_fault_type_f;
|
||||
logic ifu_ic_mb_empty;
|
||||
|
||||
logic ic_hit_f;
|
||||
logic ic_hit_f;
|
||||
|
||||
logic [1:0] ifu_bp_way_f; // way indication; right justified
|
||||
logic ifu_bp_hit_taken_f; // kill next fetch; taken target found
|
||||
logic [31:1] ifu_bp_btb_target_f; // predicted target PC
|
||||
logic ifu_bp_inst_mask_f; // tell ic which valids to kill because of a taken branch; right justified
|
||||
logic [1:0] ifu_bp_hist1_f; // history counters for all 4 potential branches; right justified
|
||||
logic [1:0] ifu_bp_hist0_f; // history counters for all 4 potential branches; right justified
|
||||
logic [11:0] ifu_bp_poffset_f; // predicted target
|
||||
logic [1:0] ifu_bp_ret_f; // predicted ret ; right justified
|
||||
logic [1:0] ifu_bp_pc4_f; // pc4 indication; right justified
|
||||
logic [1:0] ifu_bp_valid_f; // branch valid, right justified
|
||||
logic [pt.BHT_GHR_SIZE-1:0] ifu_bp_fghr_f;
|
||||
logic [1:0] [$clog2(pt.BTB_SIZE)-1:0] ifu_bp_fa_index_f;
|
||||
logic [1:0] ifu_bp_way_f; // way indication; right justified
|
||||
logic ifu_bp_hit_taken_f; // kill next fetch; taken target found
|
||||
logic [31:1] ifu_bp_btb_target_f; // predicted target PC
|
||||
logic ifu_bp_inst_mask_f; // tell ic which valids to kill because of a taken branch; right justified
|
||||
logic [1:0] ifu_bp_hist1_f; // history counters for all 4 potential branches; right justified
|
||||
logic [1:0] ifu_bp_hist0_f; // history counters for all 4 potential branches; right justified
|
||||
logic [11:0] ifu_bp_poffset_f; // predicted target
|
||||
logic [1:0] ifu_bp_ret_f; // predicted ret ; right justified
|
||||
logic [1:0] ifu_bp_pc4_f; // pc4 indication; right justified
|
||||
logic [1:0] ifu_bp_valid_f; // branch valid, right justified
|
||||
logic [pt.BHT_GHR_SIZE-1:0] ifu_bp_fghr_f;
|
||||
logic [1:0][$clog2(pt.BTB_SIZE)-1:0] ifu_bp_fa_index_f;
|
||||
|
||||
|
||||
// fetch control
|
||||
el2_ifu_ifc_ctl #(.pt(pt)) ifc (.*
|
||||
);
|
||||
// fetch control
|
||||
el2_ifu_ifc_ctl #(.pt(pt)) ifc (.*);
|
||||
|
||||
// branch predictor
|
||||
if (pt.BTB_ENABLE==1) begin : bpred
|
||||
el2_ifu_bp_ctl #(.pt(pt)) bp (.*);
|
||||
end
|
||||
else begin : bpred
|
||||
assign ifu_bp_hit_taken_f = '0;
|
||||
// verif wires
|
||||
logic btb_wr_en_way0, btb_wr_en_way1,dec_tlu_error_wb;
|
||||
logic [16+pt.BTB_BTAG_SIZE:0] btb_wr_data;
|
||||
assign btb_wr_en_way0 = '0;
|
||||
assign btb_wr_en_way1 = '0;
|
||||
assign btb_wr_data = '0;
|
||||
assign dec_tlu_error_wb ='0;
|
||||
assign ifu_bp_inst_mask_f = 1'b1;
|
||||
end
|
||||
// branch predictor
|
||||
if (pt.BTB_ENABLE == 1) begin : bpred
|
||||
el2_ifu_bp_ctl #(.pt(pt)) bp (.*);
|
||||
end else begin : bpred
|
||||
assign ifu_bp_hit_taken_f = '0;
|
||||
// verif wires
|
||||
logic btb_wr_en_way0, btb_wr_en_way1, dec_tlu_error_wb;
|
||||
logic [16+pt.BTB_BTAG_SIZE:0] btb_wr_data;
|
||||
assign btb_wr_en_way0 = '0;
|
||||
assign btb_wr_en_way1 = '0;
|
||||
assign btb_wr_data = '0;
|
||||
assign dec_tlu_error_wb = '0;
|
||||
assign ifu_bp_inst_mask_f = 1'b1;
|
||||
end
|
||||
|
||||
|
||||
logic [1:0] ic_fetch_val_f;
|
||||
logic [31:0] ic_data_f;
|
||||
logic [31:0] ifu_fetch_data_f;
|
||||
logic ifc_fetch_req_f;
|
||||
logic ifc_fetch_req_f_raw;
|
||||
logic [1:0] iccm_rd_ecc_double_err; // This fetch has an iccm double error.
|
||||
logic [1:0] ic_fetch_val_f;
|
||||
logic [31:0] ic_data_f;
|
||||
logic [31:0] ifu_fetch_data_f;
|
||||
logic ifc_fetch_req_f;
|
||||
logic ifc_fetch_req_f_raw;
|
||||
logic [1:0] iccm_rd_ecc_double_err; // This fetch has an iccm double error.
|
||||
|
||||
logic ifu_async_error_start;
|
||||
logic ifu_async_error_start;
|
||||
|
||||
|
||||
assign ifu_fetch_data_f[31:0] = ic_data_f[31:0];
|
||||
assign ifu_fetch_val[1:0] = ic_fetch_val_f[1:0];
|
||||
assign ifu_fetch_pc[31:1] = ifc_fetch_addr_f[31:1];
|
||||
assign ifu_fetch_data_f[31:0] = ic_data_f[31:0];
|
||||
assign ifu_fetch_val[1:0] = ic_fetch_val_f[1:0];
|
||||
assign ifu_fetch_pc[31:1] = ifc_fetch_addr_f[31:1];
|
||||
|
||||
logic ifc_fetch_uncacheable_bf; // The fetch request is uncacheable space. BF stage
|
||||
logic ifc_fetch_req_bf; // Fetch request. Comes with the address. BF stage
|
||||
logic ifc_fetch_req_bf_raw; // Fetch request without some qualifications. Used for clock-gating. BF stage
|
||||
logic ifc_iccm_access_bf; // This request is to the ICCM. Do not generate misses to the bus.
|
||||
logic ifc_region_acc_fault_bf; // Access fault. in ICCM region but offset is outside defined ICCM.
|
||||
logic ifc_fetch_uncacheable_bf; // The fetch request is uncacheable space. BF stage
|
||||
logic ifc_fetch_req_bf; // Fetch request. Comes with the address. BF stage
|
||||
logic ifc_fetch_req_bf_raw; // Fetch request without some qualifications. Used for clock-gating. BF stage
|
||||
logic ifc_iccm_access_bf; // This request is to the ICCM. Do not generate misses to the bus.
|
||||
logic ifc_region_acc_fault_bf; // Access fault. in ICCM region but offset is outside defined ICCM.
|
||||
|
||||
// aligner
|
||||
// aligner
|
||||
|
||||
el2_ifu_aln_ctl #(.pt(pt)) aln (
|
||||
.*
|
||||
);
|
||||
el2_ifu_aln_ctl #(.pt(pt)) aln (.*);
|
||||
|
||||
|
||||
// icache
|
||||
el2_ifu_mem_ctl #(.pt(pt)) mem_ctl
|
||||
(.*,
|
||||
// icache
|
||||
el2_ifu_mem_ctl #(
|
||||
.pt(pt)
|
||||
) mem_ctl (
|
||||
.*,
|
||||
.ic_data_f(ic_data_f[31:0])
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Performance debug info
|
||||
//
|
||||
//
|
||||
`ifdef DUMP_BTB_ON
|
||||
logic exu_mp_valid; // conditional branch mispredict
|
||||
logic exu_mp_way; // conditional branch mispredict
|
||||
logic exu_mp_ataken; // direction is actual taken
|
||||
logic exu_mp_boffset; // branch offsett
|
||||
logic exu_mp_pc4; // branch is a 4B inst
|
||||
logic exu_mp_call; // branch is a call inst
|
||||
logic exu_mp_ret; // branch is a ret inst
|
||||
logic exu_mp_ja; // branch is a jump always
|
||||
logic [ 1:0] exu_mp_hist; // new history
|
||||
logic [ 11:0] exu_mp_tgt; // target offset
|
||||
logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] exu_mp_addr; // BTB/BHT address
|
||||
|
||||
assign exu_mp_valid = exu_mp_pkt.misp; // conditional branch mispredict
|
||||
assign exu_mp_ataken = exu_mp_pkt.ataken; // direction is actual taken
|
||||
assign exu_mp_boffset = exu_mp_pkt.boffset; // branch offset
|
||||
assign exu_mp_pc4 = exu_mp_pkt.pc4; // branch is a 4B inst
|
||||
assign exu_mp_call = exu_mp_pkt.pcall; // branch is a call inst
|
||||
assign exu_mp_ret = exu_mp_pkt.pret; // branch is a ret inst
|
||||
assign exu_mp_ja = exu_mp_pkt.pja; // branch is a jump always
|
||||
assign exu_mp_way = exu_mp_pkt.way; // branch is a jump always
|
||||
assign exu_mp_hist[1:0] = exu_mp_pkt.hist[1:0]; // new history
|
||||
assign exu_mp_tgt[11:0] = exu_mp_pkt.toffset[11:0]; // target offset
|
||||
assign exu_mp_addr[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] = exu_mp_index[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] ; // BTB/BHT address
|
||||
|
||||
logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] btb_rd_addr_f;
|
||||
`define DEC top.rvtop.swerv.dec
|
||||
`define EXU top.rvtop.swerv.exu
|
||||
el2_btb_addr_hash f2hash (
|
||||
.pc (ifc_fetch_addr_f[pt.BTB_INDEX3_HI:pt.BTB_INDEX1_LO]),
|
||||
.hash(btb_rd_addr_f[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO])
|
||||
);
|
||||
logic [31:0] mppc_ns, mppc;
|
||||
logic exu_flush_final_d1;
|
||||
assign mppc_ns[31:1] = `EXU.i0_flush_upper_x ? `EXU.exu_i0_pc_x : `EXU.dec_i0_pc_d;
|
||||
assign mppc_ns[0] = 1'b0;
|
||||
rvdff #(33) junk_ff (
|
||||
.*,
|
||||
.clk (active_clk),
|
||||
.din ({mppc_ns[31:0], exu_flush_final}),
|
||||
.dout({mppc[31:0], exu_flush_final_d1})
|
||||
);
|
||||
logic tmp_bnk;
|
||||
assign tmp_bnk = bpred.bp.btb_sel_f[1];
|
||||
|
||||
always @(negedge clk) begin
|
||||
if (`DEC.tlu.mcyclel[31:0] == 32'h0000_0010) begin
|
||||
$display("BTB_CONFIG: %d", pt.BTB_SIZE);
|
||||
`ifndef BP_NOGSHARE
|
||||
$display("BHT_CONFIG: %d gshare: 1", pt.BHT_SIZE);
|
||||
`else
|
||||
$display("BHT_CONFIG: %d gshare: 0", pt.BHT_SIZE);
|
||||
`endif
|
||||
$display("RS_CONFIG: %d", pt.RET_STACK_SIZE);
|
||||
end
|
||||
if(exu_flush_final_d1 & ~(dec_tlu_br0_r_pkt.br_error | dec_tlu_br0_r_pkt.br_start_error) & (exu_mp_pkt.misp | exu_mp_pkt.ataken))
|
||||
$display(
|
||||
"%7d BTB_MP : index: %0h bank: %0h call: %b ret: %b ataken: %b hist: %h valid: %b tag: %h targ: %h eghr: %b pred: %b ghr_index: %h brpc: %h way: %h",
|
||||
`DEC.tlu.mcyclel[31:0] + 32'ha,
|
||||
exu_mp_addr[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO],
|
||||
1'b0,
|
||||
exu_mp_call,
|
||||
exu_mp_ret,
|
||||
exu_mp_ataken,
|
||||
exu_mp_hist[1:0],
|
||||
exu_mp_valid,
|
||||
exu_mp_btag[pt.BTB_BTAG_SIZE-1:0],
|
||||
{
|
||||
exu_flush_path_final[31:1], 1'b0
|
||||
},
|
||||
exu_mp_eghr[pt.BHT_GHR_SIZE-1:0],
|
||||
exu_mp_valid,
|
||||
bpred.bp.bht_wr_addr0,
|
||||
mppc[31:0],
|
||||
exu_mp_pkt.way
|
||||
);
|
||||
|
||||
for (int i = 0; i < 8; i++) begin
|
||||
if (ifu_bp_valid_f[i] & ifc_fetch_req_f)
|
||||
$display(
|
||||
"%7d BTB_HIT : index: %0h bank: %0h call: %b ret: %b taken: %b strength: %b tag: %h targ: %0h ghr: %4b ghr_index: %h way: %h",
|
||||
`DEC.tlu.mcyclel[31:0] + 32'ha,
|
||||
btb_rd_addr_f[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO],
|
||||
bpred.bp.btb_sel_f[1],
|
||||
bpred.bp.btb_rd_call_f,
|
||||
bpred.bp.btb_rd_ret_f,
|
||||
ifu_bp_hist1_f[tmp_bnk],
|
||||
ifu_bp_hist0_f[tmp_bnk],
|
||||
bpred.bp.fetch_rd_tag_f[pt.BTB_BTAG_SIZE-1:0],
|
||||
{
|
||||
ifu_bp_btb_target_f[31:1], 1'b0
|
||||
},
|
||||
bpred.bp.fghr[pt.BHT_GHR_SIZE-1:0],
|
||||
bpred.bp.bht_rd_addr_f,
|
||||
ifu_bp_way_f[tmp_bnk]
|
||||
);
|
||||
end
|
||||
if (dec_tlu_br0_r_pkt.valid & ~(dec_tlu_br0_r_pkt.br_error | dec_tlu_br0_r_pkt.br_start_error))
|
||||
$display(
|
||||
"%7d BTB_UPD0: ghr_index: %0h bank: %0h hist: %h way: %h",
|
||||
`DEC.tlu.mcyclel[31:0] + 32'ha,
|
||||
bpred.bp.br0_hashed_wb[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO],
|
||||
{
|
||||
dec_tlu_br0_r_pkt.middle
|
||||
},
|
||||
dec_tlu_br0_r_pkt.hist,
|
||||
dec_tlu_br0_r_pkt.way
|
||||
);
|
||||
|
||||
if (dec_tlu_br0_r_pkt.br_error | dec_tlu_br0_r_pkt.br_start_error)
|
||||
$display(
|
||||
"%7d BTB_ERR0: index: %0h bank: %0h start: %b rfpc: %h way: %h",
|
||||
`DEC.tlu.mcyclel[31:0] + 32'ha,
|
||||
exu_i0_br_index_r[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO],
|
||||
1'b0,
|
||||
dec_tlu_br0_r_pkt.br_start_error,
|
||||
{
|
||||
exu_flush_path_final[31:1], 1'b0
|
||||
},
|
||||
dec_tlu_br0_r_pkt.way
|
||||
);
|
||||
end // always @ (negedge clk)
|
||||
function [1:0] encode4_2;
|
||||
input [3:0] in;
|
||||
|
||||
// Performance debug info
|
||||
//
|
||||
//
|
||||
`ifdef DUMP_BTB_ON
|
||||
logic exu_mp_valid; // conditional branch mispredict
|
||||
logic exu_mp_way; // conditional branch mispredict
|
||||
logic exu_mp_ataken; // direction is actual taken
|
||||
logic exu_mp_boffset; // branch offsett
|
||||
logic exu_mp_pc4; // branch is a 4B inst
|
||||
logic exu_mp_call; // branch is a call inst
|
||||
logic exu_mp_ret; // branch is a ret inst
|
||||
logic exu_mp_ja; // branch is a jump always
|
||||
logic [1:0] exu_mp_hist; // new history
|
||||
logic [11:0] exu_mp_tgt; // target offset
|
||||
logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] exu_mp_addr; // BTB/BHT address
|
||||
encode4_2[1] = in[3] | in[2];
|
||||
encode4_2[0] = in[3] | in[1];
|
||||
|
||||
assign exu_mp_valid = exu_mp_pkt.misp; // conditional branch mispredict
|
||||
assign exu_mp_ataken = exu_mp_pkt.ataken; // direction is actual taken
|
||||
assign exu_mp_boffset = exu_mp_pkt.boffset; // branch offset
|
||||
assign exu_mp_pc4 = exu_mp_pkt.pc4; // branch is a 4B inst
|
||||
assign exu_mp_call = exu_mp_pkt.pcall; // branch is a call inst
|
||||
assign exu_mp_ret = exu_mp_pkt.pret; // branch is a ret inst
|
||||
assign exu_mp_ja = exu_mp_pkt.pja; // branch is a jump always
|
||||
assign exu_mp_way = exu_mp_pkt.way; // branch is a jump always
|
||||
assign exu_mp_hist[1:0] = exu_mp_pkt.hist[1:0]; // new history
|
||||
assign exu_mp_tgt[11:0] = exu_mp_pkt.toffset[11:0] ; // target offset
|
||||
assign exu_mp_addr[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] = exu_mp_index[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] ; // BTB/BHT address
|
||||
|
||||
logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] btb_rd_addr_f;
|
||||
`define DEC top.rvtop.swerv.dec
|
||||
`define EXU top.rvtop.swerv.exu
|
||||
el2_btb_addr_hash f2hash(.pc(ifc_fetch_addr_f[pt.BTB_INDEX3_HI:pt.BTB_INDEX1_LO]), .hash(btb_rd_addr_f[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]));
|
||||
logic [31:0] mppc_ns, mppc;
|
||||
logic exu_flush_final_d1;
|
||||
assign mppc_ns[31:1] = `EXU.i0_flush_upper_x ? `EXU.exu_i0_pc_x : `EXU.dec_i0_pc_d;
|
||||
assign mppc_ns[0] = 1'b0;
|
||||
rvdff #(33) junk_ff (.*, .clk(active_clk), .din({mppc_ns[31:0], exu_flush_final}), .dout({mppc[31:0], exu_flush_final_d1}));
|
||||
logic tmp_bnk;
|
||||
assign tmp_bnk = bpred.bp.btb_sel_f[1];
|
||||
|
||||
always @(negedge clk) begin
|
||||
if(`DEC.tlu.mcyclel[31:0] == 32'h0000_0010) begin
|
||||
$display("BTB_CONFIG: %d",pt.BTB_SIZE);
|
||||
`ifndef BP_NOGSHARE
|
||||
$display("BHT_CONFIG: %d gshare: 1",pt.BHT_SIZE);
|
||||
`else
|
||||
$display("BHT_CONFIG: %d gshare: 0",pt.BHT_SIZE);
|
||||
`endif
|
||||
$display("RS_CONFIG: %d", pt.RET_STACK_SIZE);
|
||||
end
|
||||
if(exu_flush_final_d1 & ~(dec_tlu_br0_r_pkt.br_error | dec_tlu_br0_r_pkt.br_start_error) & (exu_mp_pkt.misp | exu_mp_pkt.ataken))
|
||||
$display("%7d BTB_MP : index: %0h bank: %0h call: %b ret: %b ataken: %b hist: %h valid: %b tag: %h targ: %h eghr: %b pred: %b ghr_index: %h brpc: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha, exu_mp_addr[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO], 1'b0, exu_mp_call, exu_mp_ret, exu_mp_ataken, exu_mp_hist[1:0], exu_mp_valid, exu_mp_btag[pt.BTB_BTAG_SIZE-1:0], {exu_flush_path_final[31:1], 1'b0}, exu_mp_eghr[pt.BHT_GHR_SIZE-1:0], exu_mp_valid, bpred.bp.bht_wr_addr0, mppc[31:0], exu_mp_pkt.way);
|
||||
|
||||
for(int i = 0; i < 8; i++) begin
|
||||
if(ifu_bp_valid_f[i] & ifc_fetch_req_f)
|
||||
$display("%7d BTB_HIT : index: %0h bank: %0h call: %b ret: %b taken: %b strength: %b tag: %h targ: %0h ghr: %4b ghr_index: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,btb_rd_addr_f[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO],bpred.bp.btb_sel_f[1], bpred.bp.btb_rd_call_f, bpred.bp.btb_rd_ret_f, ifu_bp_hist1_f[tmp_bnk], ifu_bp_hist0_f[tmp_bnk], bpred.bp.fetch_rd_tag_f[pt.BTB_BTAG_SIZE-1:0], {ifu_bp_btb_target_f[31:1], 1'b0}, bpred.bp.fghr[pt.BHT_GHR_SIZE-1:0], bpred.bp.bht_rd_addr_f, ifu_bp_way_f[tmp_bnk]);
|
||||
end
|
||||
if(dec_tlu_br0_r_pkt.valid & ~(dec_tlu_br0_r_pkt.br_error | dec_tlu_br0_r_pkt.br_start_error))
|
||||
$display("%7d BTB_UPD0: ghr_index: %0h bank: %0h hist: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,bpred.bp.br0_hashed_wb[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO],{dec_tlu_br0_r_pkt.middle}, dec_tlu_br0_r_pkt.hist, dec_tlu_br0_r_pkt.way);
|
||||
|
||||
if(dec_tlu_br0_r_pkt.br_error | dec_tlu_br0_r_pkt.br_start_error)
|
||||
$display("%7d BTB_ERR0: index: %0h bank: %0h start: %b rfpc: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,exu_i0_br_index_r[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO],1'b0, dec_tlu_br0_r_pkt.br_start_error, {exu_flush_path_final[31:1], 1'b0}, dec_tlu_br0_r_pkt.way);
|
||||
end // always @ (negedge clk)
|
||||
function [1:0] encode4_2;
|
||||
input [3:0] in;
|
||||
|
||||
encode4_2[1] = in[3] | in[2];
|
||||
encode4_2[0] = in[3] | in[1];
|
||||
|
||||
endfunction
|
||||
endfunction
|
||||
`endif
|
||||
endmodule // el2_ifu
|
||||
endmodule // el2_ifu
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -18,78 +18,77 @@
|
|||
// purpose of this file is to convert 16b RISCV compressed instruction into 32b equivalent
|
||||
|
||||
module el2_ifu_compress_ctl
|
||||
import el2_pkg::*;
|
||||
import el2_pkg::*;
|
||||
#(
|
||||
`include "el2_param.vh"
|
||||
)
|
||||
(
|
||||
input logic [15:0] din, // 16-bit compressed instruction
|
||||
output logic [31:0] dout // 32-bit uncompressed instruction
|
||||
);
|
||||
`include "el2_param.vh"
|
||||
) (
|
||||
input logic [15:0] din, // 16-bit compressed instruction
|
||||
output logic [31:0] dout // 32-bit uncompressed instruction
|
||||
);
|
||||
|
||||
|
||||
logic legal;
|
||||
logic legal;
|
||||
|
||||
logic [15:0] i;
|
||||
logic [15:0] i;
|
||||
|
||||
logic [31:0] o,l1,l2,l3;
|
||||
logic [31:0] o, l1, l2, l3;
|
||||
|
||||
|
||||
assign i[15:0] = din[15:0];
|
||||
assign i[15:0] = din[15:0];
|
||||
|
||||
|
||||
logic [4:0] rs2d,rdd,rdpd,rs2pd;
|
||||
logic [4:0] rs2d, rdd, rdpd, rs2pd;
|
||||
|
||||
logic rdrd;
|
||||
logic rdrs1;
|
||||
logic rs2rs2;
|
||||
logic rdprd;
|
||||
logic rdprs1;
|
||||
logic rs2prs2;
|
||||
logic rs2prd;
|
||||
logic uimm9_2;
|
||||
logic ulwimm6_2;
|
||||
logic ulwspimm7_2;
|
||||
logic rdeq2;
|
||||
logic rdeq1;
|
||||
logic rs1eq2;
|
||||
logic sbroffset8_1;
|
||||
logic simm9_4;
|
||||
logic simm5_0;
|
||||
logic sjaloffset11_1;
|
||||
logic sluimm17_12;
|
||||
logic uimm5_0;
|
||||
logic uswimm6_2;
|
||||
logic uswspimm7_2;
|
||||
logic rdrd;
|
||||
logic rdrs1;
|
||||
logic rs2rs2;
|
||||
logic rdprd;
|
||||
logic rdprs1;
|
||||
logic rs2prs2;
|
||||
logic rs2prd;
|
||||
logic uimm9_2;
|
||||
logic ulwimm6_2;
|
||||
logic ulwspimm7_2;
|
||||
logic rdeq2;
|
||||
logic rdeq1;
|
||||
logic rs1eq2;
|
||||
logic sbroffset8_1;
|
||||
logic simm9_4;
|
||||
logic simm5_0;
|
||||
logic sjaloffset11_1;
|
||||
logic sluimm17_12;
|
||||
logic uimm5_0;
|
||||
logic uswimm6_2;
|
||||
logic uswspimm7_2;
|
||||
|
||||
|
||||
|
||||
// form the opcodes
|
||||
// form the opcodes
|
||||
|
||||
// formats
|
||||
//
|
||||
// c.add rd 11:7 rs2 6:2
|
||||
// c.and rdp 9:7 rs2p 4:2
|
||||
//
|
||||
// add rs2 24:20 rs1 19:15 rd 11:7
|
||||
// formats
|
||||
//
|
||||
// c.add rd 11:7 rs2 6:2
|
||||
// c.and rdp 9:7 rs2p 4:2
|
||||
//
|
||||
// add rs2 24:20 rs1 19:15 rd 11:7
|
||||
|
||||
assign rs2d[4:0] = i[6:2];
|
||||
assign rs2d[4:0] = i[6:2];
|
||||
|
||||
assign rdd[4:0] = i[11:7];
|
||||
assign rdd[4:0] = i[11:7];
|
||||
|
||||
assign rdpd[4:0] = {2'b01, i[9:7]};
|
||||
assign rdpd[4:0] = {2'b01, i[9:7]};
|
||||
|
||||
assign rs2pd[4:0] = {2'b01, i[4:2]};
|
||||
assign rs2pd[4:0] = {2'b01, i[4:2]};
|
||||
|
||||
|
||||
|
||||
// merge in rd, rs1, rs2
|
||||
// merge in rd, rs1, rs2
|
||||
|
||||
|
||||
// rd
|
||||
assign l1[6:0] = o[6:0];
|
||||
// rd
|
||||
assign l1[6:0] = o[6:0];
|
||||
|
||||
assign l1[11:7] = o[11:7] |
|
||||
assign l1[11:7] = o[11:7] |
|
||||
({5{rdrd}} & rdd[4:0]) |
|
||||
({5{rdprd}} & rdpd[4:0]) |
|
||||
({5{rs2prd}} & rs2pd[4:0]) |
|
||||
|
@ -97,56 +96,54 @@ import el2_pkg::*;
|
|||
({5{rdeq2}} & 5'd2);
|
||||
|
||||
|
||||
// rs1
|
||||
assign l1[14:12] = o[14:12];
|
||||
assign l1[19:15] = o[19:15] |
|
||||
// rs1
|
||||
assign l1[14:12] = o[14:12];
|
||||
assign l1[19:15] = o[19:15] |
|
||||
({5{rdrs1}} & rdd[4:0]) |
|
||||
({5{rdprs1}} & rdpd[4:0]) |
|
||||
({5{rs1eq2}} & 5'd2);
|
||||
|
||||
|
||||
// rs2
|
||||
assign l1[24:20] = o[24:20] |
|
||||
({5{rs2rs2}} & rs2d[4:0]) |
|
||||
({5{rs2prs2}} & rs2pd[4:0]);
|
||||
// rs2
|
||||
assign l1[24:20] = o[24:20] | ({5{rs2rs2}} & rs2d[4:0]) | ({5{rs2prs2}} & rs2pd[4:0]);
|
||||
|
||||
assign l1[31:25] = o[31:25];
|
||||
assign l1[31:25] = o[31:25];
|
||||
|
||||
logic [5:0] simm5d;
|
||||
logic [9:2] uimm9d;
|
||||
logic [ 5:0] simm5d;
|
||||
logic [ 9:2] uimm9d;
|
||||
|
||||
logic [9:4] simm9d;
|
||||
logic [6:2] ulwimm6d;
|
||||
logic [7:2] ulwspimm7d;
|
||||
logic [5:0] uimm5d;
|
||||
logic [20:1] sjald;
|
||||
logic [ 9:4] simm9d;
|
||||
logic [ 6:2] ulwimm6d;
|
||||
logic [ 7:2] ulwspimm7d;
|
||||
logic [ 5:0] uimm5d;
|
||||
logic [ 20:1] sjald;
|
||||
|
||||
logic [31:12] sluimmd;
|
||||
logic [31:12] sluimmd;
|
||||
|
||||
// merge in immediates + jal offset
|
||||
// merge in immediates + jal offset
|
||||
|
||||
assign simm5d[5:0] = { i[12], i[6:2] };
|
||||
assign simm5d[5:0] = {i[12], i[6:2]};
|
||||
|
||||
assign uimm9d[9:2] = { i[10:7], i[12:11], i[5], i[6] };
|
||||
assign uimm9d[9:2] = {i[10:7], i[12:11], i[5], i[6]};
|
||||
|
||||
assign simm9d[9:4] = { i[12], i[4:3], i[5], i[2], i[6] };
|
||||
assign simm9d[9:4] = {i[12], i[4:3], i[5], i[2], i[6]};
|
||||
|
||||
assign ulwimm6d[6:2] = { i[5], i[12:10], i[6] };
|
||||
assign ulwimm6d[6:2] = {i[5], i[12:10], i[6]};
|
||||
|
||||
assign ulwspimm7d[7:2] = { i[3:2], i[12], i[6:4] };
|
||||
assign ulwspimm7d[7:2] = {i[3:2], i[12], i[6:4]};
|
||||
|
||||
assign uimm5d[5:0] = { i[12], i[6:2] };
|
||||
assign uimm5d[5:0] = {i[12], i[6:2]};
|
||||
|
||||
assign sjald[11:1] = { i[12], i[8], i[10:9], i[6], i[7], i[2], i[11], i[5:4], i[3] };
|
||||
assign sjald[11:1] = {i[12], i[8], i[10:9], i[6], i[7], i[2], i[11], i[5:4], i[3]};
|
||||
|
||||
assign sjald[20:12] = {9{i[12]}};
|
||||
assign sjald[20:12] = {9{i[12]}};
|
||||
|
||||
|
||||
|
||||
assign sluimmd[31:12] = { {15{i[12]}}, i[6:2] };
|
||||
assign sluimmd[31:12] = {{15{i[12]}}, i[6:2]};
|
||||
|
||||
|
||||
assign l2[31:20] = ( l1[31:20] ) |
|
||||
assign l2[31:20] = ( l1[31:20] ) |
|
||||
( {12{simm5_0}} & {{7{simm5d[5]}},simm5d[4:0]} ) |
|
||||
( {12{uimm9_2}} & {2'b0,uimm9d[9:2],2'b0} ) |
|
||||
( {12{simm9_4}} & {{3{simm9d[9]}},simm9d[8:4],4'b0} ) |
|
||||
|
@ -158,197 +155,197 @@ import el2_pkg::*;
|
|||
|
||||
|
||||
|
||||
assign l2[19:12] = ( l1[19:12] ) |
|
||||
assign l2[19:12] = ( l1[19:12] ) |
|
||||
( {8{sjaloffset11_1}} & sjald[19:12] ) |
|
||||
( {8{sluimm17_12}} & sluimmd[19:12] );
|
||||
|
||||
|
||||
assign l2[11:0] = l1[11:0];
|
||||
assign l2[11:0] = l1[11:0];
|
||||
|
||||
|
||||
// merge in branch offset and store immediates
|
||||
// merge in branch offset and store immediates
|
||||
|
||||
logic [8:1] sbr8d;
|
||||
logic [6:2] uswimm6d;
|
||||
logic [7:2] uswspimm7d;
|
||||
logic [8:1] sbr8d;
|
||||
logic [6:2] uswimm6d;
|
||||
logic [7:2] uswspimm7d;
|
||||
|
||||
|
||||
assign sbr8d[8:1] = { i[12], i[6], i[5], i[2], i[11], i[10], i[4], i[3] };
|
||||
assign sbr8d[8:1] = {i[12], i[6], i[5], i[2], i[11], i[10], i[4], i[3]};
|
||||
|
||||
assign uswimm6d[6:2] = { i[5], i[12:10], i[6] };
|
||||
assign uswimm6d[6:2] = {i[5], i[12:10], i[6]};
|
||||
|
||||
assign uswspimm7d[7:2] = { i[8:7], i[12:9] };
|
||||
assign uswspimm7d[7:2] = {i[8:7], i[12:9]};
|
||||
|
||||
assign l3[31:25] = ( l2[31:25] ) |
|
||||
assign l3[31:25] = ( l2[31:25] ) |
|
||||
( {7{sbroffset8_1}} & { {4{sbr8d[8]}},sbr8d[7:5] } ) |
|
||||
( {7{uswimm6_2}} & { 5'b0, uswimm6d[6:5] } ) |
|
||||
( {7{uswspimm7_2}} & { 4'b0, uswspimm7d[7:5] } );
|
||||
|
||||
|
||||
assign l3[24:12] = l2[24:12];
|
||||
assign l3[24:12] = l2[24:12];
|
||||
|
||||
assign l3[11:7] = ( l2[11:7] ) |
|
||||
assign l3[11:7] = ( l2[11:7] ) |
|
||||
( {5{sbroffset8_1}} & { sbr8d[4:1], sbr8d[8] } ) |
|
||||
( {5{uswimm6_2}} & { uswimm6d[4:2], 2'b0 } ) |
|
||||
( {5{uswspimm7_2}} & { uswspimm7d[4:2], 2'b0 } );
|
||||
|
||||
assign l3[6:0] = l2[6:0];
|
||||
assign l3[6:0] = l2[6:0];
|
||||
|
||||
|
||||
assign dout[31:0] = l3[31:0] & {32{legal}};
|
||||
assign dout[31:0] = l3[31:0] & {32{legal}};
|
||||
|
||||
|
||||
// file "cdecode" is human readable file that has all of the compressed instruction decodes defined and is part of git repo
|
||||
// modify this file as needed
|
||||
// file "cdecode" is human readable file that has all of the compressed instruction decodes defined and is part of git repo
|
||||
// modify this file as needed
|
||||
|
||||
// to generate all the equations below from "cdecode" except legal equation:
|
||||
// to generate all the equations below from "cdecode" except legal equation:
|
||||
|
||||
// 1) coredecode -in cdecode > cdecode.e
|
||||
// 1) coredecode -in cdecode > cdecode.e
|
||||
|
||||
// 2) espresso -Dso -oeqntott cdecode.e | addassign > compress_equations
|
||||
// 2) espresso -Dso -oeqntott cdecode.e | addassign > compress_equations
|
||||
|
||||
// to generate the legal (16b compressed instruction is legal) equation below:
|
||||
// to generate the legal (16b compressed instruction is legal) equation below:
|
||||
|
||||
// 1) coredecode -in cdecode -legal > clegal.e
|
||||
// 1) coredecode -in cdecode -legal > clegal.e
|
||||
|
||||
// 2) espresso -Dso -oeqntott clegal.e | addassign > clegal_equation
|
||||
// 2) espresso -Dso -oeqntott clegal.e | addassign > clegal_equation
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// espresso decodes
|
||||
assign rdrd = (!i[14]&i[6]&i[1]) | (!i[15]&i[14]&i[11]&i[0]) | (!i[14]&i[5]&i[1]) | (
|
||||
// espresso decodes
|
||||
assign rdrd = (!i[14]&i[6]&i[1]) | (!i[15]&i[14]&i[11]&i[0]) | (!i[14]&i[5]&i[1]) | (
|
||||
!i[15]&i[14]&i[10]&i[0]) | (!i[14]&i[4]&i[1]) | (!i[15]&i[14]&i[9]
|
||||
&i[0]) | (!i[14]&i[3]&i[1]) | (!i[15]&i[14]&!i[8]&i[0]) | (!i[14]
|
||||
&i[2]&i[1]) | (!i[15]&i[14]&i[7]&i[0]) | (!i[15]&i[1]) | (!i[15]
|
||||
&!i[13]&i[0]);
|
||||
|
||||
assign rdrs1 = (!i[14]&i[12]&i[11]&i[1]) | (!i[14]&i[12]&i[10]&i[1]) | (!i[14]
|
||||
assign rdrs1 = (!i[14]&i[12]&i[11]&i[1]) | (!i[14]&i[12]&i[10]&i[1]) | (!i[14]
|
||||
&i[12]&i[9]&i[1]) | (!i[14]&i[12]&i[8]&i[1]) | (!i[14]&i[12]&i[7]
|
||||
&i[1]) | (!i[14]&!i[12]&!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&i[1]) | (!i[14]
|
||||
&i[12]&i[6]&i[1]) | (!i[14]&i[12]&i[5]&i[1]) | (!i[14]&i[12]&i[4]
|
||||
&i[1]) | (!i[14]&i[12]&i[3]&i[1]) | (!i[14]&i[12]&i[2]&i[1]) | (
|
||||
!i[15]&!i[14]&!i[13]&i[0]) | (!i[15]&!i[14]&i[1]);
|
||||
|
||||
assign rs2rs2 = (i[15]&i[6]&i[1]) | (i[15]&i[5]&i[1]) | (i[15]&i[4]&i[1]) | (
|
||||
assign rs2rs2 = (i[15]&i[6]&i[1]) | (i[15]&i[5]&i[1]) | (i[15]&i[4]&i[1]) | (
|
||||
i[15]&i[3]&i[1]) | (i[15]&i[2]&i[1]) | (i[15]&i[14]&i[1]);
|
||||
|
||||
assign rdprd = (i[15]&!i[14]&!i[13]&i[0]);
|
||||
assign rdprd = (i[15] & !i[14] & !i[13] & i[0]);
|
||||
|
||||
assign rdprs1 = (i[15]&!i[13]&i[0]) | (i[15]&i[14]&i[0]) | (i[14]&!i[1]&!i[0]);
|
||||
assign rdprs1 = (i[15] & !i[13] & i[0]) | (i[15] & i[14] & i[0]) | (i[14] & !i[1] & !i[0]);
|
||||
|
||||
assign rs2prs2 = (i[15]&!i[14]&!i[13]&i[11]&i[10]&i[0]) | (i[15]&!i[1]&!i[0]);
|
||||
assign rs2prs2 = (i[15] & !i[14] & !i[13] & i[11] & i[10] & i[0]) | (i[15] & !i[1] & !i[0]);
|
||||
|
||||
assign rs2prd = (!i[15]&!i[1]&!i[0]);
|
||||
assign rs2prd = (!i[15] & !i[1] & !i[0]);
|
||||
|
||||
assign uimm9_2 = (!i[14]&!i[1]&!i[0]);
|
||||
assign uimm9_2 = (!i[14] & !i[1] & !i[0]);
|
||||
|
||||
assign ulwimm6_2 = (!i[15]&i[14]&!i[1]&!i[0]);
|
||||
assign ulwimm6_2 = (!i[15] & i[14] & !i[1] & !i[0]);
|
||||
|
||||
assign ulwspimm7_2 = (!i[15]&i[14]&i[1]);
|
||||
assign ulwspimm7_2 = (!i[15] & i[14] & i[1]);
|
||||
|
||||
assign rdeq2 = (!i[15]&i[14]&i[13]&!i[11]&!i[10]&!i[9]&i[8]&!i[7]);
|
||||
assign rdeq2 = (!i[15] & i[14] & i[13] & !i[11] & !i[10] & !i[9] & i[8] & !i[7]);
|
||||
|
||||
assign rdeq1 = (!i[14]&i[12]&i[11]&!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&i[1]) | (!i[14]
|
||||
assign rdeq1 = (!i[14]&i[12]&i[11]&!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&i[1]) | (!i[14]
|
||||
&i[12]&i[10]&!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&i[1]) | (!i[14]&i[12]&i[9]
|
||||
&!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&i[1]) | (!i[14]&i[12]&i[8]&!i[6]&!i[5]
|
||||
&!i[4]&!i[3]&!i[2]&i[1]) | (!i[14]&i[12]&i[7]&!i[6]&!i[5]&!i[4]&!i[3]
|
||||
&!i[2]&i[1]) | (!i[15]&!i[14]&i[13]);
|
||||
|
||||
assign rs1eq2 = (!i[15]&i[14]&i[13]&!i[11]&!i[10]&!i[9]&i[8]&!i[7]) | (i[14]
|
||||
assign rs1eq2 = (!i[15]&i[14]&i[13]&!i[11]&!i[10]&!i[9]&i[8]&!i[7]) | (i[14]
|
||||
&i[1]) | (!i[14]&!i[1]&!i[0]);
|
||||
|
||||
assign sbroffset8_1 = (i[15]&i[14]&i[0]);
|
||||
assign sbroffset8_1 = (i[15] & i[14] & i[0]);
|
||||
|
||||
assign simm9_4 = (!i[15]&i[14]&i[13]&!i[11]&!i[10]&!i[9]&i[8]&!i[7]);
|
||||
assign simm9_4 = (!i[15] & i[14] & i[13] & !i[11] & !i[10] & !i[9] & i[8] & !i[7]);
|
||||
|
||||
assign simm5_0 = (!i[14]&!i[13]&i[11]&!i[10]&i[0]) | (!i[15]&!i[13]&i[0]);
|
||||
assign simm5_0 = (!i[14] & !i[13] & i[11] & !i[10] & i[0]) | (!i[15] & !i[13] & i[0]);
|
||||
|
||||
assign sjaloffset11_1 = (!i[14]&i[13]);
|
||||
assign sjaloffset11_1 = (!i[14] & i[13]);
|
||||
|
||||
assign sluimm17_12 = (!i[15]&i[14]&i[13]&i[7]) | (!i[15]&i[14]&i[13]&!i[8]) | (
|
||||
assign sluimm17_12 = (!i[15]&i[14]&i[13]&i[7]) | (!i[15]&i[14]&i[13]&!i[8]) | (
|
||||
!i[15]&i[14]&i[13]&i[9]) | (!i[15]&i[14]&i[13]&i[10]) | (!i[15]&i[14]
|
||||
&i[13]&i[11]);
|
||||
|
||||
assign uimm5_0 = (i[15]&!i[14]&!i[13]&!i[11]&i[0]) | (!i[15]&!i[14]&i[1]);
|
||||
assign uimm5_0 = (i[15] & !i[14] & !i[13] & !i[11] & i[0]) | (!i[15] & !i[14] & i[1]);
|
||||
|
||||
assign uswimm6_2 = (i[15]&!i[1]&!i[0]);
|
||||
assign uswimm6_2 = (i[15] & !i[1] & !i[0]);
|
||||
|
||||
assign uswspimm7_2 = (i[15]&i[14]&i[1]);
|
||||
assign uswspimm7_2 = (i[15] & i[14] & i[1]);
|
||||
|
||||
assign o[31] = 1'b0;
|
||||
assign o[31] = 1'b0;
|
||||
|
||||
assign o[30] = (i[15]&!i[14]&!i[13]&i[10]&!i[6]&!i[5]&i[0]) | (i[15]&!i[14]
|
||||
assign o[30] = (i[15]&!i[14]&!i[13]&i[10]&!i[6]&!i[5]&i[0]) | (i[15]&!i[14]
|
||||
&!i[13]&!i[11]&i[10]&i[0]);
|
||||
|
||||
assign o[29] = 1'b0;
|
||||
assign o[29] = 1'b0;
|
||||
|
||||
assign o[28] = 1'b0;
|
||||
assign o[28] = 1'b0;
|
||||
|
||||
assign o[27] = 1'b0;
|
||||
assign o[27] = 1'b0;
|
||||
|
||||
assign o[26] = 1'b0;
|
||||
assign o[26] = 1'b0;
|
||||
|
||||
assign o[25] = 1'b0;
|
||||
assign o[25] = 1'b0;
|
||||
|
||||
assign o[24] = 1'b0;
|
||||
assign o[24] = 1'b0;
|
||||
|
||||
assign o[23] = 1'b0;
|
||||
assign o[23] = 1'b0;
|
||||
|
||||
assign o[22] = 1'b0;
|
||||
assign o[22] = 1'b0;
|
||||
|
||||
assign o[21] = 1'b0;
|
||||
assign o[21] = 1'b0;
|
||||
|
||||
assign o[20] = (!i[14]&i[12]&!i[11]&!i[10]&!i[9]&!i[8]&!i[7]&!i[6]&!i[5]&!i[4]
|
||||
assign o[20] = (!i[14]&i[12]&!i[11]&!i[10]&!i[9]&!i[8]&!i[7]&!i[6]&!i[5]&!i[4]
|
||||
&!i[3]&!i[2]&i[1]);
|
||||
|
||||
assign o[19] = 1'b0;
|
||||
assign o[19] = 1'b0;
|
||||
|
||||
assign o[18] = 1'b0;
|
||||
assign o[18] = 1'b0;
|
||||
|
||||
assign o[17] = 1'b0;
|
||||
assign o[17] = 1'b0;
|
||||
|
||||
assign o[16] = 1'b0;
|
||||
assign o[16] = 1'b0;
|
||||
|
||||
assign o[15] = 1'b0;
|
||||
assign o[15] = 1'b0;
|
||||
|
||||
assign o[14] = (i[15]&!i[14]&!i[13]&!i[11]&i[0]) | (i[15]&!i[14]&!i[13]&!i[10]
|
||||
assign o[14] = (i[15]&!i[14]&!i[13]&!i[11]&i[0]) | (i[15]&!i[14]&!i[13]&!i[10]
|
||||
&i[0]) | (i[15]&!i[14]&!i[13]&i[6]&i[0]) | (i[15]&!i[14]&!i[13]&i[5]
|
||||
&i[0]);
|
||||
|
||||
assign o[13] = (i[15]&!i[14]&!i[13]&i[11]&!i[10]&i[0]) | (i[15]&!i[14]&!i[13]
|
||||
assign o[13] = (i[15]&!i[14]&!i[13]&i[11]&!i[10]&i[0]) | (i[15]&!i[14]&!i[13]
|
||||
&i[11]&i[6]&i[0]) | (i[14]&!i[0]);
|
||||
|
||||
assign o[12] = (i[15]&!i[14]&!i[13]&i[6]&i[5]&i[0]) | (i[15]&!i[14]&!i[13]&!i[11]
|
||||
assign o[12] = (i[15]&!i[14]&!i[13]&i[6]&i[5]&i[0]) | (i[15]&!i[14]&!i[13]&!i[11]
|
||||
&i[0]) | (i[15]&!i[14]&!i[13]&!i[10]&i[0]) | (!i[15]&!i[14]&i[1]) | (
|
||||
i[15]&i[14]&i[13]);
|
||||
|
||||
assign o[11] = 1'b0;
|
||||
assign o[11] = 1'b0;
|
||||
|
||||
assign o[10] = 1'b0;
|
||||
assign o[10] = 1'b0;
|
||||
|
||||
assign o[9] = 1'b0;
|
||||
assign o[9] = 1'b0;
|
||||
|
||||
assign o[8] = 1'b0;
|
||||
assign o[8] = 1'b0;
|
||||
|
||||
assign o[7] = 1'b0;
|
||||
assign o[7] = 1'b0;
|
||||
|
||||
assign o[6] = (i[15]&!i[14]&!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&!i[0]) | (!i[14]&i[13]) | (
|
||||
assign o[6] = (i[15]&!i[14]&!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&!i[0]) | (!i[14]&i[13]) | (
|
||||
i[15]&i[14]&i[0]);
|
||||
|
||||
assign o[5] = (i[15]&!i[0]) | (i[15]&i[11]&i[10]) | (i[13]&!i[8]) | (i[13]&i[7]) | (
|
||||
assign o[5] = (i[15]&!i[0]) | (i[15]&i[11]&i[10]) | (i[13]&!i[8]) | (i[13]&i[7]) | (
|
||||
i[13]&i[9]) | (i[13]&i[10]) | (i[13]&i[11]) | (!i[14]&i[13]) | (
|
||||
i[15]&i[14]);
|
||||
|
||||
assign o[4] = (!i[14]&!i[11]&!i[10]&!i[9]&!i[8]&!i[7]&!i[0]) | (!i[15]&!i[14]
|
||||
assign o[4] = (!i[14]&!i[11]&!i[10]&!i[9]&!i[8]&!i[7]&!i[0]) | (!i[15]&!i[14]
|
||||
&!i[0]) | (!i[14]&i[6]&!i[0]) | (!i[15]&i[14]&i[0]) | (!i[14]&i[5]
|
||||
&!i[0]) | (!i[14]&i[4]&!i[0]) | (!i[14]&!i[13]&i[0]) | (!i[14]&i[3]
|
||||
&!i[0]) | (!i[14]&i[2]&!i[0]);
|
||||
|
||||
assign o[3] = (!i[14]&i[13]);
|
||||
assign o[3] = (!i[14] & i[13]);
|
||||
|
||||
assign o[2] = (!i[14]&i[12]&i[11]&!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&i[1]) | (!i[14]
|
||||
assign o[2] = (!i[14]&i[12]&i[11]&!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&i[1]) | (!i[14]
|
||||
&i[12]&i[10]&!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&i[1]) | (!i[14]&i[12]&i[9]
|
||||
&!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&i[1]) | (!i[14]&i[12]&i[8]&!i[6]&!i[5]
|
||||
&!i[4]&!i[3]&!i[2]&i[1]) | (!i[14]&i[12]&i[7]&!i[6]&!i[5]&!i[4]&!i[3]
|
||||
|
@ -356,13 +353,13 @@ assign o[2] = (!i[14]&i[12]&i[11]&!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&i[1]) | (!i[14]
|
|||
&!i[0]) | (!i[15]&i[13]&!i[8]) | (!i[15]&i[13]&i[7]) | (!i[15]&i[13]
|
||||
&i[9]) | (!i[15]&i[13]&i[10]) | (!i[15]&i[13]&i[11]) | (!i[14]&i[13]);
|
||||
|
||||
// 32b instruction has lower two bits 2'b11
|
||||
// 32b instruction has lower two bits 2'b11
|
||||
|
||||
assign o[1] = 1'b1;
|
||||
assign o[1] = 1'b1;
|
||||
|
||||
assign o[0] = 1'b1;
|
||||
assign o[0] = 1'b1;
|
||||
|
||||
assign legal = (!i[13]&!i[12]&i[11]&i[1]&!i[0]) | (!i[13]&!i[12]&i[6]&i[1]&!i[0]) | (
|
||||
assign legal = (!i[13]&!i[12]&i[11]&i[1]&!i[0]) | (!i[13]&!i[12]&i[6]&i[1]&!i[0]) | (
|
||||
!i[15]&!i[13]&i[11]&!i[1]) | (!i[13]&!i[12]&i[5]&i[1]&!i[0]) | (
|
||||
!i[13]&!i[12]&i[10]&i[1]&!i[0]) | (!i[15]&!i[13]&i[6]&!i[1]) | (
|
||||
i[15]&!i[12]&!i[1]&i[0]) | (!i[13]&!i[12]&i[9]&i[1]&!i[0]) | (!i[12]
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -20,450 +20,489 @@
|
|||
//********************************************************************************
|
||||
|
||||
module el2_ifu_iccm_mem
|
||||
import el2_pkg::*;
|
||||
import el2_pkg::*;
|
||||
#(
|
||||
`include "el2_param.vh"
|
||||
)(
|
||||
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
|
||||
input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in.
|
||||
input logic rst_l, // reset, active low
|
||||
input logic clk_override, // Override non-functional clock gating
|
||||
`include "el2_param.vh"
|
||||
) (
|
||||
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
|
||||
input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in.
|
||||
input logic rst_l, // reset, active low
|
||||
input logic clk_override, // Override non-functional clock gating
|
||||
|
||||
input logic iccm_wren, // ICCM write enable
|
||||
input logic iccm_rden, // ICCM read enable
|
||||
input logic [pt.ICCM_BITS-1:1] iccm_rw_addr, // ICCM read/write address
|
||||
input logic iccm_buf_correct_ecc, // ICCM is doing a single bit error correct cycle
|
||||
input logic iccm_correction_state, // ICCM under a correction - This is needed to guard replacements when hit
|
||||
input logic [2:0] iccm_wr_size, // ICCM write size
|
||||
input logic [77:0] iccm_wr_data, // ICCM write data
|
||||
input logic iccm_wren, // ICCM write enable
|
||||
input logic iccm_rden, // ICCM read enable
|
||||
input logic [pt.ICCM_BITS-1:1] iccm_rw_addr, // ICCM read/write address
|
||||
input logic iccm_buf_correct_ecc, // ICCM is doing a single bit error correct cycle
|
||||
input logic iccm_correction_state, // ICCM under a correction - This is needed to guard replacements when hit
|
||||
input logic [2:0] iccm_wr_size, // ICCM write size
|
||||
input logic [77:0] iccm_wr_data, // ICCM write data
|
||||
|
||||
input el2_ccm_ext_in_pkt_t [pt.ICCM_NUM_BANKS-1:0] iccm_ext_in_pkt, // External packet
|
||||
input el2_ccm_ext_in_pkt_t [pt.ICCM_NUM_BANKS-1:0] iccm_ext_in_pkt, // External packet
|
||||
|
||||
output logic [63:0] iccm_rd_data, // ICCM read data
|
||||
output logic [77:0] iccm_rd_data_ecc, // ICCM read ecc
|
||||
input logic scan_mode // Scan mode control
|
||||
output logic [63:0] iccm_rd_data, // ICCM read data
|
||||
output logic [77:0] iccm_rd_data_ecc, // ICCM read ecc
|
||||
input logic scan_mode // Scan mode control
|
||||
|
||||
);
|
||||
|
||||
|
||||
logic [pt.ICCM_NUM_BANKS-1:0] wren_bank;
|
||||
logic [pt.ICCM_NUM_BANKS-1:0] rden_bank;
|
||||
logic [pt.ICCM_NUM_BANKS-1:0] iccm_clken;
|
||||
logic [pt.ICCM_NUM_BANKS-1:0] [pt.ICCM_BITS-1:pt.ICCM_BANK_INDEX_LO] addr_bank;
|
||||
logic [pt.ICCM_NUM_BANKS-1:0] wren_bank;
|
||||
logic [pt.ICCM_NUM_BANKS-1:0] rden_bank;
|
||||
logic [pt.ICCM_NUM_BANKS-1:0] iccm_clken;
|
||||
logic [pt.ICCM_NUM_BANKS-1:0][pt.ICCM_BITS-1:pt.ICCM_BANK_INDEX_LO] addr_bank;
|
||||
|
||||
logic [pt.ICCM_NUM_BANKS-1:0] [38:0] iccm_bank_dout, iccm_bank_dout_fn;
|
||||
logic [pt.ICCM_NUM_BANKS-1:0] [38:0] iccm_bank_wr_data;
|
||||
logic [pt.ICCM_BITS-1:1] addr_bank_inc;
|
||||
logic [pt.ICCM_BANK_HI : 2] iccm_rd_addr_hi_q;
|
||||
logic [pt.ICCM_BANK_HI : 1] iccm_rd_addr_lo_q;
|
||||
logic [63:0] iccm_rd_data_pre;
|
||||
logic [63:0] iccm_data;
|
||||
logic [1:0] addr_incr;
|
||||
logic [pt.ICCM_NUM_BANKS-1:0] [38:0] iccm_bank_wr_data_vec;
|
||||
logic [pt.ICCM_NUM_BANKS-1:0][38:0] iccm_bank_dout, iccm_bank_dout_fn;
|
||||
logic [pt.ICCM_NUM_BANKS-1:0][ 38:0] iccm_bank_wr_data;
|
||||
logic [ pt.ICCM_BITS-1:1] addr_bank_inc;
|
||||
logic [ pt.ICCM_BANK_HI : 2] iccm_rd_addr_hi_q;
|
||||
logic [ pt.ICCM_BANK_HI : 1] iccm_rd_addr_lo_q;
|
||||
logic [ 63:0] iccm_rd_data_pre;
|
||||
logic [ 63:0] iccm_data;
|
||||
logic [ 1:0] addr_incr;
|
||||
logic [pt.ICCM_NUM_BANKS-1:0][ 38:0] iccm_bank_wr_data_vec;
|
||||
|
||||
// logic to handle hard persisten faults
|
||||
logic [1:0] [pt.ICCM_BITS-1:2] redundant_address;
|
||||
logic [1:0] [38:0] redundant_data;
|
||||
logic [1:0] redundant_valid;
|
||||
logic [pt.ICCM_NUM_BANKS-1:0] sel_red1, sel_red0, sel_red1_q, sel_red0_q;
|
||||
// logic to handle hard persisten faults
|
||||
logic [ 1:0][pt.ICCM_BITS-1:2] redundant_address;
|
||||
logic [ 1:0][ 38:0] redundant_data;
|
||||
logic [ 1:0] redundant_valid;
|
||||
logic [pt.ICCM_NUM_BANKS-1:0] sel_red1, sel_red0, sel_red1_q, sel_red0_q;
|
||||
|
||||
|
||||
logic [38:0] redundant_data0_in, redundant_data1_in;
|
||||
logic redundant_lru, redundant_lru_in, redundant_lru_en;
|
||||
logic redundant_data0_en;
|
||||
logic redundant_data1_en;
|
||||
logic r0_addr_en, r1_addr_en;
|
||||
logic [38:0] redundant_data0_in, redundant_data1_in;
|
||||
logic redundant_lru, redundant_lru_in, redundant_lru_en;
|
||||
logic redundant_data0_en;
|
||||
logic redundant_data1_en;
|
||||
logic r0_addr_en, r1_addr_en;
|
||||
|
||||
// Testing persistent flip
|
||||
// logic [3:0] not_iccm_bank_dout;
|
||||
// logic [15:3] ecc_insert_flip_in, ecc_insert_flip;
|
||||
// logic flip_en, flip_match, flip_match_q;
|
||||
//
|
||||
// assign flip_in = (iccm_rw_addr[3:2] != 2'b00); // dont flip when bank0 - this is to make some progress in DMA streaming cases
|
||||
// assign flip_en = iccm_rden;
|
||||
//
|
||||
// rvdffs #(1) flipmatch (.*,
|
||||
// .clk(clk),
|
||||
// .din(flip_in),
|
||||
// .en(flip_en),
|
||||
// .dout(flip_match_q));
|
||||
//
|
||||
// end of testing flip
|
||||
// Testing persistent flip
|
||||
// logic [3:0] not_iccm_bank_dout;
|
||||
// logic [15:3] ecc_insert_flip_in, ecc_insert_flip;
|
||||
// logic flip_en, flip_match, flip_match_q;
|
||||
//
|
||||
// assign flip_in = (iccm_rw_addr[3:2] != 2'b00); // dont flip when bank0 - this is to make some progress in DMA streaming cases
|
||||
// assign flip_en = iccm_rden;
|
||||
//
|
||||
// rvdffs #(1) flipmatch (.*,
|
||||
// .clk(clk),
|
||||
// .din(flip_in),
|
||||
// .en(flip_en),
|
||||
// .dout(flip_match_q));
|
||||
//
|
||||
// end of testing flip
|
||||
|
||||
|
||||
assign addr_incr[1:0] = (iccm_wr_size[1:0] == 2'b11) ? 2'b10: 2'b01;
|
||||
assign addr_bank_inc[pt.ICCM_BITS-1 : 1] = iccm_rw_addr[pt.ICCM_BITS-1 : 1] + addr_incr[1:0];
|
||||
assign addr_incr[1:0] = (iccm_wr_size[1:0] == 2'b11) ? 2'b10 : 2'b01;
|
||||
assign addr_bank_inc[pt.ICCM_BITS-1 : 1] = iccm_rw_addr[pt.ICCM_BITS-1 : 1] + addr_incr[1:0];
|
||||
|
||||
for (genvar i=0; i<pt.ICCM_NUM_BANKS/2; i++) begin: mem_bank_data
|
||||
assign iccm_bank_wr_data_vec[(2*i)] = iccm_wr_data[38:0];
|
||||
assign iccm_bank_wr_data_vec[(2*i)+1] = iccm_wr_data[77:39];
|
||||
end
|
||||
for (genvar i = 0; i < pt.ICCM_NUM_BANKS / 2; i++) begin : mem_bank_data
|
||||
assign iccm_bank_wr_data_vec[(2*i)] = iccm_wr_data[38:0];
|
||||
assign iccm_bank_wr_data_vec[(2*i)+1] = iccm_wr_data[77:39];
|
||||
end
|
||||
|
||||
for (genvar i=0; i<pt.ICCM_NUM_BANKS; i++) begin: mem_bank
|
||||
assign wren_bank[i] = iccm_wren & ((iccm_rw_addr[pt.ICCM_BANK_HI:2] == i) | (addr_bank_inc[pt.ICCM_BANK_HI:2] == i));
|
||||
assign iccm_bank_wr_data[i] = iccm_bank_wr_data_vec[i];
|
||||
assign rden_bank[i] = iccm_rden & ( (iccm_rw_addr[pt.ICCM_BANK_HI:2] == i) | (addr_bank_inc[pt.ICCM_BANK_HI:2] == i));
|
||||
assign iccm_clken[i] = wren_bank[i] | rden_bank[i] | clk_override;
|
||||
assign addr_bank[i][pt.ICCM_BITS-1 : pt.ICCM_BANK_INDEX_LO] = wren_bank[i] ? iccm_rw_addr[pt.ICCM_BITS-1 : pt.ICCM_BANK_INDEX_LO] :
|
||||
for (genvar i = 0; i < pt.ICCM_NUM_BANKS; i++) begin : mem_bank
|
||||
assign wren_bank[i] = iccm_wren & ((iccm_rw_addr[pt.ICCM_BANK_HI:2] == i) | (addr_bank_inc[pt.ICCM_BANK_HI:2] == i));
|
||||
assign iccm_bank_wr_data[i] = iccm_bank_wr_data_vec[i];
|
||||
assign rden_bank[i] = iccm_rden & ( (iccm_rw_addr[pt.ICCM_BANK_HI:2] == i) | (addr_bank_inc[pt.ICCM_BANK_HI:2] == i));
|
||||
assign iccm_clken[i] = wren_bank[i] | rden_bank[i] | clk_override;
|
||||
assign addr_bank[i][pt.ICCM_BITS-1 : pt.ICCM_BANK_INDEX_LO] = wren_bank[i] ? iccm_rw_addr[pt.ICCM_BITS-1 : pt.ICCM_BANK_INDEX_LO] :
|
||||
((addr_bank_inc[pt.ICCM_BANK_HI:2] == i) ?
|
||||
addr_bank_inc[pt.ICCM_BITS-1 : pt.ICCM_BANK_INDEX_LO] :
|
||||
iccm_rw_addr[pt.ICCM_BITS-1 : pt.ICCM_BANK_INDEX_LO]);
|
||||
`ifdef VERILATOR
|
||||
`ifdef VERILATOR
|
||||
|
||||
el2_ram #(.depth(1<<pt.ICCM_INDEX_BITS), .width(39)) iccm_bank (
|
||||
// Primary ports
|
||||
.ME(iccm_clken[i]),
|
||||
.CLK(clk),
|
||||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD) ,
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
el2_ram #(
|
||||
.depth(1 << pt.ICCM_INDEX_BITS),
|
||||
.width(39)
|
||||
) iccm_bank (
|
||||
// Primary ports
|
||||
.ME(iccm_clken[i]),
|
||||
.CLK(clk),
|
||||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP(),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD),
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
|
||||
);
|
||||
`else
|
||||
);
|
||||
`else
|
||||
|
||||
if (pt.ICCM_INDEX_BITS == 6 ) begin : iccm
|
||||
ram_64x39 iccm_bank (
|
||||
// Primary ports
|
||||
.CLK(clk),
|
||||
.ME(iccm_clken[i]),
|
||||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD) ,
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
if (pt.ICCM_INDEX_BITS == 6) begin : iccm
|
||||
ram_64x39 iccm_bank (
|
||||
// Primary ports
|
||||
.CLK(clk),
|
||||
.ME(iccm_clken[i]),
|
||||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP(),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD),
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
|
||||
);
|
||||
end // block: iccm
|
||||
);
|
||||
end // block: iccm
|
||||
|
||||
else if (pt.ICCM_INDEX_BITS == 7 ) begin : iccm
|
||||
ram_128x39 iccm_bank (
|
||||
// Primary ports
|
||||
.CLK(clk),
|
||||
.ME(iccm_clken[i]),
|
||||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD) ,
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
ram_128x39 iccm_bank (
|
||||
// Primary ports
|
||||
.CLK(clk),
|
||||
.ME(iccm_clken[i]),
|
||||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP(),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD),
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
|
||||
);
|
||||
end // block: iccm
|
||||
);
|
||||
end // block: iccm
|
||||
|
||||
else if (pt.ICCM_INDEX_BITS == 8 ) begin : iccm
|
||||
ram_256x39 iccm_bank (
|
||||
// Primary ports
|
||||
.CLK(clk),
|
||||
.ME(iccm_clken[i]),
|
||||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD) ,
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
ram_256x39 iccm_bank (
|
||||
// Primary ports
|
||||
.CLK(clk),
|
||||
.ME(iccm_clken[i]),
|
||||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP(),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD),
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
|
||||
);
|
||||
end // block: iccm
|
||||
);
|
||||
end // block: iccm
|
||||
else if (pt.ICCM_INDEX_BITS == 9 ) begin : iccm
|
||||
ram_512x39 iccm_bank (
|
||||
// Primary ports
|
||||
.CLK(clk),
|
||||
.ME(iccm_clken[i]),
|
||||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD) ,
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
ram_512x39 iccm_bank (
|
||||
// Primary ports
|
||||
.CLK(clk),
|
||||
.ME(iccm_clken[i]),
|
||||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP(),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD),
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
|
||||
);
|
||||
end // block: iccm
|
||||
);
|
||||
end // block: iccm
|
||||
else if (pt.ICCM_INDEX_BITS == 10 ) begin : iccm
|
||||
ram_1024x39 iccm_bank (
|
||||
// Primary ports
|
||||
.CLK(clk),
|
||||
.ME(iccm_clken[i]),
|
||||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD) ,
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
ram_1024x39 iccm_bank (
|
||||
// Primary ports
|
||||
.CLK(clk),
|
||||
.ME(iccm_clken[i]),
|
||||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP(),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD),
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
|
||||
);
|
||||
end // block: iccm
|
||||
);
|
||||
end // block: iccm
|
||||
else if (pt.ICCM_INDEX_BITS == 11 ) begin : iccm
|
||||
ram_2048x39 iccm_bank (
|
||||
// Primary ports
|
||||
.CLK(clk),
|
||||
.ME(iccm_clken[i]),
|
||||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD) ,
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
ram_2048x39 iccm_bank (
|
||||
// Primary ports
|
||||
.CLK(clk),
|
||||
.ME(iccm_clken[i]),
|
||||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP(),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD),
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
|
||||
);
|
||||
end // block: iccm
|
||||
);
|
||||
end // block: iccm
|
||||
else if (pt.ICCM_INDEX_BITS == 12 ) begin : iccm
|
||||
ram_4096x39 iccm_bank (
|
||||
// Primary ports
|
||||
.CLK(clk),
|
||||
.ME(iccm_clken[i]),
|
||||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD) ,
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
ram_4096x39 iccm_bank (
|
||||
// Primary ports
|
||||
.CLK(clk),
|
||||
.ME(iccm_clken[i]),
|
||||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP(),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD),
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
|
||||
);
|
||||
end // block: iccm
|
||||
);
|
||||
end // block: iccm
|
||||
else if (pt.ICCM_INDEX_BITS == 13 ) begin : iccm
|
||||
ram_8192x39 iccm_bank (
|
||||
// Primary ports
|
||||
.CLK(clk),
|
||||
.ME(iccm_clken[i]),
|
||||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD) ,
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
ram_8192x39 iccm_bank (
|
||||
// Primary ports
|
||||
.CLK(clk),
|
||||
.ME(iccm_clken[i]),
|
||||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP(),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD),
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
|
||||
);
|
||||
end // block: iccm
|
||||
);
|
||||
end // block: iccm
|
||||
else if (pt.ICCM_INDEX_BITS == 14 ) begin : iccm
|
||||
ram_16384x39 iccm_bank (
|
||||
// Primary ports
|
||||
.CLK(clk),
|
||||
.ME(iccm_clken[i]),
|
||||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD) ,
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
ram_16384x39 iccm_bank (
|
||||
// Primary ports
|
||||
.CLK(clk),
|
||||
.ME(iccm_clken[i]),
|
||||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP(),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD),
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
|
||||
);
|
||||
end // block: iccm
|
||||
);
|
||||
end // block: iccm
|
||||
else begin : iccm
|
||||
ram_32768x39 iccm_bank (
|
||||
// Primary ports
|
||||
.CLK(clk),
|
||||
.ME(iccm_clken[i]),
|
||||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD) ,
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
ram_32768x39 iccm_bank (
|
||||
// Primary ports
|
||||
.CLK(clk),
|
||||
.ME(iccm_clken[i]),
|
||||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP(),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD),
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
|
||||
);
|
||||
end // block: iccm
|
||||
);
|
||||
end // block: iccm
|
||||
`endif
|
||||
|
||||
// match the redundant rows
|
||||
assign sel_red1[i] = (redundant_valid[1] & (((iccm_rw_addr[pt.ICCM_BITS-1:2] == redundant_address[1][pt.ICCM_BITS-1:2]) & (iccm_rw_addr[3:2] == i)) |
|
||||
// match the redundant rows
|
||||
assign sel_red1[i] = (redundant_valid[1] & (((iccm_rw_addr[pt.ICCM_BITS-1:2] == redundant_address[1][pt.ICCM_BITS-1:2]) & (iccm_rw_addr[3:2] == i)) |
|
||||
((addr_bank_inc[pt.ICCM_BITS-1:2]== redundant_address[1][pt.ICCM_BITS-1:2]) & (addr_bank_inc[3:2] == i))));
|
||||
|
||||
assign sel_red0[i] = (redundant_valid[0] & (((iccm_rw_addr[pt.ICCM_BITS-1:2] == redundant_address[0][pt.ICCM_BITS-1:2]) & (iccm_rw_addr[3:2] == i)) |
|
||||
assign sel_red0[i] = (redundant_valid[0] & (((iccm_rw_addr[pt.ICCM_BITS-1:2] == redundant_address[0][pt.ICCM_BITS-1:2]) & (iccm_rw_addr[3:2] == i)) |
|
||||
((addr_bank_inc[pt.ICCM_BITS-1:2]== redundant_address[0][pt.ICCM_BITS-1:2]) & (addr_bank_inc[3:2] == i))));
|
||||
|
||||
rvdff #(1) selred0 (.*,
|
||||
.clk(active_clk),
|
||||
.din(sel_red0[i]),
|
||||
.dout(sel_red0_q[i]));
|
||||
rvdff #(1) selred0 (
|
||||
.*,
|
||||
.clk (active_clk),
|
||||
.din (sel_red0[i]),
|
||||
.dout(sel_red0_q[i])
|
||||
);
|
||||
|
||||
rvdff #(1) selred1 (.*,
|
||||
.clk(active_clk),
|
||||
.din(sel_red1[i]),
|
||||
.dout(sel_red1_q[i]));
|
||||
rvdff #(1) selred1 (
|
||||
.*,
|
||||
.clk (active_clk),
|
||||
.din (sel_red1[i]),
|
||||
.dout(sel_red1_q[i])
|
||||
);
|
||||
|
||||
|
||||
// muxing out the memory data with the redundant data if the address matches
|
||||
assign iccm_bank_dout_fn[i][38:0] = ({39{sel_red1_q[i]}} & redundant_data[1][38:0]) |
|
||||
// muxing out the memory data with the redundant data if the address matches
|
||||
assign iccm_bank_dout_fn[i][38:0] = ({39{sel_red1_q[i]}} & redundant_data[1][38:0]) |
|
||||
({39{sel_red0_q[i]}} & redundant_data[0][38:0]) |
|
||||
({39{~sel_red0_q[i] & ~sel_red1_q[i]}} & iccm_bank_dout[i][38:0]);
|
||||
|
||||
end : mem_bank
|
||||
// This section does the redundancy for tolerating single bit errors
|
||||
// 2x 39 bit data values with address[hi:2] and a valid bit is needed to CAM and sub out the reads/writes to the particular locations
|
||||
// Also a LRU flop is kept to decide which of the redundant element to replace.
|
||||
assign r0_addr_en = ~redundant_lru & iccm_buf_correct_ecc;
|
||||
assign r1_addr_en = redundant_lru & iccm_buf_correct_ecc;
|
||||
assign redundant_lru_en = iccm_buf_correct_ecc | (((|sel_red0[pt.ICCM_NUM_BANKS-1:0]) | (|sel_red1[pt.ICCM_NUM_BANKS-1:0])) & iccm_rden & iccm_correction_state);
|
||||
assign redundant_lru_in = iccm_buf_correct_ecc ? ~redundant_lru : (|sel_red0[pt.ICCM_NUM_BANKS-1:0]) ? 1'b1 : 1'b0;
|
||||
// This section does the redundancy for tolerating single bit errors
|
||||
// 2x 39 bit data values with address[hi:2] and a valid bit is needed to CAM and sub out the reads/writes to the particular locations
|
||||
// Also a LRU flop is kept to decide which of the redundant element to replace.
|
||||
assign r0_addr_en = ~redundant_lru & iccm_buf_correct_ecc;
|
||||
assign r1_addr_en = redundant_lru & iccm_buf_correct_ecc;
|
||||
assign redundant_lru_en = iccm_buf_correct_ecc | (((|sel_red0[pt.ICCM_NUM_BANKS-1:0]) | (|sel_red1[pt.ICCM_NUM_BANKS-1:0])) & iccm_rden & iccm_correction_state);
|
||||
assign redundant_lru_in = iccm_buf_correct_ecc ? ~redundant_lru : (|sel_red0[pt.ICCM_NUM_BANKS-1:0]) ? 1'b1 : 1'b0;
|
||||
|
||||
rvdffs #() red_lru (.*, // LRU flop for the redundant replacements
|
||||
.clk(active_clk),
|
||||
.en(redundant_lru_en),
|
||||
.din(redundant_lru_in),
|
||||
.dout(redundant_lru));
|
||||
rvdffs #() red_lru (
|
||||
.*, // LRU flop for the redundant replacements
|
||||
.clk (active_clk),
|
||||
.en (redundant_lru_en),
|
||||
.din (redundant_lru_in),
|
||||
.dout(redundant_lru)
|
||||
);
|
||||
|
||||
rvdffs #(pt.ICCM_BITS-2) r0_address (.*, // Redundant Row 0 address
|
||||
.clk(active_clk),
|
||||
.en(r0_addr_en),
|
||||
.din(iccm_rw_addr[pt.ICCM_BITS-1:2]),
|
||||
.dout(redundant_address[0][pt.ICCM_BITS-1:2]));
|
||||
rvdffs #(pt.ICCM_BITS - 2) r0_address (
|
||||
.*, // Redundant Row 0 address
|
||||
.clk (active_clk),
|
||||
.en (r0_addr_en),
|
||||
.din (iccm_rw_addr[pt.ICCM_BITS-1:2]),
|
||||
.dout(redundant_address[0][pt.ICCM_BITS-1:2])
|
||||
);
|
||||
|
||||
rvdffs #(pt.ICCM_BITS-2) r1_address (.*, // Redundant Row 0 address
|
||||
.clk(active_clk),
|
||||
.en(r1_addr_en),
|
||||
.din(iccm_rw_addr[pt.ICCM_BITS-1:2]),
|
||||
.dout(redundant_address[1][pt.ICCM_BITS-1:2]));
|
||||
rvdffs #(pt.ICCM_BITS - 2) r1_address (
|
||||
.*, // Redundant Row 0 address
|
||||
.clk (active_clk),
|
||||
.en (r1_addr_en),
|
||||
.din (iccm_rw_addr[pt.ICCM_BITS-1:2]),
|
||||
.dout(redundant_address[1][pt.ICCM_BITS-1:2])
|
||||
);
|
||||
|
||||
rvdffs #(1) r0_valid (.*,
|
||||
.clk(active_clk), // Redundant Row 0 Valid
|
||||
.en(r0_addr_en),
|
||||
.din(1'b1),
|
||||
.dout(redundant_valid[0]));
|
||||
rvdffs #(1) r0_valid (
|
||||
.*,
|
||||
.clk (active_clk), // Redundant Row 0 Valid
|
||||
.en (r0_addr_en),
|
||||
.din (1'b1),
|
||||
.dout(redundant_valid[0])
|
||||
);
|
||||
|
||||
rvdffs #(1) r1_valid (.*, // Redundant Row 1 Valid
|
||||
.clk(active_clk),
|
||||
.en(r1_addr_en),
|
||||
.din(1'b1),
|
||||
.dout(redundant_valid[1]));
|
||||
rvdffs #(1) r1_valid (
|
||||
.*, // Redundant Row 1 Valid
|
||||
.clk (active_clk),
|
||||
.en (r1_addr_en),
|
||||
.din (1'b1),
|
||||
.dout(redundant_valid[1])
|
||||
);
|
||||
|
||||
|
||||
|
||||
// We will have to update the Redundant copies in addition to the memory on subsequent writes to this memory location.
|
||||
// The data gets updated on : 1) correction cycle, 2) Future writes - this could be W writes from DMA ( match up till addr[2]) or DW writes ( match till address[3])
|
||||
// The data to pick also depends on the current address[2], size and the addr[2] stored in the address field of the redundant flop. Correction cycle is always W write and the data is splat on both legs, so choosing lower Word
|
||||
// We will have to update the Redundant copies in addition to the memory on subsequent writes to this memory location.
|
||||
// The data gets updated on : 1) correction cycle, 2) Future writes - this could be W writes from DMA ( match up till addr[2]) or DW writes ( match till address[3])
|
||||
// The data to pick also depends on the current address[2], size and the addr[2] stored in the address field of the redundant flop. Correction cycle is always W write and the data is splat on both legs, so choosing lower Word
|
||||
|
||||
assign redundant_data0_en = ((iccm_rw_addr[pt.ICCM_BITS-1:3] == redundant_address[0][pt.ICCM_BITS-1:3]) & ((iccm_rw_addr[2] == redundant_address[0][2]) | (iccm_wr_size[1:0] == 2'b11)) & redundant_valid[0] & iccm_wren) |
|
||||
assign redundant_data0_en = ((iccm_rw_addr[pt.ICCM_BITS-1:3] == redundant_address[0][pt.ICCM_BITS-1:3]) & ((iccm_rw_addr[2] == redundant_address[0][2]) | (iccm_wr_size[1:0] == 2'b11)) & redundant_valid[0] & iccm_wren) |
|
||||
(~redundant_lru & iccm_buf_correct_ecc);
|
||||
|
||||
assign redundant_data0_in[38:0] = (((iccm_rw_addr[2] == redundant_address[0][2]) & iccm_rw_addr[2]) | (redundant_address[0][2] & (iccm_wr_size[1:0] == 2'b11))) ? iccm_wr_data[77:39] : iccm_wr_data[38:0];
|
||||
assign redundant_data0_in[38:0] = (((iccm_rw_addr[2] == redundant_address[0][2]) & iccm_rw_addr[2]) | (redundant_address[0][2] & (iccm_wr_size[1:0] == 2'b11))) ? iccm_wr_data[77:39] : iccm_wr_data[38:0];
|
||||
|
||||
rvdffs #(39) r0_data (.*, // Redundant Row 1 data
|
||||
.clk(active_clk),
|
||||
.en(redundant_data0_en),
|
||||
.din(redundant_data0_in[38:0]),
|
||||
.dout(redundant_data[0][38:0]));
|
||||
rvdffs #(39) r0_data (
|
||||
.*, // Redundant Row 1 data
|
||||
.clk (active_clk),
|
||||
.en (redundant_data0_en),
|
||||
.din (redundant_data0_in[38:0]),
|
||||
.dout(redundant_data[0][38:0])
|
||||
);
|
||||
|
||||
assign redundant_data1_en = ((iccm_rw_addr[pt.ICCM_BITS-1:3] == redundant_address[1][pt.ICCM_BITS-1:3]) & ((iccm_rw_addr[2] == redundant_address[1][2]) | (iccm_wr_size[1:0] == 2'b11)) & redundant_valid[1] & iccm_wren) |
|
||||
assign redundant_data1_en = ((iccm_rw_addr[pt.ICCM_BITS-1:3] == redundant_address[1][pt.ICCM_BITS-1:3]) & ((iccm_rw_addr[2] == redundant_address[1][2]) | (iccm_wr_size[1:0] == 2'b11)) & redundant_valid[1] & iccm_wren) |
|
||||
(redundant_lru & iccm_buf_correct_ecc);
|
||||
|
||||
assign redundant_data1_in[38:0] = (((iccm_rw_addr[2] == redundant_address[1][2]) & iccm_rw_addr[2]) | (redundant_address[1][2] & (iccm_wr_size[1:0] == 2'b11))) ? iccm_wr_data[77:39] : iccm_wr_data[38:0];
|
||||
assign redundant_data1_in[38:0] = (((iccm_rw_addr[2] == redundant_address[1][2]) & iccm_rw_addr[2]) | (redundant_address[1][2] & (iccm_wr_size[1:0] == 2'b11))) ? iccm_wr_data[77:39] : iccm_wr_data[38:0];
|
||||
|
||||
rvdffs #(39) r1_data (.*, // Redundant Row 1 data
|
||||
.clk(active_clk),
|
||||
.en(redundant_data1_en),
|
||||
.din(redundant_data1_in[38:0]),
|
||||
.dout(redundant_data[1][38:0]));
|
||||
rvdffs #(39) r1_data (
|
||||
.*, // Redundant Row 1 data
|
||||
.clk (active_clk),
|
||||
.en (redundant_data1_en),
|
||||
.din (redundant_data1_in[38:0]),
|
||||
.dout(redundant_data[1][38:0])
|
||||
);
|
||||
|
||||
|
||||
rvdffs #(pt.ICCM_BANK_HI) rd_addr_lo_ff (.*, .clk(active_clk), .din(iccm_rw_addr [pt.ICCM_BANK_HI:1]), .dout(iccm_rd_addr_lo_q[pt.ICCM_BANK_HI:1]), .en(1'b1)); // bit 0 of address is always 0
|
||||
rvdffs #(pt.ICCM_BANK_BITS) rd_addr_hi_ff (.*, .clk(active_clk), .din(addr_bank_inc[pt.ICCM_BANK_HI:2]), .dout(iccm_rd_addr_hi_q[pt.ICCM_BANK_HI:2]), .en(1'b1));
|
||||
rvdffs #(pt.ICCM_BANK_HI) rd_addr_lo_ff (
|
||||
.*,
|
||||
.clk (active_clk),
|
||||
.din (iccm_rw_addr[pt.ICCM_BANK_HI:1]),
|
||||
.dout(iccm_rd_addr_lo_q[pt.ICCM_BANK_HI:1]),
|
||||
.en (1'b1)
|
||||
); // bit 0 of address is always 0
|
||||
rvdffs #(pt.ICCM_BANK_BITS) rd_addr_hi_ff (
|
||||
.*,
|
||||
.clk (active_clk),
|
||||
.din (addr_bank_inc[pt.ICCM_BANK_HI:2]),
|
||||
.dout(iccm_rd_addr_hi_q[pt.ICCM_BANK_HI:2]),
|
||||
.en (1'b1)
|
||||
);
|
||||
|
||||
assign iccm_rd_data_pre[63:0] = {iccm_bank_dout_fn[iccm_rd_addr_hi_q][31:0], iccm_bank_dout_fn[iccm_rd_addr_lo_q[pt.ICCM_BANK_HI:2]][31:0]};
|
||||
assign iccm_data[63:0] = 64'({16'b0, (iccm_rd_data_pre[63:0] >> (16*iccm_rd_addr_lo_q[1]))});
|
||||
assign iccm_rd_data[63:0] = {iccm_data[63:0]};
|
||||
assign iccm_rd_data_ecc[77:0] = {iccm_bank_dout_fn[iccm_rd_addr_hi_q][38:0], iccm_bank_dout_fn[iccm_rd_addr_lo_q[pt.ICCM_BANK_HI:2]][38:0]};
|
||||
assign iccm_rd_data_pre[63:0] = {
|
||||
iccm_bank_dout_fn[iccm_rd_addr_hi_q][31:0],
|
||||
iccm_bank_dout_fn[iccm_rd_addr_lo_q[pt.ICCM_BANK_HI:2]][31:0]
|
||||
};
|
||||
assign iccm_data[63:0] = 64'({16'b0, (iccm_rd_data_pre[63:0] >> (16 * iccm_rd_addr_lo_q[1]))});
|
||||
assign iccm_rd_data[63:0] = {iccm_data[63:0]};
|
||||
assign iccm_rd_data_ecc[77:0] = {
|
||||
iccm_bank_dout_fn[iccm_rd_addr_hi_q][38:0],
|
||||
iccm_bank_dout_fn[iccm_rd_addr_lo_q[pt.ICCM_BANK_HI:2]][38:0]
|
||||
};
|
||||
|
||||
endmodule // el2_ifu_iccm_mem
|
||||
endmodule // el2_ifu_iccm_mem
|
||||
|
|
|
@ -21,118 +21,119 @@
|
|||
//********************************************************************************
|
||||
|
||||
module el2_ifu_ifc_ctl
|
||||
import el2_pkg::*;
|
||||
import el2_pkg::*;
|
||||
#(
|
||||
`include "el2_param.vh"
|
||||
)
|
||||
(
|
||||
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
|
||||
input logic free_l2clk, // Clock always. Through one clock header. For flops with second header built in.
|
||||
`include "el2_param.vh"
|
||||
) (
|
||||
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
|
||||
input logic free_l2clk, // Clock always. Through one clock header. For flops with second header built in.
|
||||
|
||||
input logic rst_l, // reset enable, from core pin
|
||||
input logic scan_mode, // scan
|
||||
input logic rst_l, // reset enable, from core pin
|
||||
input logic scan_mode, // scan
|
||||
|
||||
input logic ic_hit_f, // Icache hit
|
||||
input logic ifu_ic_mb_empty, // Miss buffer empty
|
||||
input logic ic_hit_f, // Icache hit
|
||||
input logic ifu_ic_mb_empty, // Miss buffer empty
|
||||
|
||||
input logic ifu_fb_consume1, // Aligner consumed 1 fetch buffer
|
||||
input logic ifu_fb_consume2, // Aligner consumed 2 fetch buffers
|
||||
input logic ifu_fb_consume1, // Aligner consumed 1 fetch buffer
|
||||
input logic ifu_fb_consume2, // Aligner consumed 2 fetch buffers
|
||||
|
||||
input logic dec_tlu_flush_noredir_wb, // Don't fetch on flush
|
||||
input logic exu_flush_final, // FLush
|
||||
input logic [31:1] exu_flush_path_final, // Flush path
|
||||
input logic dec_tlu_flush_noredir_wb, // Don't fetch on flush
|
||||
input logic exu_flush_final, // FLush
|
||||
input logic [31:1] exu_flush_path_final, // Flush path
|
||||
|
||||
input logic ifu_bp_hit_taken_f, // btb hit, select the target path
|
||||
input logic [31:1] ifu_bp_btb_target_f, // predicted target PC
|
||||
input logic ifu_bp_hit_taken_f, // btb hit, select the target path
|
||||
input logic [31:1] ifu_bp_btb_target_f, // predicted target PC
|
||||
|
||||
input logic ic_dma_active, // IC DMA active, stop fetching
|
||||
input logic ic_write_stall, // IC is writing, stop fetching
|
||||
input logic dma_iccm_stall_any, // force a stall in the fetch pipe for DMA ICCM access
|
||||
input logic ic_dma_active, // IC DMA active, stop fetching
|
||||
input logic ic_write_stall, // IC is writing, stop fetching
|
||||
input logic dma_iccm_stall_any, // force a stall in the fetch pipe for DMA ICCM access
|
||||
|
||||
input logic [31:0] dec_tlu_mrac_ff , // side_effect and cacheable for each region
|
||||
input logic [31:0] dec_tlu_mrac_ff, // side_effect and cacheable for each region
|
||||
|
||||
output logic [31:1] ifc_fetch_addr_f, // fetch addr F
|
||||
output logic [31:1] ifc_fetch_addr_bf, // fetch addr BF
|
||||
output logic [31:1] ifc_fetch_addr_f, // fetch addr F
|
||||
output logic [31:1] ifc_fetch_addr_bf, // fetch addr BF
|
||||
|
||||
output logic ifc_fetch_req_f, // fetch request valid F
|
||||
output logic ifc_fetch_req_f, // fetch request valid F
|
||||
|
||||
output logic ifu_pmu_fetch_stall, // pmu event measuring fetch stall
|
||||
output logic ifu_pmu_fetch_stall, // pmu event measuring fetch stall
|
||||
|
||||
output logic ifc_fetch_uncacheable_bf, // The fetch request is uncacheable space. BF stage
|
||||
output logic ifc_fetch_req_bf, // Fetch request. Comes with the address. BF stage
|
||||
output logic ifc_fetch_req_bf_raw, // Fetch request without some qualifications. Used for clock-gating. BF stage
|
||||
output logic ifc_iccm_access_bf, // This request is to the ICCM. Do not generate misses to the bus.
|
||||
output logic ifc_region_acc_fault_bf, // Access fault. in ICCM region but offset is outside defined ICCM.
|
||||
output logic ifc_fetch_uncacheable_bf, // The fetch request is uncacheable space. BF stage
|
||||
output logic ifc_fetch_req_bf, // Fetch request. Comes with the address. BF stage
|
||||
output logic ifc_fetch_req_bf_raw, // Fetch request without some qualifications. Used for clock-gating. BF stage
|
||||
output logic ifc_iccm_access_bf, // This request is to the ICCM. Do not generate misses to the bus.
|
||||
output logic ifc_region_acc_fault_bf, // Access fault. in ICCM region but offset is outside defined ICCM.
|
||||
|
||||
output logic ifc_dma_access_ok // fetch is not accessing the ICCM, DMA can proceed
|
||||
output logic ifc_dma_access_ok // fetch is not accessing the ICCM, DMA can proceed
|
||||
|
||||
|
||||
);
|
||||
);
|
||||
|
||||
logic [31:1] fetch_addr_bf;
|
||||
logic [31:1] fetch_addr_next;
|
||||
logic [3:0] fb_write_f, fb_write_ns;
|
||||
logic [31:1] fetch_addr_bf;
|
||||
logic [31:1] fetch_addr_next;
|
||||
logic [3:0] fb_write_f, fb_write_ns;
|
||||
|
||||
logic fb_full_f_ns, fb_full_f;
|
||||
logic fb_right, fb_right2, fb_left, wfm, idle;
|
||||
logic sel_last_addr_bf, sel_next_addr_bf;
|
||||
logic miss_f, miss_a;
|
||||
logic flush_fb, dma_iccm_stall_any_f;
|
||||
logic mb_empty_mod, goto_idle, leave_idle;
|
||||
logic fetch_bf_en;
|
||||
logic line_wrap;
|
||||
logic fetch_addr_next_1;
|
||||
logic fb_full_f_ns, fb_full_f;
|
||||
logic fb_right, fb_right2, fb_left, wfm, idle;
|
||||
logic sel_last_addr_bf, sel_next_addr_bf;
|
||||
logic miss_f, miss_a;
|
||||
logic flush_fb, dma_iccm_stall_any_f;
|
||||
logic mb_empty_mod, goto_idle, leave_idle;
|
||||
logic fetch_bf_en;
|
||||
logic line_wrap;
|
||||
logic fetch_addr_next_1;
|
||||
|
||||
// FSM assignment
|
||||
typedef enum logic [1:0] { IDLE = 2'b00 ,
|
||||
FETCH = 2'b01 ,
|
||||
STALL = 2'b10 ,
|
||||
WFM = 2'b11 } state_t ;
|
||||
state_t state ;
|
||||
state_t next_state ;
|
||||
// FSM assignment
|
||||
typedef enum logic [1:0] {
|
||||
IDLE = 2'b00,
|
||||
FETCH = 2'b01,
|
||||
STALL = 2'b10,
|
||||
WFM = 2'b11
|
||||
} state_t;
|
||||
state_t state;
|
||||
state_t next_state;
|
||||
|
||||
logic dma_stall;
|
||||
assign dma_stall = ic_dma_active | dma_iccm_stall_any_f;
|
||||
logic dma_stall;
|
||||
assign dma_stall = ic_dma_active | dma_iccm_stall_any_f;
|
||||
|
||||
|
||||
|
||||
// Fetch address mux
|
||||
// - flush
|
||||
// - Miss *or* flush during WFM (icache miss buffer is blocking)
|
||||
// - Sequential
|
||||
// Fetch address mux
|
||||
// - flush
|
||||
// - Miss *or* flush during WFM (icache miss buffer is blocking)
|
||||
// - Sequential
|
||||
|
||||
if(pt.BTB_ENABLE==1) begin
|
||||
logic sel_btb_addr_bf;
|
||||
if (pt.BTB_ENABLE == 1) begin
|
||||
logic sel_btb_addr_bf;
|
||||
|
||||
assign sel_last_addr_bf = ~exu_flush_final & (~ifc_fetch_req_f | ~ic_hit_f);
|
||||
assign sel_btb_addr_bf = ~exu_flush_final & ifc_fetch_req_f & ifu_bp_hit_taken_f & ic_hit_f;
|
||||
assign sel_next_addr_bf = ~exu_flush_final & ifc_fetch_req_f & ~ifu_bp_hit_taken_f & ic_hit_f;
|
||||
assign sel_last_addr_bf = ~exu_flush_final & (~ifc_fetch_req_f | ~ic_hit_f);
|
||||
assign sel_btb_addr_bf = ~exu_flush_final & ifc_fetch_req_f & ifu_bp_hit_taken_f & ic_hit_f;
|
||||
assign sel_next_addr_bf = ~exu_flush_final & ifc_fetch_req_f & ~ifu_bp_hit_taken_f & ic_hit_f;
|
||||
|
||||
|
||||
assign fetch_addr_bf[31:1] = ( ({31{exu_flush_final}} & exu_flush_path_final[31:1]) | // FLUSH path
|
||||
({31{sel_last_addr_bf}} & ifc_fetch_addr_f[31:1]) | // MISS path
|
||||
({31{sel_btb_addr_bf}} & {ifu_bp_btb_target_f[31:1]})| // BTB target
|
||||
({31{sel_next_addr_bf}} & {fetch_addr_next[31:1]})); // SEQ path
|
||||
assign fetch_addr_bf[31:1] = ( ({31{exu_flush_final}} & exu_flush_path_final[31:1]) | // FLUSH path
|
||||
({31{sel_last_addr_bf}} & ifc_fetch_addr_f[31:1]) | // MISS path
|
||||
({31{sel_btb_addr_bf}} & {ifu_bp_btb_target_f[31:1]}) | // BTB target
|
||||
({31{sel_next_addr_bf}} & {fetch_addr_next[31:1]})); // SEQ path
|
||||
|
||||
|
||||
end // if (pt.BTB_ENABLE=1)
|
||||
end // if (pt.BTB_ENABLE=1)
|
||||
else begin
|
||||
assign sel_last_addr_bf = ~exu_flush_final & (~ifc_fetch_req_f | ~ic_hit_f);
|
||||
assign sel_next_addr_bf = ~exu_flush_final & ifc_fetch_req_f & ic_hit_f;
|
||||
assign sel_last_addr_bf = ~exu_flush_final & (~ifc_fetch_req_f | ~ic_hit_f);
|
||||
assign sel_next_addr_bf = ~exu_flush_final & ifc_fetch_req_f & ic_hit_f;
|
||||
|
||||
|
||||
assign fetch_addr_bf[31:1] = ( ({31{exu_flush_final}} & exu_flush_path_final[31:1]) | // FLUSH path
|
||||
({31{sel_last_addr_bf}} & ifc_fetch_addr_f[31:1]) | // MISS path
|
||||
({31{sel_next_addr_bf}} & {fetch_addr_next[31:1]})); // SEQ path
|
||||
assign fetch_addr_bf[31:1] = ( ({31{exu_flush_final}} & exu_flush_path_final[31:1]) | // FLUSH path
|
||||
({31{sel_last_addr_bf}} & ifc_fetch_addr_f[31:1]) | // MISS path
|
||||
({31{sel_next_addr_bf}} & {fetch_addr_next[31:1]})); // SEQ path
|
||||
|
||||
end
|
||||
assign fetch_addr_next[31:1] = {({ifc_fetch_addr_f[31:2]} + 31'b1), fetch_addr_next_1 };
|
||||
assign line_wrap = (fetch_addr_next[pt.ICACHE_TAG_INDEX_LO] ^ ifc_fetch_addr_f[pt.ICACHE_TAG_INDEX_LO]);
|
||||
end
|
||||
assign fetch_addr_next[31:1] = {({ifc_fetch_addr_f[31:2]} + 31'b1), fetch_addr_next_1};
|
||||
assign line_wrap = (fetch_addr_next[pt.ICACHE_TAG_INDEX_LO] ^ ifc_fetch_addr_f[pt.ICACHE_TAG_INDEX_LO]);
|
||||
|
||||
assign fetch_addr_next_1 = line_wrap ? 1'b0 : ifc_fetch_addr_f[1];
|
||||
assign fetch_addr_next_1 = line_wrap ? 1'b0 : ifc_fetch_addr_f[1];
|
||||
|
||||
assign ifc_fetch_req_bf_raw = ~idle;
|
||||
assign ifc_fetch_req_bf = ifc_fetch_req_bf_raw &
|
||||
assign ifc_fetch_req_bf_raw = ~idle;
|
||||
assign ifc_fetch_req_bf = ifc_fetch_req_bf_raw &
|
||||
|
||||
~(fb_full_f_ns & ~(ifu_fb_consume2 | ifu_fb_consume1)) &
|
||||
~dma_stall &
|
||||
|
@ -140,107 +141,125 @@ end
|
|||
~dec_tlu_flush_noredir_wb;
|
||||
|
||||
|
||||
assign fetch_bf_en = exu_flush_final | ifc_fetch_req_f;
|
||||
assign fetch_bf_en = exu_flush_final | ifc_fetch_req_f;
|
||||
|
||||
assign miss_f = ifc_fetch_req_f & ~ic_hit_f & ~exu_flush_final;
|
||||
assign miss_f = ifc_fetch_req_f & ~ic_hit_f & ~exu_flush_final;
|
||||
|
||||
assign mb_empty_mod = (ifu_ic_mb_empty | exu_flush_final) & ~dma_stall & ~miss_f & ~miss_a;
|
||||
assign mb_empty_mod = (ifu_ic_mb_empty | exu_flush_final) & ~dma_stall & ~miss_f & ~miss_a;
|
||||
|
||||
// Halt flushes and takes us to IDLE
|
||||
assign goto_idle = exu_flush_final & dec_tlu_flush_noredir_wb;
|
||||
// If we're in IDLE, and we get a flush, goto FETCH
|
||||
assign leave_idle = exu_flush_final & ~dec_tlu_flush_noredir_wb & idle;
|
||||
// Halt flushes and takes us to IDLE
|
||||
assign goto_idle = exu_flush_final & dec_tlu_flush_noredir_wb;
|
||||
// If we're in IDLE, and we get a flush, goto FETCH
|
||||
assign leave_idle = exu_flush_final & ~dec_tlu_flush_noredir_wb & idle;
|
||||
|
||||
//.i 7
|
||||
//.o 2
|
||||
//.ilb state[1] state[0] reset_delayed miss_f mb_empty_mod goto_idle leave_idle
|
||||
//.ob next_state[1] next_state[0]
|
||||
//.type fr
|
||||
//
|
||||
//# fetch 01, stall 10, wfm 11, idle 00
|
||||
//-- 1---- 01
|
||||
//-- 0--1- 00
|
||||
//00 0--00 00
|
||||
//00 0--01 01
|
||||
//
|
||||
//01 01-0- 11
|
||||
//01 00-0- 01
|
||||
//
|
||||
//11 0-10- 01
|
||||
//11 0-00- 11
|
||||
//.i 7
|
||||
//.o 2
|
||||
//.ilb state[1] state[0] reset_delayed miss_f mb_empty_mod goto_idle leave_idle
|
||||
//.ob next_state[1] next_state[0]
|
||||
//.type fr
|
||||
//
|
||||
//# fetch 01, stall 10, wfm 11, idle 00
|
||||
//-- 1---- 01
|
||||
//-- 0--1- 00
|
||||
//00 0--00 00
|
||||
//00 0--01 01
|
||||
//
|
||||
//01 01-0- 11
|
||||
//01 00-0- 01
|
||||
//
|
||||
//11 0-10- 01
|
||||
//11 0-00- 11
|
||||
|
||||
assign next_state[1] = (~state[1] & state[0] & miss_f & ~goto_idle) |
|
||||
assign next_state[1] = (~state[1] & state[0] & miss_f & ~goto_idle) |
|
||||
(state[1] & ~mb_empty_mod & ~goto_idle);
|
||||
|
||||
assign next_state[0] = (~goto_idle & leave_idle) | (state[0] & ~goto_idle);
|
||||
assign next_state[0] = (~goto_idle & leave_idle) | (state[0] & ~goto_idle);
|
||||
|
||||
assign flush_fb = exu_flush_final;
|
||||
assign flush_fb = exu_flush_final;
|
||||
|
||||
// model fb write logic to mass balance the fetch buffers
|
||||
assign fb_right = ( ifu_fb_consume1 & ~ifu_fb_consume2 & (~ifc_fetch_req_f | miss_f)) | // Consumed and no new fetch
|
||||
// model fb write logic to mass balance the fetch buffers
|
||||
assign fb_right = ( ifu_fb_consume1 & ~ifu_fb_consume2 & (~ifc_fetch_req_f | miss_f)) | // Consumed and no new fetch
|
||||
(ifu_fb_consume2 & ifc_fetch_req_f); // Consumed 2 and new fetch
|
||||
|
||||
|
||||
assign fb_right2 = (ifu_fb_consume2 & (~ifc_fetch_req_f | miss_f)); // Consumed 2 and no new fetch
|
||||
assign fb_right2 = (ifu_fb_consume2 & (~ifc_fetch_req_f | miss_f)); // Consumed 2 and no new fetch
|
||||
|
||||
assign fb_left = ifc_fetch_req_f & ~(ifu_fb_consume1 | ifu_fb_consume2) & ~miss_f;
|
||||
assign fb_left = ifc_fetch_req_f & ~(ifu_fb_consume1 | ifu_fb_consume2) & ~miss_f;
|
||||
|
||||
// CBH
|
||||
assign fb_write_ns[3:0] = ( ({4{(flush_fb)}} & 4'b0001) |
|
||||
// CBH
|
||||
assign fb_write_ns[3:0] = ( ({4{(flush_fb)}} & 4'b0001) |
|
||||
({4{~flush_fb & fb_right }} & {1'b0, fb_write_f[3:1]}) |
|
||||
({4{~flush_fb & fb_right2}} & {2'b0, fb_write_f[3:2]}) |
|
||||
({4{~flush_fb & fb_left }} & {fb_write_f[2:0], 1'b0}) |
|
||||
({4{~flush_fb & ~fb_right & ~fb_right2 & ~fb_left}} & fb_write_f[3:0]));
|
||||
|
||||
|
||||
assign fb_full_f_ns = fb_write_ns[3];
|
||||
assign fb_full_f_ns = fb_write_ns[3];
|
||||
|
||||
assign idle = state == IDLE ;
|
||||
assign wfm = state == WFM ;
|
||||
assign idle = state == IDLE;
|
||||
assign wfm = state == WFM;
|
||||
|
||||
rvdffie #(10) fbwrite_ff (.*, .clk(free_l2clk),
|
||||
.din( {dma_iccm_stall_any, miss_f, ifc_fetch_req_bf, next_state[1:0], fb_full_f_ns, fb_write_ns[3:0]}),
|
||||
.dout({dma_iccm_stall_any_f, miss_a, ifc_fetch_req_f, state[1:0], fb_full_f, fb_write_f[3:0]}));
|
||||
rvdffie #(10) fbwrite_ff (
|
||||
.*,
|
||||
.clk(free_l2clk),
|
||||
.din({
|
||||
dma_iccm_stall_any,
|
||||
miss_f,
|
||||
ifc_fetch_req_bf,
|
||||
next_state[1:0],
|
||||
fb_full_f_ns,
|
||||
fb_write_ns[3:0]
|
||||
}),
|
||||
.dout({dma_iccm_stall_any_f, miss_a, ifc_fetch_req_f, state[1:0], fb_full_f, fb_write_f[3:0]})
|
||||
);
|
||||
|
||||
assign ifu_pmu_fetch_stall = wfm |
|
||||
assign ifu_pmu_fetch_stall = wfm |
|
||||
(ifc_fetch_req_bf_raw &
|
||||
( (fb_full_f & ~(ifu_fb_consume2 | ifu_fb_consume1 | exu_flush_final)) |
|
||||
dma_stall));
|
||||
|
||||
|
||||
|
||||
assign ifc_fetch_addr_bf[31:1] = fetch_addr_bf[31:1];
|
||||
assign ifc_fetch_addr_bf[31:1] = fetch_addr_bf[31:1];
|
||||
|
||||
rvdffpcie #(31) faddrf1_ff (.*, .en(fetch_bf_en), .din(fetch_addr_bf[31:1]), .dout(ifc_fetch_addr_f[31:1]));
|
||||
rvdffpcie #(31) faddrf1_ff (
|
||||
.*,
|
||||
.en (fetch_bf_en),
|
||||
.din (fetch_addr_bf[31:1]),
|
||||
.dout(ifc_fetch_addr_f[31:1])
|
||||
);
|
||||
|
||||
|
||||
if (pt.ICCM_ENABLE) begin
|
||||
logic iccm_acc_in_region_bf;
|
||||
logic iccm_acc_in_range_bf;
|
||||
rvrangecheck #( .CCM_SADR (pt.ICCM_SADR),
|
||||
.CCM_SIZE (pt.ICCM_SIZE) ) iccm_rangecheck (
|
||||
.addr ({ifc_fetch_addr_bf[31:1],1'b0}) ,
|
||||
.in_range (iccm_acc_in_range_bf) ,
|
||||
.in_region(iccm_acc_in_region_bf)
|
||||
);
|
||||
if (pt.ICCM_ENABLE) begin
|
||||
logic iccm_acc_in_region_bf;
|
||||
logic iccm_acc_in_range_bf;
|
||||
rvrangecheck #(
|
||||
.CCM_SADR(pt.ICCM_SADR),
|
||||
.CCM_SIZE(pt.ICCM_SIZE)
|
||||
) iccm_rangecheck (
|
||||
.addr ({ifc_fetch_addr_bf[31:1], 1'b0}),
|
||||
.in_range (iccm_acc_in_range_bf),
|
||||
.in_region(iccm_acc_in_region_bf)
|
||||
);
|
||||
|
||||
assign ifc_iccm_access_bf = iccm_acc_in_range_bf ;
|
||||
assign ifc_iccm_access_bf = iccm_acc_in_range_bf;
|
||||
|
||||
assign ifc_dma_access_ok = ( (~ifc_iccm_access_bf |
|
||||
assign ifc_dma_access_ok = ( (~ifc_iccm_access_bf |
|
||||
(fb_full_f & ~(ifu_fb_consume2 | ifu_fb_consume1)) |
|
||||
(wfm & ~ifc_fetch_req_bf) |
|
||||
idle ) & ~exu_flush_final) |
|
||||
dma_iccm_stall_any_f;
|
||||
|
||||
assign ifc_region_acc_fault_bf = ~iccm_acc_in_range_bf & iccm_acc_in_region_bf ;
|
||||
end
|
||||
else begin
|
||||
assign ifc_iccm_access_bf = 1'b0 ;
|
||||
assign ifc_dma_access_ok = 1'b0 ;
|
||||
assign ifc_region_acc_fault_bf = 1'b0 ;
|
||||
end
|
||||
assign ifc_region_acc_fault_bf = ~iccm_acc_in_range_bf & iccm_acc_in_region_bf;
|
||||
end else begin
|
||||
assign ifc_iccm_access_bf = 1'b0;
|
||||
assign ifc_dma_access_ok = 1'b0;
|
||||
assign ifc_region_acc_fault_bf = 1'b0;
|
||||
end
|
||||
|
||||
assign ifc_fetch_uncacheable_bf = ~dec_tlu_mrac_ff[{ifc_fetch_addr_bf[31:28] , 1'b0 }] ; // bit 0 of each region description is the cacheable bit
|
||||
assign ifc_fetch_uncacheable_bf = ~dec_tlu_mrac_ff[{
|
||||
ifc_fetch_addr_bf[31:28], 1'b0
|
||||
}]; // bit 0 of each region description is the cacheable bit
|
||||
|
||||
endmodule // el2_ifu_ifc_ctl
|
||||
endmodule // el2_ifu_ifc_ctl
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -17,73 +17,78 @@
|
|||
|
||||
module el2_ifu_tb_memread;
|
||||
|
||||
logic [15:0] compressed [0:128000]; // vector of compressed instructions
|
||||
logic [31:0] expected [0:128000]; // vector of correspoding expected instruction
|
||||
logic [15:0] compressed [0:128000]; // vector of compressed instructions
|
||||
logic [31:0] expected [0:128000]; // vector of correspoding expected instruction
|
||||
|
||||
|
||||
logic rst_l;
|
||||
logic clk;
|
||||
logic rst_l;
|
||||
logic clk;
|
||||
|
||||
int clk_count;
|
||||
int clk_count;
|
||||
|
||||
|
||||
|
||||
logic [31:0] expected_val;
|
||||
logic [15:0] compressed_din;
|
||||
logic [31:0] expected_val;
|
||||
logic [15:0] compressed_din;
|
||||
|
||||
logic [31:0] actual;
|
||||
logic [31:0] actual;
|
||||
|
||||
logic error;
|
||||
logic error;
|
||||
|
||||
integer i;
|
||||
initial begin
|
||||
integer i;
|
||||
initial begin
|
||||
|
||||
clk=0;
|
||||
rst_l=0;
|
||||
clk = 0;
|
||||
rst_l = 0;
|
||||
|
||||
// initialize the reads and populate the instruction arrays
|
||||
$readmemh ("left64k", compressed );
|
||||
$readmemh ("right64k", expected );
|
||||
// initialize the reads and populate the instruction arrays
|
||||
$readmemh("left64k", compressed);
|
||||
$readmemh("right64k", expected);
|
||||
|
||||
$dumpfile ("top.vcd");
|
||||
$dumpvars;
|
||||
$dumpon;
|
||||
$dumpfile("top.vcd");
|
||||
$dumpvars;
|
||||
$dumpon;
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
always #50 clk =~clk;
|
||||
always #50 clk = ~clk;
|
||||
|
||||
always @(posedge clk) begin
|
||||
clk_count = clk_count +1;
|
||||
if (clk_count>=1 & clk_count<=3) rst_l <= 1'b0;
|
||||
else rst_l <= 1'b1;
|
||||
always @(posedge clk) begin
|
||||
clk_count = clk_count + 1;
|
||||
if (clk_count >= 1 & clk_count <= 3) rst_l <= 1'b0;
|
||||
else rst_l <= 1'b1;
|
||||
|
||||
if (clk_count > 3) begin
|
||||
if (clk_count > 3) begin
|
||||
|
||||
compressed_din[15:0] <= compressed[clk_count-3]; // c.mv
|
||||
expected_val[31:0] <= expected[clk_count-3];
|
||||
compressed_din[15:0] <= compressed[clk_count-3]; // c.mv
|
||||
expected_val[31:0] <= expected[clk_count-3];
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
if (clk_count == 65000) begin
|
||||
$dumpoff;
|
||||
$finish;
|
||||
end
|
||||
end // always @ (posedge clk)
|
||||
if (clk_count == 65000) begin
|
||||
$dumpoff;
|
||||
$finish;
|
||||
end
|
||||
end // always @ (posedge clk)
|
||||
|
||||
always @(negedge clk) begin
|
||||
if (clk_count > 3 & error) begin
|
||||
$display("clock: %d compressed %h error actual %h expected %h",clk_count,compressed_din,actual,expected_val);
|
||||
end
|
||||
end
|
||||
always @(negedge clk) begin
|
||||
if (clk_count > 3 & error) begin
|
||||
$display("clock: %d compressed %h error actual %h expected %h", clk_count, compressed_din,
|
||||
actual, expected_val);
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
el2_ifu_compress_ctl align (.*,.din(compressed_din[15:0]),.dout(actual[31:0]));
|
||||
el2_ifu_compress_ctl align (
|
||||
.*,
|
||||
.din (compressed_din[15:0]),
|
||||
.dout(actual[31:0])
|
||||
);
|
||||
|
||||
assign error = actual[31:0] != expected_val[31:0];
|
||||
assign error = actual[31:0] != expected_val[31:0];
|
||||
|
||||
|
||||
|
||||
endmodule // el2_ifu_tb_memread
|
||||
endmodule // el2_ifu_tb_memread
|
||||
|
||||
|
||||
|
|
|
@ -3,405 +3,405 @@
|
|||
//`define EL2_DEF_SV
|
||||
package el2_pkg;
|
||||
|
||||
typedef struct packed {
|
||||
logic trace_rv_i_valid_ip;
|
||||
logic [31:0] trace_rv_i_insn_ip;
|
||||
logic [31:0] trace_rv_i_address_ip;
|
||||
logic trace_rv_i_exception_ip;
|
||||
logic [4:0] trace_rv_i_ecause_ip;
|
||||
logic trace_rv_i_interrupt_ip;
|
||||
logic [31:0] trace_rv_i_tval_ip;
|
||||
} el2_trace_pkt_t;
|
||||
typedef struct packed {
|
||||
logic trace_rv_i_valid_ip;
|
||||
logic [31:0] trace_rv_i_insn_ip;
|
||||
logic [31:0] trace_rv_i_address_ip;
|
||||
logic trace_rv_i_exception_ip;
|
||||
logic [4:0] trace_rv_i_ecause_ip;
|
||||
logic trace_rv_i_interrupt_ip;
|
||||
logic [31:0] trace_rv_i_tval_ip;
|
||||
} el2_trace_pkt_t;
|
||||
|
||||
|
||||
typedef enum logic [3:0] {
|
||||
NULL = 4'b0000,
|
||||
MUL = 4'b0001,
|
||||
LOAD = 4'b0010,
|
||||
STORE = 4'b0011,
|
||||
ALU = 4'b0100,
|
||||
CSRREAD = 4'b0101,
|
||||
CSRWRITE = 4'b0110,
|
||||
CSRRW = 4'b0111,
|
||||
EBREAK = 4'b1000,
|
||||
ECALL = 4'b1001,
|
||||
FENCE = 4'b1010,
|
||||
FENCEI = 4'b1011,
|
||||
MRET = 4'b1100,
|
||||
CONDBR = 4'b1101,
|
||||
JAL = 4'b1110,
|
||||
BITMANIPU = 4'b1111
|
||||
} el2_inst_pkt_t;
|
||||
typedef enum logic [3:0] {
|
||||
NULL = 4'b0000,
|
||||
MUL = 4'b0001,
|
||||
LOAD = 4'b0010,
|
||||
STORE = 4'b0011,
|
||||
ALU = 4'b0100,
|
||||
CSRREAD = 4'b0101,
|
||||
CSRWRITE = 4'b0110,
|
||||
CSRRW = 4'b0111,
|
||||
EBREAK = 4'b1000,
|
||||
ECALL = 4'b1001,
|
||||
FENCE = 4'b1010,
|
||||
FENCEI = 4'b1011,
|
||||
MRET = 4'b1100,
|
||||
CONDBR = 4'b1101,
|
||||
JAL = 4'b1110,
|
||||
BITMANIPU = 4'b1111
|
||||
} el2_inst_pkt_t;
|
||||
|
||||
typedef struct packed {
|
||||
logic valid;
|
||||
logic wb;
|
||||
logic [2:0] tag;
|
||||
logic [4:0] rd;
|
||||
} el2_load_cam_pkt_t;
|
||||
typedef struct packed {
|
||||
logic valid;
|
||||
logic wb;
|
||||
logic [2:0] tag;
|
||||
logic [4:0] rd;
|
||||
} el2_load_cam_pkt_t;
|
||||
|
||||
typedef struct packed {
|
||||
logic pc0_call;
|
||||
logic pc0_ret;
|
||||
logic pc0_pc4;
|
||||
} el2_rets_pkt_t;
|
||||
typedef struct packed {
|
||||
logic valid;
|
||||
logic [11:0] toffset;
|
||||
logic [1:0] hist;
|
||||
logic br_error;
|
||||
logic br_start_error;
|
||||
logic bank;
|
||||
logic [31:1] prett; // predicted ret target
|
||||
logic way;
|
||||
logic ret;
|
||||
} el2_br_pkt_t;
|
||||
typedef struct packed {
|
||||
logic pc0_call;
|
||||
logic pc0_ret;
|
||||
logic pc0_pc4;
|
||||
} el2_rets_pkt_t;
|
||||
typedef struct packed {
|
||||
logic valid;
|
||||
logic [11:0] toffset;
|
||||
logic [1:0] hist;
|
||||
logic br_error;
|
||||
logic br_start_error;
|
||||
logic bank;
|
||||
logic [31:1] prett; // predicted ret target
|
||||
logic way;
|
||||
logic ret;
|
||||
} el2_br_pkt_t;
|
||||
|
||||
typedef struct packed {
|
||||
logic valid;
|
||||
logic [1:0] hist;
|
||||
logic br_error;
|
||||
logic br_start_error;
|
||||
logic way;
|
||||
logic middle;
|
||||
} el2_br_tlu_pkt_t;
|
||||
typedef struct packed {
|
||||
logic valid;
|
||||
logic [1:0] hist;
|
||||
logic br_error;
|
||||
logic br_start_error;
|
||||
logic way;
|
||||
logic middle;
|
||||
} el2_br_tlu_pkt_t;
|
||||
|
||||
typedef struct packed {
|
||||
logic misp;
|
||||
logic ataken;
|
||||
logic boffset;
|
||||
logic pc4;
|
||||
logic [1:0] hist;
|
||||
logic [11:0] toffset;
|
||||
logic valid;
|
||||
logic br_error;
|
||||
logic br_start_error;
|
||||
logic pcall;
|
||||
logic pja;
|
||||
logic way;
|
||||
logic pret;
|
||||
// for power use the pret bit to clock the prett field
|
||||
logic [31:1] prett;
|
||||
} el2_predict_pkt_t;
|
||||
typedef struct packed {
|
||||
logic misp;
|
||||
logic ataken;
|
||||
logic boffset;
|
||||
logic pc4;
|
||||
logic [1:0] hist;
|
||||
logic [11:0] toffset;
|
||||
logic valid;
|
||||
logic br_error;
|
||||
logic br_start_error;
|
||||
logic pcall;
|
||||
logic pja;
|
||||
logic way;
|
||||
logic pret;
|
||||
// for power use the pret bit to clock the prett field
|
||||
logic [31:1] prett;
|
||||
} el2_predict_pkt_t;
|
||||
|
||||
typedef struct packed {
|
||||
// unlikely to change
|
||||
logic icaf;
|
||||
logic icaf_second;
|
||||
logic [1:0] icaf_type;
|
||||
logic fence_i;
|
||||
logic [3:0] i0trigger;
|
||||
logic pmu_i0_br_unpred; // pmu
|
||||
logic pmu_divide;
|
||||
// likely to change
|
||||
logic legal;
|
||||
logic pmu_lsu_misaligned;
|
||||
el2_inst_pkt_t pmu_i0_itype; // pmu - instruction type
|
||||
} el2_trap_pkt_t;
|
||||
typedef struct packed {
|
||||
// unlikely to change
|
||||
logic icaf;
|
||||
logic icaf_second;
|
||||
logic [1:0] icaf_type;
|
||||
logic fence_i;
|
||||
logic [3:0] i0trigger;
|
||||
logic pmu_i0_br_unpred; // pmu
|
||||
logic pmu_divide;
|
||||
// likely to change
|
||||
logic legal;
|
||||
logic pmu_lsu_misaligned;
|
||||
el2_inst_pkt_t pmu_i0_itype; // pmu - instruction type
|
||||
} el2_trap_pkt_t;
|
||||
|
||||
typedef struct packed {
|
||||
// unlikely to change
|
||||
logic i0div;
|
||||
logic csrwen;
|
||||
logic csrwonly;
|
||||
logic [11:0] csrwaddr;
|
||||
// likely to change
|
||||
logic [4:0] i0rd;
|
||||
logic i0load;
|
||||
logic i0store;
|
||||
logic i0v;
|
||||
logic i0valid;
|
||||
} el2_dest_pkt_t;
|
||||
typedef struct packed {
|
||||
// unlikely to change
|
||||
logic i0div;
|
||||
logic csrwen;
|
||||
logic csrwonly;
|
||||
logic [11:0] csrwaddr;
|
||||
// likely to change
|
||||
logic [4:0] i0rd;
|
||||
logic i0load;
|
||||
logic i0store;
|
||||
logic i0v;
|
||||
logic i0valid;
|
||||
} el2_dest_pkt_t;
|
||||
|
||||
typedef struct packed {
|
||||
logic mul;
|
||||
logic load;
|
||||
logic alu;
|
||||
} el2_class_pkt_t;
|
||||
typedef struct packed {
|
||||
logic mul;
|
||||
logic load;
|
||||
logic alu;
|
||||
} el2_class_pkt_t;
|
||||
|
||||
typedef struct packed {
|
||||
logic [4:0] rs1;
|
||||
logic [4:0] rs2;
|
||||
logic [4:0] rd;
|
||||
} el2_reg_pkt_t;
|
||||
typedef struct packed {
|
||||
logic [4:0] rs1;
|
||||
logic [4:0] rs2;
|
||||
logic [4:0] rd;
|
||||
} el2_reg_pkt_t;
|
||||
|
||||
|
||||
typedef struct packed {
|
||||
logic clz;
|
||||
logic ctz;
|
||||
logic cpop;
|
||||
logic sext_b;
|
||||
logic sext_h;
|
||||
logic min;
|
||||
logic max;
|
||||
logic pack;
|
||||
logic packu;
|
||||
logic packh;
|
||||
logic rol;
|
||||
logic ror;
|
||||
logic grev;
|
||||
logic gorc;
|
||||
logic zbb;
|
||||
logic bset;
|
||||
logic bclr;
|
||||
logic binv;
|
||||
logic bext;
|
||||
logic sh1add;
|
||||
logic sh2add;
|
||||
logic sh3add;
|
||||
logic zba;
|
||||
logic land;
|
||||
logic lor;
|
||||
logic lxor;
|
||||
logic sll;
|
||||
logic srl;
|
||||
logic sra;
|
||||
logic beq;
|
||||
logic bne;
|
||||
logic blt;
|
||||
logic bge;
|
||||
logic add;
|
||||
logic sub;
|
||||
logic slt;
|
||||
logic unsign;
|
||||
logic jal;
|
||||
logic predict_t;
|
||||
logic predict_nt;
|
||||
logic csr_write;
|
||||
logic csr_imm;
|
||||
} el2_alu_pkt_t;
|
||||
typedef struct packed {
|
||||
logic clz;
|
||||
logic ctz;
|
||||
logic cpop;
|
||||
logic sext_b;
|
||||
logic sext_h;
|
||||
logic min;
|
||||
logic max;
|
||||
logic pack;
|
||||
logic packu;
|
||||
logic packh;
|
||||
logic rol;
|
||||
logic ror;
|
||||
logic grev;
|
||||
logic gorc;
|
||||
logic zbb;
|
||||
logic bset;
|
||||
logic bclr;
|
||||
logic binv;
|
||||
logic bext;
|
||||
logic sh1add;
|
||||
logic sh2add;
|
||||
logic sh3add;
|
||||
logic zba;
|
||||
logic land;
|
||||
logic lor;
|
||||
logic lxor;
|
||||
logic sll;
|
||||
logic srl;
|
||||
logic sra;
|
||||
logic beq;
|
||||
logic bne;
|
||||
logic blt;
|
||||
logic bge;
|
||||
logic add;
|
||||
logic sub;
|
||||
logic slt;
|
||||
logic unsign;
|
||||
logic jal;
|
||||
logic predict_t;
|
||||
logic predict_nt;
|
||||
logic csr_write;
|
||||
logic csr_imm;
|
||||
} el2_alu_pkt_t;
|
||||
|
||||
typedef struct packed {
|
||||
logic fast_int;
|
||||
/* verilator lint_off SYMRSVDWORD */
|
||||
logic stack;
|
||||
/* verilator lint_on SYMRSVDWORD */
|
||||
logic by;
|
||||
logic half;
|
||||
logic word;
|
||||
logic dword; // for dma
|
||||
logic load;
|
||||
logic store;
|
||||
logic unsign;
|
||||
logic dma; // dma pkt
|
||||
logic store_data_bypass_d;
|
||||
logic load_ldst_bypass_d;
|
||||
logic store_data_bypass_m;
|
||||
logic valid;
|
||||
} el2_lsu_pkt_t;
|
||||
typedef struct packed {
|
||||
logic fast_int;
|
||||
/* verilator lint_off SYMRSVDWORD */
|
||||
logic stack;
|
||||
/* verilator lint_on SYMRSVDWORD */
|
||||
logic by;
|
||||
logic half;
|
||||
logic word;
|
||||
logic dword; // for dma
|
||||
logic load;
|
||||
logic store;
|
||||
logic unsign;
|
||||
logic dma; // dma pkt
|
||||
logic store_data_bypass_d;
|
||||
logic load_ldst_bypass_d;
|
||||
logic store_data_bypass_m;
|
||||
logic valid;
|
||||
} el2_lsu_pkt_t;
|
||||
|
||||
typedef struct packed {
|
||||
logic inst_type; //0: Load, 1: Store
|
||||
//logic dma_valid;
|
||||
logic exc_type; //0: MisAligned, 1: Access Fault
|
||||
logic [3:0] mscause;
|
||||
logic [31:0] addr;
|
||||
logic single_ecc_error;
|
||||
logic exc_valid;
|
||||
} el2_lsu_error_pkt_t;
|
||||
typedef struct packed {
|
||||
logic inst_type; //0: Load, 1: Store
|
||||
//logic dma_valid;
|
||||
logic exc_type; //0: MisAligned, 1: Access Fault
|
||||
logic [3:0] mscause;
|
||||
logic [31:0] addr;
|
||||
logic single_ecc_error;
|
||||
logic exc_valid;
|
||||
} el2_lsu_error_pkt_t;
|
||||
|
||||
typedef struct packed {
|
||||
logic clz;
|
||||
logic ctz;
|
||||
logic cpop;
|
||||
logic sext_b;
|
||||
logic sext_h;
|
||||
logic min;
|
||||
logic max;
|
||||
logic pack;
|
||||
logic packu;
|
||||
logic packh;
|
||||
logic rol;
|
||||
logic ror;
|
||||
logic grev;
|
||||
logic gorc;
|
||||
logic zbb;
|
||||
logic bset;
|
||||
logic bclr;
|
||||
logic binv;
|
||||
logic bext;
|
||||
logic zbs;
|
||||
logic bcompress;
|
||||
logic bdecompress;
|
||||
logic zbe;
|
||||
logic clmul;
|
||||
logic clmulh;
|
||||
logic clmulr;
|
||||
logic zbc;
|
||||
logic shfl;
|
||||
logic unshfl;
|
||||
logic xperm_n;
|
||||
logic xperm_b;
|
||||
logic xperm_h;
|
||||
logic zbp;
|
||||
logic crc32_b;
|
||||
logic crc32_h;
|
||||
logic crc32_w;
|
||||
logic crc32c_b;
|
||||
logic crc32c_h;
|
||||
logic crc32c_w;
|
||||
logic zbr;
|
||||
logic bfp;
|
||||
logic zbf;
|
||||
logic sh1add;
|
||||
logic sh2add;
|
||||
logic sh3add;
|
||||
logic zba;
|
||||
logic alu;
|
||||
logic rs1;
|
||||
logic rs2;
|
||||
logic imm12;
|
||||
logic rd;
|
||||
logic shimm5;
|
||||
logic imm20;
|
||||
logic pc;
|
||||
logic load;
|
||||
logic store;
|
||||
logic lsu;
|
||||
logic add;
|
||||
logic sub;
|
||||
logic land;
|
||||
logic lor;
|
||||
logic lxor;
|
||||
logic sll;
|
||||
logic sra;
|
||||
logic srl;
|
||||
logic slt;
|
||||
logic unsign;
|
||||
logic condbr;
|
||||
logic beq;
|
||||
logic bne;
|
||||
logic bge;
|
||||
logic blt;
|
||||
logic jal;
|
||||
logic by;
|
||||
logic half;
|
||||
logic word;
|
||||
logic csr_read;
|
||||
logic csr_clr;
|
||||
logic csr_set;
|
||||
logic csr_write;
|
||||
logic csr_imm;
|
||||
logic presync;
|
||||
logic postsync;
|
||||
logic ebreak;
|
||||
logic ecall;
|
||||
logic mret;
|
||||
logic mul;
|
||||
logic rs1_sign;
|
||||
logic rs2_sign;
|
||||
logic low;
|
||||
logic div;
|
||||
logic rem;
|
||||
logic fence;
|
||||
logic fence_i;
|
||||
logic pm_alu;
|
||||
logic legal;
|
||||
} el2_dec_pkt_t;
|
||||
typedef struct packed {
|
||||
logic clz;
|
||||
logic ctz;
|
||||
logic cpop;
|
||||
logic sext_b;
|
||||
logic sext_h;
|
||||
logic min;
|
||||
logic max;
|
||||
logic pack;
|
||||
logic packu;
|
||||
logic packh;
|
||||
logic rol;
|
||||
logic ror;
|
||||
logic grev;
|
||||
logic gorc;
|
||||
logic zbb;
|
||||
logic bset;
|
||||
logic bclr;
|
||||
logic binv;
|
||||
logic bext;
|
||||
logic zbs;
|
||||
logic bcompress;
|
||||
logic bdecompress;
|
||||
logic zbe;
|
||||
logic clmul;
|
||||
logic clmulh;
|
||||
logic clmulr;
|
||||
logic zbc;
|
||||
logic shfl;
|
||||
logic unshfl;
|
||||
logic xperm_n;
|
||||
logic xperm_b;
|
||||
logic xperm_h;
|
||||
logic zbp;
|
||||
logic crc32_b;
|
||||
logic crc32_h;
|
||||
logic crc32_w;
|
||||
logic crc32c_b;
|
||||
logic crc32c_h;
|
||||
logic crc32c_w;
|
||||
logic zbr;
|
||||
logic bfp;
|
||||
logic zbf;
|
||||
logic sh1add;
|
||||
logic sh2add;
|
||||
logic sh3add;
|
||||
logic zba;
|
||||
logic alu;
|
||||
logic rs1;
|
||||
logic rs2;
|
||||
logic imm12;
|
||||
logic rd;
|
||||
logic shimm5;
|
||||
logic imm20;
|
||||
logic pc;
|
||||
logic load;
|
||||
logic store;
|
||||
logic lsu;
|
||||
logic add;
|
||||
logic sub;
|
||||
logic land;
|
||||
logic lor;
|
||||
logic lxor;
|
||||
logic sll;
|
||||
logic sra;
|
||||
logic srl;
|
||||
logic slt;
|
||||
logic unsign;
|
||||
logic condbr;
|
||||
logic beq;
|
||||
logic bne;
|
||||
logic bge;
|
||||
logic blt;
|
||||
logic jal;
|
||||
logic by;
|
||||
logic half;
|
||||
logic word;
|
||||
logic csr_read;
|
||||
logic csr_clr;
|
||||
logic csr_set;
|
||||
logic csr_write;
|
||||
logic csr_imm;
|
||||
logic presync;
|
||||
logic postsync;
|
||||
logic ebreak;
|
||||
logic ecall;
|
||||
logic mret;
|
||||
logic mul;
|
||||
logic rs1_sign;
|
||||
logic rs2_sign;
|
||||
logic low;
|
||||
logic div;
|
||||
logic rem;
|
||||
logic fence;
|
||||
logic fence_i;
|
||||
logic pm_alu;
|
||||
logic legal;
|
||||
} el2_dec_pkt_t;
|
||||
|
||||
|
||||
typedef struct packed {
|
||||
logic valid;
|
||||
logic rs1_sign;
|
||||
logic rs2_sign;
|
||||
logic low;
|
||||
logic bcompress;
|
||||
logic bdecompress;
|
||||
logic clmul;
|
||||
logic clmulh;
|
||||
logic clmulr;
|
||||
logic grev;
|
||||
logic gorc;
|
||||
logic shfl;
|
||||
logic unshfl;
|
||||
logic crc32_b;
|
||||
logic crc32_h;
|
||||
logic crc32_w;
|
||||
logic crc32c_b;
|
||||
logic crc32c_h;
|
||||
logic crc32c_w;
|
||||
logic bfp;
|
||||
logic xperm_n;
|
||||
logic xperm_b;
|
||||
logic xperm_h;
|
||||
} el2_mul_pkt_t;
|
||||
typedef struct packed {
|
||||
logic valid;
|
||||
logic rs1_sign;
|
||||
logic rs2_sign;
|
||||
logic low;
|
||||
logic bcompress;
|
||||
logic bdecompress;
|
||||
logic clmul;
|
||||
logic clmulh;
|
||||
logic clmulr;
|
||||
logic grev;
|
||||
logic gorc;
|
||||
logic shfl;
|
||||
logic unshfl;
|
||||
logic crc32_b;
|
||||
logic crc32_h;
|
||||
logic crc32_w;
|
||||
logic crc32c_b;
|
||||
logic crc32c_h;
|
||||
logic crc32c_w;
|
||||
logic bfp;
|
||||
logic xperm_n;
|
||||
logic xperm_b;
|
||||
logic xperm_h;
|
||||
} el2_mul_pkt_t;
|
||||
|
||||
typedef struct packed {
|
||||
logic valid;
|
||||
logic unsign;
|
||||
logic rem;
|
||||
} el2_div_pkt_t;
|
||||
typedef struct packed {
|
||||
logic valid;
|
||||
logic unsign;
|
||||
logic rem;
|
||||
} el2_div_pkt_t;
|
||||
|
||||
typedef struct packed {
|
||||
logic TEST1;
|
||||
logic RME;
|
||||
logic [3:0] RM;
|
||||
typedef struct packed {
|
||||
logic TEST1;
|
||||
logic RME;
|
||||
logic [3:0] RM;
|
||||
|
||||
logic LS;
|
||||
logic DS;
|
||||
logic SD;
|
||||
logic TEST_RNM;
|
||||
logic BC1;
|
||||
logic BC2;
|
||||
} el2_ccm_ext_in_pkt_t;
|
||||
logic LS;
|
||||
logic DS;
|
||||
logic SD;
|
||||
logic TEST_RNM;
|
||||
logic BC1;
|
||||
logic BC2;
|
||||
} el2_ccm_ext_in_pkt_t;
|
||||
|
||||
typedef struct packed {
|
||||
logic TEST1;
|
||||
logic RME;
|
||||
logic [3:0] RM;
|
||||
logic LS;
|
||||
logic DS;
|
||||
logic SD;
|
||||
logic TEST_RNM;
|
||||
logic BC1;
|
||||
logic BC2;
|
||||
} el2_dccm_ext_in_pkt_t;
|
||||
typedef struct packed {
|
||||
logic TEST1;
|
||||
logic RME;
|
||||
logic [3:0] RM;
|
||||
logic LS;
|
||||
logic DS;
|
||||
logic SD;
|
||||
logic TEST_RNM;
|
||||
logic BC1;
|
||||
logic BC2;
|
||||
} el2_dccm_ext_in_pkt_t;
|
||||
|
||||
|
||||
typedef struct packed {
|
||||
logic TEST1;
|
||||
logic RME;
|
||||
logic [3:0] RM;
|
||||
logic LS;
|
||||
logic DS;
|
||||
logic SD;
|
||||
logic TEST_RNM;
|
||||
logic BC1;
|
||||
logic BC2;
|
||||
} el2_ic_data_ext_in_pkt_t;
|
||||
typedef struct packed {
|
||||
logic TEST1;
|
||||
logic RME;
|
||||
logic [3:0] RM;
|
||||
logic LS;
|
||||
logic DS;
|
||||
logic SD;
|
||||
logic TEST_RNM;
|
||||
logic BC1;
|
||||
logic BC2;
|
||||
} el2_ic_data_ext_in_pkt_t;
|
||||
|
||||
|
||||
typedef struct packed {
|
||||
logic TEST1;
|
||||
logic RME;
|
||||
logic [3:0] RM;
|
||||
logic LS;
|
||||
logic DS;
|
||||
logic SD;
|
||||
logic TEST_RNM;
|
||||
logic BC1;
|
||||
logic BC2;
|
||||
} el2_ic_tag_ext_in_pkt_t;
|
||||
typedef struct packed {
|
||||
logic TEST1;
|
||||
logic RME;
|
||||
logic [3:0] RM;
|
||||
logic LS;
|
||||
logic DS;
|
||||
logic SD;
|
||||
logic TEST_RNM;
|
||||
logic BC1;
|
||||
logic BC2;
|
||||
} el2_ic_tag_ext_in_pkt_t;
|
||||
|
||||
|
||||
|
||||
typedef struct packed {
|
||||
logic select;
|
||||
logic match;
|
||||
logic store;
|
||||
logic load;
|
||||
logic execute;
|
||||
logic m;
|
||||
logic [31:0] tdata2;
|
||||
} el2_trigger_pkt_t;
|
||||
typedef struct packed {
|
||||
logic select;
|
||||
logic match;
|
||||
logic store;
|
||||
logic load;
|
||||
logic execute;
|
||||
logic m;
|
||||
logic [31:0] tdata2;
|
||||
} el2_trigger_pkt_t;
|
||||
|
||||
|
||||
typedef struct packed {
|
||||
logic [70:0] icache_wrdata; // {dicad1[1:0], dicad0h[31:0], dicad0[31:0]}
|
||||
logic [16:0] icache_dicawics; // Arraysel:24, Waysel:21:20, Index:16:3
|
||||
logic icache_rd_valid;
|
||||
logic icache_wr_valid;
|
||||
} el2_cache_debug_pkt_t;
|
||||
//`endif
|
||||
typedef struct packed {
|
||||
logic [70:0] icache_wrdata; // {dicad1[1:0], dicad0h[31:0], dicad0[31:0]}
|
||||
logic [16:0] icache_dicawics; // Arraysel:24, Waysel:21:20, Index:16:3
|
||||
logic icache_rd_valid;
|
||||
logic icache_wr_valid;
|
||||
} el2_cache_debug_pkt_t;
|
||||
//`endif
|
||||
|
||||
endpackage // el2_pkg
|
||||
endpackage // el2_pkg
|
||||
|
|
|
@ -21,254 +21,412 @@
|
|||
//
|
||||
//********************************************************************************
|
||||
module ahb_to_axi4
|
||||
import el2_pkg::*;
|
||||
import el2_pkg::*;
|
||||
#(
|
||||
TAG = 1,
|
||||
`include "el2_param.vh"
|
||||
TAG = 1,
|
||||
`include "el2_param.vh"
|
||||
)
|
||||
// ,TAG = 1)
|
||||
(
|
||||
input clk,
|
||||
input rst_l,
|
||||
input scan_mode,
|
||||
input bus_clk_en,
|
||||
input clk_override,
|
||||
input clk,
|
||||
input rst_l,
|
||||
input scan_mode,
|
||||
input bus_clk_en,
|
||||
input clk_override,
|
||||
|
||||
// AXI signals
|
||||
// AXI Write Channels
|
||||
output logic axi_awvalid,
|
||||
input logic axi_awready,
|
||||
output logic [TAG-1:0] axi_awid,
|
||||
output logic [31:0] axi_awaddr,
|
||||
output logic [2:0] axi_awsize,
|
||||
output logic [2:0] axi_awprot,
|
||||
output logic [7:0] axi_awlen,
|
||||
output logic [1:0] axi_awburst,
|
||||
// AXI signals
|
||||
// AXI Write Channels
|
||||
output logic axi_awvalid,
|
||||
input logic axi_awready,
|
||||
output logic [TAG-1:0] axi_awid,
|
||||
output logic [ 31:0] axi_awaddr,
|
||||
output logic [ 2:0] axi_awsize,
|
||||
output logic [ 2:0] axi_awprot,
|
||||
output logic [ 7:0] axi_awlen,
|
||||
output logic [ 1:0] axi_awburst,
|
||||
|
||||
output logic axi_wvalid,
|
||||
input logic axi_wready,
|
||||
output logic [63:0] axi_wdata,
|
||||
output logic [7:0] axi_wstrb,
|
||||
output logic axi_wlast,
|
||||
output logic axi_wvalid,
|
||||
input logic axi_wready,
|
||||
output logic [63:0] axi_wdata,
|
||||
output logic [ 7:0] axi_wstrb,
|
||||
output logic axi_wlast,
|
||||
|
||||
input logic axi_bvalid,
|
||||
output logic axi_bready,
|
||||
input logic [1:0] axi_bresp,
|
||||
input logic [TAG-1:0] axi_bid,
|
||||
input logic axi_bvalid,
|
||||
output logic axi_bready,
|
||||
input logic [ 1:0] axi_bresp,
|
||||
input logic [TAG-1:0] axi_bid,
|
||||
|
||||
// AXI Read Channels
|
||||
output logic axi_arvalid,
|
||||
input logic axi_arready,
|
||||
output logic [TAG-1:0] axi_arid,
|
||||
output logic [31:0] axi_araddr,
|
||||
output logic [2:0] axi_arsize,
|
||||
output logic [2:0] axi_arprot,
|
||||
output logic [7:0] axi_arlen,
|
||||
output logic [1:0] axi_arburst,
|
||||
// AXI Read Channels
|
||||
output logic axi_arvalid,
|
||||
input logic axi_arready,
|
||||
output logic [TAG-1:0] axi_arid,
|
||||
output logic [ 31:0] axi_araddr,
|
||||
output logic [ 2:0] axi_arsize,
|
||||
output logic [ 2:0] axi_arprot,
|
||||
output logic [ 7:0] axi_arlen,
|
||||
output logic [ 1:0] axi_arburst,
|
||||
|
||||
input logic axi_rvalid,
|
||||
output logic axi_rready,
|
||||
input logic [TAG-1:0] axi_rid,
|
||||
input logic [63:0] axi_rdata,
|
||||
input logic [1:0] axi_rresp,
|
||||
input logic axi_rvalid,
|
||||
output logic axi_rready,
|
||||
input logic [TAG-1:0] axi_rid,
|
||||
input logic [ 63:0] axi_rdata,
|
||||
input logic [ 1:0] axi_rresp,
|
||||
|
||||
// AHB-Lite signals
|
||||
input logic [31:0] ahb_haddr, // ahb bus address
|
||||
input logic [2:0] ahb_hburst, // tied to 0
|
||||
input logic ahb_hmastlock, // tied to 0
|
||||
input logic [3:0] ahb_hprot, // tied to 4'b0011
|
||||
input logic [2:0] ahb_hsize, // size of bus transaction (possible values 0,1,2,3)
|
||||
input logic [1:0] ahb_htrans, // Transaction type (possible values 0,2 only right now)
|
||||
input logic ahb_hwrite, // ahb bus write
|
||||
input logic [63:0] ahb_hwdata, // ahb bus write data
|
||||
input logic ahb_hsel, // this slave was selected
|
||||
input logic ahb_hreadyin, // previous hready was accepted or not
|
||||
// AHB-Lite signals
|
||||
input logic [31:0] ahb_haddr, // ahb bus address
|
||||
input logic [ 2:0] ahb_hburst, // tied to 0
|
||||
input logic ahb_hmastlock, // tied to 0
|
||||
input logic [ 3:0] ahb_hprot, // tied to 4'b0011
|
||||
input logic [ 2:0] ahb_hsize, // size of bus transaction (possible values 0,1,2,3)
|
||||
input logic [ 1:0] ahb_htrans, // Transaction type (possible values 0,2 only right now)
|
||||
input logic ahb_hwrite, // ahb bus write
|
||||
input logic [63:0] ahb_hwdata, // ahb bus write data
|
||||
input logic ahb_hsel, // this slave was selected
|
||||
input logic ahb_hreadyin, // previous hready was accepted or not
|
||||
|
||||
output logic [63:0] ahb_hrdata, // ahb bus read data
|
||||
output logic ahb_hreadyout, // slave ready to accept transaction
|
||||
output logic ahb_hresp // slave response (high indicates erro)
|
||||
output logic [63:0] ahb_hrdata, // ahb bus read data
|
||||
output logic ahb_hreadyout, // slave ready to accept transaction
|
||||
output logic ahb_hresp // slave response (high indicates erro)
|
||||
|
||||
);
|
||||
|
||||
logic [7:0] master_wstrb;
|
||||
logic [7:0] master_wstrb;
|
||||
|
||||
typedef enum logic [1:0] { IDLE = 2'b00, // Nothing in the buffer. No commands yet recieved
|
||||
WR = 2'b01, // Write Command recieved
|
||||
RD = 2'b10, // Read Command recieved
|
||||
PEND = 2'b11 // Waiting on Read Data from core
|
||||
} state_t;
|
||||
state_t buf_state, buf_nxtstate;
|
||||
logic buf_state_en;
|
||||
typedef enum logic [1:0] {
|
||||
IDLE = 2'b00, // Nothing in the buffer. No commands yet recieved
|
||||
WR = 2'b01, // Write Command recieved
|
||||
RD = 2'b10, // Read Command recieved
|
||||
PEND = 2'b11 // Waiting on Read Data from core
|
||||
} state_t;
|
||||
state_t buf_state, buf_nxtstate;
|
||||
logic buf_state_en;
|
||||
|
||||
// Buffer signals (one entry buffer)
|
||||
logic buf_read_error_in, buf_read_error;
|
||||
logic [63:0] buf_rdata;
|
||||
// Buffer signals (one entry buffer)
|
||||
logic buf_read_error_in, buf_read_error;
|
||||
logic [63:0] buf_rdata;
|
||||
|
||||
logic ahb_hready;
|
||||
logic ahb_hready_q;
|
||||
logic [1:0] ahb_htrans_in, ahb_htrans_q;
|
||||
logic [2:0] ahb_hsize_q;
|
||||
logic ahb_hwrite_q;
|
||||
logic [31:0] ahb_haddr_q;
|
||||
logic [63:0] ahb_hwdata_q;
|
||||
logic ahb_hresp_q;
|
||||
logic ahb_hready;
|
||||
logic ahb_hready_q;
|
||||
logic [1:0] ahb_htrans_in, ahb_htrans_q;
|
||||
logic [ 2:0] ahb_hsize_q;
|
||||
logic ahb_hwrite_q;
|
||||
logic [31:0] ahb_haddr_q;
|
||||
logic [63:0] ahb_hwdata_q;
|
||||
logic ahb_hresp_q;
|
||||
|
||||
//Miscellaneous signals
|
||||
logic ahb_addr_in_dccm, ahb_addr_in_iccm, ahb_addr_in_pic;
|
||||
logic ahb_addr_in_dccm_region_nc, ahb_addr_in_iccm_region_nc, ahb_addr_in_pic_region_nc;
|
||||
// signals needed for the read data coming back from the core and to block any further commands as AHB is a blocking bus
|
||||
logic buf_rdata_en;
|
||||
//Miscellaneous signals
|
||||
logic ahb_addr_in_dccm, ahb_addr_in_iccm, ahb_addr_in_pic;
|
||||
logic ahb_addr_in_dccm_region_nc, ahb_addr_in_iccm_region_nc, ahb_addr_in_pic_region_nc;
|
||||
// signals needed for the read data coming back from the core and to block any further commands as AHB is a blocking bus
|
||||
logic buf_rdata_en;
|
||||
|
||||
logic ahb_addr_clk_en, buf_rdata_clk_en;
|
||||
logic bus_clk, ahb_addr_clk, buf_rdata_clk;
|
||||
// Command buffer is the holding station where we convert to AXI and send to core
|
||||
logic cmdbuf_wr_en, cmdbuf_rst;
|
||||
logic cmdbuf_full;
|
||||
logic cmdbuf_vld, cmdbuf_write;
|
||||
logic [1:0] cmdbuf_size;
|
||||
logic [7:0] cmdbuf_wstrb;
|
||||
logic [31:0] cmdbuf_addr;
|
||||
logic [63:0] cmdbuf_wdata;
|
||||
logic ahb_addr_clk_en, buf_rdata_clk_en;
|
||||
logic bus_clk, ahb_addr_clk, buf_rdata_clk;
|
||||
// Command buffer is the holding station where we convert to AXI and send to core
|
||||
logic cmdbuf_wr_en, cmdbuf_rst;
|
||||
logic cmdbuf_full;
|
||||
logic cmdbuf_vld, cmdbuf_write;
|
||||
logic [ 1:0] cmdbuf_size;
|
||||
logic [ 7:0] cmdbuf_wstrb;
|
||||
logic [31:0] cmdbuf_addr;
|
||||
logic [63:0] cmdbuf_wdata;
|
||||
|
||||
// FSM to control the bus states and when to block the hready and load the command buffer
|
||||
always_comb begin
|
||||
buf_nxtstate = IDLE;
|
||||
buf_state_en = 1'b0;
|
||||
buf_rdata_en = 1'b0; // signal to load the buffer when the core sends read data back
|
||||
buf_read_error_in = 1'b0; // signal indicating that an error came back with the read from the core
|
||||
cmdbuf_wr_en = 1'b0; // all clear from the gasket to load the buffer with the command for reads, command/dat for writes
|
||||
case (buf_state)
|
||||
IDLE: begin // No commands recieved
|
||||
buf_nxtstate = ahb_hwrite ? WR : RD;
|
||||
buf_state_en = ahb_hready & ahb_htrans[1] & ahb_hsel; // only transition on a valid hrtans
|
||||
end
|
||||
WR: begin // Write command recieved last cycle
|
||||
buf_nxtstate = (ahb_hresp | (ahb_htrans[1:0] == 2'b0) | ~ahb_hsel) ? IDLE : ahb_hwrite ? WR : RD;
|
||||
buf_state_en = (~cmdbuf_full | ahb_hresp) ;
|
||||
cmdbuf_wr_en = ~cmdbuf_full & ~(ahb_hresp | ((ahb_htrans[1:0] == 2'b01) & ahb_hsel)); // Dont send command to the buffer in case of an error or when the master is not ready with the data now.
|
||||
end
|
||||
RD: begin // Read command recieved last cycle.
|
||||
buf_nxtstate = ahb_hresp ? IDLE :PEND; // If error go to idle, else wait for read data
|
||||
buf_state_en = (~cmdbuf_full | ahb_hresp); // only when command can go, or if its an error
|
||||
cmdbuf_wr_en = ~ahb_hresp & ~cmdbuf_full; // send command only when no error
|
||||
end
|
||||
PEND: begin // Read Command has been sent. Waiting on Data.
|
||||
buf_nxtstate = IDLE; // go back for next command and present data next cycle
|
||||
buf_state_en = axi_rvalid & ~cmdbuf_write; // read data is back
|
||||
buf_rdata_en = buf_state_en; // buffer the read data coming back from core
|
||||
buf_read_error_in = buf_state_en & |axi_rresp[1:0]; // buffer error flag if return has Error ( ECC )
|
||||
end
|
||||
endcase
|
||||
end // always_comb begin
|
||||
// FSM to control the bus states and when to block the hready and load the command buffer
|
||||
always_comb begin
|
||||
buf_nxtstate = IDLE;
|
||||
buf_state_en = 1'b0;
|
||||
buf_rdata_en = 1'b0; // signal to load the buffer when the core sends read data back
|
||||
buf_read_error_in = 1'b0; // signal indicating that an error came back with the read from the core
|
||||
cmdbuf_wr_en = 1'b0; // all clear from the gasket to load the buffer with the command for reads, command/dat for writes
|
||||
case (buf_state)
|
||||
IDLE: begin // No commands recieved
|
||||
buf_nxtstate = ahb_hwrite ? WR : RD;
|
||||
buf_state_en = ahb_hready & ahb_htrans[1] & ahb_hsel; // only transition on a valid hrtans
|
||||
end
|
||||
WR: begin // Write command recieved last cycle
|
||||
buf_nxtstate = (ahb_hresp | (ahb_htrans[1:0] == 2'b0) | ~ahb_hsel) ? IDLE : ahb_hwrite ? WR : RD;
|
||||
buf_state_en = (~cmdbuf_full | ahb_hresp);
|
||||
cmdbuf_wr_en = ~cmdbuf_full & ~(ahb_hresp | ((ahb_htrans[1:0] == 2'b01) & ahb_hsel)); // Dont send command to the buffer in case of an error or when the master is not ready with the data now.
|
||||
end
|
||||
RD: begin // Read command recieved last cycle.
|
||||
buf_nxtstate = ahb_hresp ? IDLE : PEND; // If error go to idle, else wait for read data
|
||||
buf_state_en = (~cmdbuf_full | ahb_hresp); // only when command can go, or if its an error
|
||||
cmdbuf_wr_en = ~ahb_hresp & ~cmdbuf_full; // send command only when no error
|
||||
end
|
||||
PEND: begin // Read Command has been sent. Waiting on Data.
|
||||
buf_nxtstate = IDLE; // go back for next command and present data next cycle
|
||||
buf_state_en = axi_rvalid & ~cmdbuf_write; // read data is back
|
||||
buf_rdata_en = buf_state_en; // buffer the read data coming back from core
|
||||
buf_read_error_in = buf_state_en & |axi_rresp[1:0]; // buffer error flag if return has Error ( ECC )
|
||||
end
|
||||
endcase
|
||||
end // always_comb begin
|
||||
|
||||
rvdffs_fpga #($bits(state_t)) state_reg (.*, .din(buf_nxtstate), .dout({buf_state}), .en(buf_state_en), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk));
|
||||
rvdffs_fpga #($bits(
|
||||
state_t
|
||||
)) state_reg (
|
||||
.*,
|
||||
.din(buf_nxtstate),
|
||||
.dout({buf_state}),
|
||||
.en(buf_state_en),
|
||||
.clk(bus_clk),
|
||||
.clken(bus_clk_en),
|
||||
.rawclk(clk)
|
||||
);
|
||||
|
||||
assign master_wstrb[7:0] = ({8{ahb_hsize_q[2:0] == 3'b0}} & (8'b1 << ahb_haddr_q[2:0])) |
|
||||
assign master_wstrb[7:0] = ({8{ahb_hsize_q[2:0] == 3'b0}} & (8'b1 << ahb_haddr_q[2:0])) |
|
||||
({8{ahb_hsize_q[2:0] == 3'b1}} & (8'b11 << ahb_haddr_q[2:0])) |
|
||||
({8{ahb_hsize_q[2:0] == 3'b10}} & (8'b1111 << ahb_haddr_q[2:0])) |
|
||||
({8{ahb_hsize_q[2:0] == 3'b11}} & 8'b1111_1111);
|
||||
|
||||
// AHB signals
|
||||
assign ahb_hreadyout = ahb_hresp ? (ahb_hresp_q & ~ahb_hready_q) :
|
||||
// AHB signals
|
||||
assign ahb_hreadyout = ahb_hresp ? (ahb_hresp_q & ~ahb_hready_q) :
|
||||
((~cmdbuf_full | (buf_state == IDLE)) & ~(buf_state == RD | buf_state == PEND) & ~buf_read_error);
|
||||
|
||||
assign ahb_hready = ahb_hreadyout & ahb_hreadyin;
|
||||
assign ahb_htrans_in[1:0] = {2{ahb_hsel}} & ahb_htrans[1:0];
|
||||
assign ahb_hrdata[63:0] = buf_rdata[63:0];
|
||||
assign ahb_hresp = ((ahb_htrans_q[1:0] != 2'b0) & (buf_state != IDLE) &
|
||||
assign ahb_hready = ahb_hreadyout & ahb_hreadyin;
|
||||
assign ahb_htrans_in[1:0] = {2{ahb_hsel}} & ahb_htrans[1:0];
|
||||
assign ahb_hrdata[63:0] = buf_rdata[63:0];
|
||||
assign ahb_hresp = ((ahb_htrans_q[1:0] != 2'b0) & (buf_state != IDLE) &
|
||||
|
||||
((~(ahb_addr_in_dccm | ahb_addr_in_iccm)) | // request not for ICCM or DCCM
|
||||
((ahb_addr_in_iccm | (ahb_addr_in_dccm & ahb_hwrite_q)) & ~((ahb_hsize_q[1:0] == 2'b10) | (ahb_hsize_q[1:0] == 2'b11))) | // ICCM Rd/Wr OR DCCM Wr not the right size
|
||||
((ahb_hsize_q[2:0] == 3'h1) & ahb_haddr_q[0]) | // HW size but unaligned
|
||||
((ahb_hsize_q[2:0] == 3'h2) & (|ahb_haddr_q[1:0])) | // W size but unaligned
|
||||
((ahb_hsize_q[2:0] == 3'h3) & (|ahb_haddr_q[2:0])))) | // DW size but unaligned
|
||||
buf_read_error | // Read ECC error
|
||||
(ahb_hresp_q & ~ahb_hready_q);
|
||||
((ahb_addr_in_iccm | (ahb_addr_in_dccm & ahb_hwrite_q)) & ~((ahb_hsize_q[1:0] == 2'b10) | (ahb_hsize_q[1:0] == 2'b11))) | // ICCM Rd/Wr OR DCCM Wr not the right size
|
||||
((ahb_hsize_q[2:0] == 3'h1) & ahb_haddr_q[0]) | // HW size but unaligned
|
||||
((ahb_hsize_q[2:0] == 3'h2) & (|ahb_haddr_q[1:0])) | // W size but unaligned
|
||||
((ahb_hsize_q[2:0] == 3'h3) & (|ahb_haddr_q[2:0])))) | // DW size but unaligned
|
||||
buf_read_error | // Read ECC error
|
||||
(ahb_hresp_q & ~ahb_hready_q);
|
||||
|
||||
// Buffer signals - needed for the read data and ECC error response
|
||||
rvdff_fpga #(.WIDTH(64)) buf_rdata_ff (.din(axi_rdata[63:0]), .dout(buf_rdata[63:0]), .clk(buf_rdata_clk), .clken(buf_rdata_clk_en), .rawclk(clk), .*);
|
||||
rvdff_fpga #(.WIDTH(1)) buf_read_error_ff(.din(buf_read_error_in), .dout(buf_read_error), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*); // buf_read_error will be high only one cycle
|
||||
// Buffer signals - needed for the read data and ECC error response
|
||||
rvdff_fpga #(
|
||||
.WIDTH(64)
|
||||
) buf_rdata_ff (
|
||||
.din(axi_rdata[63:0]),
|
||||
.dout(buf_rdata[63:0]),
|
||||
.clk(buf_rdata_clk),
|
||||
.clken(buf_rdata_clk_en),
|
||||
.rawclk(clk),
|
||||
.*
|
||||
);
|
||||
rvdff_fpga #(
|
||||
.WIDTH(1)
|
||||
) buf_read_error_ff (
|
||||
.din(buf_read_error_in),
|
||||
.dout(buf_read_error),
|
||||
.clk(bus_clk),
|
||||
.clken(bus_clk_en),
|
||||
.rawclk(clk),
|
||||
.*
|
||||
); // buf_read_error will be high only one cycle
|
||||
|
||||
// All the Master signals are captured before presenting it to the command buffer. We check for Hresp before sending it to the cmd buffer.
|
||||
rvdff_fpga #(.WIDTH(1)) hresp_ff (.din(ahb_hresp), .dout(ahb_hresp_q), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*);
|
||||
rvdff_fpga #(.WIDTH(1)) hready_ff (.din(ahb_hready), .dout(ahb_hready_q), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*);
|
||||
rvdff_fpga #(.WIDTH(2)) htrans_ff (.din(ahb_htrans_in[1:0]), .dout(ahb_htrans_q[1:0]), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*);
|
||||
rvdff_fpga #(.WIDTH(3)) hsize_ff (.din(ahb_hsize[2:0]), .dout(ahb_hsize_q[2:0]), .clk(ahb_addr_clk), .clken(ahb_addr_clk_en), .rawclk(clk), .*);
|
||||
rvdff_fpga #(.WIDTH(1)) hwrite_ff (.din(ahb_hwrite), .dout(ahb_hwrite_q), .clk(ahb_addr_clk), .clken(ahb_addr_clk_en), .rawclk(clk), .*);
|
||||
rvdff_fpga #(.WIDTH(32)) haddr_ff (.din(ahb_haddr[31:0]), .dout(ahb_haddr_q[31:0]), .clk(ahb_addr_clk), .clken(ahb_addr_clk_en), .rawclk(clk), .*);
|
||||
// All the Master signals are captured before presenting it to the command buffer. We check for Hresp before sending it to the cmd buffer.
|
||||
rvdff_fpga #(
|
||||
.WIDTH(1)
|
||||
) hresp_ff (
|
||||
.din(ahb_hresp),
|
||||
.dout(ahb_hresp_q),
|
||||
.clk(bus_clk),
|
||||
.clken(bus_clk_en),
|
||||
.rawclk(clk),
|
||||
.*
|
||||
);
|
||||
rvdff_fpga #(
|
||||
.WIDTH(1)
|
||||
) hready_ff (
|
||||
.din(ahb_hready),
|
||||
.dout(ahb_hready_q),
|
||||
.clk(bus_clk),
|
||||
.clken(bus_clk_en),
|
||||
.rawclk(clk),
|
||||
.*
|
||||
);
|
||||
rvdff_fpga #(
|
||||
.WIDTH(2)
|
||||
) htrans_ff (
|
||||
.din(ahb_htrans_in[1:0]),
|
||||
.dout(ahb_htrans_q[1:0]),
|
||||
.clk(bus_clk),
|
||||
.clken(bus_clk_en),
|
||||
.rawclk(clk),
|
||||
.*
|
||||
);
|
||||
rvdff_fpga #(
|
||||
.WIDTH(3)
|
||||
) hsize_ff (
|
||||
.din(ahb_hsize[2:0]),
|
||||
.dout(ahb_hsize_q[2:0]),
|
||||
.clk(ahb_addr_clk),
|
||||
.clken(ahb_addr_clk_en),
|
||||
.rawclk(clk),
|
||||
.*
|
||||
);
|
||||
rvdff_fpga #(
|
||||
.WIDTH(1)
|
||||
) hwrite_ff (
|
||||
.din(ahb_hwrite),
|
||||
.dout(ahb_hwrite_q),
|
||||
.clk(ahb_addr_clk),
|
||||
.clken(ahb_addr_clk_en),
|
||||
.rawclk(clk),
|
||||
.*
|
||||
);
|
||||
rvdff_fpga #(
|
||||
.WIDTH(32)
|
||||
) haddr_ff (
|
||||
.din(ahb_haddr[31:0]),
|
||||
.dout(ahb_haddr_q[31:0]),
|
||||
.clk(ahb_addr_clk),
|
||||
.clken(ahb_addr_clk_en),
|
||||
.rawclk(clk),
|
||||
.*
|
||||
);
|
||||
|
||||
// Address check dccm
|
||||
rvrangecheck #(.CCM_SADR(pt.DCCM_SADR),
|
||||
.CCM_SIZE(pt.DCCM_SIZE)) addr_dccm_rangecheck (
|
||||
// Address check dccm
|
||||
rvrangecheck #(
|
||||
.CCM_SADR(pt.DCCM_SADR),
|
||||
.CCM_SIZE(pt.DCCM_SIZE)
|
||||
) addr_dccm_rangecheck (
|
||||
.addr(ahb_haddr_q[31:0]),
|
||||
.in_range(ahb_addr_in_dccm),
|
||||
.in_region(ahb_addr_in_dccm_region_nc)
|
||||
);
|
||||
);
|
||||
|
||||
// Address check iccm
|
||||
if (pt.ICCM_ENABLE == 1) begin: GenICCM
|
||||
rvrangecheck #(.CCM_SADR(pt.ICCM_SADR),
|
||||
.CCM_SIZE(pt.ICCM_SIZE)) addr_iccm_rangecheck (
|
||||
.addr(ahb_haddr_q[31:0]),
|
||||
.in_range(ahb_addr_in_iccm),
|
||||
.in_region(ahb_addr_in_iccm_region_nc)
|
||||
);
|
||||
end else begin: GenNoICCM
|
||||
assign ahb_addr_in_iccm = '0;
|
||||
assign ahb_addr_in_iccm_region_nc = '0;
|
||||
end
|
||||
// Address check iccm
|
||||
if (pt.ICCM_ENABLE == 1) begin : GenICCM
|
||||
rvrangecheck #(
|
||||
.CCM_SADR(pt.ICCM_SADR),
|
||||
.CCM_SIZE(pt.ICCM_SIZE)
|
||||
) addr_iccm_rangecheck (
|
||||
.addr(ahb_haddr_q[31:0]),
|
||||
.in_range(ahb_addr_in_iccm),
|
||||
.in_region(ahb_addr_in_iccm_region_nc)
|
||||
);
|
||||
end else begin : GenNoICCM
|
||||
assign ahb_addr_in_iccm = '0;
|
||||
assign ahb_addr_in_iccm_region_nc = '0;
|
||||
end
|
||||
|
||||
// PIC memory address check
|
||||
rvrangecheck #(.CCM_SADR(pt.PIC_BASE_ADDR),
|
||||
.CCM_SIZE(pt.PIC_SIZE)) addr_pic_rangecheck (
|
||||
// PIC memory address check
|
||||
rvrangecheck #(
|
||||
.CCM_SADR(pt.PIC_BASE_ADDR),
|
||||
.CCM_SIZE(pt.PIC_SIZE)
|
||||
) addr_pic_rangecheck (
|
||||
.addr(ahb_haddr_q[31:0]),
|
||||
.in_range(ahb_addr_in_pic),
|
||||
.in_region(ahb_addr_in_pic_region_nc)
|
||||
);
|
||||
);
|
||||
|
||||
// Command Buffer - Holding for the commands to be sent for the AXI. It will be converted to the AXI signals.
|
||||
assign cmdbuf_rst = (((axi_awvalid & axi_awready) | (axi_arvalid & axi_arready)) & ~cmdbuf_wr_en) | (ahb_hresp & ~cmdbuf_write);
|
||||
assign cmdbuf_full = (cmdbuf_vld & ~((axi_awvalid & axi_awready) | (axi_arvalid & axi_arready)));
|
||||
// Command Buffer - Holding for the commands to be sent for the AXI. It will be converted to the AXI signals.
|
||||
assign cmdbuf_rst = (((axi_awvalid & axi_awready) | (axi_arvalid & axi_arready)) & ~cmdbuf_wr_en) | (ahb_hresp & ~cmdbuf_write);
|
||||
assign cmdbuf_full = (cmdbuf_vld & ~((axi_awvalid & axi_awready) | (axi_arvalid & axi_arready)));
|
||||
|
||||
rvdffsc_fpga #(.WIDTH(1)) cmdbuf_vldff (.din(1'b1), .dout(cmdbuf_vld), .en(cmdbuf_wr_en), .clear(cmdbuf_rst), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*);
|
||||
rvdffs_fpga #(.WIDTH(1)) cmdbuf_writeff (.din(ahb_hwrite_q), .dout(cmdbuf_write), .en(cmdbuf_wr_en), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*);
|
||||
rvdffs_fpga #(.WIDTH(2)) cmdbuf_sizeff (.din(ahb_hsize_q[1:0]), .dout(cmdbuf_size[1:0]), .en(cmdbuf_wr_en), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*);
|
||||
rvdffs_fpga #(.WIDTH(8)) cmdbuf_wstrbff (.din(master_wstrb[7:0]), .dout(cmdbuf_wstrb[7:0]), .en(cmdbuf_wr_en), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*);
|
||||
rvdffe #(.WIDTH(32)) cmdbuf_addrff (.din(ahb_haddr_q[31:0]), .dout(cmdbuf_addr[31:0]), .en(cmdbuf_wr_en & bus_clk_en), .clk(clk), .*);
|
||||
rvdffe #(.WIDTH(64)) cmdbuf_wdataff (.din(ahb_hwdata[63:0]), .dout(cmdbuf_wdata[63:0]), .en(cmdbuf_wr_en & bus_clk_en), .clk(clk), .*);
|
||||
rvdffsc_fpga #(
|
||||
.WIDTH(1)
|
||||
) cmdbuf_vldff (
|
||||
.din(1'b1),
|
||||
.dout(cmdbuf_vld),
|
||||
.en(cmdbuf_wr_en),
|
||||
.clear(cmdbuf_rst),
|
||||
.clk(bus_clk),
|
||||
.clken(bus_clk_en),
|
||||
.rawclk(clk),
|
||||
.*
|
||||
);
|
||||
rvdffs_fpga #(
|
||||
.WIDTH(1)
|
||||
) cmdbuf_writeff (
|
||||
.din(ahb_hwrite_q),
|
||||
.dout(cmdbuf_write),
|
||||
.en(cmdbuf_wr_en),
|
||||
.clk(bus_clk),
|
||||
.clken(bus_clk_en),
|
||||
.rawclk(clk),
|
||||
.*
|
||||
);
|
||||
rvdffs_fpga #(
|
||||
.WIDTH(2)
|
||||
) cmdbuf_sizeff (
|
||||
.din(ahb_hsize_q[1:0]),
|
||||
.dout(cmdbuf_size[1:0]),
|
||||
.en(cmdbuf_wr_en),
|
||||
.clk(bus_clk),
|
||||
.clken(bus_clk_en),
|
||||
.rawclk(clk),
|
||||
.*
|
||||
);
|
||||
rvdffs_fpga #(
|
||||
.WIDTH(8)
|
||||
) cmdbuf_wstrbff (
|
||||
.din(master_wstrb[7:0]),
|
||||
.dout(cmdbuf_wstrb[7:0]),
|
||||
.en(cmdbuf_wr_en),
|
||||
.clk(bus_clk),
|
||||
.clken(bus_clk_en),
|
||||
.rawclk(clk),
|
||||
.*
|
||||
);
|
||||
rvdffe #(
|
||||
.WIDTH(32)
|
||||
) cmdbuf_addrff (
|
||||
.din (ahb_haddr_q[31:0]),
|
||||
.dout(cmdbuf_addr[31:0]),
|
||||
.en (cmdbuf_wr_en & bus_clk_en),
|
||||
.clk (clk),
|
||||
.*
|
||||
);
|
||||
rvdffe #(
|
||||
.WIDTH(64)
|
||||
) cmdbuf_wdataff (
|
||||
.din (ahb_hwdata[63:0]),
|
||||
.dout(cmdbuf_wdata[63:0]),
|
||||
.en (cmdbuf_wr_en & bus_clk_en),
|
||||
.clk (clk),
|
||||
.*
|
||||
);
|
||||
|
||||
// AXI Write Command Channel
|
||||
assign axi_awvalid = cmdbuf_vld & cmdbuf_write;
|
||||
assign axi_awid[TAG-1:0] = '0;
|
||||
assign axi_awaddr[31:0] = cmdbuf_addr[31:0];
|
||||
assign axi_awsize[2:0] = {1'b0, cmdbuf_size[1:0]};
|
||||
assign axi_awprot[2:0] = 3'b0;
|
||||
assign axi_awlen[7:0] = '0;
|
||||
assign axi_awburst[1:0] = 2'b01;
|
||||
// AXI Write Data Channel - This is tied to the command channel as we only write the command buffer once we have the data.
|
||||
assign axi_wvalid = cmdbuf_vld & cmdbuf_write;
|
||||
assign axi_wdata[63:0] = cmdbuf_wdata[63:0];
|
||||
assign axi_wstrb[7:0] = cmdbuf_wstrb[7:0];
|
||||
assign axi_wlast = 1'b1;
|
||||
// AXI Write Command Channel
|
||||
assign axi_awvalid = cmdbuf_vld & cmdbuf_write;
|
||||
assign axi_awid[TAG-1:0] = '0;
|
||||
assign axi_awaddr[31:0] = cmdbuf_addr[31:0];
|
||||
assign axi_awsize[2:0] = {1'b0, cmdbuf_size[1:0]};
|
||||
assign axi_awprot[2:0] = 3'b0;
|
||||
assign axi_awlen[7:0] = '0;
|
||||
assign axi_awburst[1:0] = 2'b01;
|
||||
// AXI Write Data Channel - This is tied to the command channel as we only write the command buffer once we have the data.
|
||||
assign axi_wvalid = cmdbuf_vld & cmdbuf_write;
|
||||
assign axi_wdata[63:0] = cmdbuf_wdata[63:0];
|
||||
assign axi_wstrb[7:0] = cmdbuf_wstrb[7:0];
|
||||
assign axi_wlast = 1'b1;
|
||||
// AXI Write Response - Always ready. AHB does not require a write response.
|
||||
assign axi_bready = 1'b1;
|
||||
// AXI Read Channels
|
||||
assign axi_arvalid = cmdbuf_vld & ~cmdbuf_write;
|
||||
assign axi_arid[TAG-1:0] = '0;
|
||||
assign axi_araddr[31:0] = cmdbuf_addr[31:0];
|
||||
assign axi_arsize[2:0] = {1'b0, cmdbuf_size[1:0]};
|
||||
assign axi_arprot = 3'b0;
|
||||
assign axi_arlen[7:0] = '0;
|
||||
assign axi_arburst[1:0] = 2'b01;
|
||||
// AXI Read Response Channel - Always ready as AHB reads are blocking and the the buffer is available for the read coming back always.
|
||||
assign axi_rready = 1'b1;
|
||||
assign axi_bready = 1'b1;
|
||||
// AXI Read Channels
|
||||
assign axi_arvalid = cmdbuf_vld & ~cmdbuf_write;
|
||||
assign axi_arid[TAG-1:0] = '0;
|
||||
assign axi_araddr[31:0] = cmdbuf_addr[31:0];
|
||||
assign axi_arsize[2:0] = {1'b0, cmdbuf_size[1:0]};
|
||||
assign axi_arprot = 3'b0;
|
||||
assign axi_arlen[7:0] = '0;
|
||||
assign axi_arburst[1:0] = 2'b01;
|
||||
// AXI Read Response Channel - Always ready as AHB reads are blocking and the the buffer is available for the read coming back always.
|
||||
assign axi_rready = 1'b1;
|
||||
|
||||
// Clock header logic
|
||||
assign ahb_addr_clk_en = bus_clk_en & (ahb_hready & ahb_htrans[1]);
|
||||
assign buf_rdata_clk_en = bus_clk_en & buf_rdata_en;
|
||||
// Clock header logic
|
||||
assign ahb_addr_clk_en = bus_clk_en & (ahb_hready & ahb_htrans[1]);
|
||||
assign buf_rdata_clk_en = bus_clk_en & buf_rdata_en;
|
||||
|
||||
rvclkhdr bus_cgc (.en(bus_clk_en), .l1clk(bus_clk), .*);
|
||||
rvclkhdr ahb_addr_cgc (.en(ahb_addr_clk_en), .l1clk(ahb_addr_clk), .*);
|
||||
rvclkhdr buf_rdata_cgc (.en(buf_rdata_clk_en), .l1clk(buf_rdata_clk), .*);
|
||||
rvclkhdr bus_cgc (
|
||||
.en(bus_clk_en),
|
||||
.l1clk(bus_clk),
|
||||
.*
|
||||
);
|
||||
rvclkhdr ahb_addr_cgc (
|
||||
.en(ahb_addr_clk_en),
|
||||
.l1clk(ahb_addr_clk),
|
||||
.*
|
||||
);
|
||||
rvclkhdr buf_rdata_cgc (
|
||||
.en(buf_rdata_clk_en),
|
||||
.l1clk(buf_rdata_clk),
|
||||
.*
|
||||
);
|
||||
|
||||
endmodule // ahb_to_axi4
|
||||
endmodule // ahb_to_axi4
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,64 +1,71 @@
|
|||
module el2_btb_tag_hash #(
|
||||
`include "el2_param.vh"
|
||||
) (
|
||||
input logic [pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1] pc,
|
||||
output logic [pt.BTB_BTAG_SIZE-1:0] hash
|
||||
);
|
||||
`include "el2_param.vh"
|
||||
) (
|
||||
input logic [pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1] pc,
|
||||
output logic [pt.BTB_BTAG_SIZE-1:0] hash
|
||||
);
|
||||
|
||||
assign hash = {(pc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+1] ^
|
||||
assign hash = {
|
||||
(pc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+1] ^
|
||||
pc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+1] ^
|
||||
pc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1])};
|
||||
pc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1])
|
||||
};
|
||||
endmodule
|
||||
|
||||
module el2_btb_tag_hash_fold #(
|
||||
`include "el2_param.vh"
|
||||
)(
|
||||
input logic [pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1] pc,
|
||||
output logic [pt.BTB_BTAG_SIZE-1:0] hash
|
||||
);
|
||||
module el2_btb_tag_hash_fold #(
|
||||
`include "el2_param.vh"
|
||||
) (
|
||||
input logic [pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1] pc,
|
||||
output logic [pt.BTB_BTAG_SIZE-1:0] hash
|
||||
);
|
||||
|
||||
assign hash = {(
|
||||
assign hash = {
|
||||
(
|
||||
pc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+1] ^
|
||||
pc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1])};
|
||||
pc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1])
|
||||
};
|
||||
|
||||
endmodule
|
||||
|
||||
module el2_btb_addr_hash #(
|
||||
`include "el2_param.vh"
|
||||
)(
|
||||
input logic [pt.BTB_INDEX3_HI:pt.BTB_INDEX1_LO] pc,
|
||||
output logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] hash
|
||||
);
|
||||
module el2_btb_addr_hash #(
|
||||
`include "el2_param.vh"
|
||||
) (
|
||||
input logic [pt.BTB_INDEX3_HI:pt.BTB_INDEX1_LO] pc,
|
||||
output logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] hash
|
||||
);
|
||||
|
||||
|
||||
if(pt.BTB_FOLD2_INDEX_HASH) begin : fold2
|
||||
assign hash[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] = pc[pt.BTB_INDEX1_HI:pt.BTB_INDEX1_LO] ^
|
||||
if (pt.BTB_FOLD2_INDEX_HASH) begin : fold2
|
||||
assign hash[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] = pc[pt.BTB_INDEX1_HI:pt.BTB_INDEX1_LO] ^
|
||||
pc[pt.BTB_INDEX3_HI:pt.BTB_INDEX3_LO];
|
||||
end
|
||||
else begin
|
||||
assign hash[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] = pc[pt.BTB_INDEX1_HI:pt.BTB_INDEX1_LO] ^
|
||||
end else begin
|
||||
assign hash[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] = pc[pt.BTB_INDEX1_HI:pt.BTB_INDEX1_LO] ^
|
||||
pc[pt.BTB_INDEX2_HI:pt.BTB_INDEX2_LO] ^
|
||||
pc[pt.BTB_INDEX3_HI:pt.BTB_INDEX3_LO];
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module el2_btb_ghr_hash #(
|
||||
`include "el2_param.vh"
|
||||
)(
|
||||
input logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] hashin,
|
||||
input logic [pt.BHT_GHR_SIZE-1:0] ghr,
|
||||
output logic [pt.BHT_ADDR_HI:pt.BHT_ADDR_LO] hash
|
||||
);
|
||||
module el2_btb_ghr_hash #(
|
||||
`include "el2_param.vh"
|
||||
) (
|
||||
input logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] hashin,
|
||||
input logic [pt.BHT_GHR_SIZE-1:0] ghr,
|
||||
output logic [pt.BHT_ADDR_HI:pt.BHT_ADDR_LO] hash
|
||||
);
|
||||
|
||||
// The hash function is too complex to write in verilog for all cases.
|
||||
// The config script generates the logic string based on the bp config.
|
||||
if(pt.BHT_GHR_HASH_1) begin : ghrhash_cfg1
|
||||
assign hash[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO] = { ghr[pt.BHT_GHR_SIZE-1:pt.BTB_INDEX1_HI-1], hashin[pt.BTB_INDEX1_HI:2]^ghr[pt.BTB_INDEX1_HI-2:0]};
|
||||
end
|
||||
else begin : ghrhash_cfg2
|
||||
assign hash[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO] = { hashin[pt.BHT_GHR_SIZE+1:2]^ghr[pt.BHT_GHR_SIZE-1:0]};
|
||||
end
|
||||
// The hash function is too complex to write in verilog for all cases.
|
||||
// The config script generates the logic string based on the bp config.
|
||||
if (pt.BHT_GHR_HASH_1) begin : ghrhash_cfg1
|
||||
assign hash[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO] = {
|
||||
ghr[pt.BHT_GHR_SIZE-1:pt.BTB_INDEX1_HI-1],
|
||||
hashin[pt.BTB_INDEX1_HI:2] ^ ghr[pt.BTB_INDEX1_HI-2:0]
|
||||
};
|
||||
end else begin : ghrhash_cfg2
|
||||
assign hash[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO] = {
|
||||
hashin[pt.BHT_GHR_SIZE+1:2] ^ ghr[pt.BHT_GHR_SIZE-1:0]
|
||||
};
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -83,22 +83,28 @@ assign ROP = ME; \
|
|||
endmodule
|
||||
|
||||
// parameterizable RAM for verilator sims
|
||||
module el2_ram #(depth=4096, width=39) (
|
||||
input logic [$clog2(depth)-1:0] ADR,
|
||||
input logic [(width-1):0] D,
|
||||
output logic [(width-1):0] Q,
|
||||
`EL2_LOCAL_RAM_TEST_IO
|
||||
module el2_ram #(
|
||||
depth = 4096,
|
||||
width = 39
|
||||
) (
|
||||
input logic [$clog2(depth)-1:0] ADR,
|
||||
input logic [(width-1):0] D,
|
||||
output logic [(width-1):0] Q,
|
||||
`EL2_LOCAL_RAM_TEST_IO
|
||||
);
|
||||
reg [(width-1):0] ram_core [(depth-1):0];
|
||||
reg [(width-1):0] ram_core[(depth-1):0];
|
||||
|
||||
always @(posedge CLK) begin
|
||||
always @(posedge CLK) begin
|
||||
`ifdef GTLSIM
|
||||
if (ME && WE) ram_core[ADR] <= D;
|
||||
if (ME && WE) ram_core[ADR] <= D;
|
||||
`else
|
||||
if (ME && WE) begin ram_core[ADR] <= D; Q <= 'x; end
|
||||
if (ME && WE) begin
|
||||
ram_core[ADR] <= D;
|
||||
Q <= 'x;
|
||||
end
|
||||
`endif
|
||||
if (ME && ~WE) Q <= ram_core[ADR];
|
||||
end
|
||||
if (ME && ~WE) Q <= ram_core[ADR];
|
||||
end
|
||||
endmodule
|
||||
|
||||
//=========================================================================================================================
|
||||
|
@ -111,7 +117,7 @@ endmodule
|
|||
`EL2_RAM(4096, 39)
|
||||
`EL2_RAM(3072, 39)
|
||||
`EL2_RAM(2048, 39)
|
||||
`EL2_RAM(1536, 39) // need this for the 48KB DCCM option)
|
||||
`EL2_RAM(1536, 39) // need this for the 48KB DCCM option)
|
||||
`EL2_RAM(1024, 39)
|
||||
`EL2_RAM(768, 39)
|
||||
`EL2_RAM(512, 39)
|
||||
|
|
|
@ -26,311 +26,312 @@
|
|||
//********************************************************************************
|
||||
|
||||
module el2_lsu
|
||||
import el2_pkg::*;
|
||||
import el2_pkg::*;
|
||||
#(
|
||||
`include "el2_param.vh"
|
||||
)
|
||||
(
|
||||
`include "el2_param.vh"
|
||||
) (
|
||||
|
||||
input logic clk_override, // Override non-functional clock gating
|
||||
input logic dec_tlu_flush_lower_r, // I0/I1 writeback flush. This is used to flush the old packets only
|
||||
input logic dec_tlu_i0_kill_writeb_r, // I0 is flushed, don't writeback any results to arch state
|
||||
input logic dec_tlu_force_halt, // This will be high till TLU goes to debug halt
|
||||
input logic clk_override, // Override non-functional clock gating
|
||||
input logic dec_tlu_flush_lower_r, // I0/I1 writeback flush. This is used to flush the old packets only
|
||||
input logic dec_tlu_i0_kill_writeb_r, // I0 is flushed, don't writeback any results to arch state
|
||||
input logic dec_tlu_force_halt, // This will be high till TLU goes to debug halt
|
||||
|
||||
// chicken signals
|
||||
input logic dec_tlu_external_ldfwd_disable, // disable load to load forwarding for externals
|
||||
input logic dec_tlu_wb_coalescing_disable, // disable the write buffer coalesce
|
||||
input logic dec_tlu_sideeffect_posted_disable, // disable the posted sideeffect load store to the bus
|
||||
input logic dec_tlu_core_ecc_disable, // disable the generation of the ecc
|
||||
// chicken signals
|
||||
input logic dec_tlu_external_ldfwd_disable, // disable load to load forwarding for externals
|
||||
input logic dec_tlu_wb_coalescing_disable, // disable the write buffer coalesce
|
||||
input logic dec_tlu_sideeffect_posted_disable, // disable the posted sideeffect load store to the bus
|
||||
input logic dec_tlu_core_ecc_disable, // disable the generation of the ecc
|
||||
|
||||
input logic [31:0] exu_lsu_rs1_d, // address rs operand
|
||||
input logic [31:0] exu_lsu_rs2_d, // store data
|
||||
input logic [11:0] dec_lsu_offset_d, // address offset operand
|
||||
input logic [31:0] exu_lsu_rs1_d, // address rs operand
|
||||
input logic [31:0] exu_lsu_rs2_d, // store data
|
||||
input logic [11:0] dec_lsu_offset_d, // address offset operand
|
||||
|
||||
input el2_lsu_pkt_t lsu_p, // lsu control packet
|
||||
input logic dec_lsu_valid_raw_d, // Raw valid for address computation
|
||||
input logic [31:0] dec_tlu_mrac_ff, // CSR for memory region control
|
||||
input el2_lsu_pkt_t lsu_p, // lsu control packet
|
||||
input logic dec_lsu_valid_raw_d, // Raw valid for address computation
|
||||
input logic [31:0] dec_tlu_mrac_ff, // CSR for memory region control
|
||||
|
||||
output logic [31:0] lsu_result_m, // lsu load data
|
||||
output logic [31:0] lsu_result_corr_r, // This is the ECC corrected data going to RF
|
||||
output logic lsu_load_stall_any, // This is for blocking loads in the decode
|
||||
output logic lsu_store_stall_any, // This is for blocking stores in the decode
|
||||
output logic lsu_fastint_stall_any, // Stall the fastint in decode-1 stage
|
||||
output logic lsu_idle_any, // lsu buffers are empty and no instruction in the pipeline. Doesn't include DMA
|
||||
output logic lsu_active, // Used to turn off top level clk
|
||||
output logic [31:0] lsu_result_m, // lsu load data
|
||||
output logic [31:0] lsu_result_corr_r, // This is the ECC corrected data going to RF
|
||||
output logic lsu_load_stall_any, // This is for blocking loads in the decode
|
||||
output logic lsu_store_stall_any, // This is for blocking stores in the decode
|
||||
output logic lsu_fastint_stall_any, // Stall the fastint in decode-1 stage
|
||||
output logic lsu_idle_any, // lsu buffers are empty and no instruction in the pipeline. Doesn't include DMA
|
||||
output logic lsu_active, // Used to turn off top level clk
|
||||
|
||||
output logic [31:1] lsu_fir_addr, // fast interrupt address
|
||||
output logic [1:0] lsu_fir_error, // Error during fast interrupt lookup
|
||||
output logic [31:1] lsu_fir_addr, // fast interrupt address
|
||||
output logic [ 1:0] lsu_fir_error, // Error during fast interrupt lookup
|
||||
|
||||
output logic lsu_single_ecc_error_incr, // Increment the ecc counter
|
||||
output el2_lsu_error_pkt_t lsu_error_pkt_r, // lsu exception packet
|
||||
output logic lsu_imprecise_error_load_any, // bus load imprecise error
|
||||
output logic lsu_imprecise_error_store_any, // bus store imprecise error
|
||||
output logic [31:0] lsu_imprecise_error_addr_any, // bus store imprecise error address
|
||||
output logic lsu_single_ecc_error_incr, // Increment the ecc counter
|
||||
output el2_lsu_error_pkt_t lsu_error_pkt_r, // lsu exception packet
|
||||
output logic lsu_imprecise_error_load_any, // bus load imprecise error
|
||||
output logic lsu_imprecise_error_store_any, // bus store imprecise error
|
||||
output logic [31:0] lsu_imprecise_error_addr_any, // bus store imprecise error address
|
||||
|
||||
// Non-blocking loads
|
||||
output logic lsu_nonblock_load_valid_m, // there is an external load -> put in the cam
|
||||
output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_m, // the tag of the external non block load
|
||||
output logic lsu_nonblock_load_inv_r, // invalidate signal for the cam entry for non block loads
|
||||
output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_r, // tag of the enrty which needs to be invalidated
|
||||
output logic lsu_nonblock_load_data_valid, // the non block is valid - sending information back to the cam
|
||||
output logic lsu_nonblock_load_data_error, // non block load has an error
|
||||
output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // the tag of the non block load sending the data/error
|
||||
output logic [31:0] lsu_nonblock_load_data, // Data of the non block load
|
||||
// Non-blocking loads
|
||||
output logic lsu_nonblock_load_valid_m, // there is an external load -> put in the cam
|
||||
output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_m, // the tag of the external non block load
|
||||
output logic lsu_nonblock_load_inv_r, // invalidate signal for the cam entry for non block loads
|
||||
output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_r, // tag of the enrty which needs to be invalidated
|
||||
output logic lsu_nonblock_load_data_valid, // the non block is valid - sending information back to the cam
|
||||
output logic lsu_nonblock_load_data_error, // non block load has an error
|
||||
output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // the tag of the non block load sending the data/error
|
||||
output logic [31:0] lsu_nonblock_load_data, // Data of the non block load
|
||||
|
||||
output logic lsu_pmu_load_external_m, // PMU : Bus loads
|
||||
output logic lsu_pmu_store_external_m, // PMU : Bus loads
|
||||
output logic lsu_pmu_misaligned_m, // PMU : misaligned
|
||||
output logic lsu_pmu_bus_trxn, // PMU : bus transaction
|
||||
output logic lsu_pmu_bus_misaligned, // PMU : misaligned access going to the bus
|
||||
output logic lsu_pmu_bus_error, // PMU : bus sending error back
|
||||
output logic lsu_pmu_bus_busy, // PMU : bus is not ready
|
||||
output logic lsu_pmu_load_external_m, // PMU : Bus loads
|
||||
output logic lsu_pmu_store_external_m, // PMU : Bus loads
|
||||
output logic lsu_pmu_misaligned_m, // PMU : misaligned
|
||||
output logic lsu_pmu_bus_trxn, // PMU : bus transaction
|
||||
output logic lsu_pmu_bus_misaligned, // PMU : misaligned access going to the bus
|
||||
output logic lsu_pmu_bus_error, // PMU : bus sending error back
|
||||
output logic lsu_pmu_bus_busy, // PMU : bus is not ready
|
||||
|
||||
// Trigger signals
|
||||
input el2_trigger_pkt_t [3:0] trigger_pkt_any, // Trigger info from the decode
|
||||
output logic [3:0] lsu_trigger_match_m, // lsu trigger hit (one bit per trigger)
|
||||
// Trigger signals
|
||||
input el2_trigger_pkt_t [3:0] trigger_pkt_any, // Trigger info from the decode
|
||||
output logic [3:0] lsu_trigger_match_m, // lsu trigger hit (one bit per trigger)
|
||||
|
||||
// DCCM ports
|
||||
output logic dccm_wren, // DCCM write enable
|
||||
output logic dccm_rden, // DCCM read enable
|
||||
output logic [pt.DCCM_BITS-1:0] dccm_wr_addr_lo, // DCCM write address low bank
|
||||
output logic [pt.DCCM_BITS-1:0] dccm_wr_addr_hi, // DCCM write address hi bank
|
||||
output logic [pt.DCCM_BITS-1:0] dccm_rd_addr_lo, // DCCM read address low bank
|
||||
output logic [pt.DCCM_BITS-1:0] dccm_rd_addr_hi, // DCCM read address hi bank (hi and low same if aligned read)
|
||||
output logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_wr_data_lo, // DCCM write data for lo bank
|
||||
output logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_wr_data_hi, // DCCM write data for hi bank
|
||||
// DCCM ports
|
||||
output logic dccm_wren, // DCCM write enable
|
||||
output logic dccm_rden, // DCCM read enable
|
||||
output logic [pt.DCCM_BITS-1:0] dccm_wr_addr_lo, // DCCM write address low bank
|
||||
output logic [pt.DCCM_BITS-1:0] dccm_wr_addr_hi, // DCCM write address hi bank
|
||||
output logic [pt.DCCM_BITS-1:0] dccm_rd_addr_lo, // DCCM read address low bank
|
||||
output logic [pt.DCCM_BITS-1:0] dccm_rd_addr_hi, // DCCM read address hi bank (hi and low same if aligned read)
|
||||
output logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_wr_data_lo, // DCCM write data for lo bank
|
||||
output logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_wr_data_hi, // DCCM write data for hi bank
|
||||
|
||||
input logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo, // DCCM read data low bank
|
||||
input logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi, // DCCM read data hi bank
|
||||
input logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo, // DCCM read data low bank
|
||||
input logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi, // DCCM read data hi bank
|
||||
|
||||
// PIC ports
|
||||
output logic picm_wren, // PIC memory write enable
|
||||
output logic picm_rden, // PIC memory read enable
|
||||
output logic picm_mken, // Need to read the mask for stores to determine which bits to write/forward
|
||||
output logic [31:0] picm_rdaddr, // address for pic read access
|
||||
output logic [31:0] picm_wraddr, // address for pic write access
|
||||
output logic [31:0] picm_wr_data, // PIC memory write data
|
||||
input logic [31:0] picm_rd_data, // PIC memory read/mask data
|
||||
// PIC ports
|
||||
output logic picm_wren, // PIC memory write enable
|
||||
output logic picm_rden, // PIC memory read enable
|
||||
output logic picm_mken, // Need to read the mask for stores to determine which bits to write/forward
|
||||
output logic [31:0] picm_rdaddr, // address for pic read access
|
||||
output logic [31:0] picm_wraddr, // address for pic write access
|
||||
output logic [31:0] picm_wr_data, // PIC memory write data
|
||||
input logic [31:0] picm_rd_data, // PIC memory read/mask data
|
||||
|
||||
// AXI Write Channels
|
||||
output logic lsu_axi_awvalid,
|
||||
input logic lsu_axi_awready,
|
||||
output logic [pt.LSU_BUS_TAG-1:0] lsu_axi_awid,
|
||||
output logic [31:0] lsu_axi_awaddr,
|
||||
output logic [3:0] lsu_axi_awregion,
|
||||
output logic [7:0] lsu_axi_awlen,
|
||||
output logic [2:0] lsu_axi_awsize,
|
||||
output logic [1:0] lsu_axi_awburst,
|
||||
output logic lsu_axi_awlock,
|
||||
output logic [3:0] lsu_axi_awcache,
|
||||
output logic [2:0] lsu_axi_awprot,
|
||||
output logic [3:0] lsu_axi_awqos,
|
||||
// AXI Write Channels
|
||||
output logic lsu_axi_awvalid,
|
||||
input logic lsu_axi_awready,
|
||||
output logic [pt.LSU_BUS_TAG-1:0] lsu_axi_awid,
|
||||
output logic [ 31:0] lsu_axi_awaddr,
|
||||
output logic [ 3:0] lsu_axi_awregion,
|
||||
output logic [ 7:0] lsu_axi_awlen,
|
||||
output logic [ 2:0] lsu_axi_awsize,
|
||||
output logic [ 1:0] lsu_axi_awburst,
|
||||
output logic lsu_axi_awlock,
|
||||
output logic [ 3:0] lsu_axi_awcache,
|
||||
output logic [ 2:0] lsu_axi_awprot,
|
||||
output logic [ 3:0] lsu_axi_awqos,
|
||||
|
||||
output logic lsu_axi_wvalid,
|
||||
input logic lsu_axi_wready,
|
||||
output logic [63:0] lsu_axi_wdata,
|
||||
output logic [7:0] lsu_axi_wstrb,
|
||||
output logic lsu_axi_wlast,
|
||||
output logic lsu_axi_wvalid,
|
||||
input logic lsu_axi_wready,
|
||||
output logic [63:0] lsu_axi_wdata,
|
||||
output logic [ 7:0] lsu_axi_wstrb,
|
||||
output logic lsu_axi_wlast,
|
||||
|
||||
input logic lsu_axi_bvalid,
|
||||
output logic lsu_axi_bready,
|
||||
input logic [1:0] lsu_axi_bresp,
|
||||
input logic [pt.LSU_BUS_TAG-1:0] lsu_axi_bid,
|
||||
input logic lsu_axi_bvalid,
|
||||
output logic lsu_axi_bready,
|
||||
input logic [ 1:0] lsu_axi_bresp,
|
||||
input logic [pt.LSU_BUS_TAG-1:0] lsu_axi_bid,
|
||||
|
||||
// AXI Read Channels
|
||||
output logic lsu_axi_arvalid,
|
||||
input logic lsu_axi_arready,
|
||||
output logic [pt.LSU_BUS_TAG-1:0] lsu_axi_arid,
|
||||
output logic [31:0] lsu_axi_araddr,
|
||||
output logic [3:0] lsu_axi_arregion,
|
||||
output logic [7:0] lsu_axi_arlen,
|
||||
output logic [2:0] lsu_axi_arsize,
|
||||
output logic [1:0] lsu_axi_arburst,
|
||||
output logic lsu_axi_arlock,
|
||||
output logic [3:0] lsu_axi_arcache,
|
||||
output logic [2:0] lsu_axi_arprot,
|
||||
output logic [3:0] lsu_axi_arqos,
|
||||
// AXI Read Channels
|
||||
output logic lsu_axi_arvalid,
|
||||
input logic lsu_axi_arready,
|
||||
output logic [pt.LSU_BUS_TAG-1:0] lsu_axi_arid,
|
||||
output logic [ 31:0] lsu_axi_araddr,
|
||||
output logic [ 3:0] lsu_axi_arregion,
|
||||
output logic [ 7:0] lsu_axi_arlen,
|
||||
output logic [ 2:0] lsu_axi_arsize,
|
||||
output logic [ 1:0] lsu_axi_arburst,
|
||||
output logic lsu_axi_arlock,
|
||||
output logic [ 3:0] lsu_axi_arcache,
|
||||
output logic [ 2:0] lsu_axi_arprot,
|
||||
output logic [ 3:0] lsu_axi_arqos,
|
||||
|
||||
input logic lsu_axi_rvalid,
|
||||
output logic lsu_axi_rready,
|
||||
input logic [pt.LSU_BUS_TAG-1:0] lsu_axi_rid,
|
||||
input logic [63:0] lsu_axi_rdata,
|
||||
input logic [1:0] lsu_axi_rresp,
|
||||
input logic lsu_axi_rlast,
|
||||
input logic lsu_axi_rvalid,
|
||||
output logic lsu_axi_rready,
|
||||
input logic [pt.LSU_BUS_TAG-1:0] lsu_axi_rid,
|
||||
input logic [ 63:0] lsu_axi_rdata,
|
||||
input logic [ 1:0] lsu_axi_rresp,
|
||||
input logic lsu_axi_rlast,
|
||||
|
||||
input logic lsu_bus_clk_en, // external drives a clock_en to control bus ratio
|
||||
input logic lsu_bus_clk_en, // external drives a clock_en to control bus ratio
|
||||
|
||||
// DMA slave
|
||||
input logic dma_dccm_req, // DMA read/write to dccm
|
||||
input logic [2:0] dma_mem_tag, // DMA request tag
|
||||
input logic [31:0] dma_mem_addr, // DMA address
|
||||
input logic [2:0] dma_mem_sz, // DMA access size
|
||||
input logic dma_mem_write, // DMA access is a write
|
||||
input logic [63:0] dma_mem_wdata, // DMA write data
|
||||
// DMA slave
|
||||
input logic dma_dccm_req, // DMA read/write to dccm
|
||||
input logic [ 2:0] dma_mem_tag, // DMA request tag
|
||||
input logic [31:0] dma_mem_addr, // DMA address
|
||||
input logic [ 2:0] dma_mem_sz, // DMA access size
|
||||
input logic dma_mem_write, // DMA access is a write
|
||||
input logic [63:0] dma_mem_wdata, // DMA write data
|
||||
|
||||
output logic dccm_dma_rvalid, // lsu data valid for DMA dccm read
|
||||
output logic dccm_dma_ecc_error, // DMA load had ecc error
|
||||
output logic [2:0] dccm_dma_rtag, // DMA request tag
|
||||
output logic [63:0] dccm_dma_rdata, // lsu data for DMA dccm read
|
||||
output logic dccm_ready, // lsu ready for DMA access
|
||||
output logic dccm_dma_rvalid, // lsu data valid for DMA dccm read
|
||||
output logic dccm_dma_ecc_error, // DMA load had ecc error
|
||||
output logic [ 2:0] dccm_dma_rtag, // DMA request tag
|
||||
output logic [63:0] dccm_dma_rdata, // lsu data for DMA dccm read
|
||||
output logic dccm_ready, // lsu ready for DMA access
|
||||
|
||||
input logic scan_mode, // scan mode
|
||||
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
|
||||
input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in.
|
||||
input logic rst_l // reset, active low
|
||||
input logic scan_mode, // scan mode
|
||||
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
|
||||
input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in.
|
||||
input logic rst_l // reset, active low
|
||||
|
||||
);
|
||||
);
|
||||
|
||||
logic lsu_dccm_rden_m;
|
||||
logic lsu_dccm_rden_r;
|
||||
logic [31:0] store_data_m;
|
||||
logic [31:0] store_data_r;
|
||||
logic [31:0] store_data_hi_r, store_data_lo_r;
|
||||
logic [31:0] store_datafn_hi_r, store_datafn_lo_r;
|
||||
logic [31:0] sec_data_lo_m, sec_data_hi_m;
|
||||
logic [31:0] sec_data_lo_r, sec_data_hi_r;
|
||||
logic lsu_dccm_rden_m;
|
||||
logic lsu_dccm_rden_r;
|
||||
logic [31:0] store_data_m;
|
||||
logic [31:0] store_data_r;
|
||||
logic [31:0] store_data_hi_r, store_data_lo_r;
|
||||
logic [31:0] store_datafn_hi_r, store_datafn_lo_r;
|
||||
logic [31:0] sec_data_lo_m, sec_data_hi_m;
|
||||
logic [31:0] sec_data_lo_r, sec_data_hi_r;
|
||||
|
||||
logic [31:0] lsu_ld_data_m;
|
||||
logic [31:0] dccm_rdata_hi_m, dccm_rdata_lo_m;
|
||||
logic [6:0] dccm_data_ecc_hi_m, dccm_data_ecc_lo_m;
|
||||
logic lsu_single_ecc_error_m;
|
||||
logic lsu_double_ecc_error_m;
|
||||
logic [31:0] lsu_ld_data_m;
|
||||
logic [31:0] dccm_rdata_hi_m, dccm_rdata_lo_m;
|
||||
logic [6:0] dccm_data_ecc_hi_m, dccm_data_ecc_lo_m;
|
||||
logic lsu_single_ecc_error_m;
|
||||
logic lsu_double_ecc_error_m;
|
||||
|
||||
logic [31:0] lsu_ld_data_r;
|
||||
logic [31:0] lsu_ld_data_corr_r;
|
||||
logic [31:0] dccm_rdata_hi_r, dccm_rdata_lo_r;
|
||||
logic [6:0] dccm_data_ecc_hi_r, dccm_data_ecc_lo_r;
|
||||
logic single_ecc_error_hi_r, single_ecc_error_lo_r;
|
||||
logic lsu_single_ecc_error_r;
|
||||
logic lsu_double_ecc_error_r;
|
||||
logic ld_single_ecc_error_r, ld_single_ecc_error_r_ff;
|
||||
logic [31:0] lsu_ld_data_r;
|
||||
logic [31:0] lsu_ld_data_corr_r;
|
||||
logic [31:0] dccm_rdata_hi_r, dccm_rdata_lo_r;
|
||||
logic [6:0] dccm_data_ecc_hi_r, dccm_data_ecc_lo_r;
|
||||
logic single_ecc_error_hi_r, single_ecc_error_lo_r;
|
||||
logic lsu_single_ecc_error_r;
|
||||
logic lsu_double_ecc_error_r;
|
||||
logic ld_single_ecc_error_r, ld_single_ecc_error_r_ff;
|
||||
|
||||
logic [31:0] picm_mask_data_m;
|
||||
logic [31:0] picm_mask_data_m;
|
||||
|
||||
logic [31:0] lsu_addr_d, lsu_addr_m, lsu_addr_r;
|
||||
logic [31:0] end_addr_d, end_addr_m, end_addr_r;
|
||||
logic [31:0] lsu_addr_d, lsu_addr_m, lsu_addr_r;
|
||||
logic [31:0] end_addr_d, end_addr_m, end_addr_r;
|
||||
|
||||
el2_lsu_pkt_t lsu_pkt_d, lsu_pkt_m, lsu_pkt_r;
|
||||
logic lsu_i0_valid_d, lsu_i0_valid_m, lsu_i0_valid_r;
|
||||
el2_lsu_pkt_t lsu_pkt_d, lsu_pkt_m, lsu_pkt_r;
|
||||
logic lsu_i0_valid_d, lsu_i0_valid_m, lsu_i0_valid_r;
|
||||
|
||||
// Store Buffer signals
|
||||
logic store_stbuf_reqvld_r;
|
||||
logic ldst_stbuf_reqvld_r;
|
||||
// Store Buffer signals
|
||||
logic store_stbuf_reqvld_r;
|
||||
logic ldst_stbuf_reqvld_r;
|
||||
|
||||
logic lsu_commit_r;
|
||||
logic lsu_exc_m;
|
||||
logic lsu_commit_r;
|
||||
logic lsu_exc_m;
|
||||
|
||||
logic addr_in_dccm_d, addr_in_dccm_m, addr_in_dccm_r;
|
||||
logic addr_in_pic_d, addr_in_pic_m, addr_in_pic_r;
|
||||
logic ldst_dual_d, ldst_dual_m, ldst_dual_r;
|
||||
logic addr_external_m;
|
||||
logic addr_in_dccm_d, addr_in_dccm_m, addr_in_dccm_r;
|
||||
logic addr_in_pic_d, addr_in_pic_m, addr_in_pic_r;
|
||||
logic ldst_dual_d, ldst_dual_m, ldst_dual_r;
|
||||
logic addr_external_m;
|
||||
|
||||
logic stbuf_reqvld_any;
|
||||
logic stbuf_reqvld_flushed_any;
|
||||
logic [pt.LSU_SB_BITS-1:0] stbuf_addr_any;
|
||||
logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_data_any;
|
||||
logic [pt.DCCM_ECC_WIDTH-1:0] stbuf_ecc_any;
|
||||
logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_lo_r_ff, sec_data_hi_r_ff;
|
||||
logic [pt.DCCM_ECC_WIDTH-1:0] sec_data_ecc_hi_r_ff, sec_data_ecc_lo_r_ff;
|
||||
logic stbuf_reqvld_any;
|
||||
logic stbuf_reqvld_flushed_any;
|
||||
logic [ pt.LSU_SB_BITS-1:0] stbuf_addr_any;
|
||||
logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_data_any;
|
||||
logic [ pt.DCCM_ECC_WIDTH-1:0] stbuf_ecc_any;
|
||||
logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_lo_r_ff, sec_data_hi_r_ff;
|
||||
logic [pt.DCCM_ECC_WIDTH-1:0] sec_data_ecc_hi_r_ff, sec_data_ecc_lo_r_ff;
|
||||
|
||||
logic lsu_cmpen_m;
|
||||
logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_fwddata_hi_m;
|
||||
logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_fwddata_lo_m;
|
||||
logic [pt.DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_hi_m;
|
||||
logic [pt.DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_m;
|
||||
logic lsu_cmpen_m;
|
||||
logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_fwddata_hi_m;
|
||||
logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_fwddata_lo_m;
|
||||
logic [pt.DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_hi_m;
|
||||
logic [pt.DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_m;
|
||||
|
||||
logic lsu_stbuf_commit_any;
|
||||
logic lsu_stbuf_empty_any; // This is for blocking loads
|
||||
logic lsu_stbuf_full_any;
|
||||
logic lsu_stbuf_commit_any;
|
||||
logic lsu_stbuf_empty_any; // This is for blocking loads
|
||||
logic lsu_stbuf_full_any;
|
||||
|
||||
// Bus signals
|
||||
logic lsu_busreq_r;
|
||||
logic lsu_bus_buffer_pend_any;
|
||||
logic lsu_bus_buffer_empty_any;
|
||||
logic lsu_bus_buffer_full_any;
|
||||
logic lsu_busreq_m;
|
||||
logic [31:0] bus_read_data_m;
|
||||
// Bus signals
|
||||
logic lsu_busreq_r;
|
||||
logic lsu_bus_buffer_pend_any;
|
||||
logic lsu_bus_buffer_empty_any;
|
||||
logic lsu_bus_buffer_full_any;
|
||||
logic lsu_busreq_m;
|
||||
logic [ 31:0] bus_read_data_m;
|
||||
|
||||
logic flush_m_up, flush_r;
|
||||
logic is_sideeffects_m;
|
||||
logic [2:0] dma_mem_tag_d, dma_mem_tag_m;
|
||||
logic ldst_nodma_mtor;
|
||||
logic dma_dccm_wen, dma_pic_wen;
|
||||
logic [31:0] dma_dccm_wdata_lo, dma_dccm_wdata_hi;
|
||||
logic [pt.DCCM_ECC_WIDTH-1:0] dma_dccm_wdata_ecc_lo, dma_dccm_wdata_ecc_hi;
|
||||
logic flush_m_up, flush_r;
|
||||
logic is_sideeffects_m;
|
||||
logic [2:0] dma_mem_tag_d, dma_mem_tag_m;
|
||||
logic ldst_nodma_mtor;
|
||||
logic dma_dccm_wen, dma_pic_wen;
|
||||
logic [31:0] dma_dccm_wdata_lo, dma_dccm_wdata_hi;
|
||||
logic [pt.DCCM_ECC_WIDTH-1:0] dma_dccm_wdata_ecc_lo, dma_dccm_wdata_ecc_hi;
|
||||
|
||||
// Clocks
|
||||
logic lsu_busm_clken;
|
||||
logic lsu_bus_obuf_c1_clken;
|
||||
logic lsu_c1_m_clk, lsu_c1_r_clk;
|
||||
logic lsu_c2_m_clk, lsu_c2_r_clk;
|
||||
logic lsu_store_c1_m_clk, lsu_store_c1_r_clk;
|
||||
// Clocks
|
||||
logic lsu_busm_clken;
|
||||
logic lsu_bus_obuf_c1_clken;
|
||||
logic lsu_c1_m_clk, lsu_c1_r_clk;
|
||||
logic lsu_c2_m_clk, lsu_c2_r_clk;
|
||||
logic lsu_store_c1_m_clk, lsu_store_c1_r_clk;
|
||||
|
||||
logic lsu_stbuf_c1_clk;
|
||||
logic lsu_bus_ibuf_c1_clk, lsu_bus_obuf_c1_clk, lsu_bus_buf_c1_clk;
|
||||
logic lsu_busm_clk;
|
||||
logic lsu_free_c2_clk;
|
||||
logic lsu_stbuf_c1_clk;
|
||||
logic lsu_bus_ibuf_c1_clk, lsu_bus_obuf_c1_clk, lsu_bus_buf_c1_clk;
|
||||
logic lsu_busm_clk;
|
||||
logic lsu_free_c2_clk;
|
||||
|
||||
logic lsu_raw_fwd_lo_m, lsu_raw_fwd_hi_m;
|
||||
logic lsu_raw_fwd_lo_r, lsu_raw_fwd_hi_r;
|
||||
logic lsu_raw_fwd_lo_m, lsu_raw_fwd_hi_m;
|
||||
logic lsu_raw_fwd_lo_r, lsu_raw_fwd_hi_r;
|
||||
|
||||
assign lsu_raw_fwd_lo_m = (|stbuf_fwdbyteen_lo_m[pt.DCCM_BYTE_WIDTH-1:0]);
|
||||
assign lsu_raw_fwd_hi_m = (|stbuf_fwdbyteen_hi_m[pt.DCCM_BYTE_WIDTH-1:0]);
|
||||
assign lsu_raw_fwd_lo_m = (|stbuf_fwdbyteen_lo_m[pt.DCCM_BYTE_WIDTH-1:0]);
|
||||
assign lsu_raw_fwd_hi_m = (|stbuf_fwdbyteen_hi_m[pt.DCCM_BYTE_WIDTH-1:0]);
|
||||
|
||||
el2_lsu_lsc_ctl #(.pt(pt)) lsu_lsc_ctl (.*);
|
||||
el2_lsu_lsc_ctl #(.pt(pt)) lsu_lsc_ctl (.*);
|
||||
|
||||
// block stores in decode - for either bus or stbuf reasons
|
||||
assign lsu_store_stall_any = lsu_stbuf_full_any | lsu_bus_buffer_full_any | ld_single_ecc_error_r_ff;
|
||||
assign lsu_load_stall_any = lsu_bus_buffer_full_any | ld_single_ecc_error_r_ff;
|
||||
assign lsu_fastint_stall_any = ld_single_ecc_error_r; // Stall the fastint in decode-1 stage
|
||||
// block stores in decode - for either bus or stbuf reasons
|
||||
assign lsu_store_stall_any = lsu_stbuf_full_any | lsu_bus_buffer_full_any | ld_single_ecc_error_r_ff;
|
||||
assign lsu_load_stall_any = lsu_bus_buffer_full_any | ld_single_ecc_error_r_ff;
|
||||
assign lsu_fastint_stall_any = ld_single_ecc_error_r; // Stall the fastint in decode-1 stage
|
||||
|
||||
// Ready to accept dma trxns
|
||||
// There can't be any inpipe forwarding from non-dma packet to dma packet since they can be flushed so we can't have st in r when dma is in m
|
||||
assign dma_mem_tag_d[2:0] = dma_mem_tag[2:0];
|
||||
assign ldst_nodma_mtor = (lsu_pkt_m.valid & ~lsu_pkt_m.dma & (addr_in_dccm_m | addr_in_pic_m) & lsu_pkt_m.store);
|
||||
// Ready to accept dma trxns
|
||||
// There can't be any inpipe forwarding from non-dma packet to dma packet since they can be flushed so we can't have st in r when dma is in m
|
||||
assign dma_mem_tag_d[2:0] = dma_mem_tag[2:0];
|
||||
assign ldst_nodma_mtor = (lsu_pkt_m.valid & ~lsu_pkt_m.dma & (addr_in_dccm_m | addr_in_pic_m) & lsu_pkt_m.store);
|
||||
|
||||
assign dccm_ready = ~(dec_lsu_valid_raw_d | ldst_nodma_mtor | ld_single_ecc_error_r_ff);
|
||||
assign dccm_ready = ~(dec_lsu_valid_raw_d | ldst_nodma_mtor | ld_single_ecc_error_r_ff);
|
||||
|
||||
assign dma_dccm_wen = dma_dccm_req & dma_mem_write & addr_in_dccm_d & dma_mem_sz[1]; // Perform DMA writes only for word/dword
|
||||
assign dma_pic_wen = dma_dccm_req & dma_mem_write & addr_in_pic_d;
|
||||
assign {dma_dccm_wdata_hi[31:0], dma_dccm_wdata_lo[31:0]} = dma_mem_wdata[63:0] >> {dma_mem_addr[2:0], 3'b000}; // Shift the dma data to lower bits to make it consistent to lsu stores
|
||||
assign dma_dccm_wen = dma_dccm_req & dma_mem_write & addr_in_dccm_d & dma_mem_sz[1]; // Perform DMA writes only for word/dword
|
||||
assign dma_pic_wen = dma_dccm_req & dma_mem_write & addr_in_pic_d;
|
||||
assign {dma_dccm_wdata_hi[31:0], dma_dccm_wdata_lo[31:0]} = dma_mem_wdata[63:0] >> {dma_mem_addr[2:0], 3'b000}; // Shift the dma data to lower bits to make it consistent to lsu stores
|
||||
|
||||
|
||||
// Generate per cycle flush signals
|
||||
assign flush_m_up = dec_tlu_flush_lower_r;
|
||||
assign flush_r = dec_tlu_i0_kill_writeb_r;
|
||||
// Generate per cycle flush signals
|
||||
assign flush_m_up = dec_tlu_flush_lower_r;
|
||||
assign flush_r = dec_tlu_i0_kill_writeb_r;
|
||||
|
||||
// lsu idle
|
||||
// lsu halt idle. This is used for entering the halt mode. Also, DMA accesses are allowed during fence.
|
||||
// Indicates non-idle if there is a instruction valid in d-r or read/write buffers are non-empty since they can come with error
|
||||
// Store buffer now have only non-dma dccm stores
|
||||
// stbuf_empty not needed since it has only dccm stores
|
||||
assign lsu_idle_any = ~((lsu_pkt_m.valid & ~lsu_pkt_m.dma) |
|
||||
// lsu idle
|
||||
// lsu halt idle. This is used for entering the halt mode. Also, DMA accesses are allowed during fence.
|
||||
// Indicates non-idle if there is a instruction valid in d-r or read/write buffers are non-empty since they can come with error
|
||||
// Store buffer now have only non-dma dccm stores
|
||||
// stbuf_empty not needed since it has only dccm stores
|
||||
assign lsu_idle_any = ~((lsu_pkt_m.valid & ~lsu_pkt_m.dma) |
|
||||
(lsu_pkt_r.valid & ~lsu_pkt_r.dma)) &
|
||||
lsu_bus_buffer_empty_any;
|
||||
|
||||
assign lsu_active = (lsu_pkt_m.valid | lsu_pkt_r.valid | ld_single_ecc_error_r_ff) | ~lsu_bus_buffer_empty_any; // This includes DMA. Used for gating top clock
|
||||
assign lsu_active = (lsu_pkt_m.valid | lsu_pkt_r.valid | ld_single_ecc_error_r_ff) | ~lsu_bus_buffer_empty_any; // This includes DMA. Used for gating top clock
|
||||
|
||||
// Instantiate the store buffer
|
||||
assign store_stbuf_reqvld_r = lsu_pkt_r.valid & lsu_pkt_r.store & addr_in_dccm_r & ~flush_r & (~lsu_pkt_r.dma | ((lsu_pkt_r.by | lsu_pkt_r.half) & ~lsu_double_ecc_error_r));
|
||||
// Instantiate the store buffer
|
||||
assign store_stbuf_reqvld_r = lsu_pkt_r.valid & lsu_pkt_r.store & addr_in_dccm_r & ~flush_r & (~lsu_pkt_r.dma | ((lsu_pkt_r.by | lsu_pkt_r.half) & ~lsu_double_ecc_error_r));
|
||||
|
||||
// Disable Forwarding for now
|
||||
assign lsu_cmpen_m = lsu_pkt_m.valid & (lsu_pkt_m.load | lsu_pkt_m.store) & (addr_in_dccm_m | addr_in_pic_m);
|
||||
// Disable Forwarding for now
|
||||
assign lsu_cmpen_m = lsu_pkt_m.valid & (lsu_pkt_m.load | lsu_pkt_m.store) & (addr_in_dccm_m | addr_in_pic_m);
|
||||
|
||||
// Bus signals
|
||||
assign lsu_busreq_m = lsu_pkt_m.valid & ((lsu_pkt_m.load | lsu_pkt_m.store) & addr_external_m) & ~flush_m_up & ~lsu_exc_m & ~lsu_pkt_m.fast_int;
|
||||
// Bus signals
|
||||
assign lsu_busreq_m = lsu_pkt_m.valid & ((lsu_pkt_m.load | lsu_pkt_m.store) & addr_external_m) & ~flush_m_up & ~lsu_exc_m & ~lsu_pkt_m.fast_int;
|
||||
|
||||
// Dual signals
|
||||
assign ldst_dual_d = (lsu_addr_d[2] != end_addr_d[2]);
|
||||
assign ldst_dual_m = (lsu_addr_m[2] != end_addr_m[2]);
|
||||
assign ldst_dual_r = (lsu_addr_r[2] != end_addr_r[2]);
|
||||
// Dual signals
|
||||
assign ldst_dual_d = (lsu_addr_d[2] != end_addr_d[2]);
|
||||
assign ldst_dual_m = (lsu_addr_m[2] != end_addr_m[2]);
|
||||
assign ldst_dual_r = (lsu_addr_r[2] != end_addr_r[2]);
|
||||
|
||||
// PMU signals
|
||||
assign lsu_pmu_misaligned_m = lsu_pkt_m.valid & ((lsu_pkt_m.half & lsu_addr_m[0]) | (lsu_pkt_m.word & (|lsu_addr_m[1:0])));
|
||||
assign lsu_pmu_load_external_m = lsu_pkt_m.valid & lsu_pkt_m.load & addr_external_m;
|
||||
assign lsu_pmu_store_external_m = lsu_pkt_m.valid & lsu_pkt_m.store & addr_external_m;
|
||||
// PMU signals
|
||||
assign lsu_pmu_misaligned_m = lsu_pkt_m.valid & ((lsu_pkt_m.half & lsu_addr_m[0]) | (lsu_pkt_m.word & (|lsu_addr_m[1:0])));
|
||||
assign lsu_pmu_load_external_m = lsu_pkt_m.valid & lsu_pkt_m.load & addr_external_m;
|
||||
assign lsu_pmu_store_external_m = lsu_pkt_m.valid & lsu_pkt_m.store & addr_external_m;
|
||||
|
||||
el2_lsu_dccm_ctl #(.pt(pt)) dccm_ctl (
|
||||
el2_lsu_dccm_ctl #(
|
||||
.pt(pt)
|
||||
) dccm_ctl (
|
||||
.lsu_addr_d(lsu_addr_d[31:0]),
|
||||
.end_addr_d(end_addr_d[pt.DCCM_BITS-1:0]),
|
||||
.lsu_addr_m(lsu_addr_m[pt.DCCM_BITS-1:0]),
|
||||
|
@ -339,34 +340,42 @@ import el2_pkg::*;
|
|||
.end_addr_m(end_addr_m[pt.DCCM_BITS-1:0]),
|
||||
.end_addr_r(end_addr_r[pt.DCCM_BITS-1:0]),
|
||||
.*
|
||||
);
|
||||
);
|
||||
|
||||
el2_lsu_stbuf #(.pt(pt)) stbuf (
|
||||
el2_lsu_stbuf #(
|
||||
.pt(pt)
|
||||
) stbuf (
|
||||
.lsu_addr_d(lsu_addr_d[pt.LSU_SB_BITS-1:0]),
|
||||
.end_addr_d(end_addr_d[pt.LSU_SB_BITS-1:0]),
|
||||
|
||||
.*
|
||||
|
||||
);
|
||||
);
|
||||
|
||||
el2_lsu_ecc #(.pt(pt)) ecc (
|
||||
el2_lsu_ecc #(
|
||||
.pt(pt)
|
||||
) ecc (
|
||||
.lsu_addr_r(lsu_addr_r[pt.DCCM_BITS-1:0]),
|
||||
.end_addr_r(end_addr_r[pt.DCCM_BITS-1:0]),
|
||||
.lsu_addr_m(lsu_addr_m[pt.DCCM_BITS-1:0]),
|
||||
.end_addr_m(end_addr_m[pt.DCCM_BITS-1:0]),
|
||||
.*
|
||||
);
|
||||
);
|
||||
|
||||
el2_lsu_trigger #(.pt(pt)) trigger (
|
||||
el2_lsu_trigger #(
|
||||
.pt(pt)
|
||||
) trigger (
|
||||
.store_data_m(store_data_m[31:0]),
|
||||
.*
|
||||
);
|
||||
);
|
||||
|
||||
// Clk domain
|
||||
el2_lsu_clkdomain #(.pt(pt)) clkdomain (.*);
|
||||
// Clk domain
|
||||
el2_lsu_clkdomain #(.pt(pt)) clkdomain (.*);
|
||||
|
||||
// Bus interface
|
||||
el2_lsu_bus_intf #(.pt(pt)) bus_intf (
|
||||
// Bus interface
|
||||
el2_lsu_bus_intf #(
|
||||
.pt(pt)
|
||||
) bus_intf (
|
||||
.lsu_addr_m(lsu_addr_m[31:0] & {32{addr_external_m & lsu_pkt_m.valid}}),
|
||||
.lsu_addr_r(lsu_addr_r[31:0] & {32{lsu_busreq_r}}),
|
||||
|
||||
|
@ -375,10 +384,20 @@ import el2_pkg::*;
|
|||
|
||||
.store_data_r(store_data_r[31:0] & {32{lsu_busreq_r}}),
|
||||
.*
|
||||
);
|
||||
);
|
||||
|
||||
//Flops
|
||||
rvdff #(3) dma_mem_tag_mff (.*, .din(dma_mem_tag_d[2:0]), .dout(dma_mem_tag_m[2:0]), .clk(lsu_c1_m_clk));
|
||||
rvdff #(2) lsu_raw_fwd_r_ff (.*, .din({lsu_raw_fwd_hi_m, lsu_raw_fwd_lo_m}), .dout({lsu_raw_fwd_hi_r, lsu_raw_fwd_lo_r}), .clk(lsu_c2_r_clk));
|
||||
//Flops
|
||||
rvdff #(3) dma_mem_tag_mff (
|
||||
.*,
|
||||
.din (dma_mem_tag_d[2:0]),
|
||||
.dout(dma_mem_tag_m[2:0]),
|
||||
.clk (lsu_c1_m_clk)
|
||||
);
|
||||
rvdff #(2) lsu_raw_fwd_r_ff (
|
||||
.*,
|
||||
.din ({lsu_raw_fwd_hi_m, lsu_raw_fwd_lo_m}),
|
||||
.dout({lsu_raw_fwd_hi_r, lsu_raw_fwd_lo_r}),
|
||||
.clk (lsu_c2_r_clk)
|
||||
);
|
||||
|
||||
endmodule // el2_lsu
|
||||
endmodule // el2_lsu
|
||||
|
|
|
@ -23,111 +23,119 @@
|
|||
//
|
||||
//********************************************************************************
|
||||
module el2_lsu_addrcheck
|
||||
import el2_pkg::*;
|
||||
import el2_pkg::*;
|
||||
#(
|
||||
`include "el2_param.vh"
|
||||
)(
|
||||
input logic lsu_c2_m_clk, // clock
|
||||
input logic rst_l, // reset
|
||||
`include "el2_param.vh"
|
||||
) (
|
||||
input logic lsu_c2_m_clk, // clock
|
||||
input logic rst_l, // reset
|
||||
|
||||
input logic [31:0] start_addr_d, // start address for lsu
|
||||
input logic [31:0] end_addr_d, // end address for lsu
|
||||
input el2_lsu_pkt_t lsu_pkt_d, // packet in d
|
||||
input logic [31:0] dec_tlu_mrac_ff, // CSR read
|
||||
input logic [3:0] rs1_region_d, // address rs operand [31:28]
|
||||
input logic [31:0] start_addr_d, // start address for lsu
|
||||
input logic [31:0] end_addr_d, // end address for lsu
|
||||
input el2_lsu_pkt_t lsu_pkt_d, // packet in d
|
||||
input logic [31:0] dec_tlu_mrac_ff, // CSR read
|
||||
input logic [ 3:0] rs1_region_d, // address rs operand [31:28]
|
||||
|
||||
input logic [31:0] rs1_d, // address rs operand
|
||||
input logic [31:0] rs1_d, // address rs operand
|
||||
|
||||
output logic is_sideeffects_m, // is sideffects space
|
||||
output logic addr_in_dccm_d, // address in dccm
|
||||
output logic addr_in_pic_d, // address in pic
|
||||
output logic addr_external_d, // address in external
|
||||
output logic is_sideeffects_m, // is sideffects space
|
||||
output logic addr_in_dccm_d, // address in dccm
|
||||
output logic addr_in_pic_d, // address in pic
|
||||
output logic addr_external_d, // address in external
|
||||
|
||||
output logic access_fault_d, // access fault
|
||||
output logic misaligned_fault_d, // misaligned
|
||||
output logic [3:0] exc_mscause_d, // mscause for access/misaligned faults
|
||||
output logic access_fault_d, // access fault
|
||||
output logic misaligned_fault_d, // misaligned
|
||||
output logic [3:0] exc_mscause_d, // mscause for access/misaligned faults
|
||||
|
||||
output logic fir_dccm_access_error_d, // Fast interrupt dccm access error
|
||||
output logic fir_nondccm_access_error_d,// Fast interrupt dccm access error
|
||||
output logic fir_dccm_access_error_d, // Fast interrupt dccm access error
|
||||
output logic fir_nondccm_access_error_d, // Fast interrupt dccm access error
|
||||
|
||||
input logic scan_mode // Scan mode
|
||||
input logic scan_mode // Scan mode
|
||||
);
|
||||
|
||||
|
||||
logic non_dccm_access_ok;
|
||||
logic is_sideeffects_d, is_aligned_d;
|
||||
logic start_addr_in_dccm_d, end_addr_in_dccm_d;
|
||||
logic start_addr_in_dccm_region_d, end_addr_in_dccm_region_d;
|
||||
logic start_addr_in_pic_d, end_addr_in_pic_d;
|
||||
logic start_addr_in_pic_region_d, end_addr_in_pic_region_d;
|
||||
logic [4:0] csr_idx;
|
||||
logic addr_in_iccm;
|
||||
logic start_addr_dccm_or_pic;
|
||||
logic base_reg_dccm_or_pic;
|
||||
logic unmapped_access_fault_d, mpu_access_fault_d, picm_access_fault_d, regpred_access_fault_d;
|
||||
logic regcross_misaligned_fault_d, sideeffect_misaligned_fault_d;
|
||||
logic [3:0] access_fault_mscause_d;
|
||||
logic [3:0] misaligned_fault_mscause_d;
|
||||
logic non_dccm_access_ok;
|
||||
logic is_sideeffects_d, is_aligned_d;
|
||||
logic start_addr_in_dccm_d, end_addr_in_dccm_d;
|
||||
logic start_addr_in_dccm_region_d, end_addr_in_dccm_region_d;
|
||||
logic start_addr_in_pic_d, end_addr_in_pic_d;
|
||||
logic start_addr_in_pic_region_d, end_addr_in_pic_region_d;
|
||||
logic [4:0] csr_idx;
|
||||
logic addr_in_iccm;
|
||||
logic start_addr_dccm_or_pic;
|
||||
logic base_reg_dccm_or_pic;
|
||||
logic unmapped_access_fault_d, mpu_access_fault_d, picm_access_fault_d, regpred_access_fault_d;
|
||||
logic regcross_misaligned_fault_d, sideeffect_misaligned_fault_d;
|
||||
logic [3:0] access_fault_mscause_d;
|
||||
logic [3:0] misaligned_fault_mscause_d;
|
||||
|
||||
if (pt.DCCM_ENABLE == 1) begin: Gen_dccm_enable
|
||||
// Start address check
|
||||
rvrangecheck #(.CCM_SADR(pt.DCCM_SADR),
|
||||
.CCM_SIZE(pt.DCCM_SIZE)) start_addr_dccm_rangecheck (
|
||||
.addr(start_addr_d[31:0]),
|
||||
.in_range(start_addr_in_dccm_d),
|
||||
.in_region(start_addr_in_dccm_region_d)
|
||||
);
|
||||
if (pt.DCCM_ENABLE == 1) begin : Gen_dccm_enable
|
||||
// Start address check
|
||||
rvrangecheck #(
|
||||
.CCM_SADR(pt.DCCM_SADR),
|
||||
.CCM_SIZE(pt.DCCM_SIZE)
|
||||
) start_addr_dccm_rangecheck (
|
||||
.addr(start_addr_d[31:0]),
|
||||
.in_range(start_addr_in_dccm_d),
|
||||
.in_region(start_addr_in_dccm_region_d)
|
||||
);
|
||||
|
||||
// End address check
|
||||
rvrangecheck #(.CCM_SADR(pt.DCCM_SADR),
|
||||
.CCM_SIZE(pt.DCCM_SIZE)) end_addr_dccm_rangecheck (
|
||||
.addr(end_addr_d[31:0]),
|
||||
.in_range(end_addr_in_dccm_d),
|
||||
.in_region(end_addr_in_dccm_region_d)
|
||||
);
|
||||
end else begin: Gen_dccm_disable // block: Gen_dccm_enable
|
||||
assign start_addr_in_dccm_d = '0;
|
||||
assign start_addr_in_dccm_region_d = '0;
|
||||
assign end_addr_in_dccm_d = '0;
|
||||
assign end_addr_in_dccm_region_d = '0;
|
||||
end
|
||||
// End address check
|
||||
rvrangecheck #(
|
||||
.CCM_SADR(pt.DCCM_SADR),
|
||||
.CCM_SIZE(pt.DCCM_SIZE)
|
||||
) end_addr_dccm_rangecheck (
|
||||
.addr(end_addr_d[31:0]),
|
||||
.in_range(end_addr_in_dccm_d),
|
||||
.in_region(end_addr_in_dccm_region_d)
|
||||
);
|
||||
end else begin : Gen_dccm_disable // block: Gen_dccm_enable
|
||||
assign start_addr_in_dccm_d = '0;
|
||||
assign start_addr_in_dccm_region_d = '0;
|
||||
assign end_addr_in_dccm_d = '0;
|
||||
assign end_addr_in_dccm_region_d = '0;
|
||||
end
|
||||
|
||||
if (pt.ICCM_ENABLE == 1) begin : check_iccm
|
||||
assign addr_in_iccm = (start_addr_d[31:28] == pt.ICCM_REGION);
|
||||
end else begin
|
||||
assign addr_in_iccm = 1'b0;
|
||||
end
|
||||
if (pt.ICCM_ENABLE == 1) begin : check_iccm
|
||||
assign addr_in_iccm = (start_addr_d[31:28] == pt.ICCM_REGION);
|
||||
end else begin
|
||||
assign addr_in_iccm = 1'b0;
|
||||
end
|
||||
|
||||
// PIC memory check
|
||||
// Start address check
|
||||
rvrangecheck #(.CCM_SADR(pt.PIC_BASE_ADDR),
|
||||
.CCM_SIZE(pt.PIC_SIZE)) start_addr_pic_rangecheck (
|
||||
// PIC memory check
|
||||
// Start address check
|
||||
rvrangecheck #(
|
||||
.CCM_SADR(pt.PIC_BASE_ADDR),
|
||||
.CCM_SIZE(pt.PIC_SIZE)
|
||||
) start_addr_pic_rangecheck (
|
||||
.addr(start_addr_d[31:0]),
|
||||
.in_range(start_addr_in_pic_d),
|
||||
.in_region(start_addr_in_pic_region_d)
|
||||
);
|
||||
);
|
||||
|
||||
// End address check
|
||||
rvrangecheck #(.CCM_SADR(pt.PIC_BASE_ADDR),
|
||||
.CCM_SIZE(pt.PIC_SIZE)) end_addr_pic_rangecheck (
|
||||
// End address check
|
||||
rvrangecheck #(
|
||||
.CCM_SADR(pt.PIC_BASE_ADDR),
|
||||
.CCM_SIZE(pt.PIC_SIZE)
|
||||
) end_addr_pic_rangecheck (
|
||||
.addr(end_addr_d[31:0]),
|
||||
.in_range(end_addr_in_pic_d),
|
||||
.in_region(end_addr_in_pic_region_d)
|
||||
);
|
||||
);
|
||||
|
||||
assign start_addr_dccm_or_pic = start_addr_in_dccm_region_d | start_addr_in_pic_region_d;
|
||||
assign base_reg_dccm_or_pic = ((rs1_region_d[3:0] == pt.DCCM_REGION) & pt.DCCM_ENABLE) | (rs1_region_d[3:0] == pt.PIC_REGION);
|
||||
assign addr_in_dccm_d = (start_addr_in_dccm_d & end_addr_in_dccm_d);
|
||||
assign addr_in_pic_d = (start_addr_in_pic_d & end_addr_in_pic_d);
|
||||
assign start_addr_dccm_or_pic = start_addr_in_dccm_region_d | start_addr_in_pic_region_d;
|
||||
assign base_reg_dccm_or_pic = ((rs1_region_d[3:0] == pt.DCCM_REGION) & pt.DCCM_ENABLE) | (rs1_region_d[3:0] == pt.PIC_REGION);
|
||||
assign addr_in_dccm_d = (start_addr_in_dccm_d & end_addr_in_dccm_d);
|
||||
assign addr_in_pic_d = (start_addr_in_pic_d & end_addr_in_pic_d);
|
||||
|
||||
assign addr_external_d = ~(start_addr_in_dccm_region_d | start_addr_in_pic_region_d);
|
||||
assign csr_idx[4:0] = {start_addr_d[31:28], 1'b1};
|
||||
assign is_sideeffects_d = dec_tlu_mrac_ff[csr_idx] & ~(start_addr_in_dccm_region_d | start_addr_in_pic_region_d | addr_in_iccm) & lsu_pkt_d.valid & (lsu_pkt_d.store | lsu_pkt_d.load); //every region has the 2 LSB indicating ( 1: sideeffects/no_side effects, and 0: cacheable ). Ignored in internal regions
|
||||
assign is_aligned_d = (lsu_pkt_d.word & (start_addr_d[1:0] == 2'b0)) |
|
||||
assign addr_external_d = ~(start_addr_in_dccm_region_d | start_addr_in_pic_region_d);
|
||||
assign csr_idx[4:0] = {start_addr_d[31:28], 1'b1};
|
||||
assign is_sideeffects_d = dec_tlu_mrac_ff[csr_idx] & ~(start_addr_in_dccm_region_d | start_addr_in_pic_region_d | addr_in_iccm) & lsu_pkt_d.valid & (lsu_pkt_d.store | lsu_pkt_d.load); //every region has the 2 LSB indicating ( 1: sideeffects/no_side effects, and 0: cacheable ). Ignored in internal regions
|
||||
assign is_aligned_d = (lsu_pkt_d.word & (start_addr_d[1:0] == 2'b0)) |
|
||||
(lsu_pkt_d.half & (start_addr_d[0] == 1'b0)) |
|
||||
lsu_pkt_d.by;
|
||||
|
||||
assign non_dccm_access_ok = (~(|{pt.DATA_ACCESS_ENABLE0,pt.DATA_ACCESS_ENABLE1,pt.DATA_ACCESS_ENABLE2,pt.DATA_ACCESS_ENABLE3,pt.DATA_ACCESS_ENABLE4,pt.DATA_ACCESS_ENABLE5,pt.DATA_ACCESS_ENABLE6,pt.DATA_ACCESS_ENABLE7})) |
|
||||
assign non_dccm_access_ok = (~(|{pt.DATA_ACCESS_ENABLE0,pt.DATA_ACCESS_ENABLE1,pt.DATA_ACCESS_ENABLE2,pt.DATA_ACCESS_ENABLE3,pt.DATA_ACCESS_ENABLE4,pt.DATA_ACCESS_ENABLE5,pt.DATA_ACCESS_ENABLE6,pt.DATA_ACCESS_ENABLE7})) |
|
||||
(((pt.DATA_ACCESS_ENABLE0 & ((start_addr_d[31:0] | pt.DATA_ACCESS_MASK0)) == (pt.DATA_ACCESS_ADDR0 | pt.DATA_ACCESS_MASK0)) |
|
||||
(pt.DATA_ACCESS_ENABLE1 & ((start_addr_d[31:0] | pt.DATA_ACCESS_MASK1)) == (pt.DATA_ACCESS_ADDR1 | pt.DATA_ACCESS_MASK1)) |
|
||||
(pt.DATA_ACCESS_ENABLE2 & ((start_addr_d[31:0] | pt.DATA_ACCESS_MASK2)) == (pt.DATA_ACCESS_ADDR2 | pt.DATA_ACCESS_MASK2)) |
|
||||
|
@ -145,47 +153,54 @@ import el2_pkg::*;
|
|||
(pt.DATA_ACCESS_ENABLE6 & ((end_addr_d[31:0] | pt.DATA_ACCESS_MASK6)) == (pt.DATA_ACCESS_ADDR6 | pt.DATA_ACCESS_MASK6)) |
|
||||
(pt.DATA_ACCESS_ENABLE7 & ((end_addr_d[31:0] | pt.DATA_ACCESS_MASK7)) == (pt.DATA_ACCESS_ADDR7 | pt.DATA_ACCESS_MASK7))));
|
||||
|
||||
// Access fault logic
|
||||
// 0. Unmapped local memory : Addr in dccm region but not in dccm offset OR Addr in picm region but not in picm offset OR DCCM -> PIC cross when DCCM/PIC in same region
|
||||
// 1. Uncorrectable (double bit) ECC error
|
||||
// 3. Address is not in a populated non-dccm region
|
||||
// 5. Region predication access fault: Base Address in DCCM/PIC and Final address in non-DCCM/non-PIC region or vice versa
|
||||
// 6. Ld/St access to picm are not word aligned or word size
|
||||
assign regpred_access_fault_d = (start_addr_dccm_or_pic ^ base_reg_dccm_or_pic); // 5. Region predication access fault: Base Address in DCCM/PIC and Final address in non-DCCM/non-PIC region or vice versa
|
||||
assign picm_access_fault_d = (addr_in_pic_d & ((start_addr_d[1:0] != 2'b0) | ~lsu_pkt_d.word)); // 6. Ld/St access to picm are not word aligned or word size
|
||||
// Access fault logic
|
||||
// 0. Unmapped local memory : Addr in dccm region but not in dccm offset OR Addr in picm region but not in picm offset OR DCCM -> PIC cross when DCCM/PIC in same region
|
||||
// 1. Uncorrectable (double bit) ECC error
|
||||
// 3. Address is not in a populated non-dccm region
|
||||
// 5. Region predication access fault: Base Address in DCCM/PIC and Final address in non-DCCM/non-PIC region or vice versa
|
||||
// 6. Ld/St access to picm are not word aligned or word size
|
||||
assign regpred_access_fault_d = (start_addr_dccm_or_pic ^ base_reg_dccm_or_pic); // 5. Region predication access fault: Base Address in DCCM/PIC and Final address in non-DCCM/non-PIC region or vice versa
|
||||
assign picm_access_fault_d = (addr_in_pic_d & ((start_addr_d[1:0] != 2'b0) | ~lsu_pkt_d.word)); // 6. Ld/St access to picm are not word aligned or word size
|
||||
|
||||
if (pt.DCCM_ENABLE & (pt.DCCM_REGION == pt.PIC_REGION)) begin
|
||||
assign unmapped_access_fault_d = ((start_addr_in_dccm_region_d & ~(start_addr_in_dccm_d | start_addr_in_pic_d)) | // 0. Addr in dccm/pic region but not in dccm/pic offset
|
||||
(end_addr_in_dccm_region_d & ~(end_addr_in_dccm_d | end_addr_in_pic_d)) | // 0. Addr in dccm/pic region but not in dccm/pic offset
|
||||
(start_addr_in_dccm_d & end_addr_in_pic_d) | // 0. DCCM -> PIC cross when DCCM/PIC in same region
|
||||
(start_addr_in_pic_d & end_addr_in_dccm_d)); // 0. DCCM -> PIC cross when DCCM/PIC in same region
|
||||
assign mpu_access_fault_d = (~start_addr_in_dccm_region_d & ~non_dccm_access_ok); // 3. Address is not in a populated non-dccm region
|
||||
end else begin
|
||||
assign unmapped_access_fault_d = ((start_addr_in_dccm_region_d & ~start_addr_in_dccm_d) | // 0. Addr in dccm region but not in dccm offset
|
||||
(end_addr_in_dccm_region_d & ~end_addr_in_dccm_d) | // 0. Addr in dccm region but not in dccm offset
|
||||
(start_addr_in_pic_region_d & ~start_addr_in_pic_d) | // 0. Addr in picm region but not in picm offset
|
||||
(end_addr_in_pic_region_d & ~end_addr_in_pic_d)); // 0. Addr in picm region but not in picm offset
|
||||
assign mpu_access_fault_d = (~start_addr_in_pic_region_d & ~start_addr_in_dccm_region_d & ~non_dccm_access_ok); // 3. Address is not in a populated non-dccm region
|
||||
end
|
||||
if (pt.DCCM_ENABLE & (pt.DCCM_REGION == pt.PIC_REGION)) begin
|
||||
assign unmapped_access_fault_d = ((start_addr_in_dccm_region_d & ~(start_addr_in_dccm_d | start_addr_in_pic_d)) | // 0. Addr in dccm/pic region but not in dccm/pic offset
|
||||
(end_addr_in_dccm_region_d & ~(end_addr_in_dccm_d | end_addr_in_pic_d)) | // 0. Addr in dccm/pic region but not in dccm/pic offset
|
||||
(start_addr_in_dccm_d & end_addr_in_pic_d) | // 0. DCCM -> PIC cross when DCCM/PIC in same region
|
||||
(start_addr_in_pic_d & end_addr_in_dccm_d)); // 0. DCCM -> PIC cross when DCCM/PIC in same region
|
||||
assign mpu_access_fault_d = (~start_addr_in_dccm_region_d & ~non_dccm_access_ok); // 3. Address is not in a populated non-dccm region
|
||||
end else begin
|
||||
assign unmapped_access_fault_d = ((start_addr_in_dccm_region_d & ~start_addr_in_dccm_d) | // 0. Addr in dccm region but not in dccm offset
|
||||
(end_addr_in_dccm_region_d & ~end_addr_in_dccm_d) | // 0. Addr in dccm region but not in dccm offset
|
||||
(start_addr_in_pic_region_d & ~start_addr_in_pic_d) | // 0. Addr in picm region but not in picm offset
|
||||
(end_addr_in_pic_region_d & ~end_addr_in_pic_d)); // 0. Addr in picm region but not in picm offset
|
||||
assign mpu_access_fault_d = (~start_addr_in_pic_region_d & ~start_addr_in_dccm_region_d & ~non_dccm_access_ok); // 3. Address is not in a populated non-dccm region
|
||||
end
|
||||
|
||||
assign access_fault_d = (unmapped_access_fault_d | mpu_access_fault_d | picm_access_fault_d | regpred_access_fault_d) & lsu_pkt_d.valid & ~lsu_pkt_d.dma;
|
||||
assign access_fault_mscause_d[3:0] = unmapped_access_fault_d ? 4'h2 : mpu_access_fault_d ? 4'h3 : regpred_access_fault_d ? 4'h5 : picm_access_fault_d ? 4'h6 : 4'h0;
|
||||
assign access_fault_d = (unmapped_access_fault_d | mpu_access_fault_d | picm_access_fault_d | regpred_access_fault_d) & lsu_pkt_d.valid & ~lsu_pkt_d.dma;
|
||||
assign access_fault_mscause_d[3:0] = unmapped_access_fault_d ? 4'h2 : mpu_access_fault_d ? 4'h3 : regpred_access_fault_d ? 4'h5 : picm_access_fault_d ? 4'h6 : 4'h0;
|
||||
|
||||
// Misaligned happens due to 2 reasons
|
||||
// 0. Region cross
|
||||
// 1. sideeffects access which are not aligned
|
||||
assign regcross_misaligned_fault_d = (start_addr_d[31:28] != end_addr_d[31:28]);
|
||||
assign sideeffect_misaligned_fault_d = (is_sideeffects_d & ~is_aligned_d);
|
||||
assign misaligned_fault_d = (regcross_misaligned_fault_d | (sideeffect_misaligned_fault_d & addr_external_d)) & lsu_pkt_d.valid & ~lsu_pkt_d.dma;
|
||||
assign misaligned_fault_mscause_d[3:0] = regcross_misaligned_fault_d ? 4'h2 : sideeffect_misaligned_fault_d ? 4'h1 : 4'h0;
|
||||
// Misaligned happens due to 2 reasons
|
||||
// 0. Region cross
|
||||
// 1. sideeffects access which are not aligned
|
||||
assign regcross_misaligned_fault_d = (start_addr_d[31:28] != end_addr_d[31:28]);
|
||||
assign sideeffect_misaligned_fault_d = (is_sideeffects_d & ~is_aligned_d);
|
||||
assign misaligned_fault_d = (regcross_misaligned_fault_d | (sideeffect_misaligned_fault_d & addr_external_d)) & lsu_pkt_d.valid & ~lsu_pkt_d.dma;
|
||||
assign misaligned_fault_mscause_d[3:0] = regcross_misaligned_fault_d ? 4'h2 : sideeffect_misaligned_fault_d ? 4'h1 : 4'h0;
|
||||
|
||||
assign exc_mscause_d[3:0] = misaligned_fault_d ? misaligned_fault_mscause_d[3:0] : access_fault_mscause_d[3:0];
|
||||
assign exc_mscause_d[3:0] = misaligned_fault_d ? misaligned_fault_mscause_d[3:0] : access_fault_mscause_d[3:0];
|
||||
|
||||
// Fast interrupt error logic
|
||||
assign fir_dccm_access_error_d = ((start_addr_in_dccm_region_d & ~start_addr_in_dccm_d) |
|
||||
// Fast interrupt error logic
|
||||
assign fir_dccm_access_error_d = ((start_addr_in_dccm_region_d & ~start_addr_in_dccm_d) |
|
||||
(end_addr_in_dccm_region_d & ~end_addr_in_dccm_d)) & lsu_pkt_d.valid & lsu_pkt_d.fast_int;
|
||||
assign fir_nondccm_access_error_d = ~(start_addr_in_dccm_region_d & end_addr_in_dccm_region_d) & lsu_pkt_d.valid & lsu_pkt_d.fast_int;
|
||||
assign fir_nondccm_access_error_d = ~(start_addr_in_dccm_region_d & end_addr_in_dccm_region_d) & lsu_pkt_d.valid & lsu_pkt_d.fast_int;
|
||||
|
||||
rvdff #(.WIDTH(1)) is_sideeffects_mff (.din(is_sideeffects_d), .dout(is_sideeffects_m), .clk(lsu_c2_m_clk), .*);
|
||||
rvdff #(
|
||||
.WIDTH(1)
|
||||
) is_sideeffects_mff (
|
||||
.din (is_sideeffects_d),
|
||||
.dout(is_sideeffects_m),
|
||||
.clk (lsu_c2_m_clk),
|
||||
.*
|
||||
);
|
||||
|
||||
endmodule // el2_lsu_addrcheck
|
||||
endmodule // el2_lsu_addrcheck
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -23,248 +23,267 @@
|
|||
//
|
||||
//********************************************************************************
|
||||
module el2_lsu_bus_intf
|
||||
import el2_pkg::*;
|
||||
import el2_pkg::*;
|
||||
#(
|
||||
`include "el2_param.vh"
|
||||
)(
|
||||
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
|
||||
input logic clk_override, // Override non-functional clock gating
|
||||
input logic rst_l, // reset, active low
|
||||
input logic scan_mode, // scan mode
|
||||
input logic dec_tlu_external_ldfwd_disable, // disable load to load forwarding for externals
|
||||
input logic dec_tlu_wb_coalescing_disable, // disable write buffer coalescing
|
||||
input logic dec_tlu_sideeffect_posted_disable, // disable the posted sideeffect load store to the bus
|
||||
`include "el2_param.vh"
|
||||
) (
|
||||
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
|
||||
input logic clk_override, // Override non-functional clock gating
|
||||
input logic rst_l, // reset, active low
|
||||
input logic scan_mode, // scan mode
|
||||
input logic dec_tlu_external_ldfwd_disable, // disable load to load forwarding for externals
|
||||
input logic dec_tlu_wb_coalescing_disable, // disable write buffer coalescing
|
||||
input logic dec_tlu_sideeffect_posted_disable, // disable the posted sideeffect load store to the bus
|
||||
|
||||
// various clocks needed for the bus reads and writes
|
||||
input logic lsu_bus_obuf_c1_clken, // obuf clock enable
|
||||
input logic lsu_busm_clken, // bus clock enable
|
||||
// various clocks needed for the bus reads and writes
|
||||
input logic lsu_bus_obuf_c1_clken, // obuf clock enable
|
||||
input logic lsu_busm_clken, // bus clock enable
|
||||
|
||||
input logic lsu_c1_r_clk, // r pipe single pulse clock
|
||||
input logic lsu_c2_r_clk, // r pipe double pulse clock
|
||||
input logic lsu_bus_ibuf_c1_clk, // ibuf single pulse clock
|
||||
input logic lsu_bus_obuf_c1_clk, // obuf single pulse clock
|
||||
input logic lsu_bus_buf_c1_clk, // buf single pulse clock
|
||||
input logic lsu_free_c2_clk, // free clock double pulse clock
|
||||
input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in.
|
||||
input logic lsu_busm_clk, // bus clock
|
||||
input logic lsu_c1_r_clk, // r pipe single pulse clock
|
||||
input logic lsu_c2_r_clk, // r pipe double pulse clock
|
||||
input logic lsu_bus_ibuf_c1_clk, // ibuf single pulse clock
|
||||
input logic lsu_bus_obuf_c1_clk, // obuf single pulse clock
|
||||
input logic lsu_bus_buf_c1_clk, // buf single pulse clock
|
||||
input logic lsu_free_c2_clk, // free clock double pulse clock
|
||||
input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in.
|
||||
input logic lsu_busm_clk, // bus clock
|
||||
|
||||
input logic dec_lsu_valid_raw_d, // Raw valid for address computation
|
||||
input logic lsu_busreq_m, // bus request is in m
|
||||
input logic dec_lsu_valid_raw_d, // Raw valid for address computation
|
||||
input logic lsu_busreq_m, // bus request is in m
|
||||
|
||||
input el2_lsu_pkt_t lsu_pkt_m, // lsu packet flowing down the pipe
|
||||
input el2_lsu_pkt_t lsu_pkt_r, // lsu packet flowing down the pipe
|
||||
input el2_lsu_pkt_t lsu_pkt_m, // lsu packet flowing down the pipe
|
||||
input el2_lsu_pkt_t lsu_pkt_r, // lsu packet flowing down the pipe
|
||||
|
||||
input logic [31:0] lsu_addr_m, // lsu address flowing down the pipe
|
||||
input logic [31:0] lsu_addr_r, // lsu address flowing down the pipe
|
||||
input logic [31:0] lsu_addr_m, // lsu address flowing down the pipe
|
||||
input logic [31:0] lsu_addr_r, // lsu address flowing down the pipe
|
||||
|
||||
input logic [31:0] end_addr_m, // lsu address flowing down the pipe
|
||||
input logic [31:0] end_addr_r, // lsu address flowing down the pipe
|
||||
input logic [31:0] end_addr_m, // lsu address flowing down the pipe
|
||||
input logic [31:0] end_addr_r, // lsu address flowing down the pipe
|
||||
|
||||
input logic [31:0] store_data_r, // store data flowing down the pipe
|
||||
input logic dec_tlu_force_halt,
|
||||
input logic [31:0] store_data_r, // store data flowing down the pipe
|
||||
input logic dec_tlu_force_halt,
|
||||
|
||||
input logic lsu_commit_r, // lsu instruction in r commits
|
||||
input logic is_sideeffects_m, // lsu attribute is side_effects
|
||||
input logic flush_m_up, // flush
|
||||
input logic flush_r, // flush
|
||||
input logic ldst_dual_d, ldst_dual_m, ldst_dual_r,
|
||||
input logic lsu_commit_r, // lsu instruction in r commits
|
||||
input logic is_sideeffects_m, // lsu attribute is side_effects
|
||||
input logic flush_m_up, // flush
|
||||
input logic flush_r, // flush
|
||||
input logic ldst_dual_d,
|
||||
ldst_dual_m,
|
||||
ldst_dual_r,
|
||||
|
||||
output logic lsu_busreq_r, // bus request is in r
|
||||
output logic lsu_bus_buffer_pend_any, // bus buffer has a pending bus entry
|
||||
output logic lsu_bus_buffer_full_any, // write buffer is full
|
||||
output logic lsu_bus_buffer_empty_any, // write buffer is empty
|
||||
output logic [31:0] bus_read_data_m, // the bus return data
|
||||
output logic lsu_busreq_r, // bus request is in r
|
||||
output logic lsu_bus_buffer_pend_any, // bus buffer has a pending bus entry
|
||||
output logic lsu_bus_buffer_full_any, // write buffer is full
|
||||
output logic lsu_bus_buffer_empty_any, // write buffer is empty
|
||||
output logic [31:0] bus_read_data_m, // the bus return data
|
||||
|
||||
|
||||
output logic lsu_imprecise_error_load_any, // imprecise load bus error
|
||||
output logic lsu_imprecise_error_store_any, // imprecise store bus error
|
||||
output logic [31:0] lsu_imprecise_error_addr_any, // address of the imprecise error
|
||||
output logic lsu_imprecise_error_load_any, // imprecise load bus error
|
||||
output logic lsu_imprecise_error_store_any, // imprecise store bus error
|
||||
output logic [31:0] lsu_imprecise_error_addr_any, // address of the imprecise error
|
||||
|
||||
// Non-blocking loads
|
||||
output logic lsu_nonblock_load_valid_m, // there is an external load -> put in the cam
|
||||
output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_m, // the tag of the external non block load
|
||||
output logic lsu_nonblock_load_inv_r, // invalidate signal for the cam entry for non block loads
|
||||
output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_r, // tag of the enrty which needs to be invalidated
|
||||
output logic lsu_nonblock_load_data_valid,// the non block is valid - sending information back to the cam
|
||||
output logic lsu_nonblock_load_data_error,// non block load has an error
|
||||
output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // the tag of the non block load sending the data/error
|
||||
output logic [31:0] lsu_nonblock_load_data, // Data of the non block load
|
||||
// Non-blocking loads
|
||||
output logic lsu_nonblock_load_valid_m, // there is an external load -> put in the cam
|
||||
output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_m, // the tag of the external non block load
|
||||
output logic lsu_nonblock_load_inv_r, // invalidate signal for the cam entry for non block loads
|
||||
output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_r, // tag of the enrty which needs to be invalidated
|
||||
output logic lsu_nonblock_load_data_valid,// the non block is valid - sending information back to the cam
|
||||
output logic lsu_nonblock_load_data_error, // non block load has an error
|
||||
output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // the tag of the non block load sending the data/error
|
||||
output logic [31:0] lsu_nonblock_load_data, // Data of the non block load
|
||||
|
||||
// PMU events
|
||||
output logic lsu_pmu_bus_trxn,
|
||||
output logic lsu_pmu_bus_misaligned,
|
||||
output logic lsu_pmu_bus_error,
|
||||
output logic lsu_pmu_bus_busy,
|
||||
// PMU events
|
||||
output logic lsu_pmu_bus_trxn,
|
||||
output logic lsu_pmu_bus_misaligned,
|
||||
output logic lsu_pmu_bus_error,
|
||||
output logic lsu_pmu_bus_busy,
|
||||
|
||||
// AXI Write Channels
|
||||
output logic lsu_axi_awvalid,
|
||||
input logic lsu_axi_awready,
|
||||
output logic [pt.LSU_BUS_TAG-1:0] lsu_axi_awid,
|
||||
output logic [31:0] lsu_axi_awaddr,
|
||||
output logic [3:0] lsu_axi_awregion,
|
||||
output logic [7:0] lsu_axi_awlen,
|
||||
output logic [2:0] lsu_axi_awsize,
|
||||
output logic [1:0] lsu_axi_awburst,
|
||||
output logic lsu_axi_awlock,
|
||||
output logic [3:0] lsu_axi_awcache,
|
||||
output logic [2:0] lsu_axi_awprot,
|
||||
output logic [3:0] lsu_axi_awqos,
|
||||
// AXI Write Channels
|
||||
output logic lsu_axi_awvalid,
|
||||
input logic lsu_axi_awready,
|
||||
output logic [pt.LSU_BUS_TAG-1:0] lsu_axi_awid,
|
||||
output logic [ 31:0] lsu_axi_awaddr,
|
||||
output logic [ 3:0] lsu_axi_awregion,
|
||||
output logic [ 7:0] lsu_axi_awlen,
|
||||
output logic [ 2:0] lsu_axi_awsize,
|
||||
output logic [ 1:0] lsu_axi_awburst,
|
||||
output logic lsu_axi_awlock,
|
||||
output logic [ 3:0] lsu_axi_awcache,
|
||||
output logic [ 2:0] lsu_axi_awprot,
|
||||
output logic [ 3:0] lsu_axi_awqos,
|
||||
|
||||
output logic lsu_axi_wvalid,
|
||||
input logic lsu_axi_wready,
|
||||
output logic [63:0] lsu_axi_wdata,
|
||||
output logic [7:0] lsu_axi_wstrb,
|
||||
output logic lsu_axi_wlast,
|
||||
output logic lsu_axi_wvalid,
|
||||
input logic lsu_axi_wready,
|
||||
output logic [63:0] lsu_axi_wdata,
|
||||
output logic [ 7:0] lsu_axi_wstrb,
|
||||
output logic lsu_axi_wlast,
|
||||
|
||||
input logic lsu_axi_bvalid,
|
||||
output logic lsu_axi_bready,
|
||||
input logic [1:0] lsu_axi_bresp,
|
||||
input logic [pt.LSU_BUS_TAG-1:0] lsu_axi_bid,
|
||||
input logic lsu_axi_bvalid,
|
||||
output logic lsu_axi_bready,
|
||||
input logic [ 1:0] lsu_axi_bresp,
|
||||
input logic [pt.LSU_BUS_TAG-1:0] lsu_axi_bid,
|
||||
|
||||
// AXI Read Channels
|
||||
output logic lsu_axi_arvalid,
|
||||
input logic lsu_axi_arready,
|
||||
output logic [pt.LSU_BUS_TAG-1:0] lsu_axi_arid,
|
||||
output logic [31:0] lsu_axi_araddr,
|
||||
output logic [3:0] lsu_axi_arregion,
|
||||
output logic [7:0] lsu_axi_arlen,
|
||||
output logic [2:0] lsu_axi_arsize,
|
||||
output logic [1:0] lsu_axi_arburst,
|
||||
output logic lsu_axi_arlock,
|
||||
output logic [3:0] lsu_axi_arcache,
|
||||
output logic [2:0] lsu_axi_arprot,
|
||||
output logic [3:0] lsu_axi_arqos,
|
||||
// AXI Read Channels
|
||||
output logic lsu_axi_arvalid,
|
||||
input logic lsu_axi_arready,
|
||||
output logic [pt.LSU_BUS_TAG-1:0] lsu_axi_arid,
|
||||
output logic [ 31:0] lsu_axi_araddr,
|
||||
output logic [ 3:0] lsu_axi_arregion,
|
||||
output logic [ 7:0] lsu_axi_arlen,
|
||||
output logic [ 2:0] lsu_axi_arsize,
|
||||
output logic [ 1:0] lsu_axi_arburst,
|
||||
output logic lsu_axi_arlock,
|
||||
output logic [ 3:0] lsu_axi_arcache,
|
||||
output logic [ 2:0] lsu_axi_arprot,
|
||||
output logic [ 3:0] lsu_axi_arqos,
|
||||
|
||||
input logic lsu_axi_rvalid,
|
||||
output logic lsu_axi_rready,
|
||||
input logic [pt.LSU_BUS_TAG-1:0] lsu_axi_rid,
|
||||
input logic [63:0] lsu_axi_rdata,
|
||||
input logic [1:0] lsu_axi_rresp,
|
||||
input logic lsu_axi_rvalid,
|
||||
output logic lsu_axi_rready,
|
||||
input logic [pt.LSU_BUS_TAG-1:0] lsu_axi_rid,
|
||||
input logic [ 63:0] lsu_axi_rdata,
|
||||
input logic [ 1:0] lsu_axi_rresp,
|
||||
|
||||
input logic lsu_bus_clk_en
|
||||
input logic lsu_bus_clk_en
|
||||
|
||||
);
|
||||
|
||||
|
||||
|
||||
logic lsu_bus_clk_en_q;
|
||||
logic lsu_bus_clk_en_q;
|
||||
|
||||
logic [3:0] ldst_byteen_m, ldst_byteen_r;
|
||||
logic [7:0] ldst_byteen_ext_m, ldst_byteen_ext_r;
|
||||
logic [3:0] ldst_byteen_hi_m, ldst_byteen_hi_r;
|
||||
logic [3:0] ldst_byteen_lo_m, ldst_byteen_lo_r;
|
||||
logic is_sideeffects_r;
|
||||
logic [3:0] ldst_byteen_m, ldst_byteen_r;
|
||||
logic [7:0] ldst_byteen_ext_m, ldst_byteen_ext_r;
|
||||
logic [3:0] ldst_byteen_hi_m, ldst_byteen_hi_r;
|
||||
logic [3:0] ldst_byteen_lo_m, ldst_byteen_lo_r;
|
||||
logic is_sideeffects_r;
|
||||
|
||||
logic [63:0] store_data_ext_r;
|
||||
logic [31:0] store_data_hi_r;
|
||||
logic [31:0] store_data_lo_r;
|
||||
logic [63:0] store_data_ext_r;
|
||||
logic [31:0] store_data_hi_r;
|
||||
logic [31:0] store_data_lo_r;
|
||||
|
||||
logic addr_match_dw_lo_r_m;
|
||||
logic addr_match_word_lo_r_m;
|
||||
logic no_word_merge_r, no_dword_merge_r;
|
||||
logic addr_match_dw_lo_r_m;
|
||||
logic addr_match_word_lo_r_m;
|
||||
logic no_word_merge_r, no_dword_merge_r;
|
||||
|
||||
logic ld_addr_rhit_lo_lo, ld_addr_rhit_hi_lo, ld_addr_rhit_lo_hi, ld_addr_rhit_hi_hi;
|
||||
logic [3:0] ld_byte_rhit_lo_lo, ld_byte_rhit_hi_lo, ld_byte_rhit_lo_hi, ld_byte_rhit_hi_hi;
|
||||
logic ld_addr_rhit_lo_lo, ld_addr_rhit_hi_lo, ld_addr_rhit_lo_hi, ld_addr_rhit_hi_hi;
|
||||
logic [3:0] ld_byte_rhit_lo_lo, ld_byte_rhit_hi_lo, ld_byte_rhit_lo_hi, ld_byte_rhit_hi_hi;
|
||||
|
||||
logic [3:0] ld_byte_hit_lo, ld_byte_rhit_lo;
|
||||
logic [3:0] ld_byte_hit_hi, ld_byte_rhit_hi;
|
||||
logic [3:0] ld_byte_hit_lo, ld_byte_rhit_lo;
|
||||
logic [3:0] ld_byte_hit_hi, ld_byte_rhit_hi;
|
||||
|
||||
logic [31:0] ld_fwddata_rpipe_lo;
|
||||
logic [31:0] ld_fwddata_rpipe_hi;
|
||||
logic [31:0] ld_fwddata_rpipe_lo;
|
||||
logic [31:0] ld_fwddata_rpipe_hi;
|
||||
|
||||
logic [3:0] ld_byte_hit_buf_lo, ld_byte_hit_buf_hi;
|
||||
logic [31:0] ld_fwddata_buf_lo, ld_fwddata_buf_hi;
|
||||
logic [3:0] ld_byte_hit_buf_lo, ld_byte_hit_buf_hi;
|
||||
logic [31:0] ld_fwddata_buf_lo, ld_fwddata_buf_hi;
|
||||
|
||||
logic [63:0] ld_fwddata_lo, ld_fwddata_hi;
|
||||
logic [63:0] ld_fwddata_m;
|
||||
logic [63:0] ld_fwddata_lo, ld_fwddata_hi;
|
||||
logic [63:0] ld_fwddata_m;
|
||||
|
||||
logic ld_full_hit_hi_m, ld_full_hit_lo_m;
|
||||
logic ld_full_hit_m;
|
||||
logic ld_full_hit_hi_m, ld_full_hit_lo_m;
|
||||
logic ld_full_hit_m;
|
||||
|
||||
assign ldst_byteen_m[3:0] = ({4{lsu_pkt_m.by}} & 4'b0001) |
|
||||
assign ldst_byteen_m[3:0] = ({4{lsu_pkt_m.by}} & 4'b0001) |
|
||||
({4{lsu_pkt_m.half}} & 4'b0011) |
|
||||
({4{lsu_pkt_m.word}} & 4'b1111);
|
||||
|
||||
// Read/Write Buffer
|
||||
el2_lsu_bus_buffer #(.pt(pt)) bus_buffer (
|
||||
.*
|
||||
);
|
||||
// Read/Write Buffer
|
||||
el2_lsu_bus_buffer #(.pt(pt)) bus_buffer (.*);
|
||||
|
||||
// Logic to determine if dc5 store can be coalesced or not with younger stores. Bypass ibuf if cannot colaesced
|
||||
assign addr_match_dw_lo_r_m = (lsu_addr_r[31:3] == lsu_addr_m[31:3]);
|
||||
assign addr_match_word_lo_r_m = addr_match_dw_lo_r_m & ~(lsu_addr_r[2]^lsu_addr_m[2]);
|
||||
// Logic to determine if dc5 store can be coalesced or not with younger stores. Bypass ibuf if cannot colaesced
|
||||
assign addr_match_dw_lo_r_m = (lsu_addr_r[31:3] == lsu_addr_m[31:3]);
|
||||
assign addr_match_word_lo_r_m = addr_match_dw_lo_r_m & ~(lsu_addr_r[2] ^ lsu_addr_m[2]);
|
||||
|
||||
assign no_word_merge_r = lsu_busreq_r & ~ldst_dual_r & lsu_busreq_m & (lsu_pkt_m.load | ~addr_match_word_lo_r_m);
|
||||
assign no_dword_merge_r = lsu_busreq_r & ~ldst_dual_r & lsu_busreq_m & (lsu_pkt_m.load | ~addr_match_dw_lo_r_m);
|
||||
assign no_word_merge_r = lsu_busreq_r & ~ldst_dual_r & lsu_busreq_m & (lsu_pkt_m.load | ~addr_match_word_lo_r_m);
|
||||
assign no_dword_merge_r = lsu_busreq_r & ~ldst_dual_r & lsu_busreq_m & (lsu_pkt_m.load | ~addr_match_dw_lo_r_m);
|
||||
|
||||
// Create Hi/Lo signals
|
||||
assign ldst_byteen_ext_m[7:0] = {4'b0,ldst_byteen_m[3:0]} << lsu_addr_m[1:0];
|
||||
assign ldst_byteen_ext_r[7:0] = {4'b0,ldst_byteen_r[3:0]} << lsu_addr_r[1:0];
|
||||
// Create Hi/Lo signals
|
||||
assign ldst_byteen_ext_m[7:0] = {4'b0, ldst_byteen_m[3:0]} << lsu_addr_m[1:0];
|
||||
assign ldst_byteen_ext_r[7:0] = {4'b0, ldst_byteen_r[3:0]} << lsu_addr_r[1:0];
|
||||
|
||||
assign store_data_ext_r[63:0] = {32'b0,store_data_r[31:0]} << {lsu_addr_r[1:0],3'b0};
|
||||
assign store_data_ext_r[63:0] = {32'b0, store_data_r[31:0]} << {lsu_addr_r[1:0], 3'b0};
|
||||
|
||||
assign ldst_byteen_hi_m[3:0] = ldst_byteen_ext_m[7:4];
|
||||
assign ldst_byteen_lo_m[3:0] = ldst_byteen_ext_m[3:0];
|
||||
assign ldst_byteen_hi_r[3:0] = ldst_byteen_ext_r[7:4];
|
||||
assign ldst_byteen_lo_r[3:0] = ldst_byteen_ext_r[3:0];
|
||||
assign ldst_byteen_hi_m[3:0] = ldst_byteen_ext_m[7:4];
|
||||
assign ldst_byteen_lo_m[3:0] = ldst_byteen_ext_m[3:0];
|
||||
assign ldst_byteen_hi_r[3:0] = ldst_byteen_ext_r[7:4];
|
||||
assign ldst_byteen_lo_r[3:0] = ldst_byteen_ext_r[3:0];
|
||||
|
||||
assign store_data_hi_r[31:0] = store_data_ext_r[63:32];
|
||||
assign store_data_lo_r[31:0] = store_data_ext_r[31:0];
|
||||
assign store_data_hi_r[31:0] = store_data_ext_r[63:32];
|
||||
assign store_data_lo_r[31:0] = store_data_ext_r[31:0];
|
||||
|
||||
assign ld_addr_rhit_lo_lo = (lsu_addr_m[31:2] == lsu_addr_r[31:2]) & lsu_pkt_r.valid & lsu_pkt_r.store & lsu_busreq_m & lsu_busreq_r;
|
||||
assign ld_addr_rhit_lo_hi = (end_addr_m[31:2] == lsu_addr_r[31:2]) & lsu_pkt_r.valid & lsu_pkt_r.store & lsu_busreq_m & lsu_busreq_r;
|
||||
assign ld_addr_rhit_hi_lo = (lsu_addr_m[31:2] == end_addr_r[31:2]) & lsu_pkt_r.valid & lsu_pkt_r.store & lsu_busreq_m & lsu_busreq_r;
|
||||
assign ld_addr_rhit_hi_hi = (end_addr_m[31:2] == end_addr_r[31:2]) & lsu_pkt_r.valid & lsu_pkt_r.store & lsu_busreq_m & lsu_busreq_r;
|
||||
assign ld_addr_rhit_lo_lo = (lsu_addr_m[31:2] == lsu_addr_r[31:2]) & lsu_pkt_r.valid & lsu_pkt_r.store & lsu_busreq_m & lsu_busreq_r;
|
||||
assign ld_addr_rhit_lo_hi = (end_addr_m[31:2] == lsu_addr_r[31:2]) & lsu_pkt_r.valid & lsu_pkt_r.store & lsu_busreq_m & lsu_busreq_r;
|
||||
assign ld_addr_rhit_hi_lo = (lsu_addr_m[31:2] == end_addr_r[31:2]) & lsu_pkt_r.valid & lsu_pkt_r.store & lsu_busreq_m & lsu_busreq_r;
|
||||
assign ld_addr_rhit_hi_hi = (end_addr_m[31:2] == end_addr_r[31:2]) & lsu_pkt_r.valid & lsu_pkt_r.store & lsu_busreq_m & lsu_busreq_r;
|
||||
|
||||
for (genvar i=0; i<4; i++) begin: GenBusBufFwd
|
||||
assign ld_byte_rhit_lo_lo[i] = ld_addr_rhit_lo_lo & ldst_byteen_lo_r[i] & ldst_byteen_lo_m[i];
|
||||
assign ld_byte_rhit_lo_hi[i] = ld_addr_rhit_lo_hi & ldst_byteen_lo_r[i] & ldst_byteen_hi_m[i];
|
||||
assign ld_byte_rhit_hi_lo[i] = ld_addr_rhit_hi_lo & ldst_byteen_hi_r[i] & ldst_byteen_lo_m[i];
|
||||
assign ld_byte_rhit_hi_hi[i] = ld_addr_rhit_hi_hi & ldst_byteen_hi_r[i] & ldst_byteen_hi_m[i];
|
||||
for (genvar i = 0; i < 4; i++) begin : GenBusBufFwd
|
||||
assign ld_byte_rhit_lo_lo[i] = ld_addr_rhit_lo_lo & ldst_byteen_lo_r[i] & ldst_byteen_lo_m[i];
|
||||
assign ld_byte_rhit_lo_hi[i] = ld_addr_rhit_lo_hi & ldst_byteen_lo_r[i] & ldst_byteen_hi_m[i];
|
||||
assign ld_byte_rhit_hi_lo[i] = ld_addr_rhit_hi_lo & ldst_byteen_hi_r[i] & ldst_byteen_lo_m[i];
|
||||
assign ld_byte_rhit_hi_hi[i] = ld_addr_rhit_hi_hi & ldst_byteen_hi_r[i] & ldst_byteen_hi_m[i];
|
||||
|
||||
assign ld_byte_hit_lo[i] = ld_byte_rhit_lo_lo[i] | ld_byte_rhit_hi_lo[i] |
|
||||
assign ld_byte_hit_lo[i] = ld_byte_rhit_lo_lo[i] | ld_byte_rhit_hi_lo[i] |
|
||||
ld_byte_hit_buf_lo[i];
|
||||
|
||||
assign ld_byte_hit_hi[i] = ld_byte_rhit_lo_hi[i] | ld_byte_rhit_hi_hi[i] |
|
||||
assign ld_byte_hit_hi[i] = ld_byte_rhit_lo_hi[i] | ld_byte_rhit_hi_hi[i] |
|
||||
ld_byte_hit_buf_hi[i];
|
||||
|
||||
assign ld_byte_rhit_lo[i] = ld_byte_rhit_lo_lo[i] | ld_byte_rhit_hi_lo[i];
|
||||
assign ld_byte_rhit_hi[i] = ld_byte_rhit_lo_hi[i] | ld_byte_rhit_hi_hi[i];
|
||||
assign ld_byte_rhit_lo[i] = ld_byte_rhit_lo_lo[i] | ld_byte_rhit_hi_lo[i];
|
||||
assign ld_byte_rhit_hi[i] = ld_byte_rhit_lo_hi[i] | ld_byte_rhit_hi_hi[i];
|
||||
|
||||
assign ld_fwddata_rpipe_lo[(8*i)+7:(8*i)] = ({8{ld_byte_rhit_lo_lo[i]}} & store_data_lo_r[(8*i)+7:(8*i)]) |
|
||||
assign ld_fwddata_rpipe_lo[(8*i)+7:(8*i)] = ({8{ld_byte_rhit_lo_lo[i]}} & store_data_lo_r[(8*i)+7:(8*i)]) |
|
||||
({8{ld_byte_rhit_hi_lo[i]}} & store_data_hi_r[(8*i)+7:(8*i)]);
|
||||
|
||||
assign ld_fwddata_rpipe_hi[(8*i)+7:(8*i)] = ({8{ld_byte_rhit_lo_hi[i]}} & store_data_lo_r[(8*i)+7:(8*i)]) |
|
||||
assign ld_fwddata_rpipe_hi[(8*i)+7:(8*i)] = ({8{ld_byte_rhit_lo_hi[i]}} & store_data_lo_r[(8*i)+7:(8*i)]) |
|
||||
({8{ld_byte_rhit_hi_hi[i]}} & store_data_hi_r[(8*i)+7:(8*i)]);
|
||||
|
||||
// Final muxing between m/r
|
||||
assign ld_fwddata_lo[(8*i)+7:(8*i)] = ld_byte_rhit_lo[i] ? ld_fwddata_rpipe_lo[(8*i)+7:(8*i)] : ld_fwddata_buf_lo[(8*i)+7:(8*i)];
|
||||
// Final muxing between m/r
|
||||
assign ld_fwddata_lo[(8*i)+7:(8*i)] = ld_byte_rhit_lo[i] ? ld_fwddata_rpipe_lo[(8*i)+7:(8*i)] : ld_fwddata_buf_lo[(8*i)+7:(8*i)];
|
||||
|
||||
assign ld_fwddata_hi[(8*i)+7:(8*i)] = ld_byte_rhit_hi[i] ? ld_fwddata_rpipe_hi[(8*i)+7:(8*i)] : ld_fwddata_buf_hi[(8*i)+7:(8*i)];
|
||||
assign ld_fwddata_hi[(8*i)+7:(8*i)] = ld_byte_rhit_hi[i] ? ld_fwddata_rpipe_hi[(8*i)+7:(8*i)] : ld_fwddata_buf_hi[(8*i)+7:(8*i)];
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
ld_full_hit_lo_m = 1'b1;
|
||||
ld_full_hit_hi_m = 1'b1;
|
||||
for (int i=0; i<4; i++) begin
|
||||
ld_full_hit_lo_m &= (ld_byte_hit_lo[i] | ~ldst_byteen_lo_m[i]);
|
||||
ld_full_hit_hi_m &= (ld_byte_hit_hi[i] | ~ldst_byteen_hi_m[i]);
|
||||
end
|
||||
end
|
||||
always_comb begin
|
||||
ld_full_hit_lo_m = 1'b1;
|
||||
ld_full_hit_hi_m = 1'b1;
|
||||
for (int i = 0; i < 4; i++) begin
|
||||
ld_full_hit_lo_m &= (ld_byte_hit_lo[i] | ~ldst_byteen_lo_m[i]);
|
||||
ld_full_hit_hi_m &= (ld_byte_hit_hi[i] | ~ldst_byteen_hi_m[i]);
|
||||
end
|
||||
end
|
||||
|
||||
// This will be high if all the bytes of load hit the stores in pipe/write buffer (m/r/wrbuf)
|
||||
assign ld_full_hit_m = ld_full_hit_lo_m & ld_full_hit_hi_m & lsu_busreq_m & lsu_pkt_m.load & ~is_sideeffects_m;
|
||||
// This will be high if all the bytes of load hit the stores in pipe/write buffer (m/r/wrbuf)
|
||||
assign ld_full_hit_m = ld_full_hit_lo_m & ld_full_hit_hi_m & lsu_busreq_m & lsu_pkt_m.load & ~is_sideeffects_m;
|
||||
|
||||
assign ld_fwddata_m[63:0] = {ld_fwddata_hi[31:0], ld_fwddata_lo[31:0]} >> (8*lsu_addr_m[1:0]);
|
||||
assign bus_read_data_m[31:0] = ld_fwddata_m[31:0];
|
||||
assign ld_fwddata_m[63:0] = {ld_fwddata_hi[31:0], ld_fwddata_lo[31:0]} >> (8 * lsu_addr_m[1:0]);
|
||||
assign bus_read_data_m[31:0] = ld_fwddata_m[31:0];
|
||||
|
||||
// Fifo flops
|
||||
// Fifo flops
|
||||
|
||||
rvdff #(.WIDTH(1)) clken_ff (.din(lsu_bus_clk_en), .dout(lsu_bus_clk_en_q), .clk(active_clk), .*);
|
||||
rvdff #(
|
||||
.WIDTH(1)
|
||||
) clken_ff (
|
||||
.din (lsu_bus_clk_en),
|
||||
.dout(lsu_bus_clk_en_q),
|
||||
.clk (active_clk),
|
||||
.*
|
||||
);
|
||||
|
||||
rvdff #(.WIDTH(1)) is_sideeffects_rff (.din(is_sideeffects_m), .dout(is_sideeffects_r), .clk(lsu_c1_r_clk), .*);
|
||||
rvdff #(
|
||||
.WIDTH(1)
|
||||
) is_sideeffects_rff (
|
||||
.din (is_sideeffects_m),
|
||||
.dout(is_sideeffects_r),
|
||||
.clk (lsu_c1_r_clk),
|
||||
.*
|
||||
);
|
||||
|
||||
rvdff #(4) lsu_byten_rff (.*, .din(ldst_byteen_m[3:0]), .dout(ldst_byteen_r[3:0]), .clk(lsu_c1_r_clk));
|
||||
rvdff #(4) lsu_byten_rff (
|
||||
.*,
|
||||
.din (ldst_byteen_m[3:0]),
|
||||
.dout(ldst_byteen_r[3:0]),
|
||||
.clk (lsu_c1_r_clk)
|
||||
);
|
||||
|
||||
endmodule // el2_lsu_bus_intf
|
||||
endmodule // el2_lsu_bus_intf
|
||||
|
|
|
@ -24,117 +24,180 @@
|
|||
|
||||
|
||||
module el2_lsu_clkdomain
|
||||
import el2_pkg::*;
|
||||
import el2_pkg::*;
|
||||
#(
|
||||
`include "el2_param.vh"
|
||||
)(
|
||||
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
|
||||
input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in.
|
||||
input logic rst_l, // reset, active low
|
||||
input logic dec_tlu_force_halt, // This will be high till TLU goes to debug halt
|
||||
`include "el2_param.vh"
|
||||
) (
|
||||
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
|
||||
input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in.
|
||||
input logic rst_l, // reset, active low
|
||||
input logic dec_tlu_force_halt, // This will be high till TLU goes to debug halt
|
||||
|
||||
// Inputs
|
||||
input logic clk_override, // chciken bit to turn off clock gating
|
||||
input logic dma_dccm_req, // dma is active
|
||||
input logic ldst_stbuf_reqvld_r, // allocating in to the store queue
|
||||
// Inputs
|
||||
input logic clk_override, // chciken bit to turn off clock gating
|
||||
input logic dma_dccm_req, // dma is active
|
||||
input logic ldst_stbuf_reqvld_r, // allocating in to the store queue
|
||||
|
||||
input logic stbuf_reqvld_any, // stbuf is draining
|
||||
input logic stbuf_reqvld_flushed_any, // instruction going to stbuf is flushed
|
||||
input logic lsu_busreq_r, // busreq in r
|
||||
input logic lsu_bus_buffer_pend_any, // bus buffer has a pending bus entry
|
||||
input logic lsu_bus_buffer_empty_any, // external bus buffer is empty
|
||||
input logic lsu_stbuf_empty_any, // stbuf is empty
|
||||
input logic stbuf_reqvld_any, // stbuf is draining
|
||||
input logic stbuf_reqvld_flushed_any, // instruction going to stbuf is flushed
|
||||
input logic lsu_busreq_r, // busreq in r
|
||||
input logic lsu_bus_buffer_pend_any, // bus buffer has a pending bus entry
|
||||
input logic lsu_bus_buffer_empty_any, // external bus buffer is empty
|
||||
input logic lsu_stbuf_empty_any, // stbuf is empty
|
||||
|
||||
input logic lsu_bus_clk_en, // bus clock enable
|
||||
input logic lsu_bus_clk_en, // bus clock enable
|
||||
|
||||
input el2_lsu_pkt_t lsu_p, // lsu packet in decode
|
||||
input el2_lsu_pkt_t lsu_pkt_d, // lsu packet in d
|
||||
input el2_lsu_pkt_t lsu_pkt_m, // lsu packet in m
|
||||
input el2_lsu_pkt_t lsu_pkt_r, // lsu packet in r
|
||||
input el2_lsu_pkt_t lsu_p, // lsu packet in decode
|
||||
input el2_lsu_pkt_t lsu_pkt_d, // lsu packet in d
|
||||
input el2_lsu_pkt_t lsu_pkt_m, // lsu packet in m
|
||||
input el2_lsu_pkt_t lsu_pkt_r, // lsu packet in r
|
||||
|
||||
// Outputs
|
||||
output logic lsu_bus_obuf_c1_clken, // obuf clock enable
|
||||
output logic lsu_busm_clken, // bus clock enable
|
||||
// Outputs
|
||||
output logic lsu_bus_obuf_c1_clken, // obuf clock enable
|
||||
output logic lsu_busm_clken, // bus clock enable
|
||||
|
||||
output logic lsu_c1_m_clk, // m pipe single pulse clock
|
||||
output logic lsu_c1_r_clk, // r pipe single pulse clock
|
||||
output logic lsu_c1_m_clk, // m pipe single pulse clock
|
||||
output logic lsu_c1_r_clk, // r pipe single pulse clock
|
||||
|
||||
output logic lsu_c2_m_clk, // m pipe double pulse clock
|
||||
output logic lsu_c2_r_clk, // r pipe double pulse clock
|
||||
output logic lsu_c2_m_clk, // m pipe double pulse clock
|
||||
output logic lsu_c2_r_clk, // r pipe double pulse clock
|
||||
|
||||
output logic lsu_store_c1_m_clk, // store in m
|
||||
output logic lsu_store_c1_r_clk, // store in r
|
||||
output logic lsu_store_c1_m_clk, // store in m
|
||||
output logic lsu_store_c1_r_clk, // store in r
|
||||
|
||||
output logic lsu_stbuf_c1_clk,
|
||||
output logic lsu_bus_obuf_c1_clk, // ibuf clock
|
||||
output logic lsu_bus_ibuf_c1_clk, // ibuf clock
|
||||
output logic lsu_bus_buf_c1_clk, // ibuf clock
|
||||
output logic lsu_busm_clk, // bus clock
|
||||
output logic lsu_stbuf_c1_clk,
|
||||
output logic lsu_bus_obuf_c1_clk, // ibuf clock
|
||||
output logic lsu_bus_ibuf_c1_clk, // ibuf clock
|
||||
output logic lsu_bus_buf_c1_clk, // ibuf clock
|
||||
output logic lsu_busm_clk, // bus clock
|
||||
|
||||
output logic lsu_free_c2_clk, // free double pulse clock
|
||||
output logic lsu_free_c2_clk, // free double pulse clock
|
||||
|
||||
input logic scan_mode // Scan mode
|
||||
input logic scan_mode // Scan mode
|
||||
);
|
||||
|
||||
logic lsu_c1_m_clken, lsu_c1_r_clken;
|
||||
logic lsu_c2_m_clken, lsu_c2_r_clken;
|
||||
logic lsu_c1_m_clken_q, lsu_c1_r_clken_q;
|
||||
logic lsu_store_c1_m_clken, lsu_store_c1_r_clken;
|
||||
logic lsu_c1_m_clken, lsu_c1_r_clken;
|
||||
logic lsu_c2_m_clken, lsu_c2_r_clken;
|
||||
logic lsu_c1_m_clken_q, lsu_c1_r_clken_q;
|
||||
logic lsu_store_c1_m_clken, lsu_store_c1_r_clken;
|
||||
|
||||
|
||||
logic lsu_stbuf_c1_clken;
|
||||
logic lsu_bus_ibuf_c1_clken, lsu_bus_buf_c1_clken;
|
||||
logic lsu_stbuf_c1_clken;
|
||||
logic lsu_bus_ibuf_c1_clken, lsu_bus_buf_c1_clken;
|
||||
|
||||
logic lsu_free_c1_clken, lsu_free_c1_clken_q, lsu_free_c2_clken;
|
||||
logic lsu_free_c1_clken, lsu_free_c1_clken_q, lsu_free_c2_clken;
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
// Clock Enable logic
|
||||
//-------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------
|
||||
// Clock Enable logic
|
||||
//-------------------------------------------------------------------------------------------
|
||||
|
||||
assign lsu_c1_m_clken = lsu_p.valid | dma_dccm_req | clk_override;
|
||||
assign lsu_c1_r_clken = lsu_pkt_m.valid | lsu_c1_m_clken_q | clk_override;
|
||||
assign lsu_c1_m_clken = lsu_p.valid | dma_dccm_req | clk_override;
|
||||
assign lsu_c1_r_clken = lsu_pkt_m.valid | lsu_c1_m_clken_q | clk_override;
|
||||
|
||||
assign lsu_c2_m_clken = lsu_c1_m_clken | lsu_c1_m_clken_q | clk_override;
|
||||
assign lsu_c2_r_clken = lsu_c1_r_clken | lsu_c1_r_clken_q | clk_override;
|
||||
assign lsu_c2_m_clken = lsu_c1_m_clken | lsu_c1_m_clken_q | clk_override;
|
||||
assign lsu_c2_r_clken = lsu_c1_r_clken | lsu_c1_r_clken_q | clk_override;
|
||||
|
||||
assign lsu_store_c1_m_clken = ((lsu_c1_m_clken & lsu_pkt_d.store) | clk_override) ;
|
||||
assign lsu_store_c1_r_clken = ((lsu_c1_r_clken & lsu_pkt_m.store) | clk_override) ;
|
||||
assign lsu_store_c1_m_clken = ((lsu_c1_m_clken & lsu_pkt_d.store) | clk_override);
|
||||
assign lsu_store_c1_r_clken = ((lsu_c1_r_clken & lsu_pkt_m.store) | clk_override);
|
||||
|
||||
assign lsu_stbuf_c1_clken = ldst_stbuf_reqvld_r | stbuf_reqvld_any | stbuf_reqvld_flushed_any | clk_override;
|
||||
assign lsu_bus_ibuf_c1_clken = lsu_busreq_r | clk_override;
|
||||
assign lsu_bus_obuf_c1_clken = (lsu_bus_buffer_pend_any | lsu_busreq_r | clk_override) & lsu_bus_clk_en;
|
||||
assign lsu_bus_buf_c1_clken = ~lsu_bus_buffer_empty_any | lsu_busreq_r | dec_tlu_force_halt | clk_override;
|
||||
assign lsu_stbuf_c1_clken = ldst_stbuf_reqvld_r | stbuf_reqvld_any | stbuf_reqvld_flushed_any | clk_override;
|
||||
assign lsu_bus_ibuf_c1_clken = lsu_busreq_r | clk_override;
|
||||
assign lsu_bus_obuf_c1_clken = (lsu_bus_buffer_pend_any | lsu_busreq_r | clk_override) & lsu_bus_clk_en;
|
||||
assign lsu_bus_buf_c1_clken = ~lsu_bus_buffer_empty_any | lsu_busreq_r | dec_tlu_force_halt | clk_override;
|
||||
|
||||
assign lsu_free_c1_clken = (lsu_p.valid | lsu_pkt_d.valid | lsu_pkt_m.valid | lsu_pkt_r.valid) |
|
||||
assign lsu_free_c1_clken = (lsu_p.valid | lsu_pkt_d.valid | lsu_pkt_m.valid | lsu_pkt_r.valid) |
|
||||
~lsu_bus_buffer_empty_any | ~lsu_stbuf_empty_any | clk_override;
|
||||
assign lsu_free_c2_clken = lsu_free_c1_clken | lsu_free_c1_clken_q | clk_override;
|
||||
assign lsu_free_c2_clken = lsu_free_c1_clken | lsu_free_c1_clken_q | clk_override;
|
||||
|
||||
// Flops
|
||||
rvdff #(1) lsu_free_c1_clkenff (.din(lsu_free_c1_clken), .dout(lsu_free_c1_clken_q), .clk(active_clk), .*);
|
||||
// Flops
|
||||
rvdff #(1) lsu_free_c1_clkenff (
|
||||
.din (lsu_free_c1_clken),
|
||||
.dout(lsu_free_c1_clken_q),
|
||||
.clk (active_clk),
|
||||
.*
|
||||
);
|
||||
|
||||
rvdff #(1) lsu_c1_m_clkenff (.din(lsu_c1_m_clken), .dout(lsu_c1_m_clken_q), .clk(lsu_free_c2_clk), .*);
|
||||
rvdff #(1) lsu_c1_r_clkenff (.din(lsu_c1_r_clken), .dout(lsu_c1_r_clken_q), .clk(lsu_free_c2_clk), .*);
|
||||
rvdff #(1) lsu_c1_m_clkenff (
|
||||
.din (lsu_c1_m_clken),
|
||||
.dout(lsu_c1_m_clken_q),
|
||||
.clk (lsu_free_c2_clk),
|
||||
.*
|
||||
);
|
||||
rvdff #(1) lsu_c1_r_clkenff (
|
||||
.din (lsu_c1_r_clken),
|
||||
.dout(lsu_c1_r_clken_q),
|
||||
.clk (lsu_free_c2_clk),
|
||||
.*
|
||||
);
|
||||
|
||||
// Clock Headers
|
||||
rvoclkhdr lsu_c1m_cgc ( .en(lsu_c1_m_clken), .l1clk(lsu_c1_m_clk), .* );
|
||||
rvoclkhdr lsu_c1r_cgc ( .en(lsu_c1_r_clken), .l1clk(lsu_c1_r_clk), .* );
|
||||
// Clock Headers
|
||||
rvoclkhdr lsu_c1m_cgc (
|
||||
.en(lsu_c1_m_clken),
|
||||
.l1clk(lsu_c1_m_clk),
|
||||
.*
|
||||
);
|
||||
rvoclkhdr lsu_c1r_cgc (
|
||||
.en(lsu_c1_r_clken),
|
||||
.l1clk(lsu_c1_r_clk),
|
||||
.*
|
||||
);
|
||||
|
||||
rvoclkhdr lsu_c2m_cgc ( .en(lsu_c2_m_clken), .l1clk(lsu_c2_m_clk), .* );
|
||||
rvoclkhdr lsu_c2r_cgc ( .en(lsu_c2_r_clken), .l1clk(lsu_c2_r_clk), .* );
|
||||
rvoclkhdr lsu_c2m_cgc (
|
||||
.en(lsu_c2_m_clken),
|
||||
.l1clk(lsu_c2_m_clk),
|
||||
.*
|
||||
);
|
||||
rvoclkhdr lsu_c2r_cgc (
|
||||
.en(lsu_c2_r_clken),
|
||||
.l1clk(lsu_c2_r_clk),
|
||||
.*
|
||||
);
|
||||
|
||||
rvoclkhdr lsu_store_c1m_cgc (.en(lsu_store_c1_m_clken), .l1clk(lsu_store_c1_m_clk), .*);
|
||||
rvoclkhdr lsu_store_c1r_cgc (.en(lsu_store_c1_r_clken), .l1clk(lsu_store_c1_r_clk), .*);
|
||||
rvoclkhdr lsu_store_c1m_cgc (
|
||||
.en(lsu_store_c1_m_clken),
|
||||
.l1clk(lsu_store_c1_m_clk),
|
||||
.*
|
||||
);
|
||||
rvoclkhdr lsu_store_c1r_cgc (
|
||||
.en(lsu_store_c1_r_clken),
|
||||
.l1clk(lsu_store_c1_r_clk),
|
||||
.*
|
||||
);
|
||||
|
||||
rvoclkhdr lsu_stbuf_c1_cgc ( .en(lsu_stbuf_c1_clken), .l1clk(lsu_stbuf_c1_clk), .* );
|
||||
rvoclkhdr lsu_bus_ibuf_c1_cgc ( .en(lsu_bus_ibuf_c1_clken), .l1clk(lsu_bus_ibuf_c1_clk), .* );
|
||||
rvoclkhdr lsu_bus_buf_c1_cgc ( .en(lsu_bus_buf_c1_clken), .l1clk(lsu_bus_buf_c1_clk), .* );
|
||||
rvoclkhdr lsu_stbuf_c1_cgc (
|
||||
.en(lsu_stbuf_c1_clken),
|
||||
.l1clk(lsu_stbuf_c1_clk),
|
||||
.*
|
||||
);
|
||||
rvoclkhdr lsu_bus_ibuf_c1_cgc (
|
||||
.en(lsu_bus_ibuf_c1_clken),
|
||||
.l1clk(lsu_bus_ibuf_c1_clk),
|
||||
.*
|
||||
);
|
||||
rvoclkhdr lsu_bus_buf_c1_cgc (
|
||||
.en(lsu_bus_buf_c1_clken),
|
||||
.l1clk(lsu_bus_buf_c1_clk),
|
||||
.*
|
||||
);
|
||||
|
||||
assign lsu_busm_clken = (~lsu_bus_buffer_empty_any | lsu_busreq_r | clk_override) & lsu_bus_clk_en;
|
||||
assign lsu_busm_clken = (~lsu_bus_buffer_empty_any | lsu_busreq_r | clk_override) & lsu_bus_clk_en;
|
||||
|
||||
rvclkhdr lsu_bus_obuf_c1_cgc ( .en(lsu_bus_obuf_c1_clken), .l1clk(lsu_bus_obuf_c1_clk), .* );
|
||||
rvclkhdr lsu_busm_cgc (.en(lsu_busm_clken), .l1clk(lsu_busm_clk), .*);
|
||||
rvclkhdr lsu_bus_obuf_c1_cgc (
|
||||
.en(lsu_bus_obuf_c1_clken),
|
||||
.l1clk(lsu_bus_obuf_c1_clk),
|
||||
.*
|
||||
);
|
||||
rvclkhdr lsu_busm_cgc (
|
||||
.en(lsu_busm_clken),
|
||||
.l1clk(lsu_busm_clk),
|
||||
.*
|
||||
);
|
||||
|
||||
rvoclkhdr lsu_free_cgc (.en(lsu_free_c2_clken), .l1clk(lsu_free_c2_clk), .*);
|
||||
rvoclkhdr lsu_free_cgc (
|
||||
.en(lsu_free_c2_clken),
|
||||
.l1clk(lsu_free_c2_clk),
|
||||
.*
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
|
@ -27,387 +27,506 @@
|
|||
// //********************************************************************************
|
||||
|
||||
module el2_lsu_dccm_ctl
|
||||
import el2_pkg::*;
|
||||
import el2_pkg::*;
|
||||
#(
|
||||
`include "el2_param.vh"
|
||||
)
|
||||
(
|
||||
input logic lsu_c2_m_clk, // clocks
|
||||
input logic lsu_c2_r_clk, // clocks
|
||||
input logic lsu_c1_r_clk, // clocks
|
||||
input logic lsu_store_c1_r_clk, // clocks
|
||||
input logic lsu_free_c2_clk, // clocks
|
||||
input logic clk_override, // Override non-functional clock gating
|
||||
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
|
||||
`include "el2_param.vh"
|
||||
) (
|
||||
input logic lsu_c2_m_clk, // clocks
|
||||
input logic lsu_c2_r_clk, // clocks
|
||||
input logic lsu_c1_r_clk, // clocks
|
||||
input logic lsu_store_c1_r_clk, // clocks
|
||||
input logic lsu_free_c2_clk, // clocks
|
||||
input logic clk_override, // Override non-functional clock gating
|
||||
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
|
||||
|
||||
input logic rst_l, // reset, active low
|
||||
input logic rst_l, // reset, active low
|
||||
|
||||
input el2_lsu_pkt_t lsu_pkt_r,// lsu packets
|
||||
input el2_lsu_pkt_t lsu_pkt_m,// lsu packets
|
||||
input el2_lsu_pkt_t lsu_pkt_d,// lsu packets
|
||||
input logic addr_in_dccm_d, // address maps to dccm
|
||||
input logic addr_in_pic_d, // address maps to pic
|
||||
input logic addr_in_pic_m, // address maps to pic
|
||||
input logic addr_in_dccm_m, addr_in_dccm_r, // address in dccm per pipe stage
|
||||
input logic addr_in_pic_r, // address in pic per pipe stage
|
||||
input logic lsu_raw_fwd_lo_r, lsu_raw_fwd_hi_r,
|
||||
input logic lsu_commit_r, // lsu instruction in r commits
|
||||
input logic ldst_dual_m, ldst_dual_r,// load/store is unaligned at 32 bit boundary per pipe stage
|
||||
input el2_lsu_pkt_t lsu_pkt_r, // lsu packets
|
||||
input el2_lsu_pkt_t lsu_pkt_m, // lsu packets
|
||||
input el2_lsu_pkt_t lsu_pkt_d, // lsu packets
|
||||
input logic addr_in_dccm_d, // address maps to dccm
|
||||
input logic addr_in_pic_d, // address maps to pic
|
||||
input logic addr_in_pic_m, // address maps to pic
|
||||
input logic addr_in_dccm_m,
|
||||
addr_in_dccm_r, // address in dccm per pipe stage
|
||||
input logic addr_in_pic_r, // address in pic per pipe stage
|
||||
input logic lsu_raw_fwd_lo_r,
|
||||
lsu_raw_fwd_hi_r,
|
||||
input logic lsu_commit_r, // lsu instruction in r commits
|
||||
input logic ldst_dual_m,
|
||||
ldst_dual_r, // load/store is unaligned at 32 bit boundary per pipe stage
|
||||
|
||||
// lsu address down the pipe
|
||||
input logic [31:0] lsu_addr_d,
|
||||
input logic [pt.DCCM_BITS-1:0] lsu_addr_m,
|
||||
input logic [31:0] lsu_addr_r,
|
||||
// lsu address down the pipe
|
||||
input logic [ 31:0] lsu_addr_d,
|
||||
input logic [pt.DCCM_BITS-1:0] lsu_addr_m,
|
||||
input logic [ 31:0] lsu_addr_r,
|
||||
|
||||
// lsu address down the pipe - needed to check unaligned
|
||||
input logic [pt.DCCM_BITS-1:0] end_addr_d,
|
||||
input logic [pt.DCCM_BITS-1:0] end_addr_m,
|
||||
input logic [pt.DCCM_BITS-1:0] end_addr_r,
|
||||
// lsu address down the pipe - needed to check unaligned
|
||||
input logic [pt.DCCM_BITS-1:0] end_addr_d,
|
||||
input logic [pt.DCCM_BITS-1:0] end_addr_m,
|
||||
input logic [pt.DCCM_BITS-1:0] end_addr_r,
|
||||
|
||||
|
||||
input logic stbuf_reqvld_any, // write enable
|
||||
input logic [pt.LSU_SB_BITS-1:0] stbuf_addr_any, // stbuf address (aligned)
|
||||
input logic stbuf_reqvld_any, // write enable
|
||||
input logic [pt.LSU_SB_BITS-1:0] stbuf_addr_any, // stbuf address (aligned)
|
||||
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_data_any, // the read out from stbuf
|
||||
input logic [pt.DCCM_ECC_WIDTH-1:0] stbuf_ecc_any, // the encoded data with ECC bits
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_fwddata_hi_m, // stbuf fowarding to load
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_fwddata_lo_m, // stbuf fowarding to load
|
||||
input logic [pt.DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_hi_m, // stbuf fowarding to load
|
||||
input logic [pt.DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_m, // stbuf fowarding to load
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_data_any, // the read out from stbuf
|
||||
input logic [ pt.DCCM_ECC_WIDTH-1:0] stbuf_ecc_any, // the encoded data with ECC bits
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_fwddata_hi_m, // stbuf fowarding to load
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_fwddata_lo_m, // stbuf fowarding to load
|
||||
input logic [pt.DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_hi_m, // stbuf fowarding to load
|
||||
input logic [pt.DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_m, // stbuf fowarding to load
|
||||
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] dccm_rdata_hi_r, // data from the dccm
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] dccm_rdata_lo_r, // data from the dccm
|
||||
output logic [pt.DCCM_ECC_WIDTH-1:0] dccm_data_ecc_hi_r, // data from the dccm + ecc
|
||||
output logic [pt.DCCM_ECC_WIDTH-1:0] dccm_data_ecc_lo_r,
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] lsu_ld_data_r, // right justified, ie load byte will have data at 7:0
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] lsu_ld_data_corr_r, // right justified & ECC corrected, ie load byte will have data at 7:0
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] dccm_rdata_hi_r, // data from the dccm
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] dccm_rdata_lo_r, // data from the dccm
|
||||
output logic [pt.DCCM_ECC_WIDTH-1:0] dccm_data_ecc_hi_r, // data from the dccm + ecc
|
||||
output logic [pt.DCCM_ECC_WIDTH-1:0] dccm_data_ecc_lo_r,
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] lsu_ld_data_r, // right justified, ie load byte will have data at 7:0
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] lsu_ld_data_corr_r, // right justified & ECC corrected, ie load byte will have data at 7:0
|
||||
|
||||
input logic lsu_double_ecc_error_r, // lsu has a DED
|
||||
input logic single_ecc_error_hi_r, // sec detected on hi dccm bank
|
||||
input logic single_ecc_error_lo_r, // sec detected on lower dccm bank
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_hi_r, // corrected dccm data
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_lo_r, // corrected dccm data
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_hi_r_ff, // corrected dccm data
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_lo_r_ff, // corrected dccm data
|
||||
input logic [pt.DCCM_ECC_WIDTH-1:0] sec_data_ecc_hi_r_ff, // the encoded data with ECC bits
|
||||
input logic [pt.DCCM_ECC_WIDTH-1:0] sec_data_ecc_lo_r_ff, // the encoded data with ECC bits
|
||||
input logic lsu_double_ecc_error_r, // lsu has a DED
|
||||
input logic single_ecc_error_hi_r, // sec detected on hi dccm bank
|
||||
input logic single_ecc_error_lo_r, // sec detected on lower dccm bank
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_hi_r, // corrected dccm data
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_lo_r, // corrected dccm data
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_hi_r_ff, // corrected dccm data
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_lo_r_ff, // corrected dccm data
|
||||
input logic [ pt.DCCM_ECC_WIDTH-1:0] sec_data_ecc_hi_r_ff, // the encoded data with ECC bits
|
||||
input logic [ pt.DCCM_ECC_WIDTH-1:0] sec_data_ecc_lo_r_ff, // the encoded data with ECC bits
|
||||
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] dccm_rdata_hi_m, // data from the dccm
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] dccm_rdata_lo_m, // data from the dccm
|
||||
output logic [pt.DCCM_ECC_WIDTH-1:0] dccm_data_ecc_hi_m, // data from the dccm + ecc
|
||||
output logic [pt.DCCM_ECC_WIDTH-1:0] dccm_data_ecc_lo_m,
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] lsu_ld_data_m, // right justified, ie load byte will have data at 7:0
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] dccm_rdata_hi_m, // data from the dccm
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] dccm_rdata_lo_m, // data from the dccm
|
||||
output logic [pt.DCCM_ECC_WIDTH-1:0] dccm_data_ecc_hi_m, // data from the dccm + ecc
|
||||
output logic [pt.DCCM_ECC_WIDTH-1:0] dccm_data_ecc_lo_m,
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] lsu_ld_data_m, // right justified, ie load byte will have data at 7:0
|
||||
|
||||
input logic lsu_double_ecc_error_m, // lsu has a DED
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_hi_m, // corrected dccm data
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_lo_m, // corrected dccm data
|
||||
input logic lsu_double_ecc_error_m, // lsu has a DED
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_hi_m, // corrected dccm data
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_lo_m, // corrected dccm data
|
||||
|
||||
input logic [31:0] store_data_m, // Store data M-stage
|
||||
input logic dma_dccm_wen, // Perform DMA writes only for word/dword
|
||||
input logic dma_pic_wen, // Perform PIC writes
|
||||
input logic [2:0] dma_mem_tag_m, // DMA Buffer entry number M-stage
|
||||
input logic [31:0] dma_mem_addr, // DMA request address
|
||||
input logic [63:0] dma_mem_wdata, // DMA write data
|
||||
input logic [31:0] dma_dccm_wdata_lo, // Shift the dma data to lower bits to make it consistent to lsu stores
|
||||
input logic [31:0] dma_dccm_wdata_hi, // Shift the dma data to lower bits to make it consistent to lsu stores
|
||||
input logic [pt.DCCM_ECC_WIDTH-1:0] dma_dccm_wdata_ecc_hi, // ECC bits for the DMA wdata
|
||||
input logic [pt.DCCM_ECC_WIDTH-1:0] dma_dccm_wdata_ecc_lo, // ECC bits for the DMA wdata
|
||||
input logic [31:0] store_data_m, // Store data M-stage
|
||||
input logic dma_dccm_wen, // Perform DMA writes only for word/dword
|
||||
input logic dma_pic_wen, // Perform PIC writes
|
||||
input logic [2:0] dma_mem_tag_m, // DMA Buffer entry number M-stage
|
||||
input logic [31:0] dma_mem_addr, // DMA request address
|
||||
input logic [63:0] dma_mem_wdata, // DMA write data
|
||||
input logic [31:0] dma_dccm_wdata_lo, // Shift the dma data to lower bits to make it consistent to lsu stores
|
||||
input logic [31:0] dma_dccm_wdata_hi, // Shift the dma data to lower bits to make it consistent to lsu stores
|
||||
input logic [pt.DCCM_ECC_WIDTH-1:0] dma_dccm_wdata_ecc_hi, // ECC bits for the DMA wdata
|
||||
input logic [pt.DCCM_ECC_WIDTH-1:0] dma_dccm_wdata_ecc_lo, // ECC bits for the DMA wdata
|
||||
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] store_data_hi_r,
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] store_data_lo_r,
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] store_datafn_hi_r, // data from the dccm
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] store_datafn_lo_r, // data from the dccm
|
||||
output logic [31:0] store_data_r, // raw store data to be sent to bus
|
||||
output logic ld_single_ecc_error_r,
|
||||
output logic ld_single_ecc_error_r_ff,
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] store_data_hi_r,
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] store_data_lo_r,
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] store_datafn_hi_r, // data from the dccm
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] store_datafn_lo_r, // data from the dccm
|
||||
output logic [31:0] store_data_r, // raw store data to be sent to bus
|
||||
output logic ld_single_ecc_error_r,
|
||||
output logic ld_single_ecc_error_r_ff,
|
||||
|
||||
output logic [31:0] picm_mask_data_m, // pic data to stbuf
|
||||
output logic lsu_stbuf_commit_any, // stbuf wins the dccm port or is to pic
|
||||
output logic lsu_dccm_rden_m, // dccm read
|
||||
output logic lsu_dccm_rden_r, // dccm read
|
||||
output logic [31:0] picm_mask_data_m, // pic data to stbuf
|
||||
output logic lsu_stbuf_commit_any, // stbuf wins the dccm port or is to pic
|
||||
output logic lsu_dccm_rden_m, // dccm read
|
||||
output logic lsu_dccm_rden_r, // dccm read
|
||||
|
||||
output logic dccm_dma_rvalid, // dccm serviving the dma load
|
||||
output logic dccm_dma_ecc_error, // DMA load had ecc error
|
||||
output logic [2:0] dccm_dma_rtag, // DMA return tag
|
||||
output logic [63:0] dccm_dma_rdata, // dccm data to dma request
|
||||
output logic dccm_dma_rvalid, // dccm serviving the dma load
|
||||
output logic dccm_dma_ecc_error, // DMA load had ecc error
|
||||
output logic [ 2:0] dccm_dma_rtag, // DMA return tag
|
||||
output logic [63:0] dccm_dma_rdata, // dccm data to dma request
|
||||
|
||||
// DCCM ports
|
||||
output logic dccm_wren, // dccm interface -- write
|
||||
output logic dccm_rden, // dccm interface -- write
|
||||
output logic [pt.DCCM_BITS-1:0] dccm_wr_addr_lo, // dccm interface -- wr addr for lo bank
|
||||
output logic [pt.DCCM_BITS-1:0] dccm_wr_addr_hi, // dccm interface -- wr addr for hi bank
|
||||
output logic [pt.DCCM_BITS-1:0] dccm_rd_addr_lo, // dccm interface -- read address for lo bank
|
||||
output logic [pt.DCCM_BITS-1:0] dccm_rd_addr_hi, // dccm interface -- read address for hi bank
|
||||
output logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_wr_data_lo, // dccm write data for lo bank
|
||||
output logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_wr_data_hi, // dccm write data for hi bank
|
||||
// DCCM ports
|
||||
output logic dccm_wren, // dccm interface -- write
|
||||
output logic dccm_rden, // dccm interface -- write
|
||||
output logic [pt.DCCM_BITS-1:0] dccm_wr_addr_lo, // dccm interface -- wr addr for lo bank
|
||||
output logic [pt.DCCM_BITS-1:0] dccm_wr_addr_hi, // dccm interface -- wr addr for hi bank
|
||||
output logic [pt.DCCM_BITS-1:0] dccm_rd_addr_lo, // dccm interface -- read address for lo bank
|
||||
output logic [pt.DCCM_BITS-1:0] dccm_rd_addr_hi, // dccm interface -- read address for hi bank
|
||||
output logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_wr_data_lo, // dccm write data for lo bank
|
||||
output logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_wr_data_hi, // dccm write data for hi bank
|
||||
|
||||
input logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo, // dccm read data back from the dccm
|
||||
input logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi, // dccm read data back from the dccm
|
||||
input logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo, // dccm read data back from the dccm
|
||||
input logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi, // dccm read data back from the dccm
|
||||
|
||||
// PIC ports
|
||||
output logic picm_wren, // write to pic
|
||||
output logic picm_rden, // read to pick
|
||||
output logic picm_mken, // write to pic need a mask
|
||||
output logic [31:0] picm_rdaddr, // address for pic read access
|
||||
output logic [31:0] picm_wraddr, // address for pic write access
|
||||
output logic [31:0] picm_wr_data, // write data
|
||||
input logic [31:0] picm_rd_data, // read data
|
||||
// PIC ports
|
||||
output logic picm_wren, // write to pic
|
||||
output logic picm_rden, // read to pick
|
||||
output logic picm_mken, // write to pic need a mask
|
||||
output logic [31:0] picm_rdaddr, // address for pic read access
|
||||
output logic [31:0] picm_wraddr, // address for pic write access
|
||||
output logic [31:0] picm_wr_data, // write data
|
||||
input logic [31:0] picm_rd_data, // read data
|
||||
|
||||
input logic scan_mode // scan mode
|
||||
input logic scan_mode // scan mode
|
||||
);
|
||||
|
||||
|
||||
localparam DCCM_WIDTH_BITS = $clog2(pt.DCCM_BYTE_WIDTH);
|
||||
localparam DCCM_WIDTH_BITS = $clog2(pt.DCCM_BYTE_WIDTH);
|
||||
|
||||
logic lsu_dccm_rden_d, lsu_dccm_wren_d;
|
||||
logic ld_single_ecc_error_lo_r, ld_single_ecc_error_hi_r;
|
||||
logic ld_single_ecc_error_lo_r_ns, ld_single_ecc_error_hi_r_ns;
|
||||
logic ld_single_ecc_error_lo_r_ff, ld_single_ecc_error_hi_r_ff;
|
||||
logic lsu_double_ecc_error_r_ff;
|
||||
logic [pt.DCCM_BITS-1:0] ld_sec_addr_lo_r_ff, ld_sec_addr_hi_r_ff;
|
||||
logic [pt.DCCM_DATA_WIDTH-1:0] store_data_lo_r_in, store_data_hi_r_in ;
|
||||
logic [63:0] picm_rd_data_m;
|
||||
logic lsu_dccm_rden_d, lsu_dccm_wren_d;
|
||||
logic ld_single_ecc_error_lo_r, ld_single_ecc_error_hi_r;
|
||||
logic ld_single_ecc_error_lo_r_ns, ld_single_ecc_error_hi_r_ns;
|
||||
logic ld_single_ecc_error_lo_r_ff, ld_single_ecc_error_hi_r_ff;
|
||||
logic lsu_double_ecc_error_r_ff;
|
||||
logic [pt.DCCM_BITS-1:0] ld_sec_addr_lo_r_ff, ld_sec_addr_hi_r_ff;
|
||||
logic [pt.DCCM_DATA_WIDTH-1:0] store_data_lo_r_in, store_data_hi_r_in;
|
||||
logic [63:0] picm_rd_data_m;
|
||||
|
||||
logic dccm_wr_bypass_d_m_hi, dccm_wr_bypass_d_r_hi;
|
||||
logic dccm_wr_bypass_d_m_lo, dccm_wr_bypass_d_r_lo;
|
||||
logic kill_ecc_corr_lo_r, kill_ecc_corr_hi_r;
|
||||
logic dccm_wr_bypass_d_m_hi, dccm_wr_bypass_d_r_hi;
|
||||
logic dccm_wr_bypass_d_m_lo, dccm_wr_bypass_d_r_lo;
|
||||
logic kill_ecc_corr_lo_r, kill_ecc_corr_hi_r;
|
||||
|
||||
// byte_en flowing down
|
||||
logic [3:0] store_byteen_m ,store_byteen_r;
|
||||
logic [7:0] store_byteen_ext_m, store_byteen_ext_r;
|
||||
// byte_en flowing down
|
||||
logic [3:0] store_byteen_m, store_byteen_r;
|
||||
logic [7:0] store_byteen_ext_m, store_byteen_ext_r;
|
||||
|
||||
if (pt.LOAD_TO_USE_PLUS1 == 1) begin: L2U_Plus1_1
|
||||
logic [63:0] lsu_rdata_r, lsu_rdata_corr_r;
|
||||
logic [63:0] dccm_rdata_r, dccm_rdata_corr_r;
|
||||
logic [63:0] stbuf_fwddata_r;
|
||||
logic [7:0] stbuf_fwdbyteen_r;
|
||||
logic [31:0] stbuf_fwddata_lo_r, stbuf_fwddata_hi_r;
|
||||
logic [3:0] stbuf_fwdbyteen_lo_r, stbuf_fwdbyteen_hi_r;
|
||||
logic [31:0] lsu_rdata_lo_r, lsu_rdata_hi_r;
|
||||
logic [63:0] picm_rd_data_r;
|
||||
logic [63:32] lsu_ld_data_r_nc, lsu_ld_data_corr_r_nc;
|
||||
logic [2:0] dma_mem_tag_r;
|
||||
logic stbuf_fwddata_en;
|
||||
if (pt.LOAD_TO_USE_PLUS1 == 1) begin : L2U_Plus1_1
|
||||
logic [63:0] lsu_rdata_r, lsu_rdata_corr_r;
|
||||
logic [63:0] dccm_rdata_r, dccm_rdata_corr_r;
|
||||
logic [63:0] stbuf_fwddata_r;
|
||||
logic [ 7:0] stbuf_fwdbyteen_r;
|
||||
logic [31:0] stbuf_fwddata_lo_r, stbuf_fwddata_hi_r;
|
||||
logic [3:0] stbuf_fwdbyteen_lo_r, stbuf_fwdbyteen_hi_r;
|
||||
logic [31:0] lsu_rdata_lo_r, lsu_rdata_hi_r;
|
||||
logic [63:0] picm_rd_data_r;
|
||||
logic [63:32] lsu_ld_data_r_nc, lsu_ld_data_corr_r_nc;
|
||||
logic [2:0] dma_mem_tag_r;
|
||||
logic stbuf_fwddata_en;
|
||||
|
||||
assign dccm_dma_rvalid = lsu_pkt_r.valid & lsu_pkt_r.load & lsu_pkt_r.dma;
|
||||
assign dccm_dma_ecc_error = lsu_double_ecc_error_r;
|
||||
assign dccm_dma_rtag[2:0] = dma_mem_tag_r[2:0];
|
||||
assign dccm_dma_rdata[63:0] = ldst_dual_r ? lsu_rdata_corr_r[63:0] : {2{lsu_rdata_corr_r[31:0]}};
|
||||
assign {lsu_ld_data_r_nc[63:32], lsu_ld_data_r[31:0]} = lsu_rdata_r[63:0] >> 8*lsu_addr_r[1:0];
|
||||
assign {lsu_ld_data_corr_r_nc[63:32], lsu_ld_data_corr_r[31:0]} = lsu_rdata_corr_r[63:0] >> 8*lsu_addr_r[1:0];
|
||||
assign dccm_dma_rvalid = lsu_pkt_r.valid & lsu_pkt_r.load & lsu_pkt_r.dma;
|
||||
assign dccm_dma_ecc_error = lsu_double_ecc_error_r;
|
||||
assign dccm_dma_rtag[2:0] = dma_mem_tag_r[2:0];
|
||||
assign dccm_dma_rdata[63:0] = ldst_dual_r ? lsu_rdata_corr_r[63:0] : {2{lsu_rdata_corr_r[31:0]}};
|
||||
assign {lsu_ld_data_r_nc[63:32], lsu_ld_data_r[31:0]} = lsu_rdata_r[63:0] >> 8*lsu_addr_r[1:0];
|
||||
assign {lsu_ld_data_corr_r_nc[63:32], lsu_ld_data_corr_r[31:0]} = lsu_rdata_corr_r[63:0] >> 8*lsu_addr_r[1:0];
|
||||
|
||||
assign picm_rd_data_r[63:32] = picm_rd_data_r[31:0];
|
||||
assign dccm_rdata_r[63:0] = {dccm_rdata_hi_r[31:0],dccm_rdata_lo_r[31:0]};
|
||||
assign dccm_rdata_corr_r[63:0] = {sec_data_hi_r[31:0],sec_data_lo_r[31:0]};
|
||||
assign stbuf_fwddata_r[63:0] = {stbuf_fwddata_hi_r[31:0], stbuf_fwddata_lo_r[31:0]};
|
||||
assign stbuf_fwdbyteen_r[7:0] = {stbuf_fwdbyteen_hi_r[3:0], stbuf_fwdbyteen_lo_r[3:0]};
|
||||
assign stbuf_fwddata_en = (|stbuf_fwdbyteen_hi_m[3:0]) | (|stbuf_fwdbyteen_lo_m[3:0]) | clk_override;
|
||||
assign picm_rd_data_r[63:32] = picm_rd_data_r[31:0];
|
||||
assign dccm_rdata_r[63:0] = {dccm_rdata_hi_r[31:0], dccm_rdata_lo_r[31:0]};
|
||||
assign dccm_rdata_corr_r[63:0] = {sec_data_hi_r[31:0], sec_data_lo_r[31:0]};
|
||||
assign stbuf_fwddata_r[63:0] = {stbuf_fwddata_hi_r[31:0], stbuf_fwddata_lo_r[31:0]};
|
||||
assign stbuf_fwdbyteen_r[7:0] = {stbuf_fwdbyteen_hi_r[3:0], stbuf_fwdbyteen_lo_r[3:0]};
|
||||
assign stbuf_fwddata_en = (|stbuf_fwdbyteen_hi_m[3:0]) | (|stbuf_fwdbyteen_lo_m[3:0]) | clk_override;
|
||||
|
||||
for (genvar i=0; i<8; i++) begin: GenDMAData
|
||||
assign lsu_rdata_corr_r[(8*i)+7:8*i] = stbuf_fwdbyteen_r[i] ? stbuf_fwddata_r[(8*i)+7:8*i] :
|
||||
for (genvar i = 0; i < 8; i++) begin : GenDMAData
|
||||
assign lsu_rdata_corr_r[(8*i)+7:8*i] = stbuf_fwdbyteen_r[i] ? stbuf_fwddata_r[(8*i)+7:8*i] :
|
||||
(addr_in_pic_r ? picm_rd_data_r[(8*i)+7:8*i] : ({8{addr_in_dccm_r}} & dccm_rdata_corr_r[(8*i)+7:8*i]));
|
||||
|
||||
assign lsu_rdata_r[(8*i)+7:8*i] = stbuf_fwdbyteen_r[i] ? stbuf_fwddata_r[(8*i)+7:8*i] :
|
||||
assign lsu_rdata_r[(8*i)+7:8*i] = stbuf_fwdbyteen_r[i] ? stbuf_fwddata_r[(8*i)+7:8*i] :
|
||||
(addr_in_pic_r ? picm_rd_data_r[(8*i)+7:8*i] : ({8{addr_in_dccm_r}} & dccm_rdata_r[(8*i)+7:8*i]));
|
||||
end
|
||||
rvdffe #(pt.DCCM_DATA_WIDTH) dccm_rdata_hi_r_ff (.*, .din(dccm_rdata_hi_m[pt.DCCM_DATA_WIDTH-1:0]), .dout(dccm_rdata_hi_r[pt.DCCM_DATA_WIDTH-1:0]), .en((lsu_dccm_rden_m & ldst_dual_m) | clk_override));
|
||||
rvdffe #(pt.DCCM_DATA_WIDTH) dccm_rdata_lo_r_ff (.*, .din(dccm_rdata_lo_m[pt.DCCM_DATA_WIDTH-1:0]), .dout(dccm_rdata_lo_r[pt.DCCM_DATA_WIDTH-1:0]), .en(lsu_dccm_rden_m | clk_override));
|
||||
rvdffe #(2*pt.DCCM_ECC_WIDTH) dccm_data_ecc_r_ff (.*, .din({dccm_data_ecc_hi_m[pt.DCCM_ECC_WIDTH-1:0], dccm_data_ecc_lo_m[pt.DCCM_ECC_WIDTH-1:0]}),
|
||||
.dout({dccm_data_ecc_hi_r[pt.DCCM_ECC_WIDTH-1:0], dccm_data_ecc_lo_r[pt.DCCM_ECC_WIDTH-1:0]}), .en(lsu_dccm_rden_m | clk_override));
|
||||
rvdff #(8) stbuf_fwdbyteen_ff (.*, .din({stbuf_fwdbyteen_hi_m[3:0], stbuf_fwdbyteen_lo_m[3:0]}), .dout({stbuf_fwdbyteen_hi_r[3:0], stbuf_fwdbyteen_lo_r[3:0]}), .clk(lsu_c2_r_clk));
|
||||
rvdffe #(64) stbuf_fwddata_ff (.*, .din({stbuf_fwddata_hi_m[31:0], stbuf_fwddata_lo_m[31:0]}), .dout({stbuf_fwddata_hi_r[31:0], stbuf_fwddata_lo_r[31:0]}), .en(stbuf_fwddata_en));
|
||||
rvdffe #(32) picm_rddata_rff (.*, .din(picm_rd_data_m[31:0]), .dout(picm_rd_data_r[31:0]), .en(addr_in_pic_m | clk_override));
|
||||
rvdff #(3) dma_mem_tag_rff (.*, .din(dma_mem_tag_m[2:0]), .dout(dma_mem_tag_r[2:0]), .clk(lsu_c1_r_clk));
|
||||
end
|
||||
rvdffe #(pt.DCCM_DATA_WIDTH) dccm_rdata_hi_r_ff (
|
||||
.*,
|
||||
.din (dccm_rdata_hi_m[pt.DCCM_DATA_WIDTH-1:0]),
|
||||
.dout(dccm_rdata_hi_r[pt.DCCM_DATA_WIDTH-1:0]),
|
||||
.en ((lsu_dccm_rden_m & ldst_dual_m) | clk_override)
|
||||
);
|
||||
rvdffe #(pt.DCCM_DATA_WIDTH) dccm_rdata_lo_r_ff (
|
||||
.*,
|
||||
.din (dccm_rdata_lo_m[pt.DCCM_DATA_WIDTH-1:0]),
|
||||
.dout(dccm_rdata_lo_r[pt.DCCM_DATA_WIDTH-1:0]),
|
||||
.en (lsu_dccm_rden_m | clk_override)
|
||||
);
|
||||
rvdffe #(2 * pt.DCCM_ECC_WIDTH) dccm_data_ecc_r_ff (
|
||||
.*,
|
||||
.din({
|
||||
dccm_data_ecc_hi_m[pt.DCCM_ECC_WIDTH-1:0], dccm_data_ecc_lo_m[pt.DCCM_ECC_WIDTH-1:0]
|
||||
}),
|
||||
.dout({
|
||||
dccm_data_ecc_hi_r[pt.DCCM_ECC_WIDTH-1:0], dccm_data_ecc_lo_r[pt.DCCM_ECC_WIDTH-1:0]
|
||||
}),
|
||||
.en(lsu_dccm_rden_m | clk_override)
|
||||
);
|
||||
rvdff #(8) stbuf_fwdbyteen_ff (
|
||||
.*,
|
||||
.din ({stbuf_fwdbyteen_hi_m[3:0], stbuf_fwdbyteen_lo_m[3:0]}),
|
||||
.dout({stbuf_fwdbyteen_hi_r[3:0], stbuf_fwdbyteen_lo_r[3:0]}),
|
||||
.clk (lsu_c2_r_clk)
|
||||
);
|
||||
rvdffe #(64) stbuf_fwddata_ff (
|
||||
.*,
|
||||
.din ({stbuf_fwddata_hi_m[31:0], stbuf_fwddata_lo_m[31:0]}),
|
||||
.dout({stbuf_fwddata_hi_r[31:0], stbuf_fwddata_lo_r[31:0]}),
|
||||
.en (stbuf_fwddata_en)
|
||||
);
|
||||
rvdffe #(32) picm_rddata_rff (
|
||||
.*,
|
||||
.din (picm_rd_data_m[31:0]),
|
||||
.dout(picm_rd_data_r[31:0]),
|
||||
.en (addr_in_pic_m | clk_override)
|
||||
);
|
||||
rvdff #(3) dma_mem_tag_rff (
|
||||
.*,
|
||||
.din (dma_mem_tag_m[2:0]),
|
||||
.dout(dma_mem_tag_r[2:0]),
|
||||
.clk (lsu_c1_r_clk)
|
||||
);
|
||||
|
||||
end else begin: L2U_Plus1_0
|
||||
end else begin : L2U_Plus1_0
|
||||
|
||||
logic [63:0] lsu_rdata_m, lsu_rdata_corr_m;
|
||||
logic [63:0] dccm_rdata_m, dccm_rdata_corr_m;
|
||||
logic [63:0] stbuf_fwddata_m;
|
||||
logic [7:0] stbuf_fwdbyteen_m;
|
||||
logic [63:32] lsu_ld_data_m_nc, lsu_ld_data_corr_m_nc;
|
||||
logic [31:0] lsu_ld_data_corr_m;
|
||||
logic [63:0] lsu_rdata_m, lsu_rdata_corr_m;
|
||||
logic [63:0] dccm_rdata_m, dccm_rdata_corr_m;
|
||||
logic [63:0] stbuf_fwddata_m;
|
||||
logic [ 7:0] stbuf_fwdbyteen_m;
|
||||
logic [63:32] lsu_ld_data_m_nc, lsu_ld_data_corr_m_nc;
|
||||
logic [31:0] lsu_ld_data_corr_m;
|
||||
|
||||
assign dccm_dma_rvalid = lsu_pkt_m.valid & lsu_pkt_m.load & lsu_pkt_m.dma;
|
||||
assign dccm_dma_ecc_error = lsu_double_ecc_error_m;
|
||||
assign dccm_dma_rtag[2:0] = dma_mem_tag_m[2:0];
|
||||
assign dccm_dma_rdata[63:0] = ldst_dual_m ? lsu_rdata_corr_m[63:0] : {2{lsu_rdata_corr_m[31:0]}};
|
||||
assign {lsu_ld_data_m_nc[63:32], lsu_ld_data_m[31:0]} = lsu_rdata_m[63:0] >> 8*lsu_addr_m[1:0];
|
||||
assign {lsu_ld_data_corr_m_nc[63:32], lsu_ld_data_corr_m[31:0]} = lsu_rdata_corr_m[63:0] >> 8*lsu_addr_m[1:0];
|
||||
assign dccm_dma_rvalid = lsu_pkt_m.valid & lsu_pkt_m.load & lsu_pkt_m.dma;
|
||||
assign dccm_dma_ecc_error = lsu_double_ecc_error_m;
|
||||
assign dccm_dma_rtag[2:0] = dma_mem_tag_m[2:0];
|
||||
assign dccm_dma_rdata[63:0] = ldst_dual_m ? lsu_rdata_corr_m[63:0] : {2{lsu_rdata_corr_m[31:0]}};
|
||||
assign {lsu_ld_data_m_nc[63:32], lsu_ld_data_m[31:0]} = lsu_rdata_m[63:0] >> 8*lsu_addr_m[1:0];
|
||||
assign {lsu_ld_data_corr_m_nc[63:32], lsu_ld_data_corr_m[31:0]} = lsu_rdata_corr_m[63:0] >> 8*lsu_addr_m[1:0];
|
||||
|
||||
assign dccm_rdata_m[63:0] = {dccm_rdata_hi_m[31:0],dccm_rdata_lo_m[31:0]};
|
||||
assign dccm_rdata_corr_m[63:0] = {sec_data_hi_m[31:0],sec_data_lo_m[31:0]};
|
||||
assign stbuf_fwddata_m[63:0] = {stbuf_fwddata_hi_m[31:0], stbuf_fwddata_lo_m[31:0]};
|
||||
assign stbuf_fwdbyteen_m[7:0] = {stbuf_fwdbyteen_hi_m[3:0], stbuf_fwdbyteen_lo_m[3:0]};
|
||||
assign dccm_rdata_m[63:0] = {dccm_rdata_hi_m[31:0], dccm_rdata_lo_m[31:0]};
|
||||
assign dccm_rdata_corr_m[63:0] = {sec_data_hi_m[31:0], sec_data_lo_m[31:0]};
|
||||
assign stbuf_fwddata_m[63:0] = {stbuf_fwddata_hi_m[31:0], stbuf_fwddata_lo_m[31:0]};
|
||||
assign stbuf_fwdbyteen_m[7:0] = {stbuf_fwdbyteen_hi_m[3:0], stbuf_fwdbyteen_lo_m[3:0]};
|
||||
|
||||
for (genvar i=0; i<8; i++) begin: GenLoop
|
||||
assign lsu_rdata_corr_m[(8*i)+7:8*i] = stbuf_fwdbyteen_m[i] ? stbuf_fwddata_m[(8*i)+7:8*i] :
|
||||
for (genvar i = 0; i < 8; i++) begin : GenLoop
|
||||
assign lsu_rdata_corr_m[(8*i)+7:8*i] = stbuf_fwdbyteen_m[i] ? stbuf_fwddata_m[(8*i)+7:8*i] :
|
||||
(addr_in_pic_m ? picm_rd_data_m[(8*i)+7:8*i] : ({8{addr_in_dccm_m}} & dccm_rdata_corr_m[(8*i)+7:8*i]));
|
||||
|
||||
assign lsu_rdata_m[(8*i)+7:8*i] = stbuf_fwdbyteen_m[i] ? stbuf_fwddata_m[(8*i)+7:8*i] :
|
||||
assign lsu_rdata_m[(8*i)+7:8*i] = stbuf_fwdbyteen_m[i] ? stbuf_fwddata_m[(8*i)+7:8*i] :
|
||||
(addr_in_pic_m ? picm_rd_data_m[(8*i)+7:8*i] : ({8{addr_in_dccm_m}} & dccm_rdata_m[(8*i)+7:8*i]));
|
||||
end
|
||||
end
|
||||
|
||||
rvdffe #(32) lsu_ld_data_corr_rff(.*, .din(lsu_ld_data_corr_m[31:0]), .dout(lsu_ld_data_corr_r[31:0]), .en((lsu_pkt_m.valid & lsu_pkt_m.load & (addr_in_pic_m | addr_in_dccm_m)) | clk_override));
|
||||
end
|
||||
rvdffe #(32) lsu_ld_data_corr_rff (
|
||||
.*,
|
||||
.din (lsu_ld_data_corr_m[31:0]),
|
||||
.dout(lsu_ld_data_corr_r[31:0]),
|
||||
.en ((lsu_pkt_m.valid & lsu_pkt_m.load & (addr_in_pic_m | addr_in_dccm_m)) | clk_override)
|
||||
);
|
||||
end
|
||||
|
||||
assign kill_ecc_corr_lo_r = (((lsu_addr_d[pt.DCCM_BITS-1:2] == lsu_addr_r[pt.DCCM_BITS-1:2]) | (end_addr_d[pt.DCCM_BITS-1:2] == lsu_addr_r[pt.DCCM_BITS-1:2])) & lsu_pkt_d.valid & lsu_pkt_d.store & lsu_pkt_d.dma & addr_in_dccm_d) |
|
||||
assign kill_ecc_corr_lo_r = (((lsu_addr_d[pt.DCCM_BITS-1:2] == lsu_addr_r[pt.DCCM_BITS-1:2]) | (end_addr_d[pt.DCCM_BITS-1:2] == lsu_addr_r[pt.DCCM_BITS-1:2])) & lsu_pkt_d.valid & lsu_pkt_d.store & lsu_pkt_d.dma & addr_in_dccm_d) |
|
||||
(((lsu_addr_m[pt.DCCM_BITS-1:2] == lsu_addr_r[pt.DCCM_BITS-1:2]) | (end_addr_m[pt.DCCM_BITS-1:2] == lsu_addr_r[pt.DCCM_BITS-1:2])) & lsu_pkt_m.valid & lsu_pkt_m.store & lsu_pkt_m.dma & addr_in_dccm_m);
|
||||
|
||||
assign kill_ecc_corr_hi_r = (((lsu_addr_d[pt.DCCM_BITS-1:2] == end_addr_r[pt.DCCM_BITS-1:2]) | (end_addr_d[pt.DCCM_BITS-1:2] == end_addr_r[pt.DCCM_BITS-1:2])) & lsu_pkt_d.valid & lsu_pkt_d.store & lsu_pkt_d.dma & addr_in_dccm_d) |
|
||||
assign kill_ecc_corr_hi_r = (((lsu_addr_d[pt.DCCM_BITS-1:2] == end_addr_r[pt.DCCM_BITS-1:2]) | (end_addr_d[pt.DCCM_BITS-1:2] == end_addr_r[pt.DCCM_BITS-1:2])) & lsu_pkt_d.valid & lsu_pkt_d.store & lsu_pkt_d.dma & addr_in_dccm_d) |
|
||||
(((lsu_addr_m[pt.DCCM_BITS-1:2] == end_addr_r[pt.DCCM_BITS-1:2]) | (end_addr_m[pt.DCCM_BITS-1:2] == end_addr_r[pt.DCCM_BITS-1:2])) & lsu_pkt_m.valid & lsu_pkt_m.store & lsu_pkt_m.dma & addr_in_dccm_m);
|
||||
|
||||
assign ld_single_ecc_error_lo_r = lsu_pkt_r.load & single_ecc_error_lo_r & ~lsu_raw_fwd_lo_r;
|
||||
assign ld_single_ecc_error_hi_r = lsu_pkt_r.load & single_ecc_error_hi_r & ~lsu_raw_fwd_hi_r;
|
||||
assign ld_single_ecc_error_r = (ld_single_ecc_error_lo_r | ld_single_ecc_error_hi_r) & ~lsu_double_ecc_error_r;
|
||||
assign ld_single_ecc_error_lo_r = lsu_pkt_r.load & single_ecc_error_lo_r & ~lsu_raw_fwd_lo_r;
|
||||
assign ld_single_ecc_error_hi_r = lsu_pkt_r.load & single_ecc_error_hi_r & ~lsu_raw_fwd_hi_r;
|
||||
assign ld_single_ecc_error_r = (ld_single_ecc_error_lo_r | ld_single_ecc_error_hi_r) & ~lsu_double_ecc_error_r;
|
||||
|
||||
assign ld_single_ecc_error_lo_r_ns = ld_single_ecc_error_lo_r & (lsu_commit_r | lsu_pkt_r.dma) & ~kill_ecc_corr_lo_r;
|
||||
assign ld_single_ecc_error_hi_r_ns = ld_single_ecc_error_hi_r & (lsu_commit_r | lsu_pkt_r.dma) & ~kill_ecc_corr_hi_r;
|
||||
assign ld_single_ecc_error_r_ff = (ld_single_ecc_error_lo_r_ff | ld_single_ecc_error_hi_r_ff) & ~lsu_double_ecc_error_r_ff;
|
||||
assign ld_single_ecc_error_lo_r_ns = ld_single_ecc_error_lo_r & (lsu_commit_r | lsu_pkt_r.dma) & ~kill_ecc_corr_lo_r;
|
||||
assign ld_single_ecc_error_hi_r_ns = ld_single_ecc_error_hi_r & (lsu_commit_r | lsu_pkt_r.dma) & ~kill_ecc_corr_hi_r;
|
||||
assign ld_single_ecc_error_r_ff = (ld_single_ecc_error_lo_r_ff | ld_single_ecc_error_hi_r_ff) & ~lsu_double_ecc_error_r_ff;
|
||||
|
||||
assign lsu_stbuf_commit_any = stbuf_reqvld_any &
|
||||
assign lsu_stbuf_commit_any = stbuf_reqvld_any &
|
||||
(~(lsu_dccm_rden_d | lsu_dccm_wren_d | ld_single_ecc_error_r_ff) |
|
||||
(lsu_dccm_rden_d & ~((stbuf_addr_any[pt.DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS] == lsu_addr_d[pt.DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS]) |
|
||||
(stbuf_addr_any[pt.DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS] == end_addr_d[pt.DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS]))));
|
||||
|
||||
// No need to read for aligned word/dword stores since ECC will come by new data completely
|
||||
assign lsu_dccm_rden_d = lsu_pkt_d.valid & (lsu_pkt_d.load | (lsu_pkt_d.store & (~(lsu_pkt_d.word | lsu_pkt_d.dword) | (lsu_addr_d[1:0] != 2'b0)))) & addr_in_dccm_d;
|
||||
// No need to read for aligned word/dword stores since ECC will come by new data completely
|
||||
assign lsu_dccm_rden_d = lsu_pkt_d.valid & (lsu_pkt_d.load | (lsu_pkt_d.store & (~(lsu_pkt_d.word | lsu_pkt_d.dword) | (lsu_addr_d[1:0] != 2'b0)))) & addr_in_dccm_d;
|
||||
|
||||
// DMA will read/write in decode stage
|
||||
assign lsu_dccm_wren_d = dma_dccm_wen;
|
||||
// DMA will read/write in decode stage
|
||||
assign lsu_dccm_wren_d = dma_dccm_wen;
|
||||
|
||||
// DCCM inputs
|
||||
assign dccm_wren = lsu_dccm_wren_d | lsu_stbuf_commit_any | ld_single_ecc_error_r_ff;
|
||||
assign dccm_rden = lsu_dccm_rden_d & addr_in_dccm_d;
|
||||
assign dccm_wr_addr_lo[pt.DCCM_BITS-1:0] = ld_single_ecc_error_r_ff ? (ld_single_ecc_error_lo_r_ff ? ld_sec_addr_lo_r_ff[pt.DCCM_BITS-1:0] : ld_sec_addr_hi_r_ff[pt.DCCM_BITS-1:0]) :
|
||||
// DCCM inputs
|
||||
assign dccm_wren = lsu_dccm_wren_d | lsu_stbuf_commit_any | ld_single_ecc_error_r_ff;
|
||||
assign dccm_rden = lsu_dccm_rden_d & addr_in_dccm_d;
|
||||
assign dccm_wr_addr_lo[pt.DCCM_BITS-1:0] = ld_single_ecc_error_r_ff ? (ld_single_ecc_error_lo_r_ff ? ld_sec_addr_lo_r_ff[pt.DCCM_BITS-1:0] : ld_sec_addr_hi_r_ff[pt.DCCM_BITS-1:0]) :
|
||||
lsu_dccm_wren_d ? lsu_addr_d[pt.DCCM_BITS-1:0] : stbuf_addr_any[pt.DCCM_BITS-1:0];
|
||||
assign dccm_wr_addr_hi[pt.DCCM_BITS-1:0] = ld_single_ecc_error_r_ff ? (ld_single_ecc_error_hi_r_ff ? ld_sec_addr_hi_r_ff[pt.DCCM_BITS-1:0] : ld_sec_addr_lo_r_ff[pt.DCCM_BITS-1:0]) :
|
||||
assign dccm_wr_addr_hi[pt.DCCM_BITS-1:0] = ld_single_ecc_error_r_ff ? (ld_single_ecc_error_hi_r_ff ? ld_sec_addr_hi_r_ff[pt.DCCM_BITS-1:0] : ld_sec_addr_lo_r_ff[pt.DCCM_BITS-1:0]) :
|
||||
lsu_dccm_wren_d ? end_addr_d[pt.DCCM_BITS-1:0] : stbuf_addr_any[pt.DCCM_BITS-1:0];
|
||||
assign dccm_rd_addr_lo[pt.DCCM_BITS-1:0] = lsu_addr_d[pt.DCCM_BITS-1:0];
|
||||
assign dccm_rd_addr_hi[pt.DCCM_BITS-1:0] = end_addr_d[pt.DCCM_BITS-1:0];
|
||||
assign dccm_wr_data_lo[pt.DCCM_FDATA_WIDTH-1:0] = ld_single_ecc_error_r_ff ? (ld_single_ecc_error_lo_r_ff ? {sec_data_ecc_lo_r_ff[pt.DCCM_ECC_WIDTH-1:0],sec_data_lo_r_ff[pt.DCCM_DATA_WIDTH-1:0]} :
|
||||
assign dccm_rd_addr_lo[pt.DCCM_BITS-1:0] = lsu_addr_d[pt.DCCM_BITS-1:0];
|
||||
assign dccm_rd_addr_hi[pt.DCCM_BITS-1:0] = end_addr_d[pt.DCCM_BITS-1:0];
|
||||
assign dccm_wr_data_lo[pt.DCCM_FDATA_WIDTH-1:0] = ld_single_ecc_error_r_ff ? (ld_single_ecc_error_lo_r_ff ? {sec_data_ecc_lo_r_ff[pt.DCCM_ECC_WIDTH-1:0],sec_data_lo_r_ff[pt.DCCM_DATA_WIDTH-1:0]} :
|
||||
{sec_data_ecc_hi_r_ff[pt.DCCM_ECC_WIDTH-1:0],sec_data_hi_r_ff[pt.DCCM_DATA_WIDTH-1:0]}) :
|
||||
(dma_dccm_wen ? {dma_dccm_wdata_ecc_lo[pt.DCCM_ECC_WIDTH-1:0],dma_dccm_wdata_lo[pt.DCCM_DATA_WIDTH-1:0]} :
|
||||
{stbuf_ecc_any[pt.DCCM_ECC_WIDTH-1:0],stbuf_data_any[pt.DCCM_DATA_WIDTH-1:0]});
|
||||
assign dccm_wr_data_hi[pt.DCCM_FDATA_WIDTH-1:0] = ld_single_ecc_error_r_ff ? (ld_single_ecc_error_hi_r_ff ? {sec_data_ecc_hi_r_ff[pt.DCCM_ECC_WIDTH-1:0],sec_data_hi_r_ff[pt.DCCM_DATA_WIDTH-1:0]} :
|
||||
assign dccm_wr_data_hi[pt.DCCM_FDATA_WIDTH-1:0] = ld_single_ecc_error_r_ff ? (ld_single_ecc_error_hi_r_ff ? {sec_data_ecc_hi_r_ff[pt.DCCM_ECC_WIDTH-1:0],sec_data_hi_r_ff[pt.DCCM_DATA_WIDTH-1:0]} :
|
||||
{sec_data_ecc_lo_r_ff[pt.DCCM_ECC_WIDTH-1:0],sec_data_lo_r_ff[pt.DCCM_DATA_WIDTH-1:0]}) :
|
||||
(dma_dccm_wen ? {dma_dccm_wdata_ecc_hi[pt.DCCM_ECC_WIDTH-1:0],dma_dccm_wdata_hi[pt.DCCM_DATA_WIDTH-1:0]} :
|
||||
{stbuf_ecc_any[pt.DCCM_ECC_WIDTH-1:0],stbuf_data_any[pt.DCCM_DATA_WIDTH-1:0]});
|
||||
|
||||
// DCCM outputs
|
||||
assign store_byteen_m[3:0] = {4{lsu_pkt_m.store}} &
|
||||
// DCCM outputs
|
||||
assign store_byteen_m[3:0] = {4{lsu_pkt_m.store}} &
|
||||
(({4{lsu_pkt_m.by}} & 4'b0001) |
|
||||
({4{lsu_pkt_m.half}} & 4'b0011) |
|
||||
({4{lsu_pkt_m.word}} & 4'b1111));
|
||||
|
||||
assign store_byteen_r[3:0] = {4{lsu_pkt_r.store}} &
|
||||
assign store_byteen_r[3:0] = {4{lsu_pkt_r.store}} &
|
||||
(({4{lsu_pkt_r.by}} & 4'b0001) |
|
||||
({4{lsu_pkt_r.half}} & 4'b0011) |
|
||||
({4{lsu_pkt_r.word}} & 4'b1111));
|
||||
|
||||
assign store_byteen_ext_m[7:0] = {4'b0,store_byteen_m[3:0]} << lsu_addr_m[1:0]; // The packet in m
|
||||
assign store_byteen_ext_r[7:0] = {4'b0,store_byteen_r[3:0]} << lsu_addr_r[1:0];
|
||||
assign store_byteen_ext_m[7:0] = {4'b0,store_byteen_m[3:0]} << lsu_addr_m[1:0]; // The packet in m
|
||||
assign store_byteen_ext_r[7:0] = {4'b0, store_byteen_r[3:0]} << lsu_addr_r[1:0];
|
||||
|
||||
|
||||
|
||||
assign dccm_wr_bypass_d_m_lo = (stbuf_addr_any[pt.DCCM_BITS-1:2] == lsu_addr_m[pt.DCCM_BITS-1:2]) & addr_in_dccm_m;
|
||||
assign dccm_wr_bypass_d_m_hi = (stbuf_addr_any[pt.DCCM_BITS-1:2] == end_addr_m[pt.DCCM_BITS-1:2]) & addr_in_dccm_m;
|
||||
assign dccm_wr_bypass_d_m_lo = (stbuf_addr_any[pt.DCCM_BITS-1:2] == lsu_addr_m[pt.DCCM_BITS-1:2]) & addr_in_dccm_m;
|
||||
assign dccm_wr_bypass_d_m_hi = (stbuf_addr_any[pt.DCCM_BITS-1:2] == end_addr_m[pt.DCCM_BITS-1:2]) & addr_in_dccm_m;
|
||||
|
||||
assign dccm_wr_bypass_d_r_lo = (stbuf_addr_any[pt.DCCM_BITS-1:2] == lsu_addr_r[pt.DCCM_BITS-1:2]) & addr_in_dccm_r;
|
||||
assign dccm_wr_bypass_d_r_hi = (stbuf_addr_any[pt.DCCM_BITS-1:2] == end_addr_r[pt.DCCM_BITS-1:2]) & addr_in_dccm_r;
|
||||
assign dccm_wr_bypass_d_r_lo = (stbuf_addr_any[pt.DCCM_BITS-1:2] == lsu_addr_r[pt.DCCM_BITS-1:2]) & addr_in_dccm_r;
|
||||
assign dccm_wr_bypass_d_r_hi = (stbuf_addr_any[pt.DCCM_BITS-1:2] == end_addr_r[pt.DCCM_BITS-1:2]) & addr_in_dccm_r;
|
||||
|
||||
|
||||
if (pt.LOAD_TO_USE_PLUS1 == 1) begin: L2U1_Plus1_1
|
||||
logic dccm_wren_Q;
|
||||
logic [31:0] dccm_wr_data_Q;
|
||||
logic dccm_wr_bypass_d_m_lo_Q, dccm_wr_bypass_d_m_hi_Q;
|
||||
logic [31:0] store_data_pre_hi_r, store_data_pre_lo_r;
|
||||
if (pt.LOAD_TO_USE_PLUS1 == 1) begin : L2U1_Plus1_1
|
||||
logic dccm_wren_Q;
|
||||
logic [31:0] dccm_wr_data_Q;
|
||||
logic dccm_wr_bypass_d_m_lo_Q, dccm_wr_bypass_d_m_hi_Q;
|
||||
logic [31:0] store_data_pre_hi_r, store_data_pre_lo_r;
|
||||
|
||||
assign {store_data_pre_hi_r[31:0], store_data_pre_lo_r[31:0]} = {32'b0,store_data_r[31:0]} << 8*lsu_addr_r[1:0];
|
||||
assign {store_data_pre_hi_r[31:0], store_data_pre_lo_r[31:0]} = {32'b0,store_data_r[31:0]} << 8*lsu_addr_r[1:0];
|
||||
|
||||
for (genvar i=0; i<4; i++) begin
|
||||
assign store_data_lo_r[(8*i)+7:(8*i)] = store_byteen_ext_r[i] ? store_data_pre_lo_r[(8*i)+7:(8*i)] : ((dccm_wren_Q & dccm_wr_bypass_d_m_lo_Q) ? dccm_wr_data_Q[(8*i)+7:(8*i)] : sec_data_lo_r[(8*i)+7:(8*i)]);
|
||||
assign store_data_hi_r[(8*i)+7:(8*i)] = store_byteen_ext_r[i+4] ? store_data_pre_hi_r[(8*i)+7:(8*i)] : ((dccm_wren_Q & dccm_wr_bypass_d_m_hi_Q) ? dccm_wr_data_Q[(8*i)+7:(8*i)] : sec_data_hi_r[(8*i)+7:(8*i)]);
|
||||
for (genvar i = 0; i < 4; i++) begin
|
||||
assign store_data_lo_r[(8*i)+7:(8*i)] = store_byteen_ext_r[i] ? store_data_pre_lo_r[(8*i)+7:(8*i)] : ((dccm_wren_Q & dccm_wr_bypass_d_m_lo_Q) ? dccm_wr_data_Q[(8*i)+7:(8*i)] : sec_data_lo_r[(8*i)+7:(8*i)]);
|
||||
assign store_data_hi_r[(8*i)+7:(8*i)] = store_byteen_ext_r[i+4] ? store_data_pre_hi_r[(8*i)+7:(8*i)] : ((dccm_wren_Q & dccm_wr_bypass_d_m_hi_Q) ? dccm_wr_data_Q[(8*i)+7:(8*i)] : sec_data_hi_r[(8*i)+7:(8*i)]);
|
||||
|
||||
assign store_datafn_lo_r[(8*i)+7:(8*i)] = store_byteen_ext_r[i] ? store_data_pre_lo_r[(8*i)+7:(8*i)] : ((lsu_stbuf_commit_any & dccm_wr_bypass_d_r_lo) ? stbuf_data_any[(8*i)+7:(8*i)] :
|
||||
assign store_datafn_lo_r[(8*i)+7:(8*i)] = store_byteen_ext_r[i] ? store_data_pre_lo_r[(8*i)+7:(8*i)] : ((lsu_stbuf_commit_any & dccm_wr_bypass_d_r_lo) ? stbuf_data_any[(8*i)+7:(8*i)] :
|
||||
((dccm_wren_Q & dccm_wr_bypass_d_m_lo_Q) ? dccm_wr_data_Q[(8*i)+7:(8*i)] : sec_data_lo_r[(8*i)+7:(8*i)]));
|
||||
assign store_datafn_hi_r[(8*i)+7:(8*i)] = store_byteen_ext_r[i+4] ? store_data_pre_hi_r[(8*i)+7:(8*i)] : ((lsu_stbuf_commit_any & dccm_wr_bypass_d_r_hi) ? stbuf_data_any[(8*i)+7:(8*i)] :
|
||||
assign store_datafn_hi_r[(8*i)+7:(8*i)] = store_byteen_ext_r[i+4] ? store_data_pre_hi_r[(8*i)+7:(8*i)] : ((lsu_stbuf_commit_any & dccm_wr_bypass_d_r_hi) ? stbuf_data_any[(8*i)+7:(8*i)] :
|
||||
((dccm_wren_Q & dccm_wr_bypass_d_m_hi_Q) ? dccm_wr_data_Q[(8*i)+7:(8*i)] : sec_data_hi_r[(8*i)+7:(8*i)]));
|
||||
end
|
||||
end
|
||||
|
||||
rvdff #(1) dccm_wren_ff (.*, .din(lsu_stbuf_commit_any), .dout(dccm_wren_Q), .clk(lsu_free_c2_clk)); // ECC load errors writing to dccm shouldn't fwd to stores in pipe
|
||||
rvdffe #(32) dccm_wrdata_ff (.*, .din(stbuf_data_any[31:0]), .dout(dccm_wr_data_Q[31:0]), .en(lsu_stbuf_commit_any | clk_override), .clk(clk));
|
||||
rvdff #(1) dccm_wrbyp_dm_loff (.*, .din(dccm_wr_bypass_d_m_lo), .dout(dccm_wr_bypass_d_m_lo_Q), .clk(lsu_free_c2_clk));
|
||||
rvdff #(1) dccm_wrbyp_dm_hiff (.*, .din(dccm_wr_bypass_d_m_hi), .dout(dccm_wr_bypass_d_m_hi_Q), .clk(lsu_free_c2_clk));
|
||||
rvdff #(32) store_data_rff (.*, .din(store_data_m[31:0]), .dout(store_data_r[31:0]), .clk(lsu_store_c1_r_clk));
|
||||
rvdff #(1) dccm_wren_ff (
|
||||
.*,
|
||||
.din (lsu_stbuf_commit_any),
|
||||
.dout(dccm_wren_Q),
|
||||
.clk (lsu_free_c2_clk)
|
||||
); // ECC load errors writing to dccm shouldn't fwd to stores in pipe
|
||||
rvdffe #(32) dccm_wrdata_ff (
|
||||
.*,
|
||||
.din (stbuf_data_any[31:0]),
|
||||
.dout(dccm_wr_data_Q[31:0]),
|
||||
.en (lsu_stbuf_commit_any | clk_override),
|
||||
.clk (clk)
|
||||
);
|
||||
rvdff #(1) dccm_wrbyp_dm_loff (
|
||||
.*,
|
||||
.din (dccm_wr_bypass_d_m_lo),
|
||||
.dout(dccm_wr_bypass_d_m_lo_Q),
|
||||
.clk (lsu_free_c2_clk)
|
||||
);
|
||||
rvdff #(1) dccm_wrbyp_dm_hiff (
|
||||
.*,
|
||||
.din (dccm_wr_bypass_d_m_hi),
|
||||
.dout(dccm_wr_bypass_d_m_hi_Q),
|
||||
.clk (lsu_free_c2_clk)
|
||||
);
|
||||
rvdff #(32) store_data_rff (
|
||||
.*,
|
||||
.din (store_data_m[31:0]),
|
||||
.dout(store_data_r[31:0]),
|
||||
.clk (lsu_store_c1_r_clk)
|
||||
);
|
||||
|
||||
end else begin: L2U1_Plus1_0
|
||||
end else begin : L2U1_Plus1_0
|
||||
|
||||
logic [31:0] store_data_hi_m, store_data_lo_m;
|
||||
logic [63:0] store_data_mask;
|
||||
assign {store_data_hi_m[31:0] , store_data_lo_m[31:0]} = {32'b0,store_data_m[31:0]} << 8*lsu_addr_m[1:0];
|
||||
logic [31:0] store_data_hi_m, store_data_lo_m;
|
||||
logic [63:0] store_data_mask;
|
||||
assign {store_data_hi_m[31:0] , store_data_lo_m[31:0]} = {32'b0,store_data_m[31:0]} << 8*lsu_addr_m[1:0];
|
||||
|
||||
for (genvar i=0; i<4; i++) begin
|
||||
assign store_data_hi_r_in[(8*i)+7:(8*i)] = store_byteen_ext_m[i+4] ? store_data_hi_m[(8*i)+7:(8*i)] :
|
||||
for (genvar i = 0; i < 4; i++) begin
|
||||
assign store_data_hi_r_in[(8*i)+7:(8*i)] = store_byteen_ext_m[i+4] ? store_data_hi_m[(8*i)+7:(8*i)] :
|
||||
((lsu_stbuf_commit_any & dccm_wr_bypass_d_m_hi) ? stbuf_data_any[(8*i)+7:(8*i)] : sec_data_hi_m[(8*i)+7:(8*i)]);
|
||||
assign store_data_lo_r_in[(8*i)+7:(8*i)] = store_byteen_ext_m[i] ? store_data_lo_m[(8*i)+7:(8*i)] :
|
||||
assign store_data_lo_r_in[(8*i)+7:(8*i)] = store_byteen_ext_m[i] ? store_data_lo_m[(8*i)+7:(8*i)] :
|
||||
((lsu_stbuf_commit_any & dccm_wr_bypass_d_m_lo) ? stbuf_data_any[(8*i)+7:(8*i)] : sec_data_lo_m[(8*i)+7:(8*i)]);
|
||||
|
||||
assign store_datafn_lo_r[(8*i)+7:(8*i)] = (lsu_stbuf_commit_any & dccm_wr_bypass_d_r_lo & ~store_byteen_ext_r[i]) ? stbuf_data_any[(8*i)+7:(8*i)] : store_data_lo_r[(8*i)+7:(8*i)];
|
||||
assign store_datafn_hi_r[(8*i)+7:(8*i)] = (lsu_stbuf_commit_any & dccm_wr_bypass_d_r_hi & ~store_byteen_ext_r[i+4]) ? stbuf_data_any[(8*i)+7:(8*i)] : store_data_hi_r[(8*i)+7:(8*i)];
|
||||
end // for (genvar i=0; i<BYTE_WIDTH; i++)
|
||||
assign store_datafn_lo_r[(8*i)+7:(8*i)] = (lsu_stbuf_commit_any & dccm_wr_bypass_d_r_lo & ~store_byteen_ext_r[i]) ? stbuf_data_any[(8*i)+7:(8*i)] : store_data_lo_r[(8*i)+7:(8*i)];
|
||||
assign store_datafn_hi_r[(8*i)+7:(8*i)] = (lsu_stbuf_commit_any & dccm_wr_bypass_d_r_hi & ~store_byteen_ext_r[i+4]) ? stbuf_data_any[(8*i)+7:(8*i)] : store_data_hi_r[(8*i)+7:(8*i)];
|
||||
end // for (genvar i=0; i<BYTE_WIDTH; i++)
|
||||
|
||||
for (genvar i=0; i<4; i++) begin
|
||||
assign store_data_mask[(8*i)+7:(8*i)] = {8{store_byteen_r[i]}};
|
||||
end
|
||||
assign store_data_r[31:0] = 32'({store_data_hi_r[31:0],store_data_lo_r[31:0]} >> 8*lsu_addr_r[1:0]) & store_data_mask[31:0];
|
||||
for (genvar i = 0; i < 4; i++) begin
|
||||
assign store_data_mask[(8*i)+7:(8*i)] = {8{store_byteen_r[i]}};
|
||||
end
|
||||
assign store_data_r[31:0] = 32'({store_data_hi_r[31:0],store_data_lo_r[31:0]} >> 8*lsu_addr_r[1:0]) & store_data_mask[31:0];
|
||||
|
||||
rvdffe #(pt.DCCM_DATA_WIDTH) store_data_hi_rff (.*, .din(store_data_hi_r_in[pt.DCCM_DATA_WIDTH-1:0]), .dout(store_data_hi_r[pt.DCCM_DATA_WIDTH-1:0]), .en((ldst_dual_m & lsu_pkt_m.valid & lsu_pkt_m.store) | clk_override), .clk(clk));
|
||||
rvdff #(pt.DCCM_DATA_WIDTH) store_data_lo_rff (.*, .din(store_data_lo_r_in[pt.DCCM_DATA_WIDTH-1:0]), .dout(store_data_lo_r[pt.DCCM_DATA_WIDTH-1:0]), .clk(lsu_store_c1_r_clk));
|
||||
rvdffe #(pt.DCCM_DATA_WIDTH) store_data_hi_rff (
|
||||
.*,
|
||||
.din (store_data_hi_r_in[pt.DCCM_DATA_WIDTH-1:0]),
|
||||
.dout(store_data_hi_r[pt.DCCM_DATA_WIDTH-1:0]),
|
||||
.en ((ldst_dual_m & lsu_pkt_m.valid & lsu_pkt_m.store) | clk_override),
|
||||
.clk (clk)
|
||||
);
|
||||
rvdff #(pt.DCCM_DATA_WIDTH) store_data_lo_rff (
|
||||
.*,
|
||||
.din (store_data_lo_r_in[pt.DCCM_DATA_WIDTH-1:0]),
|
||||
.dout(store_data_lo_r[pt.DCCM_DATA_WIDTH-1:0]),
|
||||
.clk (lsu_store_c1_r_clk)
|
||||
);
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
assign dccm_rdata_lo_m[pt.DCCM_DATA_WIDTH-1:0] = dccm_rd_data_lo[pt.DCCM_DATA_WIDTH-1:0]; // for ld choose dccm_out
|
||||
assign dccm_rdata_hi_m[pt.DCCM_DATA_WIDTH-1:0] = dccm_rd_data_hi[pt.DCCM_DATA_WIDTH-1:0]; // for ld this is used for ecc
|
||||
assign dccm_rdata_lo_m[pt.DCCM_DATA_WIDTH-1:0] = dccm_rd_data_lo[pt.DCCM_DATA_WIDTH-1:0]; // for ld choose dccm_out
|
||||
assign dccm_rdata_hi_m[pt.DCCM_DATA_WIDTH-1:0] = dccm_rd_data_hi[pt.DCCM_DATA_WIDTH-1:0]; // for ld this is used for ecc
|
||||
|
||||
assign dccm_data_ecc_lo_m[pt.DCCM_ECC_WIDTH-1:0] = dccm_rd_data_lo[pt.DCCM_FDATA_WIDTH-1:pt.DCCM_DATA_WIDTH];
|
||||
assign dccm_data_ecc_hi_m[pt.DCCM_ECC_WIDTH-1:0] = dccm_rd_data_hi[pt.DCCM_FDATA_WIDTH-1:pt.DCCM_DATA_WIDTH];
|
||||
assign dccm_data_ecc_lo_m[pt.DCCM_ECC_WIDTH-1:0] = dccm_rd_data_lo[pt.DCCM_FDATA_WIDTH-1:pt.DCCM_DATA_WIDTH];
|
||||
assign dccm_data_ecc_hi_m[pt.DCCM_ECC_WIDTH-1:0] = dccm_rd_data_hi[pt.DCCM_FDATA_WIDTH-1:pt.DCCM_DATA_WIDTH];
|
||||
|
||||
// PIC signals. PIC ignores the lower 2 bits of address since PIC memory registers are 32-bits
|
||||
assign picm_wren = (lsu_pkt_r.valid & lsu_pkt_r.store & addr_in_pic_r & lsu_commit_r) | dma_pic_wen;
|
||||
assign picm_rden = lsu_pkt_d.valid & lsu_pkt_d.load & addr_in_pic_d;
|
||||
assign picm_mken = lsu_pkt_d.valid & lsu_pkt_d.store & addr_in_pic_d; // Get the mask for stores
|
||||
assign picm_rdaddr[31:0] = pt.PIC_BASE_ADDR | {{32-pt.PIC_BITS{1'b0}},lsu_addr_d[pt.PIC_BITS-1:0]};
|
||||
// PIC signals. PIC ignores the lower 2 bits of address since PIC memory registers are 32-bits
|
||||
assign picm_wren = (lsu_pkt_r.valid & lsu_pkt_r.store & addr_in_pic_r & lsu_commit_r) | dma_pic_wen;
|
||||
assign picm_rden = lsu_pkt_d.valid & lsu_pkt_d.load & addr_in_pic_d;
|
||||
assign picm_mken = lsu_pkt_d.valid & lsu_pkt_d.store & addr_in_pic_d; // Get the mask for stores
|
||||
assign picm_rdaddr[31:0] = pt.PIC_BASE_ADDR | {{32-pt.PIC_BITS{1'b0}},lsu_addr_d[pt.PIC_BITS-1:0]};
|
||||
|
||||
assign picm_wraddr[31:0] = pt.PIC_BASE_ADDR | {{32-pt.PIC_BITS{1'b0}},(dma_pic_wen ? dma_mem_addr[pt.PIC_BITS-1:0] : lsu_addr_r[pt.PIC_BITS-1:0])};
|
||||
assign picm_wraddr[31:0] = pt.PIC_BASE_ADDR | {{32-pt.PIC_BITS{1'b0}},(dma_pic_wen ? dma_mem_addr[pt.PIC_BITS-1:0] : lsu_addr_r[pt.PIC_BITS-1:0])};
|
||||
|
||||
assign picm_wr_data[31:0] = dma_pic_wen ? dma_mem_wdata[31:0] : store_datafn_lo_r[31:0];
|
||||
assign picm_wr_data[31:0] = dma_pic_wen ? dma_mem_wdata[31:0] : store_datafn_lo_r[31:0];
|
||||
|
||||
assign picm_mask_data_m[31:0] = picm_rd_data_m[31:0];
|
||||
assign picm_rd_data_m[63:0] = {picm_rd_data[31:0],picm_rd_data[31:0]};
|
||||
assign picm_mask_data_m[31:0] = picm_rd_data_m[31:0];
|
||||
assign picm_rd_data_m[63:0] = {picm_rd_data[31:0], picm_rd_data[31:0]};
|
||||
|
||||
if (pt.DCCM_ENABLE == 1) begin: Gen_dccm_enable
|
||||
rvdff #(1) dccm_rden_mff (.*, .din(lsu_dccm_rden_d), .dout(lsu_dccm_rden_m), .clk(lsu_c2_m_clk));
|
||||
rvdff #(1) dccm_rden_rff (.*, .din(lsu_dccm_rden_m), .dout(lsu_dccm_rden_r), .clk(lsu_c2_r_clk));
|
||||
if (pt.DCCM_ENABLE == 1) begin : Gen_dccm_enable
|
||||
rvdff #(1) dccm_rden_mff (
|
||||
.*,
|
||||
.din (lsu_dccm_rden_d),
|
||||
.dout(lsu_dccm_rden_m),
|
||||
.clk (lsu_c2_m_clk)
|
||||
);
|
||||
rvdff #(1) dccm_rden_rff (
|
||||
.*,
|
||||
.din (lsu_dccm_rden_m),
|
||||
.dout(lsu_dccm_rden_r),
|
||||
.clk (lsu_c2_r_clk)
|
||||
);
|
||||
|
||||
// ECC correction flops since dccm write happens next cycle
|
||||
// We are writing to dccm in r+1 for ecc correction since fast_int needs to be blocked in decode - 1. We can probably write in r for plus0 configuration since we know ecc error in M.
|
||||
// In that case these (_ff) flops are needed only in plus1 configuration
|
||||
rvdff #(1) ld_double_ecc_error_rff (.*, .din(lsu_double_ecc_error_r), .dout(lsu_double_ecc_error_r_ff), .clk(lsu_free_c2_clk));
|
||||
rvdff #(1) ld_single_ecc_error_hi_rff (.*, .din(ld_single_ecc_error_hi_r_ns), .dout(ld_single_ecc_error_hi_r_ff), .clk(lsu_free_c2_clk));
|
||||
rvdff #(1) ld_single_ecc_error_lo_rff (.*, .din(ld_single_ecc_error_lo_r_ns), .dout(ld_single_ecc_error_lo_r_ff), .clk(lsu_free_c2_clk));
|
||||
rvdffe #(pt.DCCM_BITS) ld_sec_addr_hi_rff (.*, .din(end_addr_r[pt.DCCM_BITS-1:0]), .dout(ld_sec_addr_hi_r_ff[pt.DCCM_BITS-1:0]), .en(ld_single_ecc_error_r | clk_override), .clk(clk));
|
||||
rvdffe #(pt.DCCM_BITS) ld_sec_addr_lo_rff (.*, .din(lsu_addr_r[pt.DCCM_BITS-1:0]), .dout(ld_sec_addr_lo_r_ff[pt.DCCM_BITS-1:0]), .en(ld_single_ecc_error_r | clk_override), .clk(clk));
|
||||
// ECC correction flops since dccm write happens next cycle
|
||||
// We are writing to dccm in r+1 for ecc correction since fast_int needs to be blocked in decode - 1. We can probably write in r for plus0 configuration since we know ecc error in M.
|
||||
// In that case these (_ff) flops are needed only in plus1 configuration
|
||||
rvdff #(1) ld_double_ecc_error_rff (
|
||||
.*,
|
||||
.din (lsu_double_ecc_error_r),
|
||||
.dout(lsu_double_ecc_error_r_ff),
|
||||
.clk (lsu_free_c2_clk)
|
||||
);
|
||||
rvdff #(1) ld_single_ecc_error_hi_rff (
|
||||
.*,
|
||||
.din (ld_single_ecc_error_hi_r_ns),
|
||||
.dout(ld_single_ecc_error_hi_r_ff),
|
||||
.clk (lsu_free_c2_clk)
|
||||
);
|
||||
rvdff #(1) ld_single_ecc_error_lo_rff (
|
||||
.*,
|
||||
.din (ld_single_ecc_error_lo_r_ns),
|
||||
.dout(ld_single_ecc_error_lo_r_ff),
|
||||
.clk (lsu_free_c2_clk)
|
||||
);
|
||||
rvdffe #(pt.DCCM_BITS) ld_sec_addr_hi_rff (
|
||||
.*,
|
||||
.din (end_addr_r[pt.DCCM_BITS-1:0]),
|
||||
.dout(ld_sec_addr_hi_r_ff[pt.DCCM_BITS-1:0]),
|
||||
.en (ld_single_ecc_error_r | clk_override),
|
||||
.clk (clk)
|
||||
);
|
||||
rvdffe #(pt.DCCM_BITS) ld_sec_addr_lo_rff (
|
||||
.*,
|
||||
.din (lsu_addr_r[pt.DCCM_BITS-1:0]),
|
||||
.dout(ld_sec_addr_lo_r_ff[pt.DCCM_BITS-1:0]),
|
||||
.en (ld_single_ecc_error_r | clk_override),
|
||||
.clk (clk)
|
||||
);
|
||||
|
||||
end else begin: Gen_dccm_disable
|
||||
assign lsu_dccm_rden_m = '0;
|
||||
assign lsu_dccm_rden_r = '0;
|
||||
end else begin : Gen_dccm_disable
|
||||
assign lsu_dccm_rden_m = '0;
|
||||
assign lsu_dccm_rden_r = '0;
|
||||
|
||||
assign lsu_double_ecc_error_r_ff = 1'b0;
|
||||
assign ld_single_ecc_error_hi_r_ff = 1'b0;
|
||||
assign ld_single_ecc_error_lo_r_ff = 1'b0;
|
||||
assign ld_sec_addr_hi_r_ff[pt.DCCM_BITS-1:0] = '0;
|
||||
assign ld_sec_addr_lo_r_ff[pt.DCCM_BITS-1:0] = '0;
|
||||
end
|
||||
assign lsu_double_ecc_error_r_ff = 1'b0;
|
||||
assign ld_single_ecc_error_hi_r_ff = 1'b0;
|
||||
assign ld_single_ecc_error_lo_r_ff = 1'b0;
|
||||
assign ld_sec_addr_hi_r_ff[pt.DCCM_BITS-1:0] = '0;
|
||||
assign ld_sec_addr_lo_r_ff[pt.DCCM_BITS-1:0] = '0;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -27,17 +27,14 @@
|
|||
// //********************************************************************************
|
||||
|
||||
|
||||
`define EL2_LOCAL_DCCM_RAM_TEST_PORTS .TEST1(dccm_ext_in_pkt[i].TEST1), \
|
||||
.RME(dccm_ext_in_pkt[i].RME), \
|
||||
.RM(dccm_ext_in_pkt[i].RM), \
|
||||
.LS(dccm_ext_in_pkt[i].LS), \
|
||||
.DS(dccm_ext_in_pkt[i].DS), \
|
||||
.SD(dccm_ext_in_pkt[i].SD), \
|
||||
.TEST_RNM(dccm_ext_in_pkt[i].TEST_RNM), \
|
||||
.BC1(dccm_ext_in_pkt[i].BC1), \
|
||||
.BC2(dccm_ext_in_pkt[i].BC2), \
|
||||
|
||||
|
||||
`define EL2_LOCAL_DCCM_RAM_TEST_PORTS .TEST1(dccm_ext_in_pkt[i].TEST1),\
|
||||
.RME(dccm_ext_in_pkt[i].RME),\
|
||||
.RM(dccm_ext_in_pkt[i].RM),\
|
||||
.LS(dccm_ext_in_pkt[i].LS),\
|
||||
.DS(dccm_ext_in_pkt[i].DS),\
|
||||
.SD(dccm_ext_in_pkt[i].SD),\
|
||||
.TEST_RNM(dccm_ext_in_pkt[i].TEST_RNM),\
|
||||
.BC1(dccm_ext_in_pkt[i].BC1),.BC2(dccm_ext_in_pkt[i].BC2),
|
||||
|
||||
module el2_lsu_dccm_mem
|
||||
import el2_pkg::*;
|
||||
|
|
|
@ -26,216 +26,269 @@
|
|||
//
|
||||
//********************************************************************************
|
||||
module el2_lsu_ecc
|
||||
import el2_pkg::*;
|
||||
import el2_pkg::*;
|
||||
#(
|
||||
`include "el2_param.vh"
|
||||
)
|
||||
(
|
||||
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
|
||||
input logic lsu_c2_r_clk, // clock
|
||||
input logic clk_override, // Override non-functional clock gating
|
||||
input logic rst_l, // reset, active low
|
||||
input logic scan_mode, // scan mode
|
||||
`include "el2_param.vh"
|
||||
) (
|
||||
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
|
||||
input logic lsu_c2_r_clk, // clock
|
||||
input logic clk_override, // Override non-functional clock gating
|
||||
input logic rst_l, // reset, active low
|
||||
input logic scan_mode, // scan mode
|
||||
|
||||
input el2_lsu_pkt_t lsu_pkt_m, // packet in m
|
||||
input el2_lsu_pkt_t lsu_pkt_r, // packet in r
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_data_any,
|
||||
input el2_lsu_pkt_t lsu_pkt_m, // packet in m
|
||||
input el2_lsu_pkt_t lsu_pkt_r, // packet in r
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_data_any,
|
||||
|
||||
input logic dec_tlu_core_ecc_disable, // disables the ecc computation and error flagging
|
||||
input logic dec_tlu_core_ecc_disable, // disables the ecc computation and error flagging
|
||||
|
||||
input logic lsu_dccm_rden_r, // dccm rden
|
||||
input logic addr_in_dccm_r, // address in dccm
|
||||
input logic [pt.DCCM_BITS-1:0] lsu_addr_r, // start address
|
||||
input logic [pt.DCCM_BITS-1:0] end_addr_r, // end address
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] dccm_rdata_hi_r, // data from the dccm
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] dccm_rdata_lo_r, // data from the dccm
|
||||
input logic [pt.DCCM_ECC_WIDTH-1:0] dccm_data_ecc_hi_r, // data from the dccm + ecc
|
||||
input logic [pt.DCCM_ECC_WIDTH-1:0] dccm_data_ecc_lo_r, // data from the dccm + ecc
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_hi_r, // corrected dccm data R-stage
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_lo_r, // corrected dccm data R-stage
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_hi_r_ff, // corrected dccm data R+1 stage
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_lo_r_ff, // corrected dccm data R+1 stage
|
||||
input logic lsu_dccm_rden_r, // dccm rden
|
||||
input logic addr_in_dccm_r, // address in dccm
|
||||
input logic [ pt.DCCM_BITS-1:0] lsu_addr_r, // start address
|
||||
input logic [ pt.DCCM_BITS-1:0] end_addr_r, // end address
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] dccm_rdata_hi_r, // data from the dccm
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] dccm_rdata_lo_r, // data from the dccm
|
||||
input logic [ pt.DCCM_ECC_WIDTH-1:0] dccm_data_ecc_hi_r, // data from the dccm + ecc
|
||||
input logic [ pt.DCCM_ECC_WIDTH-1:0] dccm_data_ecc_lo_r, // data from the dccm + ecc
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_hi_r, // corrected dccm data R-stage
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_lo_r, // corrected dccm data R-stage
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_hi_r_ff, // corrected dccm data R+1 stage
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_lo_r_ff, // corrected dccm data R+1 stage
|
||||
|
||||
input logic ld_single_ecc_error_r, // ld has a single ecc error
|
||||
input logic ld_single_ecc_error_r_ff, // ld has a single ecc error
|
||||
input logic lsu_dccm_rden_m, // dccm rden
|
||||
input logic addr_in_dccm_m, // address in dccm
|
||||
input logic [pt.DCCM_BITS-1:0] lsu_addr_m, // start address
|
||||
input logic [pt.DCCM_BITS-1:0] end_addr_m, // end address
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] dccm_rdata_hi_m, // raw data from mem
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] dccm_rdata_lo_m, // raw data from mem
|
||||
input logic [pt.DCCM_ECC_WIDTH-1:0] dccm_data_ecc_hi_m, // ecc read out from mem
|
||||
input logic [pt.DCCM_ECC_WIDTH-1:0] dccm_data_ecc_lo_m, // ecc read out from mem
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_hi_m, // corrected dccm data M-stage
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_lo_m, // corrected dccm data M-stage
|
||||
input logic ld_single_ecc_error_r, // ld has a single ecc error
|
||||
input logic ld_single_ecc_error_r_ff, // ld has a single ecc error
|
||||
input logic lsu_dccm_rden_m, // dccm rden
|
||||
input logic addr_in_dccm_m, // address in dccm
|
||||
input logic [ pt.DCCM_BITS-1:0] lsu_addr_m, // start address
|
||||
input logic [ pt.DCCM_BITS-1:0] end_addr_m, // end address
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] dccm_rdata_hi_m, // raw data from mem
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] dccm_rdata_lo_m, // raw data from mem
|
||||
input logic [ pt.DCCM_ECC_WIDTH-1:0] dccm_data_ecc_hi_m, // ecc read out from mem
|
||||
input logic [ pt.DCCM_ECC_WIDTH-1:0] dccm_data_ecc_lo_m, // ecc read out from mem
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_hi_m, // corrected dccm data M-stage
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_lo_m, // corrected dccm data M-stage
|
||||
|
||||
input logic dma_dccm_wen, // Perform DMA writes only for word/dword
|
||||
input logic [31:0] dma_dccm_wdata_lo, // Shifted dma data to lower bits to make it consistent to lsu stores
|
||||
input logic [31:0] dma_dccm_wdata_hi, // Shifted dma data to lower bits to make it consistent to lsu stores
|
||||
output logic [pt.DCCM_ECC_WIDTH-1:0] dma_dccm_wdata_ecc_hi, // ECC bits for the DMA wdata
|
||||
output logic [pt.DCCM_ECC_WIDTH-1:0] dma_dccm_wdata_ecc_lo, // ECC bits for the DMA wdata
|
||||
input logic dma_dccm_wen, // Perform DMA writes only for word/dword
|
||||
input logic [31:0] dma_dccm_wdata_lo, // Shifted dma data to lower bits to make it consistent to lsu stores
|
||||
input logic [31:0] dma_dccm_wdata_hi, // Shifted dma data to lower bits to make it consistent to lsu stores
|
||||
output logic [pt.DCCM_ECC_WIDTH-1:0] dma_dccm_wdata_ecc_hi, // ECC bits for the DMA wdata
|
||||
output logic [pt.DCCM_ECC_WIDTH-1:0] dma_dccm_wdata_ecc_lo, // ECC bits for the DMA wdata
|
||||
|
||||
output logic [pt.DCCM_ECC_WIDTH-1:0] stbuf_ecc_any, // Encoded data with ECC bits
|
||||
output logic [pt.DCCM_ECC_WIDTH-1:0] sec_data_ecc_hi_r_ff, // Encoded data with ECC bits
|
||||
output logic [pt.DCCM_ECC_WIDTH-1:0] sec_data_ecc_lo_r_ff, // Encoded data with ECC bits
|
||||
output logic [pt.DCCM_ECC_WIDTH-1:0] stbuf_ecc_any, // Encoded data with ECC bits
|
||||
output logic [pt.DCCM_ECC_WIDTH-1:0] sec_data_ecc_hi_r_ff, // Encoded data with ECC bits
|
||||
output logic [pt.DCCM_ECC_WIDTH-1:0] sec_data_ecc_lo_r_ff, // Encoded data with ECC bits
|
||||
|
||||
output logic single_ecc_error_hi_r, // sec detected
|
||||
output logic single_ecc_error_lo_r, // sec detected on lower dccm bank
|
||||
output logic lsu_single_ecc_error_r, // or of the 2
|
||||
output logic lsu_double_ecc_error_r, // double error detected
|
||||
output logic single_ecc_error_hi_r, // sec detected
|
||||
output logic single_ecc_error_lo_r, // sec detected on lower dccm bank
|
||||
output logic lsu_single_ecc_error_r, // or of the 2
|
||||
output logic lsu_double_ecc_error_r, // double error detected
|
||||
|
||||
output logic lsu_single_ecc_error_m, // or of the 2
|
||||
output logic lsu_double_ecc_error_m // double error detected
|
||||
output logic lsu_single_ecc_error_m, // or of the 2
|
||||
output logic lsu_double_ecc_error_m // double error detected
|
||||
|
||||
);
|
||||
);
|
||||
|
||||
logic is_ldst_r;
|
||||
logic is_ldst_hi_any, is_ldst_lo_any;
|
||||
logic [pt.DCCM_DATA_WIDTH-1:0] dccm_wdata_hi_any, dccm_wdata_lo_any;
|
||||
logic [pt.DCCM_ECC_WIDTH-1:0] dccm_wdata_ecc_hi_any, dccm_wdata_ecc_lo_any;
|
||||
logic [pt.DCCM_DATA_WIDTH-1:0] dccm_rdata_hi_any, dccm_rdata_lo_any;
|
||||
logic [pt.DCCM_ECC_WIDTH-1:0] dccm_data_ecc_hi_any, dccm_data_ecc_lo_any;
|
||||
logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_hi_any, sec_data_lo_any;
|
||||
logic single_ecc_error_hi_any, single_ecc_error_lo_any;
|
||||
logic double_ecc_error_hi_any, double_ecc_error_lo_any;
|
||||
logic is_ldst_r;
|
||||
logic is_ldst_hi_any, is_ldst_lo_any;
|
||||
logic [pt.DCCM_DATA_WIDTH-1:0] dccm_wdata_hi_any, dccm_wdata_lo_any;
|
||||
logic [pt.DCCM_ECC_WIDTH-1:0] dccm_wdata_ecc_hi_any, dccm_wdata_ecc_lo_any;
|
||||
logic [pt.DCCM_DATA_WIDTH-1:0] dccm_rdata_hi_any, dccm_rdata_lo_any;
|
||||
logic [pt.DCCM_ECC_WIDTH-1:0] dccm_data_ecc_hi_any, dccm_data_ecc_lo_any;
|
||||
logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_hi_any, sec_data_lo_any;
|
||||
logic single_ecc_error_hi_any, single_ecc_error_lo_any;
|
||||
logic double_ecc_error_hi_any, double_ecc_error_lo_any;
|
||||
|
||||
logic double_ecc_error_hi_m, double_ecc_error_lo_m;
|
||||
logic double_ecc_error_hi_r, double_ecc_error_lo_r;
|
||||
logic double_ecc_error_hi_m, double_ecc_error_lo_m;
|
||||
logic double_ecc_error_hi_r, double_ecc_error_lo_r;
|
||||
|
||||
logic [6:0] ecc_out_hi_nc, ecc_out_lo_nc;
|
||||
logic [6:0] ecc_out_hi_nc, ecc_out_lo_nc;
|
||||
|
||||
|
||||
if (pt.LOAD_TO_USE_PLUS1 == 1) begin: L2U_Plus1_1
|
||||
logic ldst_dual_m, ldst_dual_r;
|
||||
logic is_ldst_m;
|
||||
logic is_ldst_hi_r, is_ldst_lo_r;
|
||||
if (pt.LOAD_TO_USE_PLUS1 == 1) begin : L2U_Plus1_1
|
||||
logic ldst_dual_m, ldst_dual_r;
|
||||
logic is_ldst_m;
|
||||
logic is_ldst_hi_r, is_ldst_lo_r;
|
||||
|
||||
assign ldst_dual_r = (lsu_addr_r[2] != end_addr_r[2]);
|
||||
assign is_ldst_r = lsu_pkt_r.valid & (lsu_pkt_r.load | lsu_pkt_r.store) & addr_in_dccm_r & lsu_dccm_rden_r;
|
||||
assign is_ldst_lo_r = is_ldst_r & ~dec_tlu_core_ecc_disable;
|
||||
assign is_ldst_hi_r = is_ldst_r & ldst_dual_r & ~dec_tlu_core_ecc_disable; // Always check the ECC Hi/Lo for DMA since we don't align for DMA
|
||||
assign ldst_dual_r = (lsu_addr_r[2] != end_addr_r[2]);
|
||||
assign is_ldst_r = lsu_pkt_r.valid & (lsu_pkt_r.load | lsu_pkt_r.store) & addr_in_dccm_r & lsu_dccm_rden_r;
|
||||
assign is_ldst_lo_r = is_ldst_r & ~dec_tlu_core_ecc_disable;
|
||||
assign is_ldst_hi_r = is_ldst_r & ldst_dual_r & ~dec_tlu_core_ecc_disable; // Always check the ECC Hi/Lo for DMA since we don't align for DMA
|
||||
|
||||
assign is_ldst_hi_any = is_ldst_hi_r;
|
||||
assign dccm_rdata_hi_any[pt.DCCM_DATA_WIDTH-1:0] = dccm_rdata_hi_r[pt.DCCM_DATA_WIDTH-1:0];
|
||||
assign dccm_data_ecc_hi_any[pt.DCCM_ECC_WIDTH-1:0] = dccm_data_ecc_hi_r[pt.DCCM_ECC_WIDTH-1:0];
|
||||
assign is_ldst_lo_any = is_ldst_lo_r;
|
||||
assign dccm_rdata_lo_any[pt.DCCM_DATA_WIDTH-1:0] = dccm_rdata_lo_r[pt.DCCM_DATA_WIDTH-1:0];
|
||||
assign dccm_data_ecc_lo_any[pt.DCCM_ECC_WIDTH-1:0] = dccm_data_ecc_lo_r[pt.DCCM_ECC_WIDTH-1:0];
|
||||
assign is_ldst_hi_any = is_ldst_hi_r;
|
||||
assign dccm_rdata_hi_any[pt.DCCM_DATA_WIDTH-1:0] = dccm_rdata_hi_r[pt.DCCM_DATA_WIDTH-1:0];
|
||||
assign dccm_data_ecc_hi_any[pt.DCCM_ECC_WIDTH-1:0] = dccm_data_ecc_hi_r[pt.DCCM_ECC_WIDTH-1:0];
|
||||
assign is_ldst_lo_any = is_ldst_lo_r;
|
||||
assign dccm_rdata_lo_any[pt.DCCM_DATA_WIDTH-1:0] = dccm_rdata_lo_r[pt.DCCM_DATA_WIDTH-1:0];
|
||||
assign dccm_data_ecc_lo_any[pt.DCCM_ECC_WIDTH-1:0] = dccm_data_ecc_lo_r[pt.DCCM_ECC_WIDTH-1:0];
|
||||
|
||||
assign sec_data_hi_r[pt.DCCM_DATA_WIDTH-1:0] = sec_data_hi_any[pt.DCCM_DATA_WIDTH-1:0];
|
||||
assign single_ecc_error_hi_r = single_ecc_error_hi_any;
|
||||
assign double_ecc_error_hi_r = double_ecc_error_hi_any;
|
||||
assign sec_data_lo_r[pt.DCCM_DATA_WIDTH-1:0] = sec_data_lo_any[pt.DCCM_DATA_WIDTH-1:0];
|
||||
assign single_ecc_error_lo_r = single_ecc_error_lo_any;
|
||||
assign double_ecc_error_lo_r = double_ecc_error_lo_any;
|
||||
assign sec_data_hi_r[pt.DCCM_DATA_WIDTH-1:0] = sec_data_hi_any[pt.DCCM_DATA_WIDTH-1:0];
|
||||
assign single_ecc_error_hi_r = single_ecc_error_hi_any;
|
||||
assign double_ecc_error_hi_r = double_ecc_error_hi_any;
|
||||
assign sec_data_lo_r[pt.DCCM_DATA_WIDTH-1:0] = sec_data_lo_any[pt.DCCM_DATA_WIDTH-1:0];
|
||||
assign single_ecc_error_lo_r = single_ecc_error_lo_any;
|
||||
assign double_ecc_error_lo_r = double_ecc_error_lo_any;
|
||||
|
||||
assign lsu_single_ecc_error_r = single_ecc_error_hi_r | single_ecc_error_lo_r;
|
||||
assign lsu_double_ecc_error_r = double_ecc_error_hi_r | double_ecc_error_lo_r;
|
||||
assign lsu_single_ecc_error_r = single_ecc_error_hi_r | single_ecc_error_lo_r;
|
||||
assign lsu_double_ecc_error_r = double_ecc_error_hi_r | double_ecc_error_lo_r;
|
||||
|
||||
end else begin: L2U_Plus1_0
|
||||
end else begin : L2U_Plus1_0
|
||||
|
||||
logic ldst_dual_m;
|
||||
logic is_ldst_m;
|
||||
logic is_ldst_hi_m, is_ldst_lo_m;
|
||||
logic ldst_dual_m;
|
||||
logic is_ldst_m;
|
||||
logic is_ldst_hi_m, is_ldst_lo_m;
|
||||
|
||||
assign ldst_dual_m = (lsu_addr_m[2] != end_addr_m[2]);
|
||||
assign is_ldst_m = lsu_pkt_m.valid & (lsu_pkt_m.load | lsu_pkt_m.store) & addr_in_dccm_m & lsu_dccm_rden_m;
|
||||
assign is_ldst_lo_m = is_ldst_m & ~dec_tlu_core_ecc_disable;
|
||||
assign is_ldst_hi_m = is_ldst_m & (ldst_dual_m | lsu_pkt_m.dma) & ~dec_tlu_core_ecc_disable; // Always check the ECC Hi/Lo for DMA since we don't align for DMA
|
||||
assign ldst_dual_m = (lsu_addr_m[2] != end_addr_m[2]);
|
||||
assign is_ldst_m = lsu_pkt_m.valid & (lsu_pkt_m.load | lsu_pkt_m.store) & addr_in_dccm_m & lsu_dccm_rden_m;
|
||||
assign is_ldst_lo_m = is_ldst_m & ~dec_tlu_core_ecc_disable;
|
||||
assign is_ldst_hi_m = is_ldst_m & (ldst_dual_m | lsu_pkt_m.dma) & ~dec_tlu_core_ecc_disable; // Always check the ECC Hi/Lo for DMA since we don't align for DMA
|
||||
|
||||
assign is_ldst_hi_any = is_ldst_hi_m;
|
||||
assign dccm_rdata_hi_any[pt.DCCM_DATA_WIDTH-1:0] = dccm_rdata_hi_m[pt.DCCM_DATA_WIDTH-1:0];
|
||||
assign dccm_data_ecc_hi_any[pt.DCCM_ECC_WIDTH-1:0] = dccm_data_ecc_hi_m[pt.DCCM_ECC_WIDTH-1:0];
|
||||
assign is_ldst_lo_any = is_ldst_lo_m;
|
||||
assign dccm_rdata_lo_any[pt.DCCM_DATA_WIDTH-1:0] = dccm_rdata_lo_m[pt.DCCM_DATA_WIDTH-1:0];
|
||||
assign dccm_data_ecc_lo_any[pt.DCCM_ECC_WIDTH-1:0] = dccm_data_ecc_lo_m[pt.DCCM_ECC_WIDTH-1:0];
|
||||
assign is_ldst_hi_any = is_ldst_hi_m;
|
||||
assign dccm_rdata_hi_any[pt.DCCM_DATA_WIDTH-1:0] = dccm_rdata_hi_m[pt.DCCM_DATA_WIDTH-1:0];
|
||||
assign dccm_data_ecc_hi_any[pt.DCCM_ECC_WIDTH-1:0] = dccm_data_ecc_hi_m[pt.DCCM_ECC_WIDTH-1:0];
|
||||
assign is_ldst_lo_any = is_ldst_lo_m;
|
||||
assign dccm_rdata_lo_any[pt.DCCM_DATA_WIDTH-1:0] = dccm_rdata_lo_m[pt.DCCM_DATA_WIDTH-1:0];
|
||||
assign dccm_data_ecc_lo_any[pt.DCCM_ECC_WIDTH-1:0] = dccm_data_ecc_lo_m[pt.DCCM_ECC_WIDTH-1:0];
|
||||
|
||||
assign sec_data_hi_m[pt.DCCM_DATA_WIDTH-1:0] = sec_data_hi_any[pt.DCCM_DATA_WIDTH-1:0];
|
||||
assign double_ecc_error_hi_m = double_ecc_error_hi_any;
|
||||
assign sec_data_lo_m[pt.DCCM_DATA_WIDTH-1:0] = sec_data_lo_any[pt.DCCM_DATA_WIDTH-1:0];
|
||||
assign double_ecc_error_lo_m = double_ecc_error_lo_any;
|
||||
assign sec_data_hi_m[pt.DCCM_DATA_WIDTH-1:0] = sec_data_hi_any[pt.DCCM_DATA_WIDTH-1:0];
|
||||
assign double_ecc_error_hi_m = double_ecc_error_hi_any;
|
||||
assign sec_data_lo_m[pt.DCCM_DATA_WIDTH-1:0] = sec_data_lo_any[pt.DCCM_DATA_WIDTH-1:0];
|
||||
assign double_ecc_error_lo_m = double_ecc_error_lo_any;
|
||||
|
||||
assign lsu_single_ecc_error_m = single_ecc_error_hi_any | single_ecc_error_lo_any;
|
||||
assign lsu_double_ecc_error_m = double_ecc_error_hi_m | double_ecc_error_lo_m;
|
||||
assign lsu_single_ecc_error_m = single_ecc_error_hi_any | single_ecc_error_lo_any;
|
||||
assign lsu_double_ecc_error_m = double_ecc_error_hi_m | double_ecc_error_lo_m;
|
||||
|
||||
// Flops
|
||||
rvdff #(1) lsu_single_ecc_err_r (.din(lsu_single_ecc_error_m), .dout(lsu_single_ecc_error_r), .clk(lsu_c2_r_clk), .*);
|
||||
rvdff #(1) lsu_double_ecc_err_r (.din(lsu_double_ecc_error_m), .dout(lsu_double_ecc_error_r), .clk(lsu_c2_r_clk), .*);
|
||||
rvdff #(.WIDTH(1)) ldst_sec_lo_rff (.din(single_ecc_error_lo_any), .dout(single_ecc_error_lo_r), .clk(lsu_c2_r_clk), .*);
|
||||
rvdff #(.WIDTH(1)) ldst_sec_hi_rff (.din(single_ecc_error_hi_any), .dout(single_ecc_error_hi_r), .clk(lsu_c2_r_clk), .*);
|
||||
rvdffe #(.WIDTH(pt.DCCM_DATA_WIDTH)) sec_data_hi_rff (.din(sec_data_hi_m[pt.DCCM_DATA_WIDTH-1:0]), .dout(sec_data_hi_r[pt.DCCM_DATA_WIDTH-1:0]), .en(lsu_single_ecc_error_m | clk_override), .*);
|
||||
rvdffe #(.WIDTH(pt.DCCM_DATA_WIDTH)) sec_data_lo_rff (.din(sec_data_lo_m[pt.DCCM_DATA_WIDTH-1:0]), .dout(sec_data_lo_r[pt.DCCM_DATA_WIDTH-1:0]), .en(lsu_single_ecc_error_m | clk_override), .*);
|
||||
// Flops
|
||||
rvdff #(1) lsu_single_ecc_err_r (
|
||||
.din (lsu_single_ecc_error_m),
|
||||
.dout(lsu_single_ecc_error_r),
|
||||
.clk (lsu_c2_r_clk),
|
||||
.*
|
||||
);
|
||||
rvdff #(1) lsu_double_ecc_err_r (
|
||||
.din (lsu_double_ecc_error_m),
|
||||
.dout(lsu_double_ecc_error_r),
|
||||
.clk (lsu_c2_r_clk),
|
||||
.*
|
||||
);
|
||||
rvdff #(
|
||||
.WIDTH(1)
|
||||
) ldst_sec_lo_rff (
|
||||
.din (single_ecc_error_lo_any),
|
||||
.dout(single_ecc_error_lo_r),
|
||||
.clk (lsu_c2_r_clk),
|
||||
.*
|
||||
);
|
||||
rvdff #(
|
||||
.WIDTH(1)
|
||||
) ldst_sec_hi_rff (
|
||||
.din (single_ecc_error_hi_any),
|
||||
.dout(single_ecc_error_hi_r),
|
||||
.clk (lsu_c2_r_clk),
|
||||
.*
|
||||
);
|
||||
rvdffe #(
|
||||
.WIDTH(pt.DCCM_DATA_WIDTH)
|
||||
) sec_data_hi_rff (
|
||||
.din (sec_data_hi_m[pt.DCCM_DATA_WIDTH-1:0]),
|
||||
.dout(sec_data_hi_r[pt.DCCM_DATA_WIDTH-1:0]),
|
||||
.en (lsu_single_ecc_error_m | clk_override),
|
||||
.*
|
||||
);
|
||||
rvdffe #(
|
||||
.WIDTH(pt.DCCM_DATA_WIDTH)
|
||||
) sec_data_lo_rff (
|
||||
.din (sec_data_lo_m[pt.DCCM_DATA_WIDTH-1:0]),
|
||||
.dout(sec_data_lo_r[pt.DCCM_DATA_WIDTH-1:0]),
|
||||
.en (lsu_single_ecc_error_m | clk_override),
|
||||
.*
|
||||
);
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
// Logic for ECC generation during write
|
||||
assign dccm_wdata_lo_any[pt.DCCM_DATA_WIDTH-1:0] = ld_single_ecc_error_r_ff ? sec_data_lo_r_ff[pt.DCCM_DATA_WIDTH-1:0] : (dma_dccm_wen ? dma_dccm_wdata_lo[pt.DCCM_DATA_WIDTH-1:0] : stbuf_data_any[pt.DCCM_DATA_WIDTH-1:0]);
|
||||
assign dccm_wdata_hi_any[pt.DCCM_DATA_WIDTH-1:0] = ld_single_ecc_error_r_ff ? sec_data_hi_r_ff[pt.DCCM_DATA_WIDTH-1:0] : (dma_dccm_wen ? dma_dccm_wdata_hi[pt.DCCM_DATA_WIDTH-1:0] : 32'h0);
|
||||
// Logic for ECC generation during write
|
||||
assign dccm_wdata_lo_any[pt.DCCM_DATA_WIDTH-1:0] = ld_single_ecc_error_r_ff ? sec_data_lo_r_ff[pt.DCCM_DATA_WIDTH-1:0] : (dma_dccm_wen ? dma_dccm_wdata_lo[pt.DCCM_DATA_WIDTH-1:0] : stbuf_data_any[pt.DCCM_DATA_WIDTH-1:0]);
|
||||
assign dccm_wdata_hi_any[pt.DCCM_DATA_WIDTH-1:0] = ld_single_ecc_error_r_ff ? sec_data_hi_r_ff[pt.DCCM_DATA_WIDTH-1:0] : (dma_dccm_wen ? dma_dccm_wdata_hi[pt.DCCM_DATA_WIDTH-1:0] : 32'h0);
|
||||
|
||||
assign sec_data_ecc_hi_r_ff[pt.DCCM_ECC_WIDTH-1:0] = dccm_wdata_ecc_hi_any[pt.DCCM_ECC_WIDTH-1:0];
|
||||
assign sec_data_ecc_lo_r_ff[pt.DCCM_ECC_WIDTH-1:0] = dccm_wdata_ecc_lo_any[pt.DCCM_ECC_WIDTH-1:0];
|
||||
assign stbuf_ecc_any[pt.DCCM_ECC_WIDTH-1:0] = dccm_wdata_ecc_lo_any[pt.DCCM_ECC_WIDTH-1:0];
|
||||
assign dma_dccm_wdata_ecc_hi[pt.DCCM_ECC_WIDTH-1:0] = dccm_wdata_ecc_hi_any[pt.DCCM_ECC_WIDTH-1:0];
|
||||
assign dma_dccm_wdata_ecc_lo[pt.DCCM_ECC_WIDTH-1:0] = dccm_wdata_ecc_lo_any[pt.DCCM_ECC_WIDTH-1:0];
|
||||
assign sec_data_ecc_hi_r_ff[pt.DCCM_ECC_WIDTH-1:0] = dccm_wdata_ecc_hi_any[pt.DCCM_ECC_WIDTH-1:0];
|
||||
assign sec_data_ecc_lo_r_ff[pt.DCCM_ECC_WIDTH-1:0] = dccm_wdata_ecc_lo_any[pt.DCCM_ECC_WIDTH-1:0];
|
||||
assign stbuf_ecc_any[pt.DCCM_ECC_WIDTH-1:0] = dccm_wdata_ecc_lo_any[pt.DCCM_ECC_WIDTH-1:0];
|
||||
assign dma_dccm_wdata_ecc_hi[pt.DCCM_ECC_WIDTH-1:0] = dccm_wdata_ecc_hi_any[pt.DCCM_ECC_WIDTH-1:0];
|
||||
assign dma_dccm_wdata_ecc_lo[pt.DCCM_ECC_WIDTH-1:0] = dccm_wdata_ecc_lo_any[pt.DCCM_ECC_WIDTH-1:0];
|
||||
|
||||
// Instantiate ECC blocks
|
||||
if (pt.DCCM_ENABLE == 1) begin: Gen_dccm_enable
|
||||
// Instantiate ECC blocks
|
||||
if (pt.DCCM_ENABLE == 1) begin : Gen_dccm_enable
|
||||
|
||||
//Detect/Repair for Hi
|
||||
rvecc_decode lsu_ecc_decode_hi (
|
||||
// Inputs
|
||||
.en(is_ldst_hi_any),
|
||||
.sed_ded (1'b0), // 1 : means only detection
|
||||
.din(dccm_rdata_hi_any[pt.DCCM_DATA_WIDTH-1:0]),
|
||||
.ecc_in(dccm_data_ecc_hi_any[pt.DCCM_ECC_WIDTH-1:0]),
|
||||
// Outputs
|
||||
.dout(sec_data_hi_any[pt.DCCM_DATA_WIDTH-1:0]),
|
||||
.ecc_out (ecc_out_hi_nc[6:0]),
|
||||
.single_ecc_error(single_ecc_error_hi_any),
|
||||
.double_ecc_error(double_ecc_error_hi_any),
|
||||
.*
|
||||
);
|
||||
//Detect/Repair for Hi
|
||||
rvecc_decode lsu_ecc_decode_hi (
|
||||
// Inputs
|
||||
.en(is_ldst_hi_any),
|
||||
.sed_ded(1'b0), // 1 : means only detection
|
||||
.din(dccm_rdata_hi_any[pt.DCCM_DATA_WIDTH-1:0]),
|
||||
.ecc_in(dccm_data_ecc_hi_any[pt.DCCM_ECC_WIDTH-1:0]),
|
||||
// Outputs
|
||||
.dout(sec_data_hi_any[pt.DCCM_DATA_WIDTH-1:0]),
|
||||
.ecc_out(ecc_out_hi_nc[6:0]),
|
||||
.single_ecc_error(single_ecc_error_hi_any),
|
||||
.double_ecc_error(double_ecc_error_hi_any),
|
||||
.*
|
||||
);
|
||||
|
||||
//Detect/Repair for Lo
|
||||
rvecc_decode lsu_ecc_decode_lo (
|
||||
// Inputs
|
||||
.en(is_ldst_lo_any),
|
||||
.sed_ded (1'b0), // 1 : means only detection
|
||||
.din(dccm_rdata_lo_any[pt.DCCM_DATA_WIDTH-1:0] ),
|
||||
.ecc_in(dccm_data_ecc_lo_any[pt.DCCM_ECC_WIDTH-1:0]),
|
||||
// Outputs
|
||||
.dout(sec_data_lo_any[pt.DCCM_DATA_WIDTH-1:0]),
|
||||
.ecc_out (ecc_out_lo_nc[6:0]),
|
||||
.single_ecc_error(single_ecc_error_lo_any),
|
||||
.double_ecc_error(double_ecc_error_lo_any),
|
||||
.*
|
||||
);
|
||||
//Detect/Repair for Lo
|
||||
rvecc_decode lsu_ecc_decode_lo (
|
||||
// Inputs
|
||||
.en(is_ldst_lo_any),
|
||||
.sed_ded(1'b0), // 1 : means only detection
|
||||
.din(dccm_rdata_lo_any[pt.DCCM_DATA_WIDTH-1:0]),
|
||||
.ecc_in(dccm_data_ecc_lo_any[pt.DCCM_ECC_WIDTH-1:0]),
|
||||
// Outputs
|
||||
.dout(sec_data_lo_any[pt.DCCM_DATA_WIDTH-1:0]),
|
||||
.ecc_out(ecc_out_lo_nc[6:0]),
|
||||
.single_ecc_error(single_ecc_error_lo_any),
|
||||
.double_ecc_error(double_ecc_error_lo_any),
|
||||
.*
|
||||
);
|
||||
|
||||
rvecc_encode lsu_ecc_encode_hi (
|
||||
//Inputs
|
||||
.din(dccm_wdata_hi_any[pt.DCCM_DATA_WIDTH-1:0]),
|
||||
//Outputs
|
||||
.ecc_out(dccm_wdata_ecc_hi_any[pt.DCCM_ECC_WIDTH-1:0]),
|
||||
.*
|
||||
);
|
||||
rvecc_encode lsu_ecc_encode_lo (
|
||||
//Inputs
|
||||
.din(dccm_wdata_lo_any[pt.DCCM_DATA_WIDTH-1:0]),
|
||||
//Outputs
|
||||
.ecc_out(dccm_wdata_ecc_lo_any[pt.DCCM_ECC_WIDTH-1:0]),
|
||||
.*
|
||||
);
|
||||
end else begin: Gen_dccm_disable // block: Gen_dccm_enable
|
||||
assign sec_data_hi_any[pt.DCCM_DATA_WIDTH-1:0] = '0;
|
||||
assign sec_data_lo_any[pt.DCCM_DATA_WIDTH-1:0] = '0;
|
||||
assign single_ecc_error_hi_any = '0;
|
||||
assign double_ecc_error_hi_any = '0;
|
||||
assign single_ecc_error_lo_any = '0;
|
||||
assign double_ecc_error_lo_any = '0;
|
||||
end
|
||||
rvecc_encode lsu_ecc_encode_hi (
|
||||
//Inputs
|
||||
.din(dccm_wdata_hi_any[pt.DCCM_DATA_WIDTH-1:0]),
|
||||
//Outputs
|
||||
.ecc_out(dccm_wdata_ecc_hi_any[pt.DCCM_ECC_WIDTH-1:0]),
|
||||
.*
|
||||
);
|
||||
rvecc_encode lsu_ecc_encode_lo (
|
||||
//Inputs
|
||||
.din(dccm_wdata_lo_any[pt.DCCM_DATA_WIDTH-1:0]),
|
||||
//Outputs
|
||||
.ecc_out(dccm_wdata_ecc_lo_any[pt.DCCM_ECC_WIDTH-1:0]),
|
||||
.*
|
||||
);
|
||||
end else begin : Gen_dccm_disable // block: Gen_dccm_enable
|
||||
assign sec_data_hi_any[pt.DCCM_DATA_WIDTH-1:0] = '0;
|
||||
assign sec_data_lo_any[pt.DCCM_DATA_WIDTH-1:0] = '0;
|
||||
assign single_ecc_error_hi_any = '0;
|
||||
assign double_ecc_error_hi_any = '0;
|
||||
assign single_ecc_error_lo_any = '0;
|
||||
assign double_ecc_error_lo_any = '0;
|
||||
end
|
||||
|
||||
rvdffe #(.WIDTH(pt.DCCM_DATA_WIDTH)) sec_data_hi_rplus1ff (.din(sec_data_hi_r[pt.DCCM_DATA_WIDTH-1:0]), .dout(sec_data_hi_r_ff[pt.DCCM_DATA_WIDTH-1:0]), .en(ld_single_ecc_error_r | clk_override), .clk(clk), .*);
|
||||
rvdffe #(.WIDTH(pt.DCCM_DATA_WIDTH)) sec_data_lo_rplus1ff (.din(sec_data_lo_r[pt.DCCM_DATA_WIDTH-1:0]), .dout(sec_data_lo_r_ff[pt.DCCM_DATA_WIDTH-1:0]), .en(ld_single_ecc_error_r | clk_override), .clk(clk), .*);
|
||||
rvdffe #(
|
||||
.WIDTH(pt.DCCM_DATA_WIDTH)
|
||||
) sec_data_hi_rplus1ff (
|
||||
.din (sec_data_hi_r[pt.DCCM_DATA_WIDTH-1:0]),
|
||||
.dout(sec_data_hi_r_ff[pt.DCCM_DATA_WIDTH-1:0]),
|
||||
.en (ld_single_ecc_error_r | clk_override),
|
||||
.clk (clk),
|
||||
.*
|
||||
);
|
||||
rvdffe #(
|
||||
.WIDTH(pt.DCCM_DATA_WIDTH)
|
||||
) sec_data_lo_rplus1ff (
|
||||
.din (sec_data_lo_r[pt.DCCM_DATA_WIDTH-1:0]),
|
||||
.dout(sec_data_lo_r_ff[pt.DCCM_DATA_WIDTH-1:0]),
|
||||
.en (ld_single_ecc_error_r | clk_override),
|
||||
.clk (clk),
|
||||
.*
|
||||
);
|
||||
|
||||
|
||||
endmodule // el2_lsu_ecc
|
||||
endmodule // el2_lsu_ecc
|
||||
|
|
|
@ -26,316 +26,483 @@
|
|||
//
|
||||
//********************************************************************************
|
||||
module el2_lsu_lsc_ctl
|
||||
import el2_pkg::*;
|
||||
import el2_pkg::*;
|
||||
#(
|
||||
`include "el2_param.vh"
|
||||
)(
|
||||
input logic rst_l, // reset, active low
|
||||
input logic clk_override, // Override non-functional clock gating
|
||||
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
|
||||
`include "el2_param.vh"
|
||||
) (
|
||||
input logic rst_l, // reset, active low
|
||||
input logic clk_override, // Override non-functional clock gating
|
||||
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
|
||||
|
||||
// clocks per pipe
|
||||
input logic lsu_c1_m_clk,
|
||||
input logic lsu_c1_r_clk,
|
||||
input logic lsu_c2_m_clk,
|
||||
input logic lsu_c2_r_clk,
|
||||
input logic lsu_store_c1_m_clk,
|
||||
// clocks per pipe
|
||||
input logic lsu_c1_m_clk,
|
||||
input logic lsu_c1_r_clk,
|
||||
input logic lsu_c2_m_clk,
|
||||
input logic lsu_c2_r_clk,
|
||||
input logic lsu_store_c1_m_clk,
|
||||
|
||||
input logic [31:0] lsu_ld_data_r, // Load data R-stage
|
||||
input logic [31:0] lsu_ld_data_corr_r, // ECC corrected data R-stage
|
||||
input logic lsu_single_ecc_error_r, // ECC single bit error R-stage
|
||||
input logic lsu_double_ecc_error_r, // ECC double bit error R-stage
|
||||
input logic [31:0] lsu_ld_data_r, // Load data R-stage
|
||||
input logic [31:0] lsu_ld_data_corr_r, // ECC corrected data R-stage
|
||||
input logic lsu_single_ecc_error_r, // ECC single bit error R-stage
|
||||
input logic lsu_double_ecc_error_r, // ECC double bit error R-stage
|
||||
|
||||
input logic [31:0] lsu_ld_data_m, // Load data M-stage
|
||||
input logic lsu_single_ecc_error_m, // ECC single bit error M-stage
|
||||
input logic lsu_double_ecc_error_m, // ECC double bit error M-stage
|
||||
input logic [31:0] lsu_ld_data_m, // Load data M-stage
|
||||
input logic lsu_single_ecc_error_m, // ECC single bit error M-stage
|
||||
input logic lsu_double_ecc_error_m, // ECC double bit error M-stage
|
||||
|
||||
input logic flush_m_up, // Flush M and D stage
|
||||
input logic flush_r, // Flush R-stage
|
||||
input logic ldst_dual_d, // load/store is unaligned at 32 bit boundary D-stage
|
||||
input logic ldst_dual_m, // load/store is unaligned at 32 bit boundary M-stage
|
||||
input logic ldst_dual_r, // load/store is unaligned at 32 bit boundary R-stage
|
||||
input logic flush_m_up, // Flush M and D stage
|
||||
input logic flush_r, // Flush R-stage
|
||||
input logic ldst_dual_d, // load/store is unaligned at 32 bit boundary D-stage
|
||||
input logic ldst_dual_m, // load/store is unaligned at 32 bit boundary M-stage
|
||||
input logic ldst_dual_r, // load/store is unaligned at 32 bit boundary R-stage
|
||||
|
||||
input logic [31:0] exu_lsu_rs1_d, // address
|
||||
input logic [31:0] exu_lsu_rs2_d, // store data
|
||||
input logic [31:0] exu_lsu_rs1_d, // address
|
||||
input logic [31:0] exu_lsu_rs2_d, // store data
|
||||
|
||||
input el2_lsu_pkt_t lsu_p, // lsu control packet
|
||||
input logic dec_lsu_valid_raw_d, // Raw valid for address computation
|
||||
input logic [11:0] dec_lsu_offset_d, // 12b offset for load/store addresses
|
||||
input el2_lsu_pkt_t lsu_p, // lsu control packet
|
||||
input logic dec_lsu_valid_raw_d, // Raw valid for address computation
|
||||
input logic [11:0] dec_lsu_offset_d, // 12b offset for load/store addresses
|
||||
|
||||
input logic [31:0] picm_mask_data_m, // PIC data M-stage
|
||||
input logic [31:0] bus_read_data_m, // the bus return data
|
||||
output logic [31:0] lsu_result_m, // lsu load data
|
||||
output logic [31:0] lsu_result_corr_r, // This is the ECC corrected data going to RF
|
||||
// lsu address down the pipe
|
||||
output logic [31:0] lsu_addr_d,
|
||||
output logic [31:0] lsu_addr_m,
|
||||
output logic [31:0] lsu_addr_r,
|
||||
// lsu address down the pipe - needed to check unaligned
|
||||
output logic [31:0] end_addr_d,
|
||||
output logic [31:0] end_addr_m,
|
||||
output logic [31:0] end_addr_r,
|
||||
// store data down the pipe
|
||||
output logic [31:0] store_data_m,
|
||||
input logic [31:0] picm_mask_data_m, // PIC data M-stage
|
||||
input logic [31:0] bus_read_data_m, // the bus return data
|
||||
output logic [31:0] lsu_result_m, // lsu load data
|
||||
output logic [31:0] lsu_result_corr_r, // This is the ECC corrected data going to RF
|
||||
// lsu address down the pipe
|
||||
output logic [31:0] lsu_addr_d,
|
||||
output logic [31:0] lsu_addr_m,
|
||||
output logic [31:0] lsu_addr_r,
|
||||
// lsu address down the pipe - needed to check unaligned
|
||||
output logic [31:0] end_addr_d,
|
||||
output logic [31:0] end_addr_m,
|
||||
output logic [31:0] end_addr_r,
|
||||
// store data down the pipe
|
||||
output logic [31:0] store_data_m,
|
||||
|
||||
input logic [31:0] dec_tlu_mrac_ff, // CSR for memory region control
|
||||
output logic lsu_exc_m, // Access or misaligned fault
|
||||
output logic is_sideeffects_m, // is sideffects space
|
||||
output logic lsu_commit_r, // lsu instruction in r commits
|
||||
output logic lsu_single_ecc_error_incr,// LSU inc SB error counter
|
||||
output el2_lsu_error_pkt_t lsu_error_pkt_r, // lsu exception packet
|
||||
input logic [31:0] dec_tlu_mrac_ff, // CSR for memory region control
|
||||
output logic lsu_exc_m, // Access or misaligned fault
|
||||
output logic is_sideeffects_m, // is sideffects space
|
||||
output logic lsu_commit_r, // lsu instruction in r commits
|
||||
output logic lsu_single_ecc_error_incr, // LSU inc SB error counter
|
||||
output el2_lsu_error_pkt_t lsu_error_pkt_r, // lsu exception packet
|
||||
|
||||
output logic [31:1] lsu_fir_addr, // fast interrupt address
|
||||
output logic [1:0] lsu_fir_error, // Error during fast interrupt lookup
|
||||
output logic [31:1] lsu_fir_addr, // fast interrupt address
|
||||
output logic [ 1:0] lsu_fir_error, // Error during fast interrupt lookup
|
||||
|
||||
// address in dccm/pic/external per pipe stage
|
||||
output logic addr_in_dccm_d,
|
||||
output logic addr_in_dccm_m,
|
||||
output logic addr_in_dccm_r,
|
||||
// address in dccm/pic/external per pipe stage
|
||||
output logic addr_in_dccm_d,
|
||||
output logic addr_in_dccm_m,
|
||||
output logic addr_in_dccm_r,
|
||||
|
||||
output logic addr_in_pic_d,
|
||||
output logic addr_in_pic_m,
|
||||
output logic addr_in_pic_r,
|
||||
output logic addr_in_pic_d,
|
||||
output logic addr_in_pic_m,
|
||||
output logic addr_in_pic_r,
|
||||
|
||||
output logic addr_external_m,
|
||||
output logic addr_external_m,
|
||||
|
||||
// DMA slave
|
||||
input logic dma_dccm_req,
|
||||
input logic [31:0] dma_mem_addr,
|
||||
input logic [2:0] dma_mem_sz,
|
||||
input logic dma_mem_write,
|
||||
input logic [63:0] dma_mem_wdata,
|
||||
// DMA slave
|
||||
input logic dma_dccm_req,
|
||||
input logic [31:0] dma_mem_addr,
|
||||
input logic [ 2:0] dma_mem_sz,
|
||||
input logic dma_mem_write,
|
||||
input logic [63:0] dma_mem_wdata,
|
||||
|
||||
// Store buffer related signals
|
||||
output el2_lsu_pkt_t lsu_pkt_d,
|
||||
output el2_lsu_pkt_t lsu_pkt_m,
|
||||
output el2_lsu_pkt_t lsu_pkt_r,
|
||||
// Store buffer related signals
|
||||
output el2_lsu_pkt_t lsu_pkt_d,
|
||||
output el2_lsu_pkt_t lsu_pkt_m,
|
||||
output el2_lsu_pkt_t lsu_pkt_r,
|
||||
|
||||
input logic scan_mode // Scan mode
|
||||
input logic scan_mode // Scan mode
|
||||
|
||||
);
|
||||
);
|
||||
|
||||
logic [31:3] end_addr_pre_m, end_addr_pre_r;
|
||||
logic [31:0] full_addr_d;
|
||||
logic [31:0] full_end_addr_d;
|
||||
logic [31:0] lsu_rs1_d;
|
||||
logic [11:0] lsu_offset_d;
|
||||
logic [31:0] rs1_d;
|
||||
logic [11:0] offset_d;
|
||||
logic [12:0] end_addr_offset_d;
|
||||
logic [2:0] addr_offset_d;
|
||||
logic [31:3] end_addr_pre_m, end_addr_pre_r;
|
||||
logic [31:0] full_addr_d;
|
||||
logic [31:0] full_end_addr_d;
|
||||
logic [31:0] lsu_rs1_d;
|
||||
logic [11:0] lsu_offset_d;
|
||||
logic [31:0] rs1_d;
|
||||
logic [11:0] offset_d;
|
||||
logic [12:0] end_addr_offset_d;
|
||||
logic [ 2:0] addr_offset_d;
|
||||
|
||||
logic [63:0] dma_mem_wdata_shifted;
|
||||
logic addr_external_d;
|
||||
logic addr_external_r;
|
||||
logic access_fault_d, misaligned_fault_d;
|
||||
logic access_fault_m, misaligned_fault_m;
|
||||
logic [63:0] dma_mem_wdata_shifted;
|
||||
logic addr_external_d;
|
||||
logic addr_external_r;
|
||||
logic access_fault_d, misaligned_fault_d;
|
||||
logic access_fault_m, misaligned_fault_m;
|
||||
|
||||
logic fir_dccm_access_error_d, fir_nondccm_access_error_d;
|
||||
logic fir_dccm_access_error_m, fir_nondccm_access_error_m;
|
||||
logic fir_dccm_access_error_d, fir_nondccm_access_error_d;
|
||||
logic fir_dccm_access_error_m, fir_nondccm_access_error_m;
|
||||
|
||||
logic [3:0] exc_mscause_d, exc_mscause_m;
|
||||
logic [31:0] rs1_d_raw;
|
||||
logic [31:0] store_data_d, store_data_pre_m, store_data_m_in;
|
||||
logic [31:0] bus_read_data_r;
|
||||
logic [3:0] exc_mscause_d, exc_mscause_m;
|
||||
logic [31:0] rs1_d_raw;
|
||||
logic [31:0] store_data_d, store_data_pre_m, store_data_m_in;
|
||||
logic [31:0] bus_read_data_r;
|
||||
|
||||
el2_lsu_pkt_t dma_pkt_d;
|
||||
el2_lsu_pkt_t lsu_pkt_m_in, lsu_pkt_r_in;
|
||||
el2_lsu_error_pkt_t lsu_error_pkt_m;
|
||||
el2_lsu_pkt_t dma_pkt_d;
|
||||
el2_lsu_pkt_t lsu_pkt_m_in, lsu_pkt_r_in;
|
||||
el2_lsu_error_pkt_t lsu_error_pkt_m;
|
||||
|
||||
|
||||
// Premux the rs1/offset for dma
|
||||
assign lsu_rs1_d[31:0] = dec_lsu_valid_raw_d ? exu_lsu_rs1_d[31:0] : dma_mem_addr[31:0];
|
||||
assign lsu_offset_d[11:0] = dec_lsu_offset_d[11:0] & {12{dec_lsu_valid_raw_d}};
|
||||
assign rs1_d_raw[31:0] = lsu_rs1_d[31:0];
|
||||
assign offset_d[11:0] = lsu_offset_d[11:0];
|
||||
// Premux the rs1/offset for dma
|
||||
assign lsu_rs1_d[31:0] = dec_lsu_valid_raw_d ? exu_lsu_rs1_d[31:0] : dma_mem_addr[31:0];
|
||||
assign lsu_offset_d[11:0] = dec_lsu_offset_d[11:0] & {12{dec_lsu_valid_raw_d}};
|
||||
assign rs1_d_raw[31:0] = lsu_rs1_d[31:0];
|
||||
assign offset_d[11:0] = lsu_offset_d[11:0];
|
||||
|
||||
assign rs1_d[31:0] = (lsu_pkt_d.load_ldst_bypass_d) ? lsu_result_m[31:0] : rs1_d_raw[31:0];
|
||||
assign rs1_d[31:0] = (lsu_pkt_d.load_ldst_bypass_d) ? lsu_result_m[31:0] : rs1_d_raw[31:0];
|
||||
|
||||
// generate the ls address
|
||||
rvlsadder lsadder (.rs1(rs1_d[31:0]),
|
||||
.offset(offset_d[11:0]),
|
||||
.dout(full_addr_d[31:0])
|
||||
);
|
||||
|
||||
// Module to generate the memory map of the address
|
||||
el2_lsu_addrcheck addrcheck (
|
||||
.start_addr_d(full_addr_d[31:0]),
|
||||
.end_addr_d(full_end_addr_d[31:0]),
|
||||
.rs1_region_d(rs1_d[31:28]),
|
||||
.*
|
||||
// generate the ls address
|
||||
rvlsadder lsadder (
|
||||
.rs1(rs1_d[31:0]),
|
||||
.offset(offset_d[11:0]),
|
||||
.dout(full_addr_d[31:0])
|
||||
);
|
||||
|
||||
// Calculate start/end address for load/store
|
||||
assign addr_offset_d[2:0] = ({3{lsu_pkt_d.half}} & 3'b01) | ({3{lsu_pkt_d.word}} & 3'b11) | ({3{lsu_pkt_d.dword}} & 3'b111);
|
||||
assign end_addr_offset_d[12:0] = {offset_d[11],offset_d[11:0]} + {9'b0,addr_offset_d[2:0]};
|
||||
assign full_end_addr_d[31:0] = rs1_d[31:0] + {{19{end_addr_offset_d[12]}},end_addr_offset_d[12:0]};
|
||||
assign end_addr_d[31:0] = full_end_addr_d[31:0];
|
||||
assign lsu_exc_m = access_fault_m | misaligned_fault_m;
|
||||
// Module to generate the memory map of the address
|
||||
el2_lsu_addrcheck addrcheck (
|
||||
.start_addr_d(full_addr_d[31:0]),
|
||||
.end_addr_d (full_end_addr_d[31:0]),
|
||||
.rs1_region_d(rs1_d[31:28]),
|
||||
.*
|
||||
);
|
||||
|
||||
// Goes to TLU to increment the ECC error counter
|
||||
assign lsu_single_ecc_error_incr = (lsu_single_ecc_error_r & ~lsu_double_ecc_error_r) & (lsu_commit_r | lsu_pkt_r.dma) & lsu_pkt_r.valid;
|
||||
// Calculate start/end address for load/store
|
||||
assign addr_offset_d[2:0] = ({3{lsu_pkt_d.half}} & 3'b01) | ({3{lsu_pkt_d.word}} & 3'b11) | ({3{lsu_pkt_d.dword}} & 3'b111);
|
||||
assign end_addr_offset_d[12:0] = {offset_d[11], offset_d[11:0]} + {9'b0, addr_offset_d[2:0]};
|
||||
assign full_end_addr_d[31:0] = rs1_d[31:0] + {{19{end_addr_offset_d[12]}},end_addr_offset_d[12:0]};
|
||||
assign end_addr_d[31:0] = full_end_addr_d[31:0];
|
||||
assign lsu_exc_m = access_fault_m | misaligned_fault_m;
|
||||
|
||||
if (pt.LOAD_TO_USE_PLUS1 == 1) begin: L2U_Plus1_1
|
||||
logic access_fault_r, misaligned_fault_r;
|
||||
logic [3:0] exc_mscause_r;
|
||||
logic fir_dccm_access_error_r, fir_nondccm_access_error_r;
|
||||
// Goes to TLU to increment the ECC error counter
|
||||
assign lsu_single_ecc_error_incr = (lsu_single_ecc_error_r & ~lsu_double_ecc_error_r) & (lsu_commit_r | lsu_pkt_r.dma) & lsu_pkt_r.valid;
|
||||
|
||||
// Generate exception packet
|
||||
assign lsu_error_pkt_r.exc_valid = (access_fault_r | misaligned_fault_r | lsu_double_ecc_error_r) & lsu_pkt_r.valid & ~lsu_pkt_r.dma & ~lsu_pkt_r.fast_int;
|
||||
assign lsu_error_pkt_r.single_ecc_error = lsu_single_ecc_error_r & ~lsu_error_pkt_r.exc_valid & ~lsu_pkt_r.dma;
|
||||
assign lsu_error_pkt_r.inst_type = lsu_pkt_r.store;
|
||||
assign lsu_error_pkt_r.exc_type = ~misaligned_fault_r;
|
||||
assign lsu_error_pkt_r.mscause[3:0] = (lsu_double_ecc_error_r & ~misaligned_fault_r & ~access_fault_r) ? 4'h1 : exc_mscause_r[3:0];
|
||||
assign lsu_error_pkt_r.addr[31:0] = lsu_addr_r[31:0];
|
||||
if (pt.LOAD_TO_USE_PLUS1 == 1) begin : L2U_Plus1_1
|
||||
logic access_fault_r, misaligned_fault_r;
|
||||
logic [3:0] exc_mscause_r;
|
||||
logic fir_dccm_access_error_r, fir_nondccm_access_error_r;
|
||||
|
||||
assign lsu_fir_error[1:0] = fir_nondccm_access_error_r ? 2'b11 : (fir_dccm_access_error_r ? 2'b10 : ((lsu_pkt_r.fast_int & lsu_double_ecc_error_r) ? 2'b01 : 2'b00));
|
||||
// Generate exception packet
|
||||
assign lsu_error_pkt_r.exc_valid = (access_fault_r | misaligned_fault_r | lsu_double_ecc_error_r) & lsu_pkt_r.valid & ~lsu_pkt_r.dma & ~lsu_pkt_r.fast_int;
|
||||
assign lsu_error_pkt_r.single_ecc_error = lsu_single_ecc_error_r & ~lsu_error_pkt_r.exc_valid & ~lsu_pkt_r.dma;
|
||||
assign lsu_error_pkt_r.inst_type = lsu_pkt_r.store;
|
||||
assign lsu_error_pkt_r.exc_type = ~misaligned_fault_r;
|
||||
assign lsu_error_pkt_r.mscause[3:0] = (lsu_double_ecc_error_r & ~misaligned_fault_r & ~access_fault_r) ? 4'h1 : exc_mscause_r[3:0];
|
||||
assign lsu_error_pkt_r.addr[31:0] = lsu_addr_r[31:0];
|
||||
|
||||
rvdff #(1) access_fault_rff (.din(access_fault_m), .dout(access_fault_r), .clk(lsu_c1_r_clk), .*);
|
||||
rvdff #(1) misaligned_fault_rff (.din(misaligned_fault_m), .dout(misaligned_fault_r), .clk(lsu_c1_r_clk), .*);
|
||||
rvdff #(4) exc_mscause_rff (.din(exc_mscause_m[3:0]), .dout(exc_mscause_r[3:0]), .clk(lsu_c1_r_clk), .*);
|
||||
rvdff #(1) fir_dccm_access_error_mff (.din(fir_dccm_access_error_m), .dout(fir_dccm_access_error_r), .clk(lsu_c1_r_clk), .*);
|
||||
rvdff #(1) fir_nondccm_access_error_mff (.din(fir_nondccm_access_error_m), .dout(fir_nondccm_access_error_r), .clk(lsu_c1_r_clk), .*);
|
||||
assign lsu_fir_error[1:0] = fir_nondccm_access_error_r ? 2'b11 : (fir_dccm_access_error_r ? 2'b10 : ((lsu_pkt_r.fast_int & lsu_double_ecc_error_r) ? 2'b01 : 2'b00));
|
||||
|
||||
end else begin: L2U_Plus1_0
|
||||
logic [1:0] lsu_fir_error_m;
|
||||
rvdff #(1) access_fault_rff (
|
||||
.din (access_fault_m),
|
||||
.dout(access_fault_r),
|
||||
.clk (lsu_c1_r_clk),
|
||||
.*
|
||||
);
|
||||
rvdff #(1) misaligned_fault_rff (
|
||||
.din (misaligned_fault_m),
|
||||
.dout(misaligned_fault_r),
|
||||
.clk (lsu_c1_r_clk),
|
||||
.*
|
||||
);
|
||||
rvdff #(4) exc_mscause_rff (
|
||||
.din (exc_mscause_m[3:0]),
|
||||
.dout(exc_mscause_r[3:0]),
|
||||
.clk (lsu_c1_r_clk),
|
||||
.*
|
||||
);
|
||||
rvdff #(1) fir_dccm_access_error_mff (
|
||||
.din (fir_dccm_access_error_m),
|
||||
.dout(fir_dccm_access_error_r),
|
||||
.clk (lsu_c1_r_clk),
|
||||
.*
|
||||
);
|
||||
rvdff #(1) fir_nondccm_access_error_mff (
|
||||
.din (fir_nondccm_access_error_m),
|
||||
.dout(fir_nondccm_access_error_r),
|
||||
.clk (lsu_c1_r_clk),
|
||||
.*
|
||||
);
|
||||
|
||||
// Generate exception packet
|
||||
assign lsu_error_pkt_m.exc_valid = (access_fault_m | misaligned_fault_m | lsu_double_ecc_error_m) & lsu_pkt_m.valid & ~lsu_pkt_m.dma & ~lsu_pkt_m.fast_int & ~flush_m_up;
|
||||
assign lsu_error_pkt_m.single_ecc_error = lsu_single_ecc_error_m & ~lsu_error_pkt_m.exc_valid & ~lsu_pkt_m.dma;
|
||||
assign lsu_error_pkt_m.inst_type = lsu_pkt_m.store;
|
||||
assign lsu_error_pkt_m.exc_type = ~misaligned_fault_m;
|
||||
assign lsu_error_pkt_m.mscause[3:0] = (lsu_double_ecc_error_m & ~misaligned_fault_m & ~access_fault_m) ? 4'h1 : exc_mscause_m[3:0];
|
||||
assign lsu_error_pkt_m.addr[31:0] = lsu_addr_m[31:0];
|
||||
end else begin : L2U_Plus1_0
|
||||
logic [1:0] lsu_fir_error_m;
|
||||
|
||||
assign lsu_fir_error_m[1:0] = fir_nondccm_access_error_m ? 2'b11 : (fir_dccm_access_error_m ? 2'b10 : ((lsu_pkt_m.fast_int & lsu_double_ecc_error_m) ? 2'b01 : 2'b00));
|
||||
// Generate exception packet
|
||||
assign lsu_error_pkt_m.exc_valid = (access_fault_m | misaligned_fault_m | lsu_double_ecc_error_m) & lsu_pkt_m.valid & ~lsu_pkt_m.dma & ~lsu_pkt_m.fast_int & ~flush_m_up;
|
||||
assign lsu_error_pkt_m.single_ecc_error = lsu_single_ecc_error_m & ~lsu_error_pkt_m.exc_valid & ~lsu_pkt_m.dma;
|
||||
assign lsu_error_pkt_m.inst_type = lsu_pkt_m.store;
|
||||
assign lsu_error_pkt_m.exc_type = ~misaligned_fault_m;
|
||||
assign lsu_error_pkt_m.mscause[3:0] = (lsu_double_ecc_error_m & ~misaligned_fault_m & ~access_fault_m) ? 4'h1 : exc_mscause_m[3:0];
|
||||
assign lsu_error_pkt_m.addr[31:0] = lsu_addr_m[31:0];
|
||||
|
||||
rvdff #(1) lsu_exc_valid_rff (.*, .din(lsu_error_pkt_m.exc_valid), .dout(lsu_error_pkt_r.exc_valid), .clk(lsu_c2_r_clk));
|
||||
rvdff #(1) lsu_single_ecc_error_rff(.*, .din(lsu_error_pkt_m.single_ecc_error), .dout(lsu_error_pkt_r.single_ecc_error), .clk(lsu_c2_r_clk));
|
||||
rvdffe #($bits(el2_lsu_error_pkt_t)-2) lsu_error_pkt_rff (.*, .din(lsu_error_pkt_m[$bits(el2_lsu_error_pkt_t)-1:2]), .dout(lsu_error_pkt_r[$bits(el2_lsu_error_pkt_t)-1:2]), .en(lsu_error_pkt_m.exc_valid | lsu_error_pkt_m.single_ecc_error | clk_override));
|
||||
rvdff #(2) lsu_fir_error_rff (.*, .din(lsu_fir_error_m[1:0]), .dout(lsu_fir_error[1:0]), .clk(lsu_c2_r_clk));
|
||||
end
|
||||
assign lsu_fir_error_m[1:0] = fir_nondccm_access_error_m ? 2'b11 : (fir_dccm_access_error_m ? 2'b10 : ((lsu_pkt_m.fast_int & lsu_double_ecc_error_m) ? 2'b01 : 2'b00));
|
||||
|
||||
//Create DMA packet
|
||||
always_comb begin
|
||||
dma_pkt_d = '0;
|
||||
dma_pkt_d.valid = dma_dccm_req;
|
||||
dma_pkt_d.dma = 1'b1;
|
||||
dma_pkt_d.store = dma_mem_write;
|
||||
dma_pkt_d.load = ~dma_mem_write;
|
||||
dma_pkt_d.by = (dma_mem_sz[2:0] == 3'b0);
|
||||
dma_pkt_d.half = (dma_mem_sz[2:0] == 3'b1);
|
||||
dma_pkt_d.word = (dma_mem_sz[2:0] == 3'b10);
|
||||
dma_pkt_d.dword = (dma_mem_sz[2:0] == 3'b11);
|
||||
end
|
||||
rvdff #(1) lsu_exc_valid_rff (
|
||||
.*,
|
||||
.din (lsu_error_pkt_m.exc_valid),
|
||||
.dout(lsu_error_pkt_r.exc_valid),
|
||||
.clk (lsu_c2_r_clk)
|
||||
);
|
||||
rvdff #(1) lsu_single_ecc_error_rff (
|
||||
.*,
|
||||
.din (lsu_error_pkt_m.single_ecc_error),
|
||||
.dout(lsu_error_pkt_r.single_ecc_error),
|
||||
.clk (lsu_c2_r_clk)
|
||||
);
|
||||
rvdffe #($bits(
|
||||
el2_lsu_error_pkt_t
|
||||
) - 2) lsu_error_pkt_rff (
|
||||
.*,
|
||||
.din (lsu_error_pkt_m[$bits(el2_lsu_error_pkt_t)-1:2]),
|
||||
.dout(lsu_error_pkt_r[$bits(el2_lsu_error_pkt_t)-1:2]),
|
||||
.en (lsu_error_pkt_m.exc_valid | lsu_error_pkt_m.single_ecc_error | clk_override)
|
||||
);
|
||||
rvdff #(2) lsu_fir_error_rff (
|
||||
.*,
|
||||
.din (lsu_fir_error_m[1:0]),
|
||||
.dout(lsu_fir_error[1:0]),
|
||||
.clk (lsu_c2_r_clk)
|
||||
);
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
lsu_pkt_d = dec_lsu_valid_raw_d ? lsu_p : dma_pkt_d;
|
||||
lsu_pkt_m_in = lsu_pkt_d;
|
||||
lsu_pkt_r_in = lsu_pkt_m;
|
||||
//Create DMA packet
|
||||
always_comb begin
|
||||
dma_pkt_d = '0;
|
||||
dma_pkt_d.valid = dma_dccm_req;
|
||||
dma_pkt_d.dma = 1'b1;
|
||||
dma_pkt_d.store = dma_mem_write;
|
||||
dma_pkt_d.load = ~dma_mem_write;
|
||||
dma_pkt_d.by = (dma_mem_sz[2:0] == 3'b0);
|
||||
dma_pkt_d.half = (dma_mem_sz[2:0] == 3'b1);
|
||||
dma_pkt_d.word = (dma_mem_sz[2:0] == 3'b10);
|
||||
dma_pkt_d.dword = (dma_mem_sz[2:0] == 3'b11);
|
||||
end
|
||||
|
||||
lsu_pkt_d.valid = (lsu_p.valid & ~(flush_m_up & ~lsu_p.fast_int)) | dma_dccm_req;
|
||||
lsu_pkt_m_in.valid = lsu_pkt_d.valid & ~(flush_m_up & ~lsu_pkt_d.dma);
|
||||
lsu_pkt_r_in.valid = lsu_pkt_m.valid & ~(flush_m_up & ~lsu_pkt_m.dma) ;
|
||||
end
|
||||
always_comb begin
|
||||
lsu_pkt_d = dec_lsu_valid_raw_d ? lsu_p : dma_pkt_d;
|
||||
lsu_pkt_m_in = lsu_pkt_d;
|
||||
lsu_pkt_r_in = lsu_pkt_m;
|
||||
|
||||
// C2 clock for valid and C1 for other bits of packet
|
||||
rvdff #(1) lsu_pkt_vldmff (.*, .din(lsu_pkt_m_in.valid), .dout(lsu_pkt_m.valid), .clk(lsu_c2_m_clk));
|
||||
rvdff #(1) lsu_pkt_vldrff (.*, .din(lsu_pkt_r_in.valid), .dout(lsu_pkt_r.valid), .clk(lsu_c2_r_clk));
|
||||
lsu_pkt_d.valid = (lsu_p.valid & ~(flush_m_up & ~lsu_p.fast_int)) | dma_dccm_req;
|
||||
lsu_pkt_m_in.valid = lsu_pkt_d.valid & ~(flush_m_up & ~lsu_pkt_d.dma);
|
||||
lsu_pkt_r_in.valid = lsu_pkt_m.valid & ~(flush_m_up & ~lsu_pkt_m.dma);
|
||||
end
|
||||
|
||||
rvdff #($bits(el2_lsu_pkt_t)-1) lsu_pkt_mff (.*, .din(lsu_pkt_m_in[$bits(el2_lsu_pkt_t)-1:1]), .dout(lsu_pkt_m[$bits(el2_lsu_pkt_t)-1:1]), .clk(lsu_c1_m_clk));
|
||||
rvdff #($bits(el2_lsu_pkt_t)-1) lsu_pkt_rff (.*, .din(lsu_pkt_r_in[$bits(el2_lsu_pkt_t)-1:1]), .dout(lsu_pkt_r[$bits(el2_lsu_pkt_t)-1:1]), .clk(lsu_c1_r_clk));
|
||||
// C2 clock for valid and C1 for other bits of packet
|
||||
rvdff #(1) lsu_pkt_vldmff (
|
||||
.*,
|
||||
.din (lsu_pkt_m_in.valid),
|
||||
.dout(lsu_pkt_m.valid),
|
||||
.clk (lsu_c2_m_clk)
|
||||
);
|
||||
rvdff #(1) lsu_pkt_vldrff (
|
||||
.*,
|
||||
.din (lsu_pkt_r_in.valid),
|
||||
.dout(lsu_pkt_r.valid),
|
||||
.clk (lsu_c2_r_clk)
|
||||
);
|
||||
|
||||
rvdff #($bits(
|
||||
el2_lsu_pkt_t
|
||||
) - 1) lsu_pkt_mff (
|
||||
.*,
|
||||
.din (lsu_pkt_m_in[$bits(el2_lsu_pkt_t)-1:1]),
|
||||
.dout(lsu_pkt_m[$bits(el2_lsu_pkt_t)-1:1]),
|
||||
.clk (lsu_c1_m_clk)
|
||||
);
|
||||
rvdff #($bits(
|
||||
el2_lsu_pkt_t
|
||||
) - 1) lsu_pkt_rff (
|
||||
.*,
|
||||
.din (lsu_pkt_r_in[$bits(el2_lsu_pkt_t)-1:1]),
|
||||
.dout(lsu_pkt_r[$bits(el2_lsu_pkt_t)-1:1]),
|
||||
.clk (lsu_c1_r_clk)
|
||||
);
|
||||
|
||||
|
||||
|
||||
if (pt.LOAD_TO_USE_PLUS1 == 1) begin: L2U1_Plus1_1
|
||||
logic [31:0] lsu_ld_datafn_r, lsu_ld_datafn_corr_r;
|
||||
if (pt.LOAD_TO_USE_PLUS1 == 1) begin : L2U1_Plus1_1
|
||||
logic [31:0] lsu_ld_datafn_r, lsu_ld_datafn_corr_r;
|
||||
|
||||
assign lsu_ld_datafn_r[31:0] = addr_external_r ? bus_read_data_r[31:0] : lsu_ld_data_r[31:0];
|
||||
assign lsu_ld_datafn_corr_r[31:0] = addr_external_r ? bus_read_data_r[31:0] : lsu_ld_data_corr_r[31:0];
|
||||
assign lsu_ld_datafn_r[31:0] = addr_external_r ? bus_read_data_r[31:0] : lsu_ld_data_r[31:0];
|
||||
assign lsu_ld_datafn_corr_r[31:0] = addr_external_r ? bus_read_data_r[31:0] : lsu_ld_data_corr_r[31:0];
|
||||
|
||||
// this is really R stage signal
|
||||
assign lsu_result_m[31:0] = ({32{ lsu_pkt_r.unsign & lsu_pkt_r.by }} & {24'b0,lsu_ld_datafn_r[7:0]}) |
|
||||
// this is really R stage signal
|
||||
assign lsu_result_m[31:0] = ({32{ lsu_pkt_r.unsign & lsu_pkt_r.by }} & {24'b0,lsu_ld_datafn_r[7:0]}) |
|
||||
({32{ lsu_pkt_r.unsign & lsu_pkt_r.half}} & {16'b0,lsu_ld_datafn_r[15:0]}) |
|
||||
({32{~lsu_pkt_r.unsign & lsu_pkt_r.by }} & {{24{ lsu_ld_datafn_r[7]}}, lsu_ld_datafn_r[7:0]}) |
|
||||
({32{~lsu_pkt_r.unsign & lsu_pkt_r.half}} & {{16{ lsu_ld_datafn_r[15]}},lsu_ld_datafn_r[15:0]}) |
|
||||
({32{lsu_pkt_r.word}} & lsu_ld_datafn_r[31:0]);
|
||||
|
||||
// this signal is used for gpr update
|
||||
assign lsu_result_corr_r[31:0] = ({32{ lsu_pkt_r.unsign & lsu_pkt_r.by }} & {24'b0,lsu_ld_datafn_corr_r[7:0]}) |
|
||||
// this signal is used for gpr update
|
||||
assign lsu_result_corr_r[31:0] = ({32{ lsu_pkt_r.unsign & lsu_pkt_r.by }} & {24'b0,lsu_ld_datafn_corr_r[7:0]}) |
|
||||
({32{ lsu_pkt_r.unsign & lsu_pkt_r.half}} & {16'b0,lsu_ld_datafn_corr_r[15:0]}) |
|
||||
({32{~lsu_pkt_r.unsign & lsu_pkt_r.by }} & {{24{ lsu_ld_datafn_corr_r[7]}}, lsu_ld_datafn_corr_r[7:0]}) |
|
||||
({32{~lsu_pkt_r.unsign & lsu_pkt_r.half}} & {{16{ lsu_ld_datafn_corr_r[15]}},lsu_ld_datafn_corr_r[15:0]}) |
|
||||
({32{lsu_pkt_r.word}} & lsu_ld_datafn_corr_r[31:0]);
|
||||
|
||||
end else begin: L2U1_Plus1_0 // block: L2U1_Plus1_1
|
||||
logic [31:0] lsu_ld_datafn_m, lsu_ld_datafn_corr_r;
|
||||
end else begin : L2U1_Plus1_0 // block: L2U1_Plus1_1
|
||||
logic [31:0] lsu_ld_datafn_m, lsu_ld_datafn_corr_r;
|
||||
|
||||
assign lsu_ld_datafn_m[31:0] = addr_external_m ? bus_read_data_m[31:0] : lsu_ld_data_m[31:0];
|
||||
assign lsu_ld_datafn_corr_r[31:0] = addr_external_r ? bus_read_data_r[31:0] : lsu_ld_data_corr_r[31:0];
|
||||
assign lsu_ld_datafn_m[31:0] = addr_external_m ? bus_read_data_m[31:0] : lsu_ld_data_m[31:0];
|
||||
assign lsu_ld_datafn_corr_r[31:0] = addr_external_r ? bus_read_data_r[31:0] : lsu_ld_data_corr_r[31:0];
|
||||
|
||||
// this result must look at prior stores and merge them in
|
||||
assign lsu_result_m[31:0] = ({32{ lsu_pkt_m.unsign & lsu_pkt_m.by }} & {24'b0,lsu_ld_datafn_m[7:0]}) |
|
||||
// this result must look at prior stores and merge them in
|
||||
assign lsu_result_m[31:0] = ({32{ lsu_pkt_m.unsign & lsu_pkt_m.by }} & {24'b0,lsu_ld_datafn_m[7:0]}) |
|
||||
({32{ lsu_pkt_m.unsign & lsu_pkt_m.half}} & {16'b0,lsu_ld_datafn_m[15:0]}) |
|
||||
({32{~lsu_pkt_m.unsign & lsu_pkt_m.by }} & {{24{ lsu_ld_datafn_m[7]}}, lsu_ld_datafn_m[7:0]}) |
|
||||
({32{~lsu_pkt_m.unsign & lsu_pkt_m.half}} & {{16{ lsu_ld_datafn_m[15]}},lsu_ld_datafn_m[15:0]}) |
|
||||
({32{lsu_pkt_m.word}} & lsu_ld_datafn_m[31:0]);
|
||||
|
||||
// this signal is used for gpr update
|
||||
assign lsu_result_corr_r[31:0] = ({32{ lsu_pkt_r.unsign & lsu_pkt_r.by }} & {24'b0,lsu_ld_datafn_corr_r[7:0]}) |
|
||||
// this signal is used for gpr update
|
||||
assign lsu_result_corr_r[31:0] = ({32{ lsu_pkt_r.unsign & lsu_pkt_r.by }} & {24'b0,lsu_ld_datafn_corr_r[7:0]}) |
|
||||
({32{ lsu_pkt_r.unsign & lsu_pkt_r.half}} & {16'b0,lsu_ld_datafn_corr_r[15:0]}) |
|
||||
({32{~lsu_pkt_r.unsign & lsu_pkt_r.by }} & {{24{ lsu_ld_datafn_corr_r[7]}}, lsu_ld_datafn_corr_r[7:0]}) |
|
||||
({32{~lsu_pkt_r.unsign & lsu_pkt_r.half}} & {{16{ lsu_ld_datafn_corr_r[15]}},lsu_ld_datafn_corr_r[15:0]}) |
|
||||
({32{lsu_pkt_r.word}} & lsu_ld_datafn_corr_r[31:0]);
|
||||
end
|
||||
end
|
||||
|
||||
// Fast interrupt address
|
||||
assign lsu_fir_addr[31:1] = lsu_ld_data_corr_r[31:1];
|
||||
// Fast interrupt address
|
||||
assign lsu_fir_addr[31:1] = lsu_ld_data_corr_r[31:1];
|
||||
|
||||
// absence load/store all 0's
|
||||
assign lsu_addr_d[31:0] = full_addr_d[31:0];
|
||||
// absence load/store all 0's
|
||||
assign lsu_addr_d[31:0] = full_addr_d[31:0];
|
||||
|
||||
// Interrupt as a flush source allows the WB to occur
|
||||
assign lsu_commit_r = lsu_pkt_r.valid & (lsu_pkt_r.store | lsu_pkt_r.load) & ~flush_r & ~lsu_pkt_r.dma;
|
||||
// Interrupt as a flush source allows the WB to occur
|
||||
assign lsu_commit_r = lsu_pkt_r.valid & (lsu_pkt_r.store | lsu_pkt_r.load) & ~flush_r & ~lsu_pkt_r.dma;
|
||||
|
||||
assign dma_mem_wdata_shifted[63:0] = dma_mem_wdata[63:0] >> {dma_mem_addr[2:0], 3'b000}; // Shift the dma data to lower bits to make it consistent to lsu stores
|
||||
assign store_data_d[31:0] = dma_dccm_req ? dma_mem_wdata_shifted[31:0] : exu_lsu_rs2_d[31:0]; // Write to PIC still happens in r stage
|
||||
assign dma_mem_wdata_shifted[63:0] = dma_mem_wdata[63:0] >> {dma_mem_addr[2:0], 3'b000}; // Shift the dma data to lower bits to make it consistent to lsu stores
|
||||
assign store_data_d[31:0] = dma_dccm_req ? dma_mem_wdata_shifted[31:0] : exu_lsu_rs2_d[31:0]; // Write to PIC still happens in r stage
|
||||
|
||||
assign store_data_m_in[31:0] = (lsu_pkt_d.store_data_bypass_d) ? lsu_result_m[31:0] : store_data_d[31:0];
|
||||
assign store_data_m_in[31:0] = (lsu_pkt_d.store_data_bypass_d) ? lsu_result_m[31:0] : store_data_d[31:0];
|
||||
|
||||
assign store_data_m[31:0] = (picm_mask_data_m[31:0] | {32{~addr_in_pic_m}}) & ((lsu_pkt_m.store_data_bypass_m) ? lsu_result_m[31:0] : store_data_pre_m[31:0]);
|
||||
assign store_data_m[31:0] = (picm_mask_data_m[31:0] | {32{~addr_in_pic_m}}) & ((lsu_pkt_m.store_data_bypass_m) ? lsu_result_m[31:0] : store_data_pre_m[31:0]);
|
||||
|
||||
|
||||
rvdff #(32) sdmff (.*, .din(store_data_m_in[31:0]), .dout(store_data_pre_m[31:0]), .clk(lsu_store_c1_m_clk));
|
||||
rvdff #(32) sdmff (
|
||||
.*,
|
||||
.din (store_data_m_in[31:0]),
|
||||
.dout(store_data_pre_m[31:0]),
|
||||
.clk (lsu_store_c1_m_clk)
|
||||
);
|
||||
|
||||
rvdff #(32) samff (.*, .din(lsu_addr_d[31:0]), .dout(lsu_addr_m[31:0]), .clk(lsu_c1_m_clk));
|
||||
rvdff #(32) sarff (.*, .din(lsu_addr_m[31:0]), .dout(lsu_addr_r[31:0]), .clk(lsu_c1_r_clk));
|
||||
rvdff #(32) samff (
|
||||
.*,
|
||||
.din (lsu_addr_d[31:0]),
|
||||
.dout(lsu_addr_m[31:0]),
|
||||
.clk (lsu_c1_m_clk)
|
||||
);
|
||||
rvdff #(32) sarff (
|
||||
.*,
|
||||
.din (lsu_addr_m[31:0]),
|
||||
.dout(lsu_addr_r[31:0]),
|
||||
.clk (lsu_c1_r_clk)
|
||||
);
|
||||
|
||||
assign end_addr_m[31:3] = ldst_dual_m ? end_addr_pre_m[31:3] : lsu_addr_m[31:3]; // This is for power saving
|
||||
assign end_addr_r[31:3] = ldst_dual_r ? end_addr_pre_r[31:3] : lsu_addr_r[31:3]; // This is for power saving
|
||||
assign end_addr_m[31:3] = ldst_dual_m ? end_addr_pre_m[31:3] : lsu_addr_m[31:3]; // This is for power saving
|
||||
assign end_addr_r[31:3] = ldst_dual_r ? end_addr_pre_r[31:3] : lsu_addr_r[31:3]; // This is for power saving
|
||||
|
||||
rvdffe #(29) end_addr_hi_mff (.*, .din(end_addr_d[31:3]), .dout(end_addr_pre_m[31:3]), .en((lsu_pkt_d.valid & ldst_dual_d) | clk_override));
|
||||
rvdffe #(29) end_addr_hi_rff (.*, .din(end_addr_m[31:3]), .dout(end_addr_pre_r[31:3]), .en((lsu_pkt_m.valid & ldst_dual_m) | clk_override));
|
||||
rvdffe #(29) end_addr_hi_mff (
|
||||
.*,
|
||||
.din (end_addr_d[31:3]),
|
||||
.dout(end_addr_pre_m[31:3]),
|
||||
.en ((lsu_pkt_d.valid & ldst_dual_d) | clk_override)
|
||||
);
|
||||
rvdffe #(29) end_addr_hi_rff (
|
||||
.*,
|
||||
.din (end_addr_m[31:3]),
|
||||
.dout(end_addr_pre_r[31:3]),
|
||||
.en ((lsu_pkt_m.valid & ldst_dual_m) | clk_override)
|
||||
);
|
||||
|
||||
rvdff #(3) end_addr_lo_mff (.*, .din(end_addr_d[2:0]), .dout(end_addr_m[2:0]), .clk(lsu_c1_m_clk));
|
||||
rvdff #(3) end_addr_lo_rff (.*, .din(end_addr_m[2:0]), .dout(end_addr_r[2:0]), .clk(lsu_c1_r_clk));
|
||||
rvdff #(3) end_addr_lo_mff (
|
||||
.*,
|
||||
.din (end_addr_d[2:0]),
|
||||
.dout(end_addr_m[2:0]),
|
||||
.clk (lsu_c1_m_clk)
|
||||
);
|
||||
rvdff #(3) end_addr_lo_rff (
|
||||
.*,
|
||||
.din (end_addr_m[2:0]),
|
||||
.dout(end_addr_r[2:0]),
|
||||
.clk (lsu_c1_r_clk)
|
||||
);
|
||||
|
||||
rvdff #(1) addr_in_dccm_mff(.din(addr_in_dccm_d), .dout(addr_in_dccm_m), .clk(lsu_c1_m_clk), .*);
|
||||
rvdff #(1) addr_in_dccm_rff(.din(addr_in_dccm_m), .dout(addr_in_dccm_r), .clk(lsu_c1_r_clk), .*);
|
||||
rvdff #(1) addr_in_dccm_mff (
|
||||
.din (addr_in_dccm_d),
|
||||
.dout(addr_in_dccm_m),
|
||||
.clk (lsu_c1_m_clk),
|
||||
.*
|
||||
);
|
||||
rvdff #(1) addr_in_dccm_rff (
|
||||
.din (addr_in_dccm_m),
|
||||
.dout(addr_in_dccm_r),
|
||||
.clk (lsu_c1_r_clk),
|
||||
.*
|
||||
);
|
||||
|
||||
rvdff #(1) addr_in_pic_mff(.din(addr_in_pic_d), .dout(addr_in_pic_m), .clk(lsu_c1_m_clk), .*);
|
||||
rvdff #(1) addr_in_pic_rff(.din(addr_in_pic_m), .dout(addr_in_pic_r), .clk(lsu_c1_r_clk), .*);
|
||||
rvdff #(1) addr_in_pic_mff (
|
||||
.din (addr_in_pic_d),
|
||||
.dout(addr_in_pic_m),
|
||||
.clk (lsu_c1_m_clk),
|
||||
.*
|
||||
);
|
||||
rvdff #(1) addr_in_pic_rff (
|
||||
.din (addr_in_pic_m),
|
||||
.dout(addr_in_pic_r),
|
||||
.clk (lsu_c1_r_clk),
|
||||
.*
|
||||
);
|
||||
|
||||
rvdff #(1) addr_external_mff(.din(addr_external_d), .dout(addr_external_m), .clk(lsu_c1_m_clk), .*);
|
||||
rvdff #(1) addr_external_rff(.din(addr_external_m), .dout(addr_external_r), .clk(lsu_c1_r_clk), .*);
|
||||
rvdff #(1) addr_external_mff (
|
||||
.din (addr_external_d),
|
||||
.dout(addr_external_m),
|
||||
.clk (lsu_c1_m_clk),
|
||||
.*
|
||||
);
|
||||
rvdff #(1) addr_external_rff (
|
||||
.din (addr_external_m),
|
||||
.dout(addr_external_r),
|
||||
.clk (lsu_c1_r_clk),
|
||||
.*
|
||||
);
|
||||
|
||||
rvdff #(1) access_fault_mff (.din(access_fault_d), .dout(access_fault_m), .clk(lsu_c1_m_clk), .*);
|
||||
rvdff #(1) misaligned_fault_mff (.din(misaligned_fault_d), .dout(misaligned_fault_m), .clk(lsu_c1_m_clk), .*);
|
||||
rvdff #(4) exc_mscause_mff (.din(exc_mscause_d[3:0]), .dout(exc_mscause_m[3:0]), .clk(lsu_c1_m_clk), .*);
|
||||
rvdff #(1) access_fault_mff (
|
||||
.din (access_fault_d),
|
||||
.dout(access_fault_m),
|
||||
.clk (lsu_c1_m_clk),
|
||||
.*
|
||||
);
|
||||
rvdff #(1) misaligned_fault_mff (
|
||||
.din (misaligned_fault_d),
|
||||
.dout(misaligned_fault_m),
|
||||
.clk (lsu_c1_m_clk),
|
||||
.*
|
||||
);
|
||||
rvdff #(4) exc_mscause_mff (
|
||||
.din (exc_mscause_d[3:0]),
|
||||
.dout(exc_mscause_m[3:0]),
|
||||
.clk (lsu_c1_m_clk),
|
||||
.*
|
||||
);
|
||||
|
||||
rvdff #(1) fir_dccm_access_error_mff (.din(fir_dccm_access_error_d), .dout(fir_dccm_access_error_m), .clk(lsu_c1_m_clk), .*);
|
||||
rvdff #(1) fir_nondccm_access_error_mff (.din(fir_nondccm_access_error_d), .dout(fir_nondccm_access_error_m), .clk(lsu_c1_m_clk), .*);
|
||||
rvdff #(1) fir_dccm_access_error_mff (
|
||||
.din (fir_dccm_access_error_d),
|
||||
.dout(fir_dccm_access_error_m),
|
||||
.clk (lsu_c1_m_clk),
|
||||
.*
|
||||
);
|
||||
rvdff #(1) fir_nondccm_access_error_mff (
|
||||
.din (fir_nondccm_access_error_d),
|
||||
.dout(fir_nondccm_access_error_m),
|
||||
.clk (lsu_c1_m_clk),
|
||||
.*
|
||||
);
|
||||
|
||||
rvdffe #(32) bus_read_data_r_ff (.*, .din(bus_read_data_m[31:0]), .dout(bus_read_data_r[31:0]), .en(addr_external_m | clk_override));
|
||||
rvdffe #(32) bus_read_data_r_ff (
|
||||
.*,
|
||||
.din (bus_read_data_m[31:0]),
|
||||
.dout(bus_read_data_r[31:0]),
|
||||
.en (addr_external_m | clk_override)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -28,313 +28,392 @@
|
|||
|
||||
|
||||
module el2_lsu_stbuf
|
||||
import el2_pkg::*;
|
||||
import el2_pkg::*;
|
||||
#(
|
||||
`include "el2_param.vh"
|
||||
)
|
||||
(
|
||||
input logic clk, // core clock
|
||||
input logic rst_l, // reset
|
||||
`include "el2_param.vh"
|
||||
) (
|
||||
input logic clk, // core clock
|
||||
input logic rst_l, // reset
|
||||
|
||||
input logic lsu_stbuf_c1_clk, // stbuf clock
|
||||
input logic lsu_free_c2_clk, // free clk
|
||||
input logic lsu_stbuf_c1_clk, // stbuf clock
|
||||
input logic lsu_free_c2_clk, // free clk
|
||||
|
||||
// Store Buffer input
|
||||
input logic store_stbuf_reqvld_r, // core instruction goes to stbuf
|
||||
input logic lsu_commit_r, // lsu commits
|
||||
input logic dec_lsu_valid_raw_d, // Speculative decode valid
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] store_data_hi_r, // merged data from the dccm for stores. This is used for fwding
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] store_data_lo_r, // merged data from the dccm for stores. This is used for fwding
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] store_datafn_hi_r, // merged data from the dccm for stores
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] store_datafn_lo_r, // merged data from the dccm for stores
|
||||
// Store Buffer input
|
||||
input logic store_stbuf_reqvld_r, // core instruction goes to stbuf
|
||||
input logic lsu_commit_r, // lsu commits
|
||||
input logic dec_lsu_valid_raw_d, // Speculative decode valid
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] store_data_hi_r, // merged data from the dccm for stores. This is used for fwding
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] store_data_lo_r, // merged data from the dccm for stores. This is used for fwding
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] store_datafn_hi_r, // merged data from the dccm for stores
|
||||
input logic [pt.DCCM_DATA_WIDTH-1:0] store_datafn_lo_r, // merged data from the dccm for stores
|
||||
|
||||
// Store Buffer output
|
||||
output logic stbuf_reqvld_any, // stbuf is draining
|
||||
output logic stbuf_reqvld_flushed_any, // Top entry is flushed
|
||||
output logic [pt.LSU_SB_BITS-1:0] stbuf_addr_any, // address
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_data_any, // stbuf data
|
||||
// Store Buffer output
|
||||
output logic stbuf_reqvld_any, // stbuf is draining
|
||||
output logic stbuf_reqvld_flushed_any, // Top entry is flushed
|
||||
output logic [ pt.LSU_SB_BITS-1:0] stbuf_addr_any, // address
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_data_any, // stbuf data
|
||||
|
||||
input logic lsu_stbuf_commit_any, // pop the stbuf as it commite
|
||||
output logic lsu_stbuf_full_any, // stbuf is full
|
||||
output logic lsu_stbuf_empty_any, // stbuf is empty
|
||||
output logic ldst_stbuf_reqvld_r, // needed for clocking
|
||||
input logic lsu_stbuf_commit_any, // pop the stbuf as it commite
|
||||
output logic lsu_stbuf_full_any, // stbuf is full
|
||||
output logic lsu_stbuf_empty_any, // stbuf is empty
|
||||
output logic ldst_stbuf_reqvld_r, // needed for clocking
|
||||
|
||||
input logic [pt.LSU_SB_BITS-1:0] lsu_addr_d, // lsu address D-stage
|
||||
input logic [31:0] lsu_addr_m, // lsu address M-stage
|
||||
input logic [31:0] lsu_addr_r, // lsu address R-stage
|
||||
input logic [pt.LSU_SB_BITS-1:0] lsu_addr_d, // lsu address D-stage
|
||||
input logic [ 31:0] lsu_addr_m, // lsu address M-stage
|
||||
input logic [ 31:0] lsu_addr_r, // lsu address R-stage
|
||||
|
||||
input logic [pt.LSU_SB_BITS-1:0] end_addr_d, // lsu end address D-stage - needed to check unaligned
|
||||
input logic [31:0] end_addr_m, // lsu end address M-stage - needed to check unaligned
|
||||
input logic [31:0] end_addr_r, // lsu end address R-stage - needed to check unaligned
|
||||
input logic [pt.LSU_SB_BITS-1:0] end_addr_d, // lsu end address D-stage - needed to check unaligned
|
||||
input logic [31:0] end_addr_m, // lsu end address M-stage - needed to check unaligned
|
||||
input logic [31:0] end_addr_r, // lsu end address R-stage - needed to check unaligned
|
||||
|
||||
input logic ldst_dual_d, ldst_dual_m, ldst_dual_r,
|
||||
input logic addr_in_dccm_m, // address is in dccm
|
||||
input logic addr_in_dccm_r, // address is in dccm
|
||||
input logic ldst_dual_d,
|
||||
ldst_dual_m,
|
||||
ldst_dual_r,
|
||||
input logic addr_in_dccm_m, // address is in dccm
|
||||
input logic addr_in_dccm_r, // address is in dccm
|
||||
|
||||
// Forwarding signals
|
||||
input logic lsu_cmpen_m, // needed for forwarding stbuf - load
|
||||
input el2_lsu_pkt_t lsu_pkt_m, // LSU packet M-stage
|
||||
input el2_lsu_pkt_t lsu_pkt_r, // LSU packet R-stage
|
||||
// Forwarding signals
|
||||
input logic lsu_cmpen_m, // needed for forwarding stbuf - load
|
||||
input el2_lsu_pkt_t lsu_pkt_m, // LSU packet M-stage
|
||||
input el2_lsu_pkt_t lsu_pkt_r, // LSU packet R-stage
|
||||
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_fwddata_hi_m, // stbuf data
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_fwddata_lo_m, // stbuf data
|
||||
output logic [pt.DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_hi_m, // stbuf data
|
||||
output logic [pt.DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_m, // stbuf data
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_fwddata_hi_m, // stbuf data
|
||||
output logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_fwddata_lo_m, // stbuf data
|
||||
output logic [pt.DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_hi_m, // stbuf data
|
||||
output logic [pt.DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_m, // stbuf data
|
||||
|
||||
input logic scan_mode // Scan mode
|
||||
input logic scan_mode // Scan mode
|
||||
|
||||
);
|
||||
|
||||
|
||||
localparam DEPTH = pt.LSU_STBUF_DEPTH;
|
||||
localparam DATA_WIDTH = pt.DCCM_DATA_WIDTH;
|
||||
localparam BYTE_WIDTH = pt.DCCM_BYTE_WIDTH;
|
||||
localparam DEPTH_LOG2 = $clog2(DEPTH);
|
||||
localparam DEPTH = pt.LSU_STBUF_DEPTH;
|
||||
localparam DATA_WIDTH = pt.DCCM_DATA_WIDTH;
|
||||
localparam BYTE_WIDTH = pt.DCCM_BYTE_WIDTH;
|
||||
localparam DEPTH_LOG2 = $clog2(DEPTH);
|
||||
|
||||
// These are the fields in the store queue
|
||||
logic [DEPTH-1:0] stbuf_vld;
|
||||
logic [DEPTH-1:0] stbuf_dma_kill;
|
||||
logic [DEPTH-1:0][pt.LSU_SB_BITS-1:0] stbuf_addr;
|
||||
logic [DEPTH-1:0][BYTE_WIDTH-1:0] stbuf_byteen;
|
||||
logic [DEPTH-1:0][DATA_WIDTH-1:0] stbuf_data;
|
||||
// These are the fields in the store queue
|
||||
logic [ DEPTH-1:0] stbuf_vld;
|
||||
logic [ DEPTH-1:0] stbuf_dma_kill;
|
||||
logic [ DEPTH-1:0][pt.LSU_SB_BITS-1:0] stbuf_addr;
|
||||
logic [ DEPTH-1:0][ BYTE_WIDTH-1:0] stbuf_byteen;
|
||||
logic [ DEPTH-1:0][ DATA_WIDTH-1:0] stbuf_data;
|
||||
|
||||
logic [DEPTH-1:0] sel_lo;
|
||||
logic [DEPTH-1:0] stbuf_wr_en;
|
||||
logic [DEPTH-1:0] stbuf_dma_kill_en;
|
||||
logic [DEPTH-1:0] stbuf_reset;
|
||||
logic [DEPTH-1:0][pt.LSU_SB_BITS-1:0] stbuf_addrin;
|
||||
logic [DEPTH-1:0][DATA_WIDTH-1:0] stbuf_datain;
|
||||
logic [DEPTH-1:0][BYTE_WIDTH-1:0] stbuf_byteenin;
|
||||
logic [ DEPTH-1:0] sel_lo;
|
||||
logic [ DEPTH-1:0] stbuf_wr_en;
|
||||
logic [ DEPTH-1:0] stbuf_dma_kill_en;
|
||||
logic [ DEPTH-1:0] stbuf_reset;
|
||||
logic [ DEPTH-1:0][pt.LSU_SB_BITS-1:0] stbuf_addrin;
|
||||
logic [ DEPTH-1:0][ DATA_WIDTH-1:0] stbuf_datain;
|
||||
logic [ DEPTH-1:0][ BYTE_WIDTH-1:0] stbuf_byteenin;
|
||||
|
||||
logic [7:0] store_byteen_ext_r;
|
||||
logic [BYTE_WIDTH-1:0] store_byteen_hi_r;
|
||||
logic [BYTE_WIDTH-1:0] store_byteen_lo_r;
|
||||
logic [ 7:0] store_byteen_ext_r;
|
||||
logic [BYTE_WIDTH-1:0] store_byteen_hi_r;
|
||||
logic [BYTE_WIDTH-1:0] store_byteen_lo_r;
|
||||
|
||||
logic WrPtrEn, RdPtrEn;
|
||||
logic [DEPTH_LOG2-1:0] WrPtr, RdPtr;
|
||||
logic [DEPTH_LOG2-1:0] NxtWrPtr, NxtRdPtr;
|
||||
logic [DEPTH_LOG2-1:0] WrPtrPlus1, WrPtrPlus2, RdPtrPlus1;
|
||||
logic WrPtrEn, RdPtrEn;
|
||||
logic [DEPTH_LOG2-1:0] WrPtr, RdPtr;
|
||||
logic [DEPTH_LOG2-1:0] NxtWrPtr, NxtRdPtr;
|
||||
logic [DEPTH_LOG2-1:0] WrPtrPlus1, WrPtrPlus2, RdPtrPlus1;
|
||||
|
||||
logic dual_stbuf_write_r;
|
||||
logic dual_stbuf_write_r;
|
||||
|
||||
logic isdccmst_m, isdccmst_r;
|
||||
logic [3:0] stbuf_numvld_any, stbuf_specvld_any;
|
||||
logic [1:0] stbuf_specvld_m, stbuf_specvld_r;
|
||||
logic isdccmst_m, isdccmst_r;
|
||||
logic [3:0] stbuf_numvld_any, stbuf_specvld_any;
|
||||
logic [1:0] stbuf_specvld_m, stbuf_specvld_r;
|
||||
|
||||
logic [pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] cmpaddr_hi_m, cmpaddr_lo_m;
|
||||
logic [pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] cmpaddr_hi_m, cmpaddr_lo_m;
|
||||
|
||||
// variables to detect matching from the store queue
|
||||
logic [DEPTH-1:0] stbuf_match_hi, stbuf_match_lo;
|
||||
logic [DEPTH-1:0][BYTE_WIDTH-1:0] stbuf_fwdbyteenvec_hi, stbuf_fwdbyteenvec_lo;
|
||||
logic [DATA_WIDTH-1:0] stbuf_fwddata_hi_pre_m, stbuf_fwddata_lo_pre_m;
|
||||
logic [BYTE_WIDTH-1:0] stbuf_fwdbyteen_hi_pre_m, stbuf_fwdbyteen_lo_pre_m;
|
||||
// variables to detect matching from the store queue
|
||||
logic [DEPTH-1:0] stbuf_match_hi, stbuf_match_lo;
|
||||
logic [DEPTH-1:0][BYTE_WIDTH-1:0] stbuf_fwdbyteenvec_hi, stbuf_fwdbyteenvec_lo;
|
||||
logic [DATA_WIDTH-1:0] stbuf_fwddata_hi_pre_m, stbuf_fwddata_lo_pre_m;
|
||||
logic [BYTE_WIDTH-1:0] stbuf_fwdbyteen_hi_pre_m, stbuf_fwdbyteen_lo_pre_m;
|
||||
|
||||
// logic to detect matching from the pipe - needed for store - load forwarding
|
||||
logic [BYTE_WIDTH-1:0] ld_byte_rhit_lo_lo, ld_byte_rhit_hi_lo, ld_byte_rhit_lo_hi, ld_byte_rhit_hi_hi;
|
||||
logic ld_addr_rhit_lo_lo, ld_addr_rhit_hi_lo, ld_addr_rhit_lo_hi, ld_addr_rhit_hi_hi;
|
||||
// logic to detect matching from the pipe - needed for store - load forwarding
|
||||
logic [BYTE_WIDTH-1:0]
|
||||
ld_byte_rhit_lo_lo, ld_byte_rhit_hi_lo, ld_byte_rhit_lo_hi, ld_byte_rhit_hi_hi;
|
||||
logic ld_addr_rhit_lo_lo, ld_addr_rhit_hi_lo, ld_addr_rhit_lo_hi, ld_addr_rhit_hi_hi;
|
||||
|
||||
logic [BYTE_WIDTH-1:0] ld_byte_hit_lo, ld_byte_rhit_lo;
|
||||
logic [BYTE_WIDTH-1:0] ld_byte_hit_hi, ld_byte_rhit_hi;
|
||||
logic [BYTE_WIDTH-1:0] ld_byte_hit_lo, ld_byte_rhit_lo;
|
||||
logic [BYTE_WIDTH-1:0] ld_byte_hit_hi, ld_byte_rhit_hi;
|
||||
|
||||
logic [BYTE_WIDTH-1:0] ldst_byteen_hi_r;
|
||||
logic [BYTE_WIDTH-1:0] ldst_byteen_lo_r;
|
||||
// byte_en flowing down
|
||||
logic [7:0] ldst_byteen_r;
|
||||
logic [7:0] ldst_byteen_ext_r;
|
||||
// fwd data through the pipe
|
||||
logic [31:0] ld_fwddata_rpipe_lo;
|
||||
logic [31:0] ld_fwddata_rpipe_hi;
|
||||
logic [BYTE_WIDTH-1:0] ldst_byteen_hi_r;
|
||||
logic [BYTE_WIDTH-1:0] ldst_byteen_lo_r;
|
||||
// byte_en flowing down
|
||||
logic [ 7:0] ldst_byteen_r;
|
||||
logic [ 7:0] ldst_byteen_ext_r;
|
||||
// fwd data through the pipe
|
||||
logic [ 31:0] ld_fwddata_rpipe_lo;
|
||||
logic [ 31:0] ld_fwddata_rpipe_hi;
|
||||
|
||||
// coalescing signals
|
||||
logic [DEPTH-1:0] store_matchvec_lo_r, store_matchvec_hi_r;
|
||||
logic store_coalesce_lo_r, store_coalesce_hi_r;
|
||||
// coalescing signals
|
||||
logic [DEPTH-1:0] store_matchvec_lo_r, store_matchvec_hi_r;
|
||||
logic store_coalesce_lo_r, store_coalesce_hi_r;
|
||||
|
||||
//----------------------------------------
|
||||
// Logic starts here
|
||||
//----------------------------------------
|
||||
// Create high/low byte enables
|
||||
assign store_byteen_ext_r[7:0] = ldst_byteen_r[7:0] << lsu_addr_r[1:0];
|
||||
assign store_byteen_hi_r[BYTE_WIDTH-1:0] = store_byteen_ext_r[7:4] & {4{lsu_pkt_r.store}};
|
||||
assign store_byteen_lo_r[BYTE_WIDTH-1:0] = store_byteen_ext_r[3:0] & {4{lsu_pkt_r.store}};
|
||||
//----------------------------------------
|
||||
// Logic starts here
|
||||
//----------------------------------------
|
||||
// Create high/low byte enables
|
||||
assign store_byteen_ext_r[7:0] = ldst_byteen_r[7:0] << lsu_addr_r[1:0];
|
||||
assign store_byteen_hi_r[BYTE_WIDTH-1:0] = store_byteen_ext_r[7:4] & {4{lsu_pkt_r.store}};
|
||||
assign store_byteen_lo_r[BYTE_WIDTH-1:0] = store_byteen_ext_r[3:0] & {4{lsu_pkt_r.store}};
|
||||
|
||||
assign RdPtrPlus1[DEPTH_LOG2-1:0] = RdPtr[DEPTH_LOG2-1:0] + 1'b1;
|
||||
assign WrPtrPlus1[DEPTH_LOG2-1:0] = WrPtr[DEPTH_LOG2-1:0] + 1'b1;
|
||||
assign WrPtrPlus2[DEPTH_LOG2-1:0] = WrPtr[DEPTH_LOG2-1:0] + 2'b10;
|
||||
assign RdPtrPlus1[DEPTH_LOG2-1:0] = RdPtr[DEPTH_LOG2-1:0] + 1'b1;
|
||||
assign WrPtrPlus1[DEPTH_LOG2-1:0] = WrPtr[DEPTH_LOG2-1:0] + 1'b1;
|
||||
assign WrPtrPlus2[DEPTH_LOG2-1:0] = WrPtr[DEPTH_LOG2-1:0] + 2'b10;
|
||||
|
||||
// ecc error on both hi/lo
|
||||
assign dual_stbuf_write_r = ldst_dual_r & store_stbuf_reqvld_r;
|
||||
assign ldst_stbuf_reqvld_r = ((lsu_commit_r | lsu_pkt_r.dma) & store_stbuf_reqvld_r);
|
||||
// ecc error on both hi/lo
|
||||
assign dual_stbuf_write_r = ldst_dual_r & store_stbuf_reqvld_r;
|
||||
assign ldst_stbuf_reqvld_r = ((lsu_commit_r | lsu_pkt_r.dma) & store_stbuf_reqvld_r);
|
||||
|
||||
// Store Buffer coalescing
|
||||
for (genvar i=0; i<DEPTH; i++) begin: FindMatchEntry
|
||||
assign store_matchvec_lo_r[i] = (stbuf_addr[i][pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] == lsu_addr_r[pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]) & stbuf_vld[i] & ~stbuf_dma_kill[i] & ~stbuf_reset[i];
|
||||
assign store_matchvec_hi_r[i] = (stbuf_addr[i][pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] == end_addr_r[pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]) & stbuf_vld[i] & ~stbuf_dma_kill[i] & dual_stbuf_write_r & ~stbuf_reset[i];
|
||||
end: FindMatchEntry
|
||||
for (genvar i = 0; i < DEPTH; i++) begin : FindMatchEntry
|
||||
assign store_matchvec_lo_r[i] = (stbuf_addr[i][pt.LSU_SB_BITS-1:$clog2(
|
||||
BYTE_WIDTH
|
||||
)] == lsu_addr_r[pt.LSU_SB_BITS-1:$clog2(
|
||||
BYTE_WIDTH
|
||||
)]) & stbuf_vld[i] & ~stbuf_dma_kill[i] & ~stbuf_reset[i];
|
||||
assign store_matchvec_hi_r[i] = (stbuf_addr[i][pt.LSU_SB_BITS-1:$clog2(
|
||||
BYTE_WIDTH
|
||||
)] == end_addr_r[pt.LSU_SB_BITS-1:$clog2(
|
||||
BYTE_WIDTH
|
||||
)]) & stbuf_vld[i] & ~stbuf_dma_kill[i] & dual_stbuf_write_r & ~stbuf_reset[i];
|
||||
end : FindMatchEntry
|
||||
|
||||
assign store_coalesce_lo_r = |store_matchvec_lo_r[DEPTH-1:0];
|
||||
assign store_coalesce_hi_r = |store_matchvec_hi_r[DEPTH-1:0];
|
||||
assign store_coalesce_lo_r = |store_matchvec_lo_r[DEPTH-1:0];
|
||||
assign store_coalesce_hi_r = |store_matchvec_hi_r[DEPTH-1:0];
|
||||
|
||||
|
||||
if (pt.DCCM_ENABLE == 1) begin: Gen_dccm_enable
|
||||
// Allocate new in this entry if :
|
||||
// 1. wrptr, single allocate, lo did not coalesce
|
||||
// 2. wrptr, double allocate, lo ^ hi coalesced
|
||||
// 3. wrptr + 1, double alloacte, niether lo or hi coalesced
|
||||
// Also update if there is a hi or a lo coalesce to this entry
|
||||
// Store Buffer instantiation
|
||||
for (genvar i=0; i<DEPTH; i++) begin: GenStBuf
|
||||
assign stbuf_wr_en[i] = ldst_stbuf_reqvld_r & (
|
||||
if (pt.DCCM_ENABLE == 1) begin : Gen_dccm_enable
|
||||
// Allocate new in this entry if :
|
||||
// 1. wrptr, single allocate, lo did not coalesce
|
||||
// 2. wrptr, double allocate, lo ^ hi coalesced
|
||||
// 3. wrptr + 1, double alloacte, niether lo or hi coalesced
|
||||
// Also update if there is a hi or a lo coalesce to this entry
|
||||
// Store Buffer instantiation
|
||||
for (genvar i = 0; i < DEPTH; i++) begin : GenStBuf
|
||||
assign stbuf_wr_en[i] = ldst_stbuf_reqvld_r & (
|
||||
( (i == WrPtr[DEPTH_LOG2-1:0]) & ~store_coalesce_lo_r) | // Allocate : new Lo
|
||||
( (i == WrPtr[DEPTH_LOG2-1:0]) & dual_stbuf_write_r & ~store_coalesce_hi_r) | // Allocate : only 1 new Write Either
|
||||
( (i == WrPtrPlus1[DEPTH_LOG2-1:0]) & dual_stbuf_write_r & ~(store_coalesce_lo_r | store_coalesce_hi_r)) | // Allocate2 : 2 new so Write Hi
|
||||
store_matchvec_lo_r[i] | store_matchvec_hi_r[i]); // Coalesced Write Lo or Hi
|
||||
assign stbuf_reset[i] = (lsu_stbuf_commit_any | stbuf_reqvld_flushed_any) & (i == RdPtr[DEPTH_LOG2-1:0]);
|
||||
( (i == WrPtr[DEPTH_LOG2-1:0]) & dual_stbuf_write_r & ~store_coalesce_hi_r) | // Allocate : only 1 new Write Either
|
||||
( (i == WrPtrPlus1[DEPTH_LOG2-1:0]) & dual_stbuf_write_r & ~(store_coalesce_lo_r | store_coalesce_hi_r)) | // Allocate2 : 2 new so Write Hi
|
||||
store_matchvec_lo_r[i] | store_matchvec_hi_r[i]); // Coalesced Write Lo or Hi
|
||||
assign stbuf_reset[i] = (lsu_stbuf_commit_any | stbuf_reqvld_flushed_any) & (i == RdPtr[DEPTH_LOG2-1:0]);
|
||||
|
||||
// Mux select for start/end address
|
||||
assign sel_lo[i] = ((~ldst_dual_r | store_stbuf_reqvld_r) & (i == WrPtr[DEPTH_LOG2-1:0]) & ~store_coalesce_lo_r) | // lo allocated new entry
|
||||
// Mux select for start/end address
|
||||
assign sel_lo[i] = ((~ldst_dual_r | store_stbuf_reqvld_r) & (i == WrPtr[DEPTH_LOG2-1:0]) & ~store_coalesce_lo_r) | // lo allocated new entry
|
||||
store_matchvec_lo_r[i]; // lo coalesced in to this entry
|
||||
assign stbuf_addrin[i][pt.LSU_SB_BITS-1:0] = sel_lo[i] ? lsu_addr_r[pt.LSU_SB_BITS-1:0] : end_addr_r[pt.LSU_SB_BITS-1:0];
|
||||
assign stbuf_byteenin[i][BYTE_WIDTH-1:0] = sel_lo[i] ? (stbuf_byteen[i][BYTE_WIDTH-1:0] | store_byteen_lo_r[BYTE_WIDTH-1:0]) : (stbuf_byteen[i][BYTE_WIDTH-1:0] | store_byteen_hi_r[BYTE_WIDTH-1:0]);
|
||||
assign stbuf_datain[i][7:0] = sel_lo[i] ? ((~stbuf_byteen[i][0] | store_byteen_lo_r[0]) ? store_datafn_lo_r[7:0] : stbuf_data[i][7:0]) :
|
||||
assign stbuf_addrin[i][pt.LSU_SB_BITS-1:0] = sel_lo[i] ? lsu_addr_r[pt.LSU_SB_BITS-1:0] : end_addr_r[pt.LSU_SB_BITS-1:0];
|
||||
assign stbuf_byteenin[i][BYTE_WIDTH-1:0] = sel_lo[i] ? (stbuf_byteen[i][BYTE_WIDTH-1:0] | store_byteen_lo_r[BYTE_WIDTH-1:0]) : (stbuf_byteen[i][BYTE_WIDTH-1:0] | store_byteen_hi_r[BYTE_WIDTH-1:0]);
|
||||
assign stbuf_datain[i][7:0] = sel_lo[i] ? ((~stbuf_byteen[i][0] | store_byteen_lo_r[0]) ? store_datafn_lo_r[7:0] : stbuf_data[i][7:0]) :
|
||||
((~stbuf_byteen[i][0] | store_byteen_hi_r[0]) ? store_datafn_hi_r[7:0] : stbuf_data[i][7:0]);
|
||||
assign stbuf_datain[i][15:8] = sel_lo[i] ? ((~stbuf_byteen[i][1] | store_byteen_lo_r[1]) ? store_datafn_lo_r[15:8] : stbuf_data[i][15:8]) :
|
||||
assign stbuf_datain[i][15:8] = sel_lo[i] ? ((~stbuf_byteen[i][1] | store_byteen_lo_r[1]) ? store_datafn_lo_r[15:8] : stbuf_data[i][15:8]) :
|
||||
((~stbuf_byteen[i][1] | store_byteen_hi_r[1]) ? store_datafn_hi_r[15:8] : stbuf_data[i][15:8]);
|
||||
assign stbuf_datain[i][23:16] = sel_lo[i] ? ((~stbuf_byteen[i][2] | store_byteen_lo_r[2]) ? store_datafn_lo_r[23:16] : stbuf_data[i][23:16]) :
|
||||
assign stbuf_datain[i][23:16] = sel_lo[i] ? ((~stbuf_byteen[i][2] | store_byteen_lo_r[2]) ? store_datafn_lo_r[23:16] : stbuf_data[i][23:16]) :
|
||||
((~stbuf_byteen[i][2] | store_byteen_hi_r[2]) ? store_datafn_hi_r[23:16] : stbuf_data[i][23:16]);
|
||||
assign stbuf_datain[i][31:24] = sel_lo[i] ? ((~stbuf_byteen[i][3] | store_byteen_lo_r[3]) ? store_datafn_lo_r[31:24] : stbuf_data[i][31:24]) :
|
||||
assign stbuf_datain[i][31:24] = sel_lo[i] ? ((~stbuf_byteen[i][3] | store_byteen_lo_r[3]) ? store_datafn_lo_r[31:24] : stbuf_data[i][31:24]) :
|
||||
((~stbuf_byteen[i][3] | store_byteen_hi_r[3]) ? store_datafn_hi_r[31:24] : stbuf_data[i][31:24]);
|
||||
|
||||
rvdffsc #(.WIDTH(1)) stbuf_vldff (.din(1'b1), .dout(stbuf_vld[i]), .en(stbuf_wr_en[i]), .clear(stbuf_reset[i]), .clk(lsu_free_c2_clk), .*);
|
||||
rvdffsc #(.WIDTH(1)) stbuf_killff (.din(1'b1), .dout(stbuf_dma_kill[i]), .en(stbuf_dma_kill_en[i]), .clear(stbuf_reset[i]), .clk(lsu_free_c2_clk), .*);
|
||||
rvdffe #(.WIDTH(pt.LSU_SB_BITS)) stbuf_addrff (.din(stbuf_addrin[i][pt.LSU_SB_BITS-1:0]), .dout(stbuf_addr[i][pt.LSU_SB_BITS-1:0]), .en(stbuf_wr_en[i]), .*);
|
||||
rvdffsc #(.WIDTH(BYTE_WIDTH)) stbuf_byteenff (.din(stbuf_byteenin[i][BYTE_WIDTH-1:0]), .dout(stbuf_byteen[i][BYTE_WIDTH-1:0]), .en(stbuf_wr_en[i]), .clear(stbuf_reset[i]), .clk(lsu_stbuf_c1_clk), .*);
|
||||
rvdffe #(.WIDTH(DATA_WIDTH)) stbuf_dataff (.din(stbuf_datain[i][DATA_WIDTH-1:0]), .dout(stbuf_data[i][DATA_WIDTH-1:0]), .en(stbuf_wr_en[i]), .*);
|
||||
end
|
||||
end else begin: Gen_dccm_disable
|
||||
assign stbuf_wr_en[DEPTH-1:0] = '0;
|
||||
assign stbuf_reset[DEPTH-1:0] = '0;
|
||||
assign stbuf_vld[DEPTH-1:0] = '0;
|
||||
assign stbuf_dma_kill[DEPTH-1:0] = '0;
|
||||
assign stbuf_addr[DEPTH-1:0] = '0;
|
||||
assign stbuf_byteen[DEPTH-1:0] = '0;
|
||||
assign stbuf_data[DEPTH-1:0] = '0;
|
||||
end
|
||||
rvdffsc #(
|
||||
.WIDTH(1)
|
||||
) stbuf_vldff (
|
||||
.din(1'b1),
|
||||
.dout(stbuf_vld[i]),
|
||||
.en(stbuf_wr_en[i]),
|
||||
.clear(stbuf_reset[i]),
|
||||
.clk(lsu_free_c2_clk),
|
||||
.*
|
||||
);
|
||||
rvdffsc #(
|
||||
.WIDTH(1)
|
||||
) stbuf_killff (
|
||||
.din(1'b1),
|
||||
.dout(stbuf_dma_kill[i]),
|
||||
.en(stbuf_dma_kill_en[i]),
|
||||
.clear(stbuf_reset[i]),
|
||||
.clk(lsu_free_c2_clk),
|
||||
.*
|
||||
);
|
||||
rvdffe #(
|
||||
.WIDTH(pt.LSU_SB_BITS)
|
||||
) stbuf_addrff (
|
||||
.din (stbuf_addrin[i][pt.LSU_SB_BITS-1:0]),
|
||||
.dout(stbuf_addr[i][pt.LSU_SB_BITS-1:0]),
|
||||
.en (stbuf_wr_en[i]),
|
||||
.*
|
||||
);
|
||||
rvdffsc #(
|
||||
.WIDTH(BYTE_WIDTH)
|
||||
) stbuf_byteenff (
|
||||
.din(stbuf_byteenin[i][BYTE_WIDTH-1:0]),
|
||||
.dout(stbuf_byteen[i][BYTE_WIDTH-1:0]),
|
||||
.en(stbuf_wr_en[i]),
|
||||
.clear(stbuf_reset[i]),
|
||||
.clk(lsu_stbuf_c1_clk),
|
||||
.*
|
||||
);
|
||||
rvdffe #(
|
||||
.WIDTH(DATA_WIDTH)
|
||||
) stbuf_dataff (
|
||||
.din (stbuf_datain[i][DATA_WIDTH-1:0]),
|
||||
.dout(stbuf_data[i][DATA_WIDTH-1:0]),
|
||||
.en (stbuf_wr_en[i]),
|
||||
.*
|
||||
);
|
||||
end
|
||||
end else begin : Gen_dccm_disable
|
||||
assign stbuf_wr_en[DEPTH-1:0] = '0;
|
||||
assign stbuf_reset[DEPTH-1:0] = '0;
|
||||
assign stbuf_vld[DEPTH-1:0] = '0;
|
||||
assign stbuf_dma_kill[DEPTH-1:0] = '0;
|
||||
assign stbuf_addr[DEPTH-1:0] = '0;
|
||||
assign stbuf_byteen[DEPTH-1:0] = '0;
|
||||
assign stbuf_data[DEPTH-1:0] = '0;
|
||||
end
|
||||
|
||||
// Store Buffer drain logic
|
||||
assign stbuf_reqvld_flushed_any = stbuf_vld[RdPtr] & stbuf_dma_kill[RdPtr];
|
||||
assign stbuf_reqvld_any = stbuf_vld[RdPtr] & ~stbuf_dma_kill[RdPtr] & ~(|stbuf_dma_kill_en[DEPTH-1:0]); // Don't drain if some kill bit is being set this cycle
|
||||
assign stbuf_addr_any[pt.LSU_SB_BITS-1:0] = stbuf_addr[RdPtr][pt.LSU_SB_BITS-1:0];
|
||||
assign stbuf_data_any[DATA_WIDTH-1:0] = stbuf_data[RdPtr][DATA_WIDTH-1:0];
|
||||
// Store Buffer drain logic
|
||||
assign stbuf_reqvld_flushed_any = stbuf_vld[RdPtr] & stbuf_dma_kill[RdPtr];
|
||||
assign stbuf_reqvld_any = stbuf_vld[RdPtr] & ~stbuf_dma_kill[RdPtr] & ~(|stbuf_dma_kill_en[DEPTH-1:0]); // Don't drain if some kill bit is being set this cycle
|
||||
assign stbuf_addr_any[pt.LSU_SB_BITS-1:0] = stbuf_addr[RdPtr][pt.LSU_SB_BITS-1:0];
|
||||
assign stbuf_data_any[DATA_WIDTH-1:0] = stbuf_data[RdPtr][DATA_WIDTH-1:0];
|
||||
|
||||
// Update the RdPtr/WrPtr logic
|
||||
// Need to revert the WrPtr for flush cases. Also revert the pipe WrPtrs
|
||||
assign WrPtrEn = (ldst_stbuf_reqvld_r & ~dual_stbuf_write_r & ~(store_coalesce_hi_r | store_coalesce_lo_r)) | // writing 1 and did not coalesce
|
||||
// Update the RdPtr/WrPtr logic
|
||||
// Need to revert the WrPtr for flush cases. Also revert the pipe WrPtrs
|
||||
assign WrPtrEn = (ldst_stbuf_reqvld_r & ~dual_stbuf_write_r & ~(store_coalesce_hi_r | store_coalesce_lo_r)) | // writing 1 and did not coalesce
|
||||
(ldst_stbuf_reqvld_r & dual_stbuf_write_r & ~(store_coalesce_hi_r & store_coalesce_lo_r)); // writing 2 and atleast 1 did not coalesce
|
||||
assign NxtWrPtr[DEPTH_LOG2-1:0] = (ldst_stbuf_reqvld_r & dual_stbuf_write_r & ~(store_coalesce_hi_r | store_coalesce_lo_r)) ? WrPtrPlus2[DEPTH_LOG2-1:0] : WrPtrPlus1[DEPTH_LOG2-1:0];
|
||||
assign RdPtrEn = lsu_stbuf_commit_any | stbuf_reqvld_flushed_any;
|
||||
assign NxtRdPtr[DEPTH_LOG2-1:0] = RdPtrPlus1[DEPTH_LOG2-1:0];
|
||||
assign NxtWrPtr[DEPTH_LOG2-1:0] = (ldst_stbuf_reqvld_r & dual_stbuf_write_r & ~(store_coalesce_hi_r | store_coalesce_lo_r)) ? WrPtrPlus2[DEPTH_LOG2-1:0] : WrPtrPlus1[DEPTH_LOG2-1:0];
|
||||
assign RdPtrEn = lsu_stbuf_commit_any | stbuf_reqvld_flushed_any;
|
||||
assign NxtRdPtr[DEPTH_LOG2-1:0] = RdPtrPlus1[DEPTH_LOG2-1:0];
|
||||
|
||||
always_comb begin
|
||||
stbuf_numvld_any[3:0] = '0;
|
||||
for (int i=0; i<DEPTH; i++) begin
|
||||
stbuf_numvld_any[3:0] += {3'b0, stbuf_vld[i]};
|
||||
always_comb begin
|
||||
stbuf_numvld_any[3:0] = '0;
|
||||
for (int i = 0; i < DEPTH; i++) begin
|
||||
stbuf_numvld_any[3:0] += {3'b0, stbuf_vld[i]};
|
||||
end
|
||||
end
|
||||
|
||||
// These go to store buffer to detect full
|
||||
assign isdccmst_m = lsu_pkt_m.valid & lsu_pkt_m.store & addr_in_dccm_m & ~lsu_pkt_m.dma;
|
||||
assign isdccmst_r = lsu_pkt_r.valid & lsu_pkt_r.store & addr_in_dccm_r & ~lsu_pkt_r.dma;
|
||||
|
||||
assign stbuf_specvld_m[1:0] = {1'b0, isdccmst_m} << (isdccmst_m & ldst_dual_m);
|
||||
assign stbuf_specvld_r[1:0] = {1'b0, isdccmst_r} << (isdccmst_r & ldst_dual_r);
|
||||
assign stbuf_specvld_any[3:0] = stbuf_numvld_any[3:0] + {2'b0, stbuf_specvld_m[1:0]} + {2'b0, stbuf_specvld_r[1:0]};
|
||||
|
||||
assign lsu_stbuf_full_any = (~ldst_dual_d & dec_lsu_valid_raw_d) ? (stbuf_specvld_any[3:0] >= DEPTH) : (stbuf_specvld_any[3:0] >= (DEPTH-1));
|
||||
assign lsu_stbuf_empty_any = (stbuf_numvld_any[3:0] == 4'b0);
|
||||
|
||||
// Load forwarding logic from the store queue
|
||||
assign cmpaddr_hi_m[pt.LSU_SB_BITS-1:$clog2(
|
||||
BYTE_WIDTH
|
||||
)] = end_addr_m[pt.LSU_SB_BITS-1:$clog2(
|
||||
BYTE_WIDTH
|
||||
)];
|
||||
|
||||
assign cmpaddr_lo_m[pt.LSU_SB_BITS-1:$clog2(
|
||||
BYTE_WIDTH
|
||||
)] = lsu_addr_m[pt.LSU_SB_BITS-1:$clog2(
|
||||
BYTE_WIDTH
|
||||
)];
|
||||
|
||||
always_comb begin : GenLdFwd
|
||||
stbuf_fwdbyteen_hi_pre_m[BYTE_WIDTH-1:0] = '0;
|
||||
stbuf_fwdbyteen_lo_pre_m[BYTE_WIDTH-1:0] = '0;
|
||||
|
||||
for (int i = 0; i < DEPTH; i++) begin
|
||||
stbuf_match_hi[i] = (stbuf_addr[i][pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] ==
|
||||
cmpaddr_hi_m[pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]) &
|
||||
stbuf_vld[i] & ~stbuf_dma_kill[i] & addr_in_dccm_m;
|
||||
stbuf_match_lo[i] = (stbuf_addr[i][pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] ==
|
||||
cmpaddr_lo_m[pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]) &
|
||||
stbuf_vld[i] & ~stbuf_dma_kill[i] & addr_in_dccm_m;
|
||||
|
||||
// Kill the store buffer entry if there is a dma store since it already updated the dccm
|
||||
stbuf_dma_kill_en[i] = (stbuf_match_hi[i] | stbuf_match_lo[i]) & lsu_pkt_m.valid & lsu_pkt_m.dma & lsu_pkt_m.store;
|
||||
|
||||
for (int j = 0; j < BYTE_WIDTH; j++) begin
|
||||
stbuf_fwdbyteenvec_hi[i][j] = stbuf_match_hi[i] & stbuf_byteen[i][j] & stbuf_vld[i];
|
||||
stbuf_fwdbyteen_hi_pre_m[j] |= stbuf_fwdbyteenvec_hi[i][j];
|
||||
|
||||
stbuf_fwdbyteenvec_lo[i][j] = stbuf_match_lo[i] & stbuf_byteen[i][j] & stbuf_vld[i];
|
||||
stbuf_fwdbyteen_lo_pre_m[j] |= stbuf_fwdbyteenvec_lo[i][j];
|
||||
end
|
||||
end
|
||||
end
|
||||
end // block: GenLdFwd
|
||||
|
||||
// These go to store buffer to detect full
|
||||
assign isdccmst_m = lsu_pkt_m.valid & lsu_pkt_m.store & addr_in_dccm_m & ~lsu_pkt_m.dma;
|
||||
assign isdccmst_r = lsu_pkt_r.valid & lsu_pkt_r.store & addr_in_dccm_r & ~lsu_pkt_r.dma;
|
||||
always_comb begin : GenLdData
|
||||
stbuf_fwddata_hi_pre_m[31:0] = '0;
|
||||
stbuf_fwddata_lo_pre_m[31:0] = '0;
|
||||
|
||||
assign stbuf_specvld_m[1:0] = {1'b0,isdccmst_m} << (isdccmst_m & ldst_dual_m);
|
||||
assign stbuf_specvld_r[1:0] = {1'b0,isdccmst_r} << (isdccmst_r & ldst_dual_r);
|
||||
assign stbuf_specvld_any[3:0] = stbuf_numvld_any[3:0] + {2'b0, stbuf_specvld_m[1:0]} + {2'b0, stbuf_specvld_r[1:0]};
|
||||
for (int i = 0; i < DEPTH; i++) begin
|
||||
stbuf_fwddata_hi_pre_m[31:0] |= {32{stbuf_match_hi[i]}} & stbuf_data[i][31:0];
|
||||
stbuf_fwddata_lo_pre_m[31:0] |= {32{stbuf_match_lo[i]}} & stbuf_data[i][31:0];
|
||||
|
||||
assign lsu_stbuf_full_any = (~ldst_dual_d & dec_lsu_valid_raw_d) ? (stbuf_specvld_any[3:0] >= DEPTH) : (stbuf_specvld_any[3:0] >= (DEPTH-1));
|
||||
assign lsu_stbuf_empty_any = (stbuf_numvld_any[3:0] == 4'b0);
|
||||
end
|
||||
|
||||
// Load forwarding logic from the store queue
|
||||
assign cmpaddr_hi_m[pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] = end_addr_m[pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)];
|
||||
end // block: GenLdData
|
||||
|
||||
assign cmpaddr_lo_m[pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] = lsu_addr_m[pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)];
|
||||
|
||||
always_comb begin: GenLdFwd
|
||||
stbuf_fwdbyteen_hi_pre_m[BYTE_WIDTH-1:0] = '0;
|
||||
stbuf_fwdbyteen_lo_pre_m[BYTE_WIDTH-1:0] = '0;
|
||||
|
||||
for (int i=0; i<DEPTH; i++) begin
|
||||
stbuf_match_hi[i] = (stbuf_addr[i][pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] == cmpaddr_hi_m[pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]) & stbuf_vld[i] & ~stbuf_dma_kill[i] & addr_in_dccm_m;
|
||||
stbuf_match_lo[i] = (stbuf_addr[i][pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] == cmpaddr_lo_m[pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]) & stbuf_vld[i] & ~stbuf_dma_kill[i] & addr_in_dccm_m;
|
||||
|
||||
// Kill the store buffer entry if there is a dma store since it already updated the dccm
|
||||
stbuf_dma_kill_en[i] = (stbuf_match_hi[i] | stbuf_match_lo[i]) & lsu_pkt_m.valid & lsu_pkt_m.dma & lsu_pkt_m.store;
|
||||
|
||||
for (int j=0; j<BYTE_WIDTH; j++) begin
|
||||
stbuf_fwdbyteenvec_hi[i][j] = stbuf_match_hi[i] & stbuf_byteen[i][j] & stbuf_vld[i];
|
||||
stbuf_fwdbyteen_hi_pre_m[j] |= stbuf_fwdbyteenvec_hi[i][j];
|
||||
|
||||
stbuf_fwdbyteenvec_lo[i][j] = stbuf_match_lo[i] & stbuf_byteen[i][j] & stbuf_vld[i];
|
||||
stbuf_fwdbyteen_lo_pre_m[j] |= stbuf_fwdbyteenvec_lo[i][j];
|
||||
end
|
||||
end
|
||||
end // block: GenLdFwd
|
||||
|
||||
always_comb begin: GenLdData
|
||||
stbuf_fwddata_hi_pre_m[31:0] = '0;
|
||||
stbuf_fwddata_lo_pre_m[31:0] = '0;
|
||||
|
||||
for (int i=0; i<DEPTH; i++) begin
|
||||
stbuf_fwddata_hi_pre_m[31:0] |= {32{stbuf_match_hi[i]}} & stbuf_data[i][31:0];
|
||||
stbuf_fwddata_lo_pre_m[31:0] |= {32{stbuf_match_lo[i]}} & stbuf_data[i][31:0];
|
||||
|
||||
end
|
||||
|
||||
end // block: GenLdData
|
||||
|
||||
// Create Hi/Lo signals - needed for the pipe forwarding
|
||||
assign ldst_byteen_r[7:0] = ({8{lsu_pkt_r.by}} & 8'b0000_0001) |
|
||||
// Create Hi/Lo signals - needed for the pipe forwarding
|
||||
assign ldst_byteen_r[7:0] = ({8{lsu_pkt_r.by}} & 8'b0000_0001) |
|
||||
({8{lsu_pkt_r.half}} & 8'b0000_0011) |
|
||||
({8{lsu_pkt_r.word}} & 8'b0000_1111) |
|
||||
({8{lsu_pkt_r.dword}} & 8'b1111_1111);
|
||||
|
||||
assign ldst_byteen_ext_r[7:0] = ldst_byteen_r[7:0] << lsu_addr_r[1:0];
|
||||
assign ldst_byteen_ext_r[7:0] = ldst_byteen_r[7:0] << lsu_addr_r[1:0];
|
||||
|
||||
assign ldst_byteen_hi_r[3:0] = ldst_byteen_ext_r[7:4];
|
||||
assign ldst_byteen_lo_r[3:0] = ldst_byteen_ext_r[3:0];
|
||||
assign ldst_byteen_hi_r[3:0] = ldst_byteen_ext_r[7:4];
|
||||
assign ldst_byteen_lo_r[3:0] = ldst_byteen_ext_r[3:0];
|
||||
|
||||
assign ld_addr_rhit_lo_lo = (lsu_addr_m[31:2] == lsu_addr_r[31:2]) & lsu_pkt_r.valid & lsu_pkt_r.store & ~lsu_pkt_r.dma;
|
||||
assign ld_addr_rhit_lo_hi = (end_addr_m[31:2] == lsu_addr_r[31:2]) & lsu_pkt_r.valid & lsu_pkt_r.store & ~lsu_pkt_r.dma;
|
||||
assign ld_addr_rhit_hi_lo = (lsu_addr_m[31:2] == end_addr_r[31:2]) & lsu_pkt_r.valid & lsu_pkt_r.store & ~lsu_pkt_r.dma & dual_stbuf_write_r;
|
||||
assign ld_addr_rhit_hi_hi = (end_addr_m[31:2] == end_addr_r[31:2]) & lsu_pkt_r.valid & lsu_pkt_r.store & ~lsu_pkt_r.dma & dual_stbuf_write_r;
|
||||
assign ld_addr_rhit_lo_lo = (lsu_addr_m[31:2] == lsu_addr_r[31:2]) & lsu_pkt_r.valid & lsu_pkt_r.store & ~lsu_pkt_r.dma;
|
||||
assign ld_addr_rhit_lo_hi = (end_addr_m[31:2] == lsu_addr_r[31:2]) & lsu_pkt_r.valid & lsu_pkt_r.store & ~lsu_pkt_r.dma;
|
||||
assign ld_addr_rhit_hi_lo = (lsu_addr_m[31:2] == end_addr_r[31:2]) & lsu_pkt_r.valid & lsu_pkt_r.store & ~lsu_pkt_r.dma & dual_stbuf_write_r;
|
||||
assign ld_addr_rhit_hi_hi = (end_addr_m[31:2] == end_addr_r[31:2]) & lsu_pkt_r.valid & lsu_pkt_r.store & ~lsu_pkt_r.dma & dual_stbuf_write_r;
|
||||
|
||||
for (genvar i=0; i<BYTE_WIDTH; i++) begin
|
||||
assign ld_byte_rhit_lo_lo[i] = ld_addr_rhit_lo_lo & ldst_byteen_lo_r[i];
|
||||
assign ld_byte_rhit_lo_hi[i] = ld_addr_rhit_lo_hi & ldst_byteen_lo_r[i];
|
||||
assign ld_byte_rhit_hi_lo[i] = ld_addr_rhit_hi_lo & ldst_byteen_hi_r[i];
|
||||
assign ld_byte_rhit_hi_hi[i] = ld_addr_rhit_hi_hi & ldst_byteen_hi_r[i];
|
||||
for (genvar i = 0; i < BYTE_WIDTH; i++) begin
|
||||
assign ld_byte_rhit_lo_lo[i] = ld_addr_rhit_lo_lo & ldst_byteen_lo_r[i];
|
||||
assign ld_byte_rhit_lo_hi[i] = ld_addr_rhit_lo_hi & ldst_byteen_lo_r[i];
|
||||
assign ld_byte_rhit_hi_lo[i] = ld_addr_rhit_hi_lo & ldst_byteen_hi_r[i];
|
||||
assign ld_byte_rhit_hi_hi[i] = ld_addr_rhit_hi_hi & ldst_byteen_hi_r[i];
|
||||
|
||||
assign ld_byte_rhit_lo[i] = ld_byte_rhit_lo_lo[i] | ld_byte_rhit_hi_lo[i];
|
||||
assign ld_byte_rhit_hi[i] = ld_byte_rhit_lo_hi[i] | ld_byte_rhit_hi_hi[i];
|
||||
assign ld_byte_rhit_lo[i] = ld_byte_rhit_lo_lo[i] | ld_byte_rhit_hi_lo[i];
|
||||
assign ld_byte_rhit_hi[i] = ld_byte_rhit_lo_hi[i] | ld_byte_rhit_hi_hi[i];
|
||||
|
||||
assign ld_fwddata_rpipe_lo[(8*i)+7:(8*i)] = ({8{ld_byte_rhit_lo_lo[i]}} & store_data_lo_r[(8*i)+7:(8*i)]) |
|
||||
assign ld_fwddata_rpipe_lo[(8*i)+7:(8*i)] = ({8{ld_byte_rhit_lo_lo[i]}} & store_data_lo_r[(8*i)+7:(8*i)]) |
|
||||
({8{ld_byte_rhit_hi_lo[i]}} & store_data_hi_r[(8*i)+7:(8*i)]);
|
||||
|
||||
assign ld_fwddata_rpipe_hi[(8*i)+7:(8*i)] = ({8{ld_byte_rhit_lo_hi[i]}} & store_data_lo_r[(8*i)+7:(8*i)]) |
|
||||
assign ld_fwddata_rpipe_hi[(8*i)+7:(8*i)] = ({8{ld_byte_rhit_lo_hi[i]}} & store_data_lo_r[(8*i)+7:(8*i)]) |
|
||||
({8{ld_byte_rhit_hi_hi[i]}} & store_data_hi_r[(8*i)+7:(8*i)]);
|
||||
|
||||
assign ld_byte_hit_lo[i] = ld_byte_rhit_lo_lo[i] | ld_byte_rhit_hi_lo[i];
|
||||
assign ld_byte_hit_hi[i] = ld_byte_rhit_lo_hi[i] | ld_byte_rhit_hi_hi[i];
|
||||
assign ld_byte_hit_lo[i] = ld_byte_rhit_lo_lo[i] | ld_byte_rhit_hi_lo[i];
|
||||
assign ld_byte_hit_hi[i] = ld_byte_rhit_lo_hi[i] | ld_byte_rhit_hi_hi[i];
|
||||
|
||||
assign stbuf_fwdbyteen_hi_m[i] = ld_byte_hit_hi[i] | stbuf_fwdbyteen_hi_pre_m[i];
|
||||
assign stbuf_fwdbyteen_lo_m[i] = ld_byte_hit_lo[i] | stbuf_fwdbyteen_lo_pre_m[i];
|
||||
// // Pipe vs Store Queue priority
|
||||
assign stbuf_fwddata_lo_m[(8*i)+7:(8*i)] = ld_byte_rhit_lo[i] ? ld_fwddata_rpipe_lo[(8*i)+7:(8*i)] : stbuf_fwddata_lo_pre_m[(8*i)+7:(8*i)];
|
||||
// // Pipe vs Store Queue priority
|
||||
assign stbuf_fwddata_hi_m[(8*i)+7:(8*i)] = ld_byte_rhit_hi[i] ? ld_fwddata_rpipe_hi[(8*i)+7:(8*i)] : stbuf_fwddata_hi_pre_m[(8*i)+7:(8*i)];
|
||||
end
|
||||
assign stbuf_fwdbyteen_hi_m[i] = ld_byte_hit_hi[i] | stbuf_fwdbyteen_hi_pre_m[i];
|
||||
assign stbuf_fwdbyteen_lo_m[i] = ld_byte_hit_lo[i] | stbuf_fwdbyteen_lo_pre_m[i];
|
||||
// // Pipe vs Store Queue priority
|
||||
assign stbuf_fwddata_lo_m[(8*i)+7:(8*i)] = ld_byte_rhit_lo[i] ? ld_fwddata_rpipe_lo[(8*i)+7:(8*i)] : stbuf_fwddata_lo_pre_m[(8*i)+7:(8*i)];
|
||||
// // Pipe vs Store Queue priority
|
||||
assign stbuf_fwddata_hi_m[(8*i)+7:(8*i)] = ld_byte_rhit_hi[i] ? ld_fwddata_rpipe_hi[(8*i)+7:(8*i)] : stbuf_fwddata_hi_pre_m[(8*i)+7:(8*i)];
|
||||
end
|
||||
|
||||
// Flops
|
||||
rvdffs #(.WIDTH(DEPTH_LOG2)) WrPtrff (.din(NxtWrPtr[DEPTH_LOG2-1:0]), .dout(WrPtr[DEPTH_LOG2-1:0]), .en(WrPtrEn), .clk(lsu_stbuf_c1_clk), .*);
|
||||
rvdffs #(.WIDTH(DEPTH_LOG2)) RdPtrff (.din(NxtRdPtr[DEPTH_LOG2-1:0]), .dout(RdPtr[DEPTH_LOG2-1:0]), .en(RdPtrEn), .clk(lsu_stbuf_c1_clk), .*);
|
||||
// Flops
|
||||
rvdffs #(
|
||||
.WIDTH(DEPTH_LOG2)
|
||||
) WrPtrff (
|
||||
.din (NxtWrPtr[DEPTH_LOG2-1:0]),
|
||||
.dout(WrPtr[DEPTH_LOG2-1:0]),
|
||||
.en (WrPtrEn),
|
||||
.clk (lsu_stbuf_c1_clk),
|
||||
.*
|
||||
);
|
||||
rvdffs #(
|
||||
.WIDTH(DEPTH_LOG2)
|
||||
) RdPtrff (
|
||||
.din (NxtRdPtr[DEPTH_LOG2-1:0]),
|
||||
.dout(RdPtr[DEPTH_LOG2-1:0]),
|
||||
.en (RdPtrEn),
|
||||
.clk (lsu_stbuf_c1_clk),
|
||||
.*
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
|
@ -23,46 +23,51 @@
|
|||
//
|
||||
//********************************************************************************
|
||||
module el2_lsu_trigger
|
||||
import el2_pkg::*;
|
||||
import el2_pkg::*;
|
||||
#(
|
||||
`include "el2_param.vh"
|
||||
)(
|
||||
input el2_trigger_pkt_t [3:0] trigger_pkt_any, // trigger packet from dec
|
||||
input el2_lsu_pkt_t lsu_pkt_m, // lsu packet
|
||||
input logic [31:0] lsu_addr_m, // address
|
||||
input logic [31:0] store_data_m, // store data
|
||||
`include "el2_param.vh"
|
||||
) (
|
||||
input el2_trigger_pkt_t [ 3:0] trigger_pkt_any, // trigger packet from dec
|
||||
input el2_lsu_pkt_t lsu_pkt_m, // lsu packet
|
||||
input logic [31:0] lsu_addr_m, // address
|
||||
input logic [31:0] store_data_m, // store data
|
||||
|
||||
output logic [3:0] lsu_trigger_match_m // match result
|
||||
output logic [3:0] lsu_trigger_match_m // match result
|
||||
);
|
||||
|
||||
logic trigger_enable;
|
||||
logic [3:0][31:0] lsu_match_data;
|
||||
logic [3:0] lsu_trigger_data_match;
|
||||
logic [31:0] store_data_trigger_m;
|
||||
logic [31:0] ldst_addr_trigger_m;
|
||||
logic trigger_enable;
|
||||
logic [ 3:0][31:0] lsu_match_data;
|
||||
logic [ 3:0] lsu_trigger_data_match;
|
||||
logic [31:0] store_data_trigger_m;
|
||||
logic [31:0] ldst_addr_trigger_m;
|
||||
|
||||
// Generate the trigger enable (This is for power)
|
||||
always_comb begin
|
||||
trigger_enable = 1'b0;
|
||||
for (int i=0; i<4; i++) begin
|
||||
trigger_enable |= trigger_pkt_any[i].m;
|
||||
end
|
||||
end
|
||||
// Generate the trigger enable (This is for power)
|
||||
always_comb begin
|
||||
trigger_enable = 1'b0;
|
||||
for (int i = 0; i < 4; i++) begin
|
||||
trigger_enable |= trigger_pkt_any[i].m;
|
||||
end
|
||||
end
|
||||
|
||||
assign store_data_trigger_m[31:0] = {({16{lsu_pkt_m.word}} & store_data_m[31:16]),({8{(lsu_pkt_m.half | lsu_pkt_m.word)}} & store_data_m[15:8]), store_data_m[7:0]} & {32{trigger_enable}};
|
||||
assign ldst_addr_trigger_m[31:0] = lsu_addr_m[31:0] & {32{trigger_enable}};
|
||||
assign store_data_trigger_m[31:0] = {({16{lsu_pkt_m.word}} & store_data_m[31:16]),({8{(lsu_pkt_m.half | lsu_pkt_m.word)}} & store_data_m[15:8]), store_data_m[7:0]} & {32{trigger_enable}};
|
||||
assign ldst_addr_trigger_m[31:0] = lsu_addr_m[31:0] & {32{trigger_enable}};
|
||||
|
||||
|
||||
for (genvar i=0; i<4; i++) begin
|
||||
assign lsu_match_data[i][31:0] = ({32{~trigger_pkt_any[i].select}} & ldst_addr_trigger_m[31:0]) |
|
||||
for (genvar i = 0; i < 4; i++) begin
|
||||
assign lsu_match_data[i][31:0] = ({32{~trigger_pkt_any[i].select}} & ldst_addr_trigger_m[31:0]) |
|
||||
({32{trigger_pkt_any[i].select & trigger_pkt_any[i].store}} & store_data_trigger_m[31:0]);
|
||||
|
||||
rvmaskandmatch trigger_match (.mask(trigger_pkt_any[i].tdata2[31:0]), .data(lsu_match_data[i][31:0]), .masken(trigger_pkt_any[i].match), .match(lsu_trigger_data_match[i]));
|
||||
rvmaskandmatch trigger_match (
|
||||
.mask (trigger_pkt_any[i].tdata2[31:0]),
|
||||
.data (lsu_match_data[i][31:0]),
|
||||
.masken(trigger_pkt_any[i].match),
|
||||
.match (lsu_trigger_data_match[i])
|
||||
);
|
||||
|
||||
assign lsu_trigger_match_m[i] = lsu_pkt_m.valid & ~lsu_pkt_m.dma & trigger_enable &
|
||||
assign lsu_trigger_match_m[i] = lsu_pkt_m.valid & ~lsu_pkt_m.dma & trigger_enable &
|
||||
((trigger_pkt_any[i].store & lsu_pkt_m.store) | (trigger_pkt_any[i].load & lsu_pkt_m.load & ~trigger_pkt_any[i].select)) &
|
||||
lsu_trigger_data_match[i];
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule // el2_lsu_trigger
|
||||
endmodule // el2_lsu_trigger
|
||||
|
|
Loading…
Reference in New Issue