package lib import chisel3._ import chisel3.util._ trait param { val BHT_ADDR_HI = 9 val BHT_ADDR_LO = 2 val BHT_ARRAY_DEPTH = 256 val BHT_GHR_HASH_1 = false val BHT_GHR_SIZE = 8 val BHT_SIZE = 512 val BTB_ADDR_HI = 9 val BTB_ADDR_LO = 2 val BTB_ARRAY_DEPTH = 256 val BTB_BTAG_FOLD = false val BTB_BTAG_SIZE = 5 val BTB_FOLD2_INDEX_HASH = false val BTB_INDEX1_HI = 9 val BTB_INDEX1_LO = 2 val BTB_INDEX2_HI = 17 val BTB_INDEX2_LO = 10 val BTB_INDEX3_HI = 25 val BTB_INDEX3_LO = 18 val BTB_SIZE = 512 val BUILD_AHB_LITE = false val BUILD_AXI4 = true val BUILD_AXI_NATIVE = true val BUS_PRTY_DEFAULT = 3 val DATA_ACCESS_ADDR0 = 0x00000000 //.U(32.W) val DATA_ACCESS_ADDR1 = 0xC0000000 //.U(32.W) val DATA_ACCESS_ADDR2 = 0xA0000000 //.U(32.W) val DATA_ACCESS_ADDR3 = 0x80000000 //.U(32.W) val DATA_ACCESS_ADDR4 = 0x00000000 //.U(32.W) val DATA_ACCESS_ADDR5 = 0x00000000 //.U(32.W) val DATA_ACCESS_ADDR6 = 0x00000000 //.U(32.W) val DATA_ACCESS_ADDR7 = 0x00000000 //.U(32.W) val DATA_ACCESS_ENABLE0 = 0x1 //.U(1.W) val DATA_ACCESS_ENABLE1 = 0x1 //.U(1.W) val DATA_ACCESS_ENABLE2 = 0x1 //.U(1.W) val DATA_ACCESS_ENABLE3 = 0x1 //.U(1.W) val DATA_ACCESS_ENABLE4 = 0x0 //.U(1.W) val DATA_ACCESS_ENABLE5 = 0x0 //.U(1.W) val DATA_ACCESS_ENABLE6 = 0x0 //.U(1.W) val DATA_ACCESS_ENABLE7 = 0x0 //.U(1.W) val DATA_ACCESS_MASK0 = 0x7FFFFFFF //.U(32.W) val DATA_ACCESS_MASK1 = 0x3FFFFFFF //.U(32.W) val DATA_ACCESS_MASK2 = 0x1FFFFFFF //.U(32.W) val DATA_ACCESS_MASK3 = 0x0FFFFFFF //.U(32.W) val DATA_ACCESS_MASK4 = 0xFFFFFFFF //.U(32.W) val DATA_ACCESS_MASK5 = 0xFFFFFFFF //.U(32.W) val DATA_ACCESS_MASK6 = 0xFFFFFFFF //.U(32.W) val DATA_ACCESS_MASK7 = 0xFFFFFFFF //.U(32.W) val DCCM_BANK_BITS = 0x2 //.U(3.W) val DCCM_BITS = 0x10 //.U(5.W) val DCCM_BYTE_WIDTH = 0x4 //.U(3.W) val DCCM_DATA_WIDTH = 0x20 //.U(6.W) val DCCM_ECC_WIDTH = 0x7 //.U(3.W) val DCCM_ENABLE = 0x1 //.U(1.W) val DCCM_FDATA_WIDTH = 0x27 //.U(6.W) val DCCM_INDEX_BITS = 0xC //.U(4.W) val DCCM_NUM_BANKS = 0x04 //.U(5.W) val DCCM_REGION = 0xF //.U(4.W) val DCCM_SADR = 0xF0040000 val DCCM_SIZE = 0x040 val DCCM_WIDTH_BITS = 0x2 //.U(2.W) val DMA_BUF_DEPTH = 0x5 //.U(3.W) val DMA_BUS_ID = 0x1 //.U(1.W) val DMA_BUS_PRTY = 0x2 //.U(2.W) val DMA_BUS_TAG = 0x1 //.U(4.W) val FAST_INTERRUPT_REDIRECT= 0x1 //.U(1.W) val ICACHE_2BANKS = 1 val ICACHE_BANK_BITS = 1 val ICACHE_BANK_HI = 3 val ICACHE_BANK_LO = 3 val ICACHE_BANK_WIDTH = 8 val ICACHE_BANKS_WAY = 2 val ICACHE_BEAT_ADDR_HI = 5 val ICACHE_BEAT_BITS = 3 val ICACHE_DATA_DEPTH = 512 val ICACHE_DATA_INDEX_LO = 4 val ICACHE_DATA_WIDTH = 64 val ICACHE_ECC = true val ICACHE_ENABLE = true val ICACHE_FDATA_WIDTH = 71 val ICACHE_INDEX_HI = 12 val ICACHE_LN_SZ = 64 val ICACHE_NUM_BEATS = 8 val ICACHE_NUM_WAYS = 2 val ICACHE_ONLY = false val ICACHE_SCND_LAST = 6 val ICACHE_SIZE = 16 val ICACHE_STATUS_BITS = 1 val ICACHE_TAG_DEPTH = 128 val ICACHE_TAG_INDEX_LO = 6 val ICACHE_TAG_LO = 13 val ICACHE_WAYPACK = false val ICCM_BANK_BITS = 2 val ICCM_BANK_HI = 0x03 //.U(5.W) val ICCM_BANK_INDEX_LO = 0x04 //.U(5.W) val ICCM_BITS = 0x10 //.U(5.W) val ICCM_ENABLE = 0x1 //.U(1.W) val ICCM_ICACHE = 0x1 //.U(1.W) val ICCM_INDEX_BITS = 0xC //.U(4.W) val ICCM_NUM_BANKS = 0x04 //.U(5.W) val ICCM_ONLY = 0x0 //.U(1.W) val ICCM_REGION = 0xE //.U(4.W) val ICCM_SADR = 0xEE000000 //.U(32.W) val ICCM_SIZE = 0x040 //.U(10.W) val IFU_BUS_ID = 0x1 //.U(1.W) val IFU_BUS_PRTY = 0x2 //.U(2.W) val IFU_BUS_TAG = 0x3 //.U(4.W) val INST_ACCESS_ADDR0 = 0x00000000 //.U(32.W) val INST_ACCESS_ADDR1 = 0xC0000000 //.U(32.W) val INST_ACCESS_ADDR2 = 0xA0000000 //.U(32.W) val INST_ACCESS_ADDR3 = 0x80000000 //.U(32.W) val INST_ACCESS_ADDR4 = 0x00000000 //.U(32.W) val INST_ACCESS_ADDR5 = 0x00000000 //.U(32.W) val INST_ACCESS_ADDR6 = 0x00000000 //.U(32.W) val INST_ACCESS_ADDR7 = 0x00000000 //.U(32.W) val INST_ACCESS_ENABLE0 = 0x1 //.U(1.W) val INST_ACCESS_ENABLE1 = 0x1 //.U(1.W) val INST_ACCESS_ENABLE2 = 0x1 //.U(1.W) val INST_ACCESS_ENABLE3 = 0x1 //.U(1.W) val INST_ACCESS_ENABLE4 = 0x0 //.U(1.W) val INST_ACCESS_ENABLE5 = 0x0 //.U(1.W) val INST_ACCESS_ENABLE6 = 0x0 //.U(1.W) val INST_ACCESS_ENABLE7 = 0x0 //.U(1.W) val INST_ACCESS_MASK0 = 0x7FFFFFFF //.U(32.W) val INST_ACCESS_MASK1 = 0x3FFFFFFF //.U(32.W) val INST_ACCESS_MASK2 = 0x1FFFFFFF //.U(32.W) val INST_ACCESS_MASK3 = 0x0FFFFFFF //.U(32.W) val INST_ACCESS_MASK4 = 0xFFFFFFFF //.U(32.W) val INST_ACCESS_MASK5 = 0xFFFFFFFF //.U(32.W) val INST_ACCESS_MASK6 = 0xFFFFFFFF //.U(32.W) val INST_ACCESS_MASK7 = 0xFFFFFFFF //.U(32.W) val LOAD_TO_USE_PLUS1 = 0x0 //.U(1.W) val LSU2DMA = 0x0 //.U(1.W) val LSU_BUS_ID = 0x1 //.U(1.W) val LSU_BUS_PRTY = 0x2 //.U(2.W) val LSU_BUS_TAG = 0x3 //.U(4.W) val LSU_NUM_NBLOAD = 0x04 //.U(5.W) val LSU_NUM_NBLOAD_WIDTH = 0x2 //.U(3.W) val LSU_SB_BITS = 0x10 //.U(5.W) val LSU_STBUF_DEPTH = 0x4 //.U(4.W) val NO_ICCM_NO_ICACHE = 0x0 //.U(1.W) val PIC_2CYCLE = 0x0 //.U(1.W) val PIC_BASE_ADDR = 0xF00C0000 //.U(32.W) val PIC_BITS = 0x0F //.U(5.W) val PIC_INT_WORDS = 0x1 //.U(4.W) val PIC_REGION = 0xF //.U(4.W) val PIC_SIZE = 0x020 //.U(9.W) val PIC_TOTAL_INT = 0x1F //.U(8.W) val PIC_TOTAL_INT_PLUS1 = 0x020 //.U(9.W) val RET_STACK_SIZE = 0x8 //.U(4.W) val SB_BUS_ID = 0x1 //.U(1.W) val SB_BUS_PRTY = 0x2 //.U(2.W) val SB_BUS_TAG = 0x1 //.U(4.W) val TIMER_LEGAL_EN = 0x1 //.U(1.W) // Configuration Methods def MEM_CAL : (Int, Int, Int)= (ICACHE_WAYPACK, ICACHE_ECC) match{ case(false,false) => (68,22, 68) case(false,true) => (71,26, 71) case(true,false) => (68*ICACHE_NUM_WAYS,22*ICACHE_NUM_WAYS, 68) case(true,true) => (71*ICACHE_NUM_WAYS,26*ICACHE_NUM_WAYS, 71) } val DATA_MEM_LINE = MEM_CAL } trait el2_lib extends param{ def el2_btb_tag_hash(pc : UInt) = (VecInit.tabulate(3)(i => pc(BTB_ADDR_HI+((i+1)*(BTB_BTAG_SIZE)),BTB_ADDR_HI+(i*BTB_BTAG_SIZE)+1))).reduce(_^_) def el2_btb_tag_hash_fold(pc : UInt) = pc(BTB_ADDR_HI+(2*BTB_BTAG_SIZE),BTB_ADDR_HI+BTB_BTAG_SIZE+1)^pc(BTB_ADDR_HI+BTB_BTAG_SIZE,BTB_ADDR_HI+1) def el2_btb_addr_hash(pc : UInt) = if(BTB_FOLD2_INDEX_HASH) pc(BTB_INDEX1_HI,BTB_INDEX1_LO) ^ pc(BTB_INDEX3_HI,BTB_INDEX3_LO) else pc(BTB_INDEX1_HI,BTB_INDEX1_LO) ^ pc(BTB_INDEX2_HI,BTB_INDEX2_LO) ^ pc(BTB_INDEX3_HI,BTB_INDEX3_LO) def el2_btb_ghr_hash(hashin : UInt, ghr :UInt) = if(BHT_GHR_HASH_1) Cat(ghr(BHT_GHR_SIZE-1,BTB_INDEX1_HI-1), hashin(BTB_INDEX1_HI,2) ^ ghr(BTB_INDEX1_HI-2,0)) else hashin(BHT_GHR_SIZE+1,2) ^ ghr(BHT_GHR_SIZE-1,0) def repl(b:Int, a:UInt) = VecInit.tabulate(b)(i => a).reduce(Cat(_,_)) def Mux1H_LM(a:Seq[Bool], b:Seq[UInt]) = (0 until b.size).map(i=> repl(b(i).getWidth,a(i)) & b(i)).reduce(_|_) def rveven_paritycheck(data_in:UInt, parity_in:UInt) : UInt = (data_in.xorR.asUInt) ^ parity_in def rveven_paritygen(data_in : UInt) = data_in.xorR.asUInt // Move rvecc_encode to a proper trait def rvecc_encode(din:UInt) = { //Done for verification and testing val mask0 = Array(0,1,0,1,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,1,0,1,0,1,1,0,1,1) val mask1 = Array(1,0,0,1,1,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,1) val mask2 = Array(1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,0) val mask3 = Array(0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0) val mask4 = Array(0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0) val mask5 = Array(1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) val w0 = Wire(Vec(18,UInt(1.W))) val w1 = Wire(Vec(18,UInt(1.W))) val w2 = Wire(Vec(18,UInt(1.W))) val w3 = Wire(Vec(15,UInt(1.W))) val w4 = Wire(Vec(15,UInt(1.W))) val w5 = Wire(Vec(6, UInt(1.W))) var j = 0;var k = 0;var m = 0; var x = 0;var y = 0;var z = 0 for(i <- 0 to 31) { if(mask0(i)==1) {w0(j) := din(i); j = j +1 } if(mask1(i)==1) {w1(k) := din(i); k = k +1 } if(mask2(i)==1) {w2(m) := din(i); m = m +1 } if(mask3(i)==1) {w3(x) := din(i); x = x +1 } if(mask4(i)==1) {w4(y) := din(i); y = y +1 } if(mask5(i)==1) {w5(z) := din(i); z = z +1 } } val w6 = Cat((w0.asUInt.xorR),(w1.asUInt.xorR),(w2.asUInt.xorR),(w3.asUInt.xorR),(w4.asUInt.xorR),(w5.asUInt.xorR)) Cat(din.xorR ^ w6.xorR, w6) } class rvecc_decode extends Module{ //Done for verification and testing val io = IO(new Bundle{ val en = Input(UInt(1.W)) val din = Input(UInt(32.W)) val ecc_in = Input(UInt(7.W)) val sed_ded = Input(UInt(1.W)) val ecc_out = Output(UInt(7.W)) val dout = Output(UInt(32.W)) val single_ecc_error = Output(UInt(1.W)) val double_ecc_error = Output(UInt(1.W)) }) val mask0 = Array(1,1,0,1,1,0,1,0,1,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,1,0,1,0) val mask1 = Array(1,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,1,1,0,0,1) val mask2 = Array(0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1) val mask3 = Array(0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0) val mask4 = Array(0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0) val mask5 = Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1) val w0 = Wire(Vec(18,UInt(1.W))) val w1 = Wire(Vec(18,UInt(1.W))) val w2 = Wire(Vec(18,UInt(1.W))) val w3 = Wire(Vec(15,UInt(1.W))) val w4 = Wire(Vec(15,UInt(1.W))) val w5 = Wire(Vec(6,UInt(1.W))) var j = 0;var k = 0;var m = 0; var n =0; var x = 0;var y = 0; for(i <- 0 to 31) { if(mask0(i)==1) {w0(j) := io.din(i); j = j +1 } if(mask1(i)==1) {w1(k) := io.din(i); k = k +1 } if(mask2(i)==1) {w2(m) := io.din(i); m = m +1 } if(mask3(i)==1) {w3(n) := io.din(i); n = n +1 } if(mask4(i)==1) {w4(x) := io.din(i); x = x +1 } if(mask5(i)==1) {w5(y) := io.din(i); y = y +1 } } val ecc_check = Cat((io.din.xorR ^ io.ecc_in.xorR) & ~io.sed_ded ,io.ecc_in(5)^(w5.asUInt.xorR),io.ecc_in(4)^(w4.asUInt.xorR),io.ecc_in(3)^(w3.asUInt.xorR),io.ecc_in(2)^(w2.asUInt.xorR),io.ecc_in(1)^(w1.asUInt.xorR),io.ecc_in(0)^(w0.asUInt.xorR)) io.ecc_out := ecc_check io.single_ecc_error := io.en & (ecc_check!= 0.U) & ((io.din.xorR ^ io.ecc_in.xorR) & ~io.sed_ded) io.double_ecc_error := io.en & (ecc_check!= 0.U) & ((io.din.xorR ^ io.ecc_in.xorR) & ~io.sed_ded) val error_mask = Wire(Vec(39,UInt(1.W))) for(i <- 1 until 40){ error_mask(i-1) := ecc_check(5,0) === i.asUInt } val din_plus_parity = Cat(io.ecc_in(6), io.din(31,26), io.ecc_in(5), io.din(25,11), io.ecc_in(4), io.din(10,4), io.ecc_in(3), io.din(3,1), io.ecc_in(2), io.din(0), io.ecc_in(1,0)) val dout_plus_parity = Mux(io.single_ecc_error.asBool, (error_mask.asUInt ^ din_plus_parity), din_plus_parity) io.dout := Cat(dout_plus_parity(37,32),dout_plus_parity(30,16), dout_plus_parity(14,8), dout_plus_parity(6,4), dout_plus_parity(2)) io.ecc_out := Cat(dout_plus_parity(38) ^ (ecc_check(6,0) === "b1000000".U), dout_plus_parity(31), dout_plus_parity(15), dout_plus_parity(7), dout_plus_parity(3), dout_plus_parity(1,0)) } }