IFU added

This commit is contained in:
​Laraib Khan 2020-12-16 18:06:34 +05:00
parent 9a6d820227
commit 4cf7b083e5
22 changed files with 37944 additions and 37983 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -13,56 +13,22 @@ class ifu extends Module with lib with RequireAsyncReset {
val exu_flush_path_final = Input(UInt(31.W))
val free_clk = Input(Clock())
val active_clk = Input(Clock())
val ifu_dec = new ifu_dec()
val exu_ifu = new exu_ifu()
val iccm = new iccm_mem()
val ic = new ic_mem()
// AXI Write Channel
val ifu = new axi_channels(IFU_BUS_TAG)
val ifu_dec = new ifu_dec() // IFU and DEC interconnects
val exu_ifu = new exu_ifu() // IFU and EXU interconnects
val iccm = new iccm_mem() // ICCM memory signals
val ic = new ic_mem() // I$ memory signals
val ifu = new axi_channels(IFU_BUS_TAG) // AXI Write Channel
val ifu_bus_clk_en = Input(Bool())
// DMA signals
val ifu_dma = new ifu_dma()
// ICCM
val ifu_dma = new ifu_dma() // DMA signals
// ICCM DMA signals
val iccm_dma_ecc_error = Output(Bool())
val iccm_dma_rvalid = Output(Bool())
val iccm_dma_rdata = Output(UInt(64.W))
val iccm_dma_rtag = Output(UInt(3.W))
val iccm_ready = Output(Bool())
// I$
// val ic_rw_addr = Output(UInt(31.W))
// val ic_wr_en = Output(UInt(ICACHE_NUM_WAYS.W))
// val ic_rd_en = Output(Bool())
// val ic_wr_data = Output(Vec(ICACHE_BANKS_WAY, UInt(71.W)))
// val ic_rd_data = Input(UInt(64.W))
// val ic_debug_rd_data = Input(UInt(71.W))
// val ictag_debug_rd_data = Input(UInt(26.W))
// val ic_debug_wr_data = Output(UInt(71.W))
// val ic_eccerr = Input(UInt(ICACHE_BANKS_WAY.W))
// val ic_parerr = Input(UInt(ICACHE_BANKS_WAY.W))
// val ic_premux_data = Output(UInt(64.W))
// val ic_sel_premux_data = Output(Bool())
// val ic_debug_addr = Output(UInt((ICACHE_INDEX_HI-2).W))
// val ic_debug_rd_en = Output(Bool())
// val ic_debug_wr_en = Output(Bool())
// val ic_debug_tag_array = Output(Bool())
// val ic_debug_way = Output(UInt(ICACHE_NUM_WAYS.W))
// val ic_tag_valid = Output(UInt(ICACHE_NUM_WAYS.W))
// val ic_rd_hit = Input(UInt(ICACHE_NUM_WAYS.W))
// val ic_tag_perr = Input(Bool())
// ICCM cont'd
// val iccm_rw_addr = Output(UInt((ICCM_BITS-1).W))
// val iccm_wren = Output(Bool())
// val iccm_rden = Output(Bool())
// val iccm_wr_data = Output(UInt(78.W))
// val iccm_wr_size = Output(UInt(3.W))
// val iccm_rd_data = Input(UInt(64.W))
// val iccm_rd_data_ecc = Input(UInt(78.W))
// Performance counter
val iccm_dma_sb_error = Output(Bool())
// val iccm_buf_correct_ecc = Output(Bool())
// val iccm_correction_state = Output(Bool())
val dec_tlu_flush_lower_wb = Input(Bool())
val scan_mode = Input(Bool())
})
val mem_ctl = Module(new ifu_mem_ctl)
@ -118,8 +84,9 @@ class ifu extends Module with lib with RequireAsyncReset {
bp_ctl.io.dec_bp <> io.ifu_dec.dec_bp
bp_ctl.io.exu_bp <> io.exu_ifu.exu_bp
bp_ctl.io.exu_flush_final := io.exu_flush_final
bp_ctl.io.dec_tlu_flush_lower_wb := io.dec_tlu_flush_lower_wb
// mem-ctl wiring
// mem-ctl Inputs
mem_ctl.io.free_clk := io.free_clk
mem_ctl.io.active_clk := io.active_clk
mem_ctl.io.exu_flush_final := io.exu_flush_final
@ -138,49 +105,19 @@ class ifu extends Module with lib with RequireAsyncReset {
mem_ctl.io.dma_mem_ctl <> io.ifu_dma.dma_mem_ctl
mem_ctl.io.ic <> io.ic
mem_ctl.io.iccm <> io.iccm
// mem_ctl.io.ic_rd_data := io.ic_rd_data
// mem_ctl.io.ic_debug_rd_data := io.ic_debug_rd_data
// mem_ctl.io.ictag_debug_rd_data := io.ictag_debug_rd_data
// mem_ctl.io.ic_eccerr := io.ic_eccerr
// mem_ctl.io.ic_parerr := io.ic_parerr
// mem_ctl.io.ic_rd_hit := io.ic_rd_hit
// mem_ctl.io.ic_tag_perr := io.ic_tag_perr
// mem_ctl.io.iccm_rd_data := io.iccm_rd_data
// mem_ctl.io.iccm_rd_data_ecc := io.iccm_rd_data_ecc
mem_ctl.io.ifu_fetch_val := mem_ctl.io.ic_fetch_val_f
mem_ctl.io.dec_tlu_flush_lower_wb := io.dec_tlu_flush_lower_wb
mem_ctl.io.scan_mode := io.scan_mode
// Connecting the final outputs
// DMA to the ICCM
io.iccm_dma_ecc_error := mem_ctl.io.iccm_dma_ecc_error
io.iccm_dma_rvalid := mem_ctl.io.iccm_dma_rvalid
io.iccm_dma_rdata := mem_ctl.io.iccm_dma_rdata
io.iccm_dma_rtag := mem_ctl.io.iccm_dma_rtag
io.iccm_ready := mem_ctl.io.iccm_ready
// I$
// io.ic_rw_addr := mem_ctl.io.ic_rw_addr
// io.ic_wr_en := mem_ctl.io.ic_wr_en
// io.ic_rd_en := mem_ctl.io.ic_rd_en
// io.ic_wr_data := mem_ctl.io.ic_wr_data
// io.ic_debug_wr_data := mem_ctl.io.ic_debug_wr_data
// io.ic_sel_premux_data := mem_ctl.io.ic_sel_premux_data
// io.ic_debug_addr := mem_ctl.io.ic_debug_addr
// io.ic_debug_rd_en := mem_ctl.io.ic_debug_rd_en
// io.ic_debug_wr_en := mem_ctl.io.ic_debug_wr_en
// io.ic_debug_tag_array := mem_ctl.io.ic_debug_tag_array
// io.ic_debug_way := mem_ctl.io.ic_debug_way
// io.ic_tag_valid := mem_ctl.io.ic_tag_valid
// io.iccm_rw_addr := mem_ctl.io.iccm_rw_addr
// io.iccm_wren := mem_ctl.io.iccm_wren
// io.iccm_rden := mem_ctl.io.iccm_rden
// io.iccm_wr_data := mem_ctl.io.iccm_wr_data
// io.iccm_wr_size := mem_ctl.io.iccm_wr_size
// Performance counter
io.iccm_dma_sb_error := mem_ctl.io.iccm_dma_sb_error
// Aligner branch data
// io.iccm_buf_correct_ecc := mem_ctl.io.iccm_buf_correct_ecc
// io.iccm_correction_state := mem_ctl.io.iccm_correction_state
// io.ic_premux_data := mem_ctl.io.ic_premux_data
}
object ifu_main extends App {
println((new chisel3.stage.ChiselStage).emitVerilog(new ifu()))
}

View File

@ -8,27 +8,27 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
val io = IO(new Bundle{
val scan_mode = Input(Bool())
val active_clk = Input(Clock())
val ifu_async_error_start = Input(Bool())
val iccm_rd_ecc_double_err = Input(Bool())
val ic_access_fault_f = Input(Bool())
val ic_access_fault_type_f = Input(UInt(2.W))
val ifu_bp_fghr_f = Input(UInt(BHT_GHR_SIZE.W))
val ifu_bp_btb_target_f = Input(UInt(31.W))
val ifu_bp_poffset_f = Input(UInt(12.W))
val ifu_bp_hist0_f = Input(UInt(2.W))
val ifu_bp_hist1_f = Input(UInt(2.W))
val ifu_bp_pc4_f = Input(UInt(2.W))
val ifu_bp_way_f = Input(UInt(2.W))
val ifu_bp_valid_f = Input(UInt(2.W))
val ifu_bp_ret_f = Input(UInt(2.W))
val exu_flush_final = Input(Bool())
val dec_aln = new dec_aln()
val ifu_fetch_data_f = Input(UInt(32.W))
val ifu_fetch_val = Input(UInt(2.W))
val ifu_fetch_pc = Input(UInt(31.W))
val ifu_async_error_start = Input(Bool()) // Error coming from mem-ctl
val iccm_rd_ecc_double_err = Input(Bool()) // ICCM double error coming from mem-ctl
val ic_access_fault_f = Input(Bool()) // Access fault in I$
val ic_access_fault_type_f = Input(UInt(2.W)) // Type of access fault occured
val ifu_bp_fghr_f = Input(UInt(BHT_GHR_SIZE.W)) // Data coming from the branch predictor to put in the FP
val ifu_bp_btb_target_f = Input(UInt(31.W)) // Target for the instruction enqueue in the FP
val ifu_bp_poffset_f = Input(UInt(12.W)) // Offset to the current PC for branch
val ifu_bp_hist0_f = Input(UInt(2.W)) // History to EXU
val ifu_bp_hist1_f = Input(UInt(2.W)) // History to EXU
val ifu_bp_pc4_f = Input(UInt(2.W)) // PC4
val ifu_bp_way_f = Input(UInt(2.W)) // Way to help in miss prediction
val ifu_bp_valid_f = Input(UInt(2.W)) // Valid Branch prediction
val ifu_bp_ret_f = Input(UInt(2.W)) // BP ret
val exu_flush_final = Input(Bool()) // Miss prediction
val dec_aln = new dec_aln() // Data going to the dec from the ALN
val ifu_fetch_data_f = Input(UInt(32.W)) // PC of the current instruction in the FP
val ifu_fetch_val = Input(UInt(2.W)) // PC boundary i.e 'x' of 2 or 4
val ifu_fetch_pc = Input(UInt(31.W)) // Current PC
/////////////////////////////////////////////////
val ifu_fb_consume1 = Output(Bool())
val ifu_fb_consume2 = Output(Bool())
val ifu_fb_consume1 = Output(Bool()) // FP used 1
val ifu_fb_consume2 = Output(Bool()) // FP used 2
})
val MHI = 46+BHT_GHR_SIZE // 54
@ -95,12 +95,16 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
val shift_2B = WireInit(Bool(), 0.U)
val f0_shift_2B = WireInit(Bool(), 0.U)
// Stall if there is an error in the instrucion
error_stall_in := (error_stall | io.ifu_async_error_start) & !io.exu_flush_final
// Flop the stall until flush
error_stall := withClock(io.active_clk) {RegNext(error_stall_in, init = 0.U)}
// Write Ptr of the FP
val wrptr = withClock(io.active_clk) {RegNext(wrptr_in, init = 0.U)}
// Read Ptr of the FP
val rdptr = withClock(io.active_clk) {RegNext(rdptr_in, init = 0.U)}
// Fetch Instruction boundary
val f2val = withClock(io.active_clk) {RegNext(f2val_in, init = 0.U)}
val f1val = withClock(io.active_clk) {RegNext(f1val_in, init = 0.U)}
val f0val = withClock(io.active_clk) {RegNext(f0val_in, init = 0.U)}
@ -108,30 +112,34 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
val q2off = withClock(io.active_clk) {RegNext(q2off_in, init = 0.U)}
val q1off = withClock(io.active_clk) {RegNext(q1off_in, init = 0.U)}
val q0off = withClock(io.active_clk) {RegNext(q0off_in, init = 0.U)}
// Instrution PC to the FP
val f2pc = rvdffe(io.ifu_fetch_pc, f2_wr_en.asBool, clock, io.scan_mode)
val f1pc = rvdffe(f1pc_in, f1_shift_wr_en.asBool, clock, io.scan_mode)
val f0pc = rvdffe(f0pc_in, f0_shift_wr_en.asBool, clock, io.scan_mode)
// Branch data to the FP
brdata2 := rvdffe(brdata_in, qwen(2), clock, io.scan_mode)
brdata1 := rvdffe(brdata_in, qwen(1), clock, io.scan_mode)
brdata0 := rvdffe(brdata_in, qwen(0), clock, io.scan_mode)
// Miscalanious data to the FP including error's
misc2 := rvdffe(misc_data_in, qwen(2), clock, io.scan_mode)
misc1 := rvdffe(misc_data_in, qwen(1), clock, io.scan_mode)
misc0 := rvdffe(misc_data_in, qwen(0), clock, io.scan_mode)
// Instruction in the FP
q2 := rvdffe(io.ifu_fetch_data_f, qwen(2), clock, io.scan_mode)
q1 := rvdffe(io.ifu_fetch_data_f, qwen(1), clock, io.scan_mode)
q0 := rvdffe(io.ifu_fetch_data_f, qwen(0), clock, io.scan_mode)
// Shift FP logic
f2_wr_en := fetch_to_f2
f1_shift_wr_en := fetch_to_f1 | shift_f2_f1 | f1_shift_2B
f0_shift_wr_en := fetch_to_f0 | shift_f2_f0 | shift_f1_f0 | shift_2B | shift_4B
// FP read enable .. 3-bit for Implemenation of 1HMux
val qren = Cat(rdptr === 2.U, rdptr === 1.U, rdptr === 0.U)
// FP write enable .. 3-bit for Implemenation of 1HMux
qwen := Cat(wrptr === 2.U & ifvalid, wrptr === 1.U & ifvalid, wrptr === 0.U & ifvalid)
// Read Pointer calculation
// Next rdptr = # of consume + current ptr location (Rounding it from 2)
rdptr_in := Mux1H(Seq((qren(0) & io.ifu_fb_consume1 & !io.exu_flush_final).asBool -> 1.U,
(qren(1) & io.ifu_fb_consume1 & !io.exu_flush_final).asBool -> 2.U,
(qren(2) & io.ifu_fb_consume1 & !io.exu_flush_final).asBool -> 0.U,
@ -140,6 +148,7 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
(qren(2) & io.ifu_fb_consume2 & !io.exu_flush_final).asBool -> 1.U,
(!io.ifu_fb_consume1 & !io.ifu_fb_consume2 & !io.exu_flush_final).asBool -> rdptr))
// As there is only 1 enqueue so each time move by 1
wrptr_in := Mux1H(Seq((qwen(0) & !io.exu_flush_final).asBool -> 1.U,
(qwen(1) & !io.exu_flush_final).asBool -> 2.U,
(qwen(2) & !io.exu_flush_final).asBool -> 0.U,
@ -166,7 +175,7 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
val q0sel = Cat(q0ptr, !q0ptr)
val q1sel = Cat(q1ptr, !q1ptr)
// Misc data error, access-fault, type of fault, target, offset and ghr value
misc_data_in := Cat(io.iccm_rd_ecc_double_err, io.ic_access_fault_f, io.ic_access_fault_type_f,
io.ifu_bp_btb_target_f, io.ifu_bp_poffset_f, io.ifu_bp_fghr_f)
@ -192,10 +201,11 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
val f0poffset = misc0eff(BHT_GHR_SIZE+11, BHT_GHR_SIZE)
val f0fghr = misc0eff(BHT_GHR_SIZE-1, 0)
// Branch information
brdata_in := Cat(io.ifu_bp_hist1_f(1),io.ifu_bp_hist0_f(1),io.ifu_bp_pc4_f(1),io.ifu_bp_way_f(1),io.ifu_bp_valid_f(1),
io.ifu_bp_ret_f(1), io.ifu_bp_hist1_f(0),io.ifu_bp_hist0_f(0),io.ifu_bp_pc4_f(0),io.ifu_bp_way_f(0),
io.ifu_bp_valid_f(0),io.ifu_bp_ret_f(0))
// Effective branch information
val brdataeff = Mux1H(Seq(qren(0).asBool->Cat(brdata1,brdata0),
qren(1).asBool->Cat(brdata2,brdata1),
qren(2).asBool->Cat(brdata0,brdata2)))
@ -227,11 +237,13 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
val consume_fb0 = !sf0val(0) & f0val(0)
val consume_fb1 = !sf1val(0) & f1val(0)
// Depending on type of instruction and boundary determine how many FP to consume
io.ifu_fb_consume1 := consume_fb0 & !consume_fb1 & !io.exu_flush_final
io.ifu_fb_consume2 := consume_fb0 & consume_fb1 & !io.exu_flush_final
ifvalid := io.ifu_fetch_val(0)
// Shift logic for each dequeue
shift_f1_f0 := !sf0_valid & sf1_valid
shift_f2_f0 := !sf0_valid & !sf1_valid & f2_valid
shift_f2_f1 := !sf0_valid & sf1_valid & f2_valid
@ -285,6 +297,7 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
q1final := Mux1H(Seq(q1sel(0).asBool->q1eff(15,0), q1sel(1).asBool->q1eff(31,16)))
// Alinging the data according to the boundary of PC
val aligndata = Mux1H(Seq(f0val(1).asBool -> q0final, (~f0val(1) & f0val(0)).asBool -> Cat(q1final(15,0),q0final(15,0))))
alignval := Mux1H(Seq(f0val(1).asBool->3.U, (!f0val(1) & f0val(0)) -> Cat(f1val(0),1.U)))
@ -317,6 +330,7 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
io.dec_aln.aln_dec.ifu_i0_cinst := aligndata(15,0)
// Instruction is compressed or not
first4B := aligndata(1,0) === 3.U
val first2B = ~first4B
@ -334,11 +348,12 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
io.dec_aln.aln_ib.ifu_i0_dbecc := Mux1H(Seq(first4B.asBool->aligndbecc.orR, first2B.asBool->aligndbecc(0)))
val ifirst = aligndata
// Expander from 16-bit to 32-bit
val decompressed = Module(new ifu_compress_ctl())
io.dec_aln.aln_ib.ifu_i0_instr := Mux1H(Seq(first4B.asBool -> ifirst, first2B.asBool -> decompressed.io.dout))
// Hashing the PC
val firstpc_hash = btb_addr_hash(f0pc)
val secondpc_hash = btb_addr_hash(secondpc)

View File

@ -15,6 +15,7 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
val ifc_fetch_addr_f = Input(UInt(31.W))
val ifc_fetch_req_f = Input(Bool()) // Fetch request generated by the IFC
val dec_bp = new dec_bp()
val dec_tlu_flush_lower_wb = Input(Bool())
val exu_bp = Flipped(new exu_bp())
val ifu_bp_hit_taken_f = Output(Bool())
val ifu_bp_btb_target_f = Output(UInt(31.W))
@ -119,7 +120,7 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
val exu_flush_final_d1 = withClock(io.active_clk) {RegNext(io.exu_flush_final, init = 0.U)}
// If there is a flush from the lower pipe wait until the flush gets deasserted from the (decode) side
leak_one_f := (io.dec_bp.dec_tlu_flush_leak_one_wb & io.dec_bp.dec_tlu_flush_lower_wb) | (leak_one_f_d1 & !io.dec_bp.dec_tlu_flush_lower_wb)
leak_one_f := (io.dec_bp.dec_tlu_flush_leak_one_wb & io.dec_tlu_flush_lower_wb) | (leak_one_f_d1 & !io.dec_tlu_flush_lower_wb)
// For a tag to match the branch should be valid tag should match and a fetch request should be generated
// Also there should be no bank conflict or leak-one

View File

@ -7,32 +7,32 @@ import chisel3.util._
class ifu_ifc_ctl extends Module with lib with RequireAsyncReset {
val io = IO(new Bundle{
val exu_flush_final = Input(Bool())
val exu_flush_path_final = Input(UInt(31.W))
val exu_flush_final = Input(Bool()) // Miss Prediction for EXU
val exu_flush_path_final = Input(UInt(31.W)) // Replay PC
val free_clk = Input(Clock())
val active_clk = Input(Clock())
val scan_mode = Input(Bool())
val ic_hit_f = Input(Bool())
val ifu_ic_mb_empty = Input(Bool())
val ifu_fb_consume1 = Input(Bool())
val ifu_fb_consume2 = Input(Bool())
val ifu_bp_hit_taken_f = Input(Bool())
val ifu_bp_btb_target_f = Input(UInt(31.W))
val ic_dma_active = Input(Bool())
val ifu_ic_mb_empty = Input(Bool()) // Miss buffer of mem-ctl empty
val ifu_fb_consume1 = Input(Bool()) // Consume 1 fetch from FP
val ifu_fb_consume2 = Input(Bool()) // Consume 2 fetch from FP
val ifu_bp_hit_taken_f = Input(Bool()) // Branch taken from BP
val ifu_bp_btb_target_f = Input(UInt(31.W)) // Predicted PC
val ic_dma_active = Input(Bool()) // DMA for I$
val ic_write_stall = Input(Bool())
val dec_ifc = new dec_ifc()
val dma_ifc = new dma_ifc()
val ifc_fetch_addr_f = Output(UInt(31.W))
val ifc_fetch_addr_bf = Output(UInt(31.W))
val dec_ifc = new dec_ifc() // DEC to IFC Bundle
val dma_ifc = new dma_ifc() // DMA to IFC Bundle
val ifc_fetch_addr_f = Output(UInt(31.W)) // Previous PC
val ifc_fetch_addr_bf = Output(UInt(31.W)) // Next PC
val ifc_fetch_req_f = Output(Bool())
val ifc_fetch_req_f = Output(Bool()) // Fetch State
val ifc_fetch_uncacheable_bf = Output(Bool())
val ifc_fetch_uncacheable_bf = Output(Bool()) // Fetch req for uncacheable
val ifc_fetch_req_bf = Output(Bool())
val ifc_fetch_req_bf_raw = Output(Bool())
val ifc_iccm_access_bf = Output(Bool())
val ifc_region_acc_fault_bf = Output(Bool())
val ifc_dma_access_ok = Output(Bool())
val ifc_iccm_access_bf = Output(Bool()) // ICCM access
val ifc_region_acc_fault_bf = Output(Bool()) // Region access fault
val ifc_dma_access_ok = Output(Bool()) // DMA accesing
})
val fetch_addr_bf = WireInit(UInt(31.W), init = 0.U)
@ -69,6 +69,7 @@ class ifu_ifc_ctl extends Module with lib with RequireAsyncReset {
val sel_next_addr_bf = !io.exu_flush_final & io.ifc_fetch_req_f & !io.ifu_bp_hit_taken_f & io.ic_hit_f
// TODO: Make an assertion for the 1H-Mux under here
// Next PC calculation
io.ifc_fetch_addr_bf := Mux1H(Seq(io.exu_flush_final.asBool -> io.exu_flush_path_final, // Replay PC
sel_last_addr_bf.asBool -> io.ifc_fetch_addr_f, // Hold the current PC
sel_btb_addr_bf.asBool -> io.ifu_bp_btb_target_f, // Take the predicted PC
@ -77,6 +78,7 @@ class ifu_ifc_ctl extends Module with lib with RequireAsyncReset {
val address_upper = io.ifc_fetch_addr_f(30,1)+1.U
fetch_addr_next_0 := !(address_upper(ICACHE_TAG_INDEX_LO-2) ^ io.ifc_fetch_addr_f(ICACHE_TAG_INDEX_LO-1)) & io.ifc_fetch_addr_f(0)
// Next PC to check from which boundary it is comming from
fetch_addr_next := Cat(address_upper, fetch_addr_next_0)
io.ifc_fetch_req_bf_raw := ~idle
@ -103,12 +105,14 @@ class ifu_ifc_ctl extends Module with lib with RequireAsyncReset {
flush_fb := io.exu_flush_final
// Checking FP for PMU
fb_right := ( io.ifu_fb_consume1 & !io.ifu_fb_consume2 & (!io.ifc_fetch_req_f | miss_f)) |
(io.ifu_fb_consume2 & io.ifc_fetch_req_f)
fb_right2 := (io.ifu_fb_consume2 & (~io.ifc_fetch_req_f | miss_f))
fb_left := io.ifc_fetch_req_f & !(io.ifu_fb_consume1 | io.ifu_fb_consume2) & !miss_f
// Shifting the fb to remember the FP state
fb_write_ns := Mux1H(Seq(flush_fb.asBool -> 1.U(4.W),
(!flush_fb & fb_right).asBool -> Cat(0.U(1.W), fb_write_f(3,1)),
(!flush_fb & fb_right2).asBool -> Cat(0.U(2.W), fb_write_f(3,2)),
@ -126,6 +130,7 @@ class ifu_ifc_ctl extends Module with lib with RequireAsyncReset {
io.dec_ifc.ifu_pmu_fetch_stall := wfm | (io.ifc_fetch_req_bf_raw &
((fb_full_f & !(io.ifu_fb_consume2 | io.ifu_fb_consume1 | io.exu_flush_final)) | dma_stall))
// Checking the next PC range and its region to access the ICCM or I$
val (iccm_acc_in_region_bf, iccm_acc_in_range_bf) = if(ICCM_ENABLE)
rvrangecheck(ICCM_SADR, ICCM_SIZE, Cat(io.ifc_fetch_addr_bf,0.U))
else (0.U, 0.U)

View File

@ -39,7 +39,7 @@ class mem_ctl_io extends Bundle with lib{
val iccm_dma_rtag = Output(UInt(3.W))
val iccm_ready = Output(Bool())
val dec_tlu_flush_lower_wb = Input(Bool())
val iccm_rd_ecc_double_err = Output(Bool())
val iccm_dma_sb_error = Output(Bool())
@ -54,26 +54,7 @@ class mem_ctl_io extends Bundle with lib{
class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
val io = IO(new mem_ctl_io)
io.ifu_axi.w.valid := 0.U
io.ifu_axi.w.bits.data := 0.U
io.ifu_axi.aw.bits.qos := 0.U
io.ifu_axi.aw.bits.addr := 0.U
io.ifu_axi.aw.bits.prot := 0.U
io.ifu_axi.aw.bits.len := 0.U
io.ifu_axi.ar.bits.lock := 0.U
io.ifu_axi.aw.bits.region := 0.U
io.ifu_axi.aw.bits.id := 0.U
io.ifu_axi.aw.valid := 0.U
io.ifu_axi.w.bits.strb := 0.U
io.ifu_axi.aw.bits.cache := 0.U
io.ifu_axi.ar.bits.qos := 0.U
io.ifu_axi.aw.bits.lock := 0.U
io.ifu_axi.b.ready := 0.U
io.ifu_axi.ar.bits.len := 0.U
io.ifu_axi.aw.bits.size := 0.U
io.ifu_axi.ar.bits.prot := 0.U
io.ifu_axi.aw.bits.burst := 0.U
io.ifu_axi.w.bits.last := 0.U
val idle_C :: crit_byp_ok_C :: hit_u_miss_C :: miss_wait_C :: crit_wrd_rdy_C :: scnd_miss_C :: stream_C :: stall_scnd_miss_C :: Nil = Enum(8)
val err_stop_idle_C :: err_fetch1_C :: err_fetch2_C :: err_stop_fetch_C :: Nil = Enum(4)
val err_idle_C :: ic_wff_C :: ecc_wff_C :: ecc_cor_C :: dma_sb_err_C :: Nil = Enum(5)
@ -104,6 +85,7 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
val ic_miss_under_miss_f = WireInit(Bool(), false.B)
val ic_ignore_2nd_miss_f = WireInit(Bool(), false.B)
val ic_debug_rd_en_ff = WireInit(Bool(), false.B)
val debug_data_clk = rvclkhdr(clock, ic_debug_rd_en_ff, io.scan_mode)
val flush_final_f = withClock(io.free_clk){RegNext(io.exu_flush_final, 0.U)}
val fetch_bf_f_c1_clken = io.ifc_fetch_req_bf_raw | ifc_fetch_req_f | miss_pending | io.exu_flush_final | scnd_miss_req
@ -120,11 +102,11 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
val ifu_bp_hit_taken_q_f = io.ifu_bp_hit_taken_f & io.ic_hit_f
///////////////////////////////// MISS FSM /////////////////////////////////
switch(miss_state){
is (idle_C){
is (idle_C){ // Idle meaning there is not pending miss
miss_nxtstate := Mux((ic_act_miss_f & !io.exu_flush_final).asBool, crit_byp_ok_C, hit_u_miss_C)
miss_state_en := ic_act_miss_f & !io.dec_mem_ctrl.dec_tlu_force_halt}
is (crit_byp_ok_C){
is (crit_byp_ok_C){ // Miss started meaning each beat is checked if, it is the critical word
miss_nxtstate := Mux((io.dec_mem_ctrl.dec_tlu_force_halt | (ic_byp_hit_f & (last_data_recieved_ff | (bus_ifu_wr_en_ff & last_beat)) & uncacheable_miss_ff)).asBool, idle_C,
Mux((ic_byp_hit_f & !last_data_recieved_ff & uncacheable_miss_ff).asBool, miss_wait_C,
Mux((!ic_byp_hit_f & !io.exu_flush_final & (bus_ifu_wr_en_ff & last_beat) & uncacheable_miss_ff).asBool, crit_wrd_rdy_C,
@ -135,35 +117,36 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
Mux(((io.exu_flush_final | ifu_bp_hit_taken_q_f) & !(bus_ifu_wr_en_ff & last_beat)).asBool, hit_u_miss_C, idle_C))))))))
miss_state_en := io.dec_mem_ctrl.dec_tlu_force_halt | io.exu_flush_final | ic_byp_hit_f | ifu_bp_hit_taken_q_f | (bus_ifu_wr_en_ff & last_beat) | (bus_ifu_wr_en_ff & !uncacheable_miss_ff)
}
is (crit_wrd_rdy_C){
is (crit_wrd_rdy_C){ // Critical word hit but not complete, its going to be available in next cycle
miss_nxtstate := idle_C
miss_state_en := io.exu_flush_final | flush_final_f | ic_byp_hit_f | io.dec_mem_ctrl.dec_tlu_force_halt
}
is (stream_C){
is (stream_C){ // The miss was a miss of uncacheable range
miss_nxtstate := Mux(((io.exu_flush_final | ifu_bp_hit_taken_q_f | stream_eol_f)&(!(bus_ifu_wr_en_ff & last_beat)) & !io.dec_mem_ctrl.dec_tlu_force_halt).asBool, hit_u_miss_C, idle_C)
miss_state_en := io.exu_flush_final | ifu_bp_hit_taken_q_f | stream_eol_f | (bus_ifu_wr_en_ff & last_beat) | io.dec_mem_ctrl.dec_tlu_force_halt
}
is (miss_wait_C){
is (miss_wait_C){ // Critial word hit but the miss is not complete
miss_nxtstate := Mux((io.exu_flush_final & !(bus_ifu_wr_en_ff & last_beat) & !io.dec_mem_ctrl.dec_tlu_force_halt).asBool, hit_u_miss_C, idle_C)
miss_state_en := io.exu_flush_final | (bus_ifu_wr_en_ff & last_beat) | io.dec_mem_ctrl.dec_tlu_force_halt
}
is (hit_u_miss_C){
is (hit_u_miss_C){ // The critical word was a hit taken, or miss due to a miss predicted pc occured
miss_nxtstate := Mux((ic_miss_under_miss_f & !(bus_ifu_wr_en_ff & last_beat) & !io.dec_mem_ctrl.dec_tlu_force_halt).asBool, scnd_miss_C,
Mux((ic_ignore_2nd_miss_f & !(bus_ifu_wr_en_ff & last_beat) & !io.dec_mem_ctrl.dec_tlu_force_halt).asBool, stall_scnd_miss_C, idle_C))
miss_state_en := (bus_ifu_wr_en_ff & last_beat) | ic_miss_under_miss_f | ic_ignore_2nd_miss_f | io.dec_mem_ctrl.dec_tlu_force_halt
}
is (scnd_miss_C){
is (scnd_miss_C){ // Miss of the different pc occured
miss_nxtstate := Mux(io.dec_mem_ctrl.dec_tlu_force_halt, idle_C, Mux(io.exu_flush_final,
Mux((bus_ifu_wr_en_ff & last_beat).asBool, idle_C, hit_u_miss_C), crit_byp_ok_C))
miss_state_en := (bus_ifu_wr_en_ff & last_beat) | io.exu_flush_final | io.dec_mem_ctrl.dec_tlu_force_halt
}
is (stall_scnd_miss_C){
is (stall_scnd_miss_C){ // Miss from the same pc occured
miss_nxtstate := Mux(io.dec_mem_ctrl.dec_tlu_force_halt, idle_C, Mux(io.exu_flush_final,
Mux((bus_ifu_wr_en_ff & last_beat).asBool, idle_C, hit_u_miss_C), idle_C))
miss_state_en := (bus_ifu_wr_en_ff & last_beat) | io.exu_flush_final | io.dec_mem_ctrl.dec_tlu_force_halt
}
}
miss_state := withClock(io.free_clk){RegEnable(miss_nxtstate, 0.U, miss_state_en.asBool)}
// Calculation all the relevant signals for the miss FSM
val crit_byp_hit_f = WireInit(Bool(), 0.U)
val way_status_mb_scnd_ff = WireInit(UInt(ICACHE_STATUS_BITS.W), 0.U)
val way_status = WireInit(UInt(ICACHE_STATUS_BITS.W), 0.U)
@ -262,6 +245,8 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
sel_mb_addr_ff := withClock(io.free_clk){RegNext(sel_mb_addr, 0.U)}
val ifu_bus_rdata_ff = WireInit(UInt(64.W), 0.U)
val ic_miss_buff_half = WireInit(UInt(64.W), 0.U)
// Ecc of the read data from the AXI
val ic_wr_ecc = rvecc_encode_64(ifu_bus_rdata_ff)
val ic_miss_buff_ecc = rvecc_encode_64(ic_miss_buff_half)
val ic_wr_16bytes_data = WireInit(UInt((ICACHE_BANKS_WAY * (if(ICACHE_ECC) 71 else 68)).W), 0.U)
@ -271,6 +256,7 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
io.dec_mem_ctrl.ifu_ic_error_start := ((if(ICACHE_ECC)io.ic.eccerr.orR()else io.ic.parerr.orR()) & ic_act_hit_f) | ic_rd_parity_final_err
val ic_debug_tag_val_rd_out = WireInit(Bool(), 0.U)
val ic_debug_ict_array_sel_ff = WireInit(Bool(), 0.U)
val ifu_ic_debug_rd_data_in = Mux(ic_debug_ict_array_sel_ff.asBool, if(ICACHE_ECC) Cat(0.U(2.W),io.ic.tag_debug_rd_data(25,21),0.U(32.W),io.ic.tag_debug_rd_data(20,0), 0.U((7-ICACHE_STATUS_BITS).W), way_status, 0.U(3.W),ic_debug_tag_val_rd_out)
else Cat(0.U(6.W),io.ic.tag_debug_rd_data(21),0.U(32.W),io.ic.tag_debug_rd_data(20,0),0.U(7-ICACHE_STATUS_BITS),way_status ,0.U(3.W) ,ic_debug_tag_val_rd_out) ,
io.ic.debug_rd_data)
@ -395,6 +381,7 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
ic_miss_buff_half := Cat(Mux1H((0 until 2*ICACHE_NUM_BEATS).map(i=>(Cat(other_tag,1.U)===i.U).asBool->ic_miss_buff_data(i))),
Mux1H((0 until 2*ICACHE_NUM_BEATS).map(i=>(Cat(other_tag,0.U)===i.U).asBool->ic_miss_buff_data(i))))
// Parity check for the I$ logic
ic_rd_parity_final_err := io.ic.tag_perr & sel_ic_data & !(ifc_region_acc_fault_final_f | ifc_bus_acc_fault_f)
val ifu_ic_rw_int_addr_ff = WireInit(UInt((ICACHE_INDEX_HI-ICACHE_TAG_INDEX_LO+1).W), 0.U)
@ -408,7 +395,7 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
io.iccm.buf_correct_ecc := iccm_correct_ecc & !dma_sb_err_state_ff
dma_sb_err_state_ff := withClock(io.active_clk){RegNext(dma_sb_err_state, false.B)}
///////////////////////////////// ERROR FSM /////////////////////////////////
///////////////////////////////// PARITY ERROR FSM /////////////////////////////////
val perr_nxtstate = WireInit(UInt(3.W), 0.U)
val perr_state_en = WireInit(Bool(), false.B)
val iccm_error_start = WireInit(Bool(), false.B)
@ -420,12 +407,12 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
}
is(ic_wff_C){
perr_nxtstate := err_idle_C
perr_state_en := io.dec_mem_ctrl.dec_tlu_flush_lower_wb | io.dec_mem_ctrl.dec_tlu_force_halt
perr_sel_invalidate := io.dec_mem_ctrl.dec_tlu_flush_lower_wb & io.dec_mem_ctrl.dec_tlu_flush_err_wb
perr_state_en := io.dec_tlu_flush_lower_wb | io.dec_mem_ctrl.dec_tlu_force_halt
perr_sel_invalidate := io.dec_tlu_flush_lower_wb & io.dec_mem_ctrl.dec_tlu_flush_err_wb
}
is(ecc_wff_C){
perr_nxtstate := Mux(((!io.dec_mem_ctrl.dec_tlu_flush_err_wb & io.dec_mem_ctrl.dec_tlu_flush_lower_wb ) | io.dec_mem_ctrl.dec_tlu_force_halt).asBool(), err_idle_C, ecc_cor_C)
perr_state_en := io.dec_mem_ctrl.dec_tlu_flush_lower_wb | io.dec_mem_ctrl.dec_tlu_force_halt
perr_nxtstate := Mux(((!io.dec_mem_ctrl.dec_tlu_flush_err_wb & io.dec_tlu_flush_lower_wb ) | io.dec_mem_ctrl.dec_tlu_force_halt).asBool(), err_idle_C, ecc_cor_C)
perr_state_en := io.dec_tlu_flush_lower_wb | io.dec_mem_ctrl.dec_tlu_force_halt
}
is(dma_sb_err_C){
perr_nxtstate := Mux(io.dec_mem_ctrl.dec_tlu_force_halt, err_idle_C, ecc_cor_C)
@ -447,24 +434,24 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
err_stop_state_en := io.dec_mem_ctrl.dec_tlu_flush_err_wb & (perr_state === ecc_wff_C) & !io.dec_mem_ctrl.dec_tlu_force_halt
}
is(err_fetch1_C){
err_stop_nxtstate := Mux((io.dec_mem_ctrl.dec_tlu_flush_lower_wb | io.dec_mem_ctrl.dec_tlu_i0_commit_cmt | io.dec_mem_ctrl.dec_tlu_force_halt).asBool(), err_stop_idle_C,
err_stop_nxtstate := Mux((io.dec_tlu_flush_lower_wb | io.dec_mem_ctrl.dec_tlu_i0_commit_cmt | io.dec_mem_ctrl.dec_tlu_force_halt).asBool(), err_stop_idle_C,
Mux(((io.ifu_fetch_val===3.U)|(io.ifu_fetch_val(0)&two_byte_instr)).asBool(), err_stop_fetch_C,
Mux(io.ifu_fetch_val(0).asBool(), err_fetch2_C, err_fetch1_C)))
err_stop_state_en := io.dec_mem_ctrl.dec_tlu_flush_lower_wb | io.dec_mem_ctrl.dec_tlu_i0_commit_cmt | io.ifu_fetch_val(0) | ifu_bp_hit_taken_q_f | io.dec_mem_ctrl.dec_tlu_force_halt
err_stop_state_en := io.dec_tlu_flush_lower_wb | io.dec_mem_ctrl.dec_tlu_i0_commit_cmt | io.ifu_fetch_val(0) | ifu_bp_hit_taken_q_f | io.dec_mem_ctrl.dec_tlu_force_halt
err_stop_fetch := ((io.ifu_fetch_val(1,0)===3.U) | (io.ifu_fetch_val(0) & two_byte_instr)) & !(io.exu_flush_final | io.dec_mem_ctrl.dec_tlu_i0_commit_cmt)
io.iccm.correction_state := true.B
}
is(err_fetch2_C){
err_stop_nxtstate := Mux((io.dec_mem_ctrl.dec_tlu_flush_lower_wb | io.dec_mem_ctrl.dec_tlu_i0_commit_cmt | io.dec_mem_ctrl.dec_tlu_force_halt).asBool,
err_stop_nxtstate := Mux((io.dec_tlu_flush_lower_wb | io.dec_mem_ctrl.dec_tlu_i0_commit_cmt | io.dec_mem_ctrl.dec_tlu_force_halt).asBool,
err_stop_idle_C, Mux(io.ifu_fetch_val(0).asBool, err_stop_fetch_C, err_fetch2_C))
err_stop_state_en := io.dec_mem_ctrl.dec_tlu_flush_lower_wb | io.dec_mem_ctrl.dec_tlu_i0_commit_cmt | io.ifu_fetch_val(0) | io.dec_mem_ctrl.dec_tlu_force_halt
err_stop_state_en := io.dec_tlu_flush_lower_wb | io.dec_mem_ctrl.dec_tlu_i0_commit_cmt | io.ifu_fetch_val(0) | io.dec_mem_ctrl.dec_tlu_force_halt
err_stop_fetch := io.ifu_fetch_val(0) & !io.exu_flush_final & !io.dec_mem_ctrl.dec_tlu_i0_commit_cmt
io.iccm.correction_state := true.B
}
is(err_stop_fetch_C){
err_stop_nxtstate := Mux(((io.dec_mem_ctrl.dec_tlu_flush_lower_wb & !io.dec_mem_ctrl.dec_tlu_flush_err_wb) | io.dec_mem_ctrl.dec_tlu_i0_commit_cmt | io.dec_mem_ctrl.dec_tlu_force_halt).asBool,
err_stop_nxtstate := Mux(((io.dec_tlu_flush_lower_wb & !io.dec_mem_ctrl.dec_tlu_flush_err_wb) | io.dec_mem_ctrl.dec_tlu_i0_commit_cmt | io.dec_mem_ctrl.dec_tlu_force_halt).asBool,
err_stop_idle_C, Mux(io.dec_mem_ctrl.dec_tlu_flush_err_wb.asBool(), err_fetch1_C, err_stop_fetch_C))
err_stop_state_en := io.dec_mem_ctrl.dec_tlu_flush_lower_wb | io.dec_mem_ctrl.dec_tlu_i0_commit_cmt | io.dec_mem_ctrl.dec_tlu_force_halt
err_stop_state_en := io.dec_tlu_flush_lower_wb | io.dec_mem_ctrl.dec_tlu_i0_commit_cmt | io.dec_mem_ctrl.dec_tlu_force_halt
err_stop_fetch := true.B
io.iccm.correction_state := true.B
}
@ -487,6 +474,26 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
val bus_cmd_req_in = (ic_act_miss_f | bus_cmd_req_hold) & !bus_cmd_sent & !io.dec_mem_ctrl.dec_tlu_force_halt
bus_cmd_req_hold := withClock(io.free_clk){RegNext(bus_cmd_req_in, false.B)}
// AXI Read-Channel
io.ifu_axi.w.valid := 0.U
io.ifu_axi.w.bits.data := 0.U
io.ifu_axi.aw.bits.qos := 0.U
io.ifu_axi.aw.bits.addr := 0.U
io.ifu_axi.aw.bits.prot := 0.U
io.ifu_axi.aw.bits.len := 0.U
io.ifu_axi.ar.bits.lock := 0.U
io.ifu_axi.aw.bits.region := 0.U
io.ifu_axi.aw.bits.id := 0.U
io.ifu_axi.aw.valid := 0.U
io.ifu_axi.w.bits.strb := 0.U
io.ifu_axi.aw.bits.cache := 0.U
io.ifu_axi.ar.bits.qos := 0.U
io.ifu_axi.aw.bits.lock := 0.U
io.ifu_axi.b.ready := 0.U
io.ifu_axi.ar.bits.len := 0.U
io.ifu_axi.aw.bits.size := 0.U
io.ifu_axi.ar.bits.prot := 0.U
io.ifu_axi.aw.bits.burst := 0.U
io.ifu_axi.w.bits.last := 0.U
io.ifu_axi.ar.valid := ifu_bus_cmd_valid
io.ifu_axi.ar.bits.id := bus_rd_addr_count & Fill(IFU_BUS_TAG, ifu_bus_cmd_valid)
io.ifu_axi.ar.bits.addr := Cat(ifu_ic_req_addr_f, 0.U(3.W)) & Fill(32, ifu_bus_cmd_valid)
@ -499,7 +506,6 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
val ifu_bus_arready_unq = io.ifu_axi.ar.ready
val ifu_bus_rvalid_unq = io.ifu_axi.r.valid
val ifu_bus_arvalid = io.ifu_axi.ar.valid
bus_ifu_bus_clk_en
val ifu_bus_arready_unq_ff = withClock(busclk){RegNext(ifu_bus_arready_unq, false.B)}
val ifu_bus_rvalid_unq_ff = withClock(busclk){RegNext(ifu_bus_rvalid_unq, false.B)}
val ifu_bus_arvalid_ff = withClock(busclk){RegNext(ifu_bus_arvalid, false.B)}
@ -516,6 +522,7 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
val ifu_bus_arready = ifu_bus_arready_unq & bus_ifu_bus_clk_en
val ifu_bus_arready_ff = ifu_bus_arready_unq_ff & bus_ifu_bus_clk_en_ff
val ifu_bus_rvalid_ff = ifu_bus_rvalid_unq_ff & bus_ifu_bus_clk_en_ff
// Write signals to write to the bus
bus_cmd_sent := ifu_bus_arvalid & ifu_bus_arready & miss_pending & !io.dec_mem_ctrl.dec_tlu_force_halt
val bus_last_data_beat = WireInit(Bool(), false.B)
val bus_inc_data_beat_cnt = bus_ifu_wr_en_ff & !bus_last_data_beat & !io.dec_mem_ctrl.dec_tlu_force_halt
@ -594,7 +601,7 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
val ic_fetch_val_int_f = Cat(0.U(2.W), io.ic_fetch_val_f)
val ic_fetch_val_shift_right = ic_fetch_val_int_f << ifu_fetch_addr_int_f(0)
val iccm_rdmux_data = io.iccm.rd_data_ecc
// ICCM ECC Check logic
val iccm_ecc_word_enable = (0 until 2).map(i=>((ic_fetch_val_shift_right((2*i+1),(2*i)).orR & !io.exu_flush_final & sel_iccm_data) | iccm_dma_rvalid_in) & !io.dec_mem_ctrl.dec_tlu_core_ecc_disable).reverse.reduce(Cat(_,_))
val ecc_decoded = (0 until 2).map(i=>rvecc_decode(iccm_ecc_word_enable(i), iccm_rdmux_data((39*i+31),(39*i)), iccm_rdmux_data((39*i+38),(39*i+32)), 0.U))
val iccm_corrected_ecc = Wire(Vec(2, UInt(7.W)))
@ -628,7 +635,7 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
io.ic.wr_en := bus_ic_wr_en & Fill(ICACHE_NUM_WAYS, write_ic_16_bytes)
io.ic_write_stall := write_ic_16_bytes & !((((miss_state===crit_byp_ok_C) | ((miss_state===stream_C) & !(io.exu_flush_final | ifu_bp_hit_taken_q_f | stream_eol_f ))) & !(bus_ifu_wr_en_ff & last_beat & !uncacheable_miss_ff)))
reset_all_tags := withClock(io.active_clk){RegNext(io.dec_mem_ctrl.dec_tlu_fence_i_wb, false.B)}
// I$ status and P-LRU
val ic_valid = !ifu_wr_cumulative_err_data & !(reset_ic_in | reset_ic_ff) & !reset_tag_valid_for_miss
val ifu_status_wr_addr_w_debug = Mux((io.ic.debug_rd_en | io.ic.debug_wr_en) & io.ic.debug_tag_array, io.ic.debug_addr(ICACHE_INDEX_HI - 3, ICACHE_TAG_INDEX_LO - 3),
ifu_status_wr_addr(ICACHE_INDEX_HI - 1, ICACHE_TAG_INDEX_LO - 1))
@ -688,8 +695,7 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
val ic_tag_valid_unq = (0 until ICACHE_NUM_WAYS).map(k => (0 until ICACHE_TAG_DEPTH).map(j =>
Mux(ifu_ic_rw_int_addr_ff === j.U, ic_tag_valid_out(k)(j), false.B).asUInt).reduce(_|_)).reverse.reduce(Cat(_,_))
// Making a sudo LRU
// val replace_way_mb_any = Wire(Vec(ICACHE_NUM_WAYS, Bool()))
// Making sudo LRU
val way_status_hit_new = WireInit(UInt(ICACHE_STATUS_BITS.W), 0.U)
if (ICACHE_NUM_WAYS == 4) {
replace_way_mb_any(3) := (way_status_mb_ff(2) & way_status_mb_ff(0) & tagv_mb_ff(3, 0).andR) |
@ -762,6 +768,7 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
ic_debug_ict_array_sel_ff := withClock(debug_c1_clk){RegNext(ic_debug_ict_array_sel_in, 0.U)}
ic_debug_rd_en_ff := withClock(io.free_clk){RegNext(io.ic.debug_rd_en, false.B)}
io.dec_mem_ctrl.ifu_ic_debug_rd_data_valid := withClock(io.free_clk){RegNext(ic_debug_rd_en_ff, 0.U)}
// Memory protection each access enable with its Mask
val ifc_region_acc_okay = !(Cat(INST_ACCESS_ENABLE0.U,INST_ACCESS_ENABLE1.U,INST_ACCESS_ENABLE2.U,INST_ACCESS_ENABLE3.U,INST_ACCESS_ENABLE4.U,INST_ACCESS_ENABLE5.U,INST_ACCESS_ENABLE6.U,INST_ACCESS_ENABLE7.U).orR()) |
(INST_ACCESS_ENABLE0.U & ((Cat(io.ifc_fetch_addr_bf, 0.U) | aslong(INST_ACCESS_MASK0).U) === (aslong(INST_ACCESS_ADDR0).U | aslong(INST_ACCESS_MASK0).U))) |
(INST_ACCESS_ENABLE1.U & ((Cat(io.ifc_fetch_addr_bf, 0.U) | aslong(INST_ACCESS_MASK1).U) === (aslong(INST_ACCESS_ADDR1).U | aslong(INST_ACCESS_MASK1).U))) |

View File

@ -201,6 +201,7 @@ class quasar extends Module with RequireAsyncReset with lib {
ifu.io.exu_ifu.exu_bp <> exu.io.exu_bp
ifu.io.exu_ifu.exu_bp.exu_i0_br_fghr_r := exu.io.exu_bp.exu_i0_br_fghr_r
ifu.io.exu_ifu.exu_bp.exu_i0_br_index_r := exu.io.dec_exu.tlu_exu.exu_i0_br_index_r
ifu.io.dec_tlu_flush_lower_wb := dec.io.dec_exu.tlu_exu.dec_tlu_flush_lower_r
ifu.io.ifu_dec.dec_mem_ctrl.dec_tlu_flush_lower_wb := dec.io.dec_exu.tlu_exu.dec_tlu_flush_lower_r
ifu.io.ifu_dec.dec_mem_ctrl.dec_tlu_ic_diag_pkt := dec.io.ifu_dec.dec_mem_ctrl.dec_tlu_ic_diag_pkt

View File

@ -85,180 +85,180 @@ class quasar_wrapper extends Module with lib with RequireAsyncReset {
})
val mem = Module(new quasar.mem())
val dmi_wrapper = Module(new dmi_wrapper())
val swerv = Module(new quasar())
val core = Module(new quasar())
dmi_wrapper.io.trst_n := io.jtag_trst_n
dmi_wrapper.io.tck := io.jtag_tck
dmi_wrapper.io.tms := io.jtag_tms
dmi_wrapper.io.tdi := io.jtag_tdi
dmi_wrapper.io.core_clk := clock
dmi_wrapper.io.jtag_id := io.jtag_id
dmi_wrapper.io.rd_data := swerv.io.dmi_reg_rdata
dmi_wrapper.io.rd_data := core.io.dmi_reg_rdata
dmi_wrapper.io.core_rst_n := io.dbg_rst_l
swerv.io.dmi_reg_wdata := dmi_wrapper.io.reg_wr_data
swerv.io.dmi_reg_addr := dmi_wrapper.io.reg_wr_addr
swerv.io.dmi_reg_en := dmi_wrapper.io.reg_en
swerv.io.dmi_reg_wr_en := dmi_wrapper.io.reg_wr_en
swerv.io.dmi_hard_reset := dmi_wrapper.io.dmi_hard_reset
core.io.dmi_reg_wdata := dmi_wrapper.io.reg_wr_data
core.io.dmi_reg_addr := dmi_wrapper.io.reg_wr_addr
core.io.dmi_reg_en := dmi_wrapper.io.reg_en
core.io.dmi_reg_wr_en := dmi_wrapper.io.reg_wr_en
core.io.dmi_hard_reset := dmi_wrapper.io.dmi_hard_reset
io.jtag_tdo := dmi_wrapper.io.tdo
// Memory signals
mem.io.dccm_clk_override := swerv.io.dccm_clk_override
mem.io.icm_clk_override := swerv.io.icm_clk_override
mem.io.dec_tlu_core_ecc_disable := swerv.io.dec_tlu_core_ecc_disable
mem.io.dccm <> swerv.io.swerv_mem
// mem.io.iccm_rw_addr := swerv.io.iccm_rw_addr
// mem.io.iccm_buf_correct_ecc := swerv.io.iccm_buf_correct_ecc
// mem.io.iccm_correction_state := swerv.io.iccm_correction_state
// mem.io.iccm_wren := swerv.io.iccm_wren
// mem.io.iccm_rden := swerv.io.iccm_rden
// mem.io.iccm_wr_size := swerv.io.iccm_wr_size
// mem.io.iccm_wr_data := swerv.io.iccm_wr_data
mem.io.dccm_clk_override := core.io.dccm_clk_override
mem.io.icm_clk_override := core.io.icm_clk_override
mem.io.dec_tlu_core_ecc_disable := core.io.dec_tlu_core_ecc_disable
mem.io.dccm <> core.io.swerv_mem
// mem.io.iccm_rw_addr := core.io.iccm_rw_addr
// mem.io.iccm_buf_correct_ecc := core.io.iccm_buf_correct_ecc
// mem.io.iccm_correction_state := core.io.iccm_correction_state
// mem.io.iccm_wren := core.io.iccm_wren
// mem.io.iccm_rden := core.io.iccm_rden
// mem.io.iccm_wr_size := core.io.iccm_wr_size
// mem.io.iccm_wr_data := core.io.iccm_wr_data
// mem.io.ic_rw_addr := swerv.io.ic_rw_addr
// mem.io.ic_tag_valid := swerv.io.ic_tag_valid
// mem.io.ic_wr_en := swerv.io.ic_wr_en
// mem.io.ic_rd_en := swerv.io.ic_rd_en
// mem.io.ic_premux_data := swerv.io.ic_premux_data
// mem.io.ic_sel_premux_data := swerv.io.ic_sel_premux_data
// mem.io.ic_wr_data := swerv.io.ic_wr_data
// mem.io.ic_debug_wr_data := swerv.io.ic_debug_wr_data
// mem.io.ic_rw_addr := core.io.ic_rw_addr
// mem.io.ic_tag_valid := core.io.ic_tag_valid
// mem.io.ic_wr_en := core.io.ic_wr_en
// mem.io.ic_rd_en := core.io.ic_rd_en
// mem.io.ic_premux_data := core.io.ic_premux_data
// mem.io.ic_sel_premux_data := core.io.ic_sel_premux_data
// mem.io.ic_wr_data := core.io.ic_wr_data
// mem.io.ic_debug_wr_data := core.io.ic_debug_wr_data
//
// mem.io.ic_debug_addr := swerv.io.ic_debug_addr
// mem.io.ic_debug_rd_en := swerv.io.ic_debug_rd_en
// mem.io.ic_debug_wr_en := swerv.io.ic_debug_wr_en
// mem.io.ic_debug_tag_array := swerv.io.ic_debug_tag_array
// mem.io.ic_debug_way := swerv.io.ic_debug_way
// mem.io.ic_debug_addr := core.io.ic_debug_addr
// mem.io.ic_debug_rd_en := core.io.ic_debug_rd_en
// mem.io.ic_debug_wr_en := core.io.ic_debug_wr_en
// mem.io.ic_debug_tag_array := core.io.ic_debug_tag_array
// mem.io.ic_debug_way := core.io.ic_debug_way
mem.io.rst_l := reset
mem.io.clk := clock
mem.io.scan_mode := io.scan_mode
// Memory outputs
swerv.io.dbg_rst_l := io.dbg_rst_l
swerv.io.ic <> mem.io.ic
swerv.io.iccm <> mem.io.iccm
// swerv.io.iccm_rd_data_ecc := mem.io.iccm_rd_data_ecc
// swerv.io.dccm_rd_data_hi := mem.io.dccm_rd_data_hi
// swerv.io.ic_rd_data := mem.io.ic_rd_data
// swerv.io.ictag_debug_rd_data := mem.io.ictag_debug_rd_data
// swerv.io.ic_eccerr := mem.io.ic_eccerr
// swerv.io.ic_parerr := mem.io.ic_parerr
// swerv.io.ic_rd_hit := mem.io.ic_rd_hit
// swerv.io.ic_tag_perr := mem.io.ic_tag_perr
// swerv.io.ic_debug_rd_data := mem.io.ic_debug_rd_data
// swerv.io.iccm_rd_data := mem.io.iccm_rd_data
swerv.io.sb_hready := 0.U
swerv.io.hrdata := 0.U
swerv.io.sb_hresp := 0.U
swerv.io.lsu_hrdata := 0.U
swerv.io.lsu_hresp := 0.U
swerv.io.lsu_hready := 0.U
swerv.io.hready := 0.U
swerv.io.hresp := 0.U
swerv.io.sb_hrdata := 0.U
swerv.io.scan_mode := io.scan_mode
// SweRV Inputs
swerv.io.dbg_rst_l := io.dbg_rst_l
swerv.io.rst_vec := io.rst_vec
swerv.io.nmi_int := io.nmi_int
swerv.io.nmi_vec := io.nmi_vec
core.io.dbg_rst_l := io.dbg_rst_l
core.io.ic <> mem.io.ic
core.io.iccm <> mem.io.iccm
// core.io.iccm_rd_data_ecc := mem.io.iccm_rd_data_ecc
// core.io.dccm_rd_data_hi := mem.io.dccm_rd_data_hi
// core.io.ic_rd_data := mem.io.ic_rd_data
// core.io.ictag_debug_rd_data := mem.io.ictag_debug_rd_data
// core.io.ic_eccerr := mem.io.ic_eccerr
// core.io.ic_parerr := mem.io.ic_parerr
// core.io.ic_rd_hit := mem.io.ic_rd_hit
// core.io.ic_tag_perr := mem.io.ic_tag_perr
// core.io.ic_debug_rd_data := mem.io.ic_debug_rd_data
// core.io.iccm_rd_data := mem.io.iccm_rd_data
core.io.sb_hready := 0.U
core.io.hrdata := 0.U
core.io.sb_hresp := 0.U
core.io.lsu_hrdata := 0.U
core.io.lsu_hresp := 0.U
core.io.lsu_hready := 0.U
core.io.hready := 0.U
core.io.hresp := 0.U
core.io.sb_hrdata := 0.U
core.io.scan_mode := io.scan_mode
// core Inputs
core.io.dbg_rst_l := io.dbg_rst_l
core.io.rst_vec := io.rst_vec
core.io.nmi_int := io.nmi_int
core.io.nmi_vec := io.nmi_vec
// external halt/run interface
swerv.io.i_cpu_halt_req := io.i_cpu_halt_req
swerv.io.i_cpu_run_req := io.i_cpu_run_req
swerv.io.core_id := io.core_id
core.io.i_cpu_halt_req := io.i_cpu_halt_req
core.io.i_cpu_run_req := io.i_cpu_run_req
core.io.core_id := io.core_id
// external MPC halt/run interface
swerv.io.mpc_debug_halt_req := io.mpc_debug_halt_req
swerv.io.mpc_debug_run_req := io.mpc_debug_run_req
swerv.io.mpc_reset_run_req := io.mpc_reset_run_req
core.io.mpc_debug_halt_req := io.mpc_debug_halt_req
core.io.mpc_debug_run_req := io.mpc_debug_run_req
core.io.mpc_reset_run_req := io.mpc_reset_run_req
//-------------------------- LSU AXI signals--------------------------
// AXI Write Channels
swerv.io.lsu_axi <> io.lsu_axi
core.io.lsu_axi <> io.lsu_axi
//-------------------------- IFU AXI signals--------------------------
// AXI Write Channels
swerv.io.ifu_axi <> io.ifu_axi
core.io.ifu_axi <> io.ifu_axi
//-------------------------- SB AXI signals--------------------------
// AXI Write Channels
swerv.io.sb_axi <> io.sb_axi
core.io.sb_axi <> io.sb_axi
//-------------------------- DMA AXI signals--------------------------
// AXI Write Channels
swerv.io.dma_axi <> io.dma_axi
core.io.dma_axi <> io.dma_axi
// DMA Slave
swerv.io.dma_hsel := io.dma_hsel
swerv.io.dma_haddr := io.dma_haddr
swerv.io.dma_hburst := io.dma_hburst
swerv.io.dma_hmastlock := io.dma_hmastlock
swerv.io.dma_hprot := io.dma_hprot
swerv.io.dma_hsize := io.dma_hsize
swerv.io.dma_htrans := io.dma_htrans
swerv.io.dma_hwrite := io.dma_hwrite
swerv.io.dma_hwdata := io.dma_hwdata
swerv.io.dma_hreadyin := io.dma_hreadyin
core.io.dma_hsel := io.dma_hsel
core.io.dma_haddr := io.dma_haddr
core.io.dma_hburst := io.dma_hburst
core.io.dma_hmastlock := io.dma_hmastlock
core.io.dma_hprot := io.dma_hprot
core.io.dma_hsize := io.dma_hsize
core.io.dma_htrans := io.dma_htrans
core.io.dma_hwrite := io.dma_hwrite
core.io.dma_hwdata := io.dma_hwdata
core.io.dma_hreadyin := io.dma_hreadyin
swerv.io.lsu_bus_clk_en
swerv.io.ifu_bus_clk_en
swerv.io.dbg_bus_clk_en
swerv.io.dma_bus_clk_en
core.io.lsu_bus_clk_en
core.io.ifu_bus_clk_en
core.io.dbg_bus_clk_en
core.io.dma_bus_clk_en
swerv.io.dmi_reg_en
swerv.io.dmi_reg_addr
swerv.io.dmi_reg_wr_en
swerv.io.dmi_reg_wdata
swerv.io.dmi_hard_reset
core.io.dmi_reg_en
core.io.dmi_reg_addr
core.io.dmi_reg_wr_en
core.io.dmi_reg_wdata
core.io.dmi_hard_reset
swerv.io.extintsrc_req
swerv.io.timer_int
swerv.io.soft_int
swerv.io.scan_mode
core.io.extintsrc_req
core.io.timer_int
core.io.soft_int
core.io.scan_mode
swerv.io.lsu_bus_clk_en := io.lsu_bus_clk_en
swerv.io.ifu_bus_clk_en := io.ifu_bus_clk_en
swerv.io.dbg_bus_clk_en := io.dbg_bus_clk_en
swerv.io.dma_bus_clk_en := io.dma_bus_clk_en
core.io.lsu_bus_clk_en := io.lsu_bus_clk_en
core.io.ifu_bus_clk_en := io.ifu_bus_clk_en
core.io.dbg_bus_clk_en := io.dbg_bus_clk_en
core.io.dma_bus_clk_en := io.dma_bus_clk_en
swerv.io.timer_int := io.timer_int
swerv.io.soft_int := io.soft_int
swerv.io.extintsrc_req := io.extintsrc_req
core.io.timer_int := io.timer_int
core.io.soft_int := io.soft_int
core.io.extintsrc_req := io.extintsrc_req
// Outputs
val core_rst_l = swerv.io.core_rst_l
io.trace <> swerv.io.trace
// io.trace_rv_i_insn_ip := swerv.io.trace_rv_i_insn_ip
// io.trace_rv_i_address_ip := swerv.io.trace_rv_i_address_ip
// io.trace_rv_i_valid_ip := swerv.io.trace_rv_i_valid_ip
// io.trace_rv_i_exception_ip := swerv.io.trace_rv_i_exception_ip
// io.trace_rv_i_ecause_ip := swerv.io.trace_rv_i_ecause_ip
// io.trace_rv_i_interrupt_ip := swerv.io.trace_rv_i_interrupt_ip
// io.trace_rv_i_tval_ip := swerv.io.trace_rv_i_tval_ip
val core_rst_l = core.io.core_rst_l
io.trace <> core.io.trace
// io.trace_rv_i_insn_ip := core.io.trace_rv_i_insn_ip
// io.trace_rv_i_address_ip := core.io.trace_rv_i_address_ip
// io.trace_rv_i_valid_ip := core.io.trace_rv_i_valid_ip
// io.trace_rv_i_exception_ip := core.io.trace_rv_i_exception_ip
// io.trace_rv_i_ecause_ip := core.io.trace_rv_i_ecause_ip
// io.trace_rv_i_interrupt_ip := core.io.trace_rv_i_interrupt_ip
// io.trace_rv_i_tval_ip := core.io.trace_rv_i_tval_ip
// external halt/run interface
io.o_cpu_halt_ack := swerv.io.o_cpu_halt_ack
io.o_cpu_halt_status := swerv.io.o_cpu_halt_status
io.o_cpu_run_ack := swerv.io.o_cpu_run_ack
io.o_debug_mode_status := swerv.io.o_debug_mode_status
io.o_cpu_halt_ack := core.io.o_cpu_halt_ack
io.o_cpu_halt_status := core.io.o_cpu_halt_status
io.o_cpu_run_ack := core.io.o_cpu_run_ack
io.o_debug_mode_status := core.io.o_debug_mode_status
io.mpc_debug_halt_ack := swerv.io.mpc_debug_halt_ack
io.mpc_debug_run_ack := swerv.io.mpc_debug_run_ack
io.debug_brkpt_status := swerv.io.debug_brkpt_status
io.mpc_debug_halt_ack := core.io.mpc_debug_halt_ack
io.mpc_debug_run_ack := core.io.mpc_debug_run_ack
io.debug_brkpt_status := core.io.debug_brkpt_status
io.dec_tlu_perfcnt0 := swerv.io.dec_tlu_perfcnt0
io.dec_tlu_perfcnt1 := swerv.io.dec_tlu_perfcnt1
io.dec_tlu_perfcnt2 := swerv.io.dec_tlu_perfcnt2
io.dec_tlu_perfcnt3 := swerv.io.dec_tlu_perfcnt3
io.dec_tlu_perfcnt0 := core.io.dec_tlu_perfcnt0
io.dec_tlu_perfcnt1 := core.io.dec_tlu_perfcnt1
io.dec_tlu_perfcnt2 := core.io.dec_tlu_perfcnt2
io.dec_tlu_perfcnt3 := core.io.dec_tlu_perfcnt3
//-------------------------- LSU AXI signals--------------------------
// AXI Write Channels
// DMA Slave
io.dma_hrdata := swerv.io.dma_hrdata
io.dma_hreadyout := swerv.io.dma_hreadyout
io.dma_hresp := swerv.io.dma_hresp
io.dma_hrdata := core.io.dma_hrdata
io.dma_hreadyout := core.io.dma_hreadyout
io.dma_hresp := core.io.dma_hresp
}
object QUASAR_Wrp extends App {

Binary file not shown.

Binary file not shown.