18882eb68SXin Tian/*************************************************************************************** 28882eb68SXin Tian* Copyright (c) 2024-2025 Institute of Information Engineering, Chinese Academy of Sciences 38882eb68SXin Tian* 48882eb68SXin Tian* XiangShan is licensed under Mulan PSL v2. 58882eb68SXin Tian* You can use this software according to the terms and conditions of the Mulan PSL v2. 68882eb68SXin Tian* You may obtain a copy of Mulan PSL v2 at: 78882eb68SXin Tian* http://license.coscl.org.cn/MulanPSL2 88882eb68SXin Tian* 98882eb68SXin Tian* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 108882eb68SXin Tian* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 118882eb68SXin Tian* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 128882eb68SXin Tian* 138882eb68SXin Tian* See the Mulan PSL v2 for more details. 148882eb68SXin Tian***************************************************************************************/ 158882eb68SXin Tian 168882eb68SXin Tianpackage device 178882eb68SXin Tian 188882eb68SXin Tianimport chisel3._ 198882eb68SXin Tianimport chisel3.util._ 208882eb68SXin Tianimport chisel3.util.HasBlackBoxResource 218882eb68SXin Tianimport org.chipsalliance.cde.config.Field 228882eb68SXin Tianimport org.chipsalliance.cde.config.Parameters 238882eb68SXin Tianimport freechips.rocketchip.amba.axi4._ 248882eb68SXin Tianimport freechips.rocketchip.diplomacy._ 258882eb68SXin Tianimport freechips.rocketchip.util._ 268882eb68SXin Tianimport freechips.rocketchip.amba.apb._ 278882eb68SXin Tianimport freechips.rocketchip.tilelink.AXI4TLState 288882eb68SXin Tianimport javax.xml.crypto.dsig.keyinfo.KeyInfo 298882eb68SXin Tianimport system._ 308882eb68SXin Tian 318882eb68SXin Tiancase object MemcEdgeInKey extends Field[AXI4EdgeParameters] 328882eb68SXin Tiancase object MemcEdgeOutKey extends Field[AXI4EdgeParameters] 338882eb68SXin Tian 348882eb68SXin Tiantrait Memconsts { 358882eb68SXin Tian val p: Parameters 368882eb68SXin Tian val cvm = p(CVMParamskey) 378882eb68SXin Tian val soc = p(SoCParamsKey) 388882eb68SXin Tian val PAddrBits= soc.PAddrBits 398882eb68SXin Tian val KeyIDBits= cvm.KeyIDBits 408882eb68SXin Tian val MemencPipes = cvm.MemencPipes 418882eb68SXin Tian lazy val MemcedgeIn = p(MemcEdgeInKey) 428882eb68SXin Tian lazy val MemcedgeOut = p(MemcEdgeOutKey) 438882eb68SXin Tian require (isPow2(MemencPipes), s"AXI4MemEncrypt: MemencPipes must be a power of two, not $MemencPipes") 448882eb68SXin Tian require (PAddrBits > KeyIDBits, s"AXI4MemEncrypt: PAddrBits must be greater than KeyIDBits") 458882eb68SXin Tian def HasDelayNoencryption = cvm.HasDelayNoencryption 468882eb68SXin Tian} 478882eb68SXin Tian 488882eb68SXin Tian 498882eb68SXin Tianabstract class MemEncryptModule(implicit val p: Parameters) extends Module with Memconsts 508882eb68SXin Tian 518882eb68SXin Tianclass TweakEncrptyQueue(implicit p: Parameters) extends MemEncryptModule 528882eb68SXin Tian{ 538882eb68SXin Tian val io = IO(new Bundle { 548882eb68SXin Tian val enq = Flipped(DecoupledIO(new Bundle { 558882eb68SXin Tian val addr = UInt(PAddrBits.W) 568882eb68SXin Tian val len = UInt(MemcedgeIn.bundle.lenBits.W) // number of beats - 1 578882eb68SXin Tian })) 588882eb68SXin Tian val deq = DecoupledIO(new Bundle { 598882eb68SXin Tian val keyid = UInt(KeyIDBits.W) 608882eb68SXin Tian val tweak = UInt(MemcedgeIn.bundle.dataBits.W) 618882eb68SXin Tian val addr = UInt(MemcedgeIn.bundle.addrBits.W) 628882eb68SXin Tian }) 638882eb68SXin Tian val tweak_round_keys = Input(Vec(32, UInt(32.W))) 648882eb68SXin Tian }) 658882eb68SXin Tian val tweak_in = Cat(0.U((128 - PAddrBits).W), Cat(io.enq.bits.addr(PAddrBits - 1, 6), 0.U(6.W))) 668882eb68SXin Tian 678882eb68SXin Tian val tweak_enc_module = Module(new TweakEncrypt(opt = true)) 688882eb68SXin Tian val tweakgf128_module = Module(new TweakGF128()) 698882eb68SXin Tian 708882eb68SXin Tian tweak_enc_module.io.tweak_enc_req.valid := io.enq.valid 718882eb68SXin Tian tweak_enc_module.io.tweak_enc_resp.ready := tweakgf128_module.io.req.ready 728882eb68SXin Tian tweak_enc_module.io.tweak_enc_req.bits.tweak := tweak_in 738882eb68SXin Tian tweak_enc_module.io.tweak_enc_req.bits.addr_in := io.enq.bits.addr 748882eb68SXin Tian tweak_enc_module.io.tweak_enc_req.bits.len_in := io.enq.bits.len 758882eb68SXin Tian tweak_enc_module.io.tweak_enc_req.bits.id_in := 0.U 768882eb68SXin Tian tweak_enc_module.io.tweak_enc_req.bits.tweak_round_keys := io.tweak_round_keys 778882eb68SXin Tian 788882eb68SXin Tian io.enq.ready := tweak_enc_module.io.tweak_enc_req.ready 798882eb68SXin Tian 808882eb68SXin Tian tweakgf128_module.io.req.bits.len := tweak_enc_module.io.tweak_enc_resp.bits.len_out 818882eb68SXin Tian tweakgf128_module.io.req.bits.addr := tweak_enc_module.io.tweak_enc_resp.bits.addr_out 828882eb68SXin Tian tweakgf128_module.io.req.bits.tweak_in := tweak_enc_module.io.tweak_enc_resp.bits.tweak_encrpty 838882eb68SXin Tian tweakgf128_module.io.req.valid := tweak_enc_module.io.tweak_enc_resp.valid 848882eb68SXin Tian tweakgf128_module.io.resp.ready := io.deq.ready 858882eb68SXin Tian 868882eb68SXin Tian io.deq.bits.keyid := tweakgf128_module.io.resp.bits.keyid_out 878882eb68SXin Tian io.deq.bits.tweak := tweakgf128_module.io.resp.bits.tweak_out 888882eb68SXin Tian io.deq.bits.addr := tweakgf128_module.io.resp.bits.addr_out 898882eb68SXin Tian io.deq.valid := tweakgf128_module.io.resp.valid 908882eb68SXin Tian} 918882eb68SXin Tian 928882eb68SXin Tianclass AXI4W_KT(opt:Boolean)(implicit val p: Parameters) extends Bundle with Memconsts 938882eb68SXin Tian{ 948882eb68SXin Tian val edgeUse = if (opt) MemcedgeIn else MemcedgeOut 958882eb68SXin Tian val axi4 = new AXI4BundleW(edgeUse.bundle) 968882eb68SXin Tian val keyid = UInt(KeyIDBits.W) 978882eb68SXin Tian val tweak = UInt(edgeUse.bundle.dataBits.W) 988882eb68SXin Tian} 998882eb68SXin Tian 1008882eb68SXin Tian// Used to indicate the source of the req (L1I/L1D/PTW) 1018882eb68SXin Tiancase object ReqSourceKey extends ControlKey[UInt]("reqSource") 1028882eb68SXin Tian 1038882eb68SXin Tianclass AXI4WriteMachine(implicit p: Parameters) extends MemEncryptModule 1048882eb68SXin Tian{ 1058882eb68SXin Tian val io = IO(new Bundle { 1068882eb68SXin Tian val in_w = Flipped(Irrevocable(new AXI4BundleW(MemcedgeOut.bundle))) 1078882eb68SXin Tian val in_kt = Flipped(DecoupledIO(new Bundle { 1088882eb68SXin Tian val keyid = UInt(KeyIDBits.W) 1098882eb68SXin Tian val tweak = UInt(MemcedgeOut.bundle.dataBits.W) 1108882eb68SXin Tian val addr = UInt(MemcedgeOut.bundle.addrBits.W) 1118882eb68SXin Tian })) 1128882eb68SXin Tian val out_ar = Irrevocable(new AXI4BundleAR(MemcedgeOut.bundle)) 1138882eb68SXin Tian val in_r = Flipped(Irrevocable(new AXI4BundleR(MemcedgeOut.bundle))) 1148882eb68SXin Tian val out_w = DecoupledIO(new AXI4W_KT(true)) 1158882eb68SXin Tian val uncache_en = Output(Bool()) 1168882eb68SXin Tian val uncache_commit = Input(Bool()) 1178882eb68SXin Tian }) 1188882eb68SXin Tian // ---------------- 1198882eb68SXin Tian // s0 stage 1208882eb68SXin Tian // ---------------- 1218882eb68SXin Tian val w_cacheable = io.in_w.bits.strb.andR 1228882eb68SXin Tian 1238882eb68SXin Tian // ---------------- 1248882eb68SXin Tian // s1 stage 1258882eb68SXin Tian // ---------------- 1268882eb68SXin Tian val in_w_v = RegInit(false.B) 1278882eb68SXin Tian val in_kt_v = RegInit(false.B) 1288882eb68SXin Tian 1298882eb68SXin Tian val in_w_req = RegEnable(io.in_w.bits, io.in_w.fire) 1308882eb68SXin Tian val in_kt_req = RegEnable(io.in_kt.bits, io.in_kt.fire) 1318882eb68SXin Tian io.in_w.ready := !in_w_v || io.out_w.fire 1328882eb68SXin Tian io.in_kt.ready := !in_kt_v || io.out_w.fire 1338882eb68SXin Tian 1348882eb68SXin Tian when(io.in_w.fire) { 1358882eb68SXin Tian in_w_v := true.B 1368882eb68SXin Tian }.elsewhen(io.out_w.fire) { 1378882eb68SXin Tian in_w_v := false.B 1388882eb68SXin Tian }.otherwise { 1398882eb68SXin Tian in_w_v := in_w_v 1408882eb68SXin Tian } 1418882eb68SXin Tian 1428882eb68SXin Tian when(io.in_kt.fire) { 1438882eb68SXin Tian in_kt_v := true.B 1448882eb68SXin Tian }.elsewhen(io.out_w.fire) { 1458882eb68SXin Tian in_kt_v := false.B 1468882eb68SXin Tian }.otherwise { 1478882eb68SXin Tian in_kt_v := in_kt_v 1488882eb68SXin Tian } 1498882eb68SXin Tian 1508882eb68SXin Tian // ----------------------------- 1518882eb68SXin Tian // s2 stage only uncacheable use 1528882eb68SXin Tian // ----------------------------- 1538882eb68SXin Tian val out_ar_v = RegInit(false.B) 1548882eb68SXin Tian val out_ar_mask = RegInit(false.B) 1558882eb68SXin Tian val in_r_v = RegInit(false.B) 1568882eb68SXin Tian val r_uncache_en = RegInit(false.B) 1578882eb68SXin Tian when(io.in_r.fire) { 1588882eb68SXin Tian in_r_v := true.B 1598882eb68SXin Tian }.elsewhen(io.out_w.fire) { 1608882eb68SXin Tian in_r_v := false.B 1618882eb68SXin Tian }.otherwise { 1628882eb68SXin Tian in_r_v := in_r_v 1638882eb68SXin Tian } 1648882eb68SXin Tian 1658882eb68SXin Tian when(io.in_r.fire) { 1668882eb68SXin Tian r_uncache_en := true.B 1678882eb68SXin Tian }.elsewhen(io.uncache_commit) { 1688882eb68SXin Tian r_uncache_en := false.B 1698882eb68SXin Tian }.otherwise { 1708882eb68SXin Tian r_uncache_en := r_uncache_en 1718882eb68SXin Tian } 1728882eb68SXin Tian 1738882eb68SXin Tian io.in_r.ready := !r_uncache_en || io.uncache_commit 1748882eb68SXin Tian io.uncache_en := r_uncache_en 1758882eb68SXin Tian 1768882eb68SXin Tian val s1_w_cacheable = RegEnable(w_cacheable, io.in_w.fire) 1778882eb68SXin Tian 1788882eb68SXin Tian when(in_w_v && in_kt_v && !s1_w_cacheable && !out_ar_mask) { 1798882eb68SXin Tian out_ar_v := true.B 1808882eb68SXin Tian }.elsewhen(io.out_ar.fire) { 1818882eb68SXin Tian out_ar_v := false.B 1828882eb68SXin Tian }.otherwise { 1838882eb68SXin Tian out_ar_v := out_ar_v 1848882eb68SXin Tian } 1858882eb68SXin Tian 1868882eb68SXin Tian when(in_w_v && in_kt_v && !s1_w_cacheable && !out_ar_mask) { 1878882eb68SXin Tian out_ar_mask := true.B 1888882eb68SXin Tian }.elsewhen(io.out_w.fire) { 1898882eb68SXin Tian out_ar_mask := false.B 1908882eb68SXin Tian }.otherwise { 1918882eb68SXin Tian out_ar_mask := out_ar_mask 1928882eb68SXin Tian } 1938882eb68SXin Tian 1948882eb68SXin Tian io.out_ar.valid := out_ar_v 1958882eb68SXin Tian val ar = io.out_ar.bits 1968882eb68SXin Tian ar.id := 1.U << (MemcedgeOut.bundle.idBits - 1) 1978882eb68SXin Tian ar.addr := (in_kt_req.addr >> log2Ceil(MemcedgeOut.bundle.dataBits/8)) << log2Ceil(MemcedgeOut.bundle.dataBits/8) 1988882eb68SXin Tian ar.len := 0.U 1998882eb68SXin Tian ar.size := log2Ceil(MemcedgeOut.bundle.dataBits/8).U 2008882eb68SXin Tian ar.burst := AXI4Parameters.BURST_INCR 2018882eb68SXin Tian ar.lock := 0.U // not exclusive (LR/SC unsupported b/c no forward progress guarantee) 2028882eb68SXin Tian ar.cache := 0.U // do not allow AXI to modify our transactions 2038882eb68SXin Tian ar.prot := AXI4Parameters.PROT_PRIVILEGED 2048882eb68SXin Tian ar.qos := 0.U // no QoS 2058882eb68SXin Tian if (MemcedgeOut.bundle.echoFields != Nil) { 2068882eb68SXin Tian val ar_extra = ar.echo(AXI4TLState) 2078882eb68SXin Tian ar_extra.source := 0.U 2088882eb68SXin Tian ar_extra.size := 0.U 2098882eb68SXin Tian } 2108882eb68SXin Tian if (MemcedgeOut.bundle.requestFields != Nil) { 2118882eb68SXin Tian val ar_user = ar.user(ReqSourceKey) 2128882eb68SXin Tian ar_user := 0.U 2138882eb68SXin Tian } 2148882eb68SXin Tian 2158882eb68SXin Tian def gen_wmask(strb: UInt): UInt = { 2168882eb68SXin Tian val extendedBits = VecInit((0 until MemcedgeOut.bundle.dataBits/8).map(i => Cat(Fill(7, strb((MemcedgeOut.bundle.dataBits/8)-1-i)), strb((MemcedgeOut.bundle.dataBits/8)-1-i)))) 2178882eb68SXin Tian extendedBits.reduce(_ ## _) 2188882eb68SXin Tian } 2198882eb68SXin Tian 2208882eb68SXin Tian val new_data = Reg(UInt(MemcedgeOut.bundle.dataBits.W)) 2218882eb68SXin Tian val new_strb = ~0.U((MemcedgeOut.bundle.dataBits/8).W) 2228882eb68SXin Tian val wmask = gen_wmask(in_w_req.strb) 2238882eb68SXin Tian 2248882eb68SXin Tian when(io.in_r.fire) { 2258882eb68SXin Tian new_data := (io.in_r.bits.data & ~wmask) | (in_w_req.data & wmask) 2268882eb68SXin Tian } 2278882eb68SXin Tian 2288882eb68SXin Tian when(s1_w_cacheable) { 2298882eb68SXin Tian io.out_w.valid := in_w_v && in_kt_v 2308882eb68SXin Tian io.out_w.bits.axi4 := in_w_req 2318882eb68SXin Tian io.out_w.bits.keyid := in_kt_req.keyid 2328882eb68SXin Tian io.out_w.bits.tweak := in_kt_req.tweak 2338882eb68SXin Tian }.otherwise { 2348882eb68SXin Tian io.out_w.valid := in_w_v && in_kt_v && in_r_v 2358882eb68SXin Tian io.out_w.bits.axi4 := in_w_req 2368882eb68SXin Tian io.out_w.bits.axi4.data := new_data 2378882eb68SXin Tian io.out_w.bits.axi4.strb := new_strb 2388882eb68SXin Tian io.out_w.bits.keyid := in_kt_req.keyid 2398882eb68SXin Tian io.out_w.bits.tweak := in_kt_req.tweak 2408882eb68SXin Tian } 2418882eb68SXin Tian 2428882eb68SXin Tian} 2438882eb68SXin Tian 2448882eb68SXin Tianclass WdataEncrptyPipe(implicit p: Parameters) extends MemEncryptModule 2458882eb68SXin Tian{ 2468882eb68SXin Tian val io = IO(new Bundle { 2478882eb68SXin Tian val in_w = Flipped(DecoupledIO(new AXI4W_KT(true))) 2488882eb68SXin Tian val out_w = Irrevocable(new AXI4BundleW(MemcedgeIn.bundle)) 2498882eb68SXin Tian val enc_keyids = Output(Vec(MemencPipes, UInt(KeyIDBits.W))) 2508882eb68SXin Tian val enc_round_keys = Input(Vec(MemencPipes, UInt((32*32/MemencPipes).W))) 2518882eb68SXin Tian }) 2528882eb68SXin Tian val reg_encdec_result_0 = Reg(Vec(MemencPipes, UInt(128.W))) 2538882eb68SXin Tian val reg_encdec_result_1 = Reg(Vec(MemencPipes, UInt(128.W))) 2548882eb68SXin Tian val reg_axi4_other_result = Reg(Vec(MemencPipes, new AXI4BundleWWithoutData(MemcedgeIn.bundle))) 2558882eb68SXin Tian val reg_tweak_result_0 = Reg(Vec(MemencPipes, UInt(128.W))) 2568882eb68SXin Tian val reg_tweak_result_1 = Reg(Vec(MemencPipes, UInt(128.W))) 2578882eb68SXin Tian val reg_keyid = Reg(Vec(MemencPipes, UInt(KeyIDBits.W))) 2588882eb68SXin Tian val reg_encdec_valid = RegInit(VecInit(Seq.fill(MemencPipes)(false.B))) 2598882eb68SXin Tian val wire_ready_result = WireInit(VecInit(Seq.fill(MemencPipes)(false.B))) 2608882eb68SXin Tian 2618882eb68SXin Tian val wire_axi4_other = Wire(new AXI4BundleWWithoutData(MemcedgeIn.bundle)) 2628882eb68SXin Tian wire_axi4_other.strb := io.in_w.bits.axi4.strb 2638882eb68SXin Tian wire_axi4_other.last := io.in_w.bits.axi4.last 2648882eb68SXin Tian wire_axi4_other.user := io.in_w.bits.axi4.user 2658882eb68SXin Tian 2668882eb68SXin Tian 2678882eb68SXin Tian val pipes_first_data_0 = Wire(UInt(128.W)) 2688882eb68SXin Tian val pipes_first_data_1 = Wire(UInt(128.W)) 2698882eb68SXin Tian if (HasDelayNoencryption) { 2708882eb68SXin Tian pipes_first_data_0 := io.in_w.bits.axi4.data(127,0) 2718882eb68SXin Tian pipes_first_data_1 := io.in_w.bits.axi4.data(255,128) 2728882eb68SXin Tian } else { 2738882eb68SXin Tian pipes_first_data_0 := io.in_w.bits.axi4.data(127,0) ^ io.in_w.bits.tweak(127, 0) 2748882eb68SXin Tian pipes_first_data_1 := io.in_w.bits.axi4.data(255,128) ^ io.in_w.bits.tweak(255,128) 2758882eb68SXin Tian } 2768882eb68SXin Tian 2778882eb68SXin Tian def configureModule(flag: Boolean, i: Int, keyId: UInt, dataIn: UInt, tweakIn: UInt, axi4In: AXI4BundleWWithoutData, roundKeys: UInt): OnePipeEncBase = { 2788882eb68SXin Tian when(wire_ready_result(i) && (if (i == 0) io.in_w.valid else reg_encdec_valid(i-1))) { 2798882eb68SXin Tian reg_encdec_valid(i) := true.B 2808882eb68SXin Tian }.elsewhen(reg_encdec_valid(i) && (if (i == MemencPipes - 1) io.out_w.ready else wire_ready_result(i + 1))) { 2818882eb68SXin Tian reg_encdec_valid(i) := false.B 2828882eb68SXin Tian }.otherwise { 2838882eb68SXin Tian reg_encdec_valid(i) := reg_encdec_valid(i) 2848882eb68SXin Tian } 2858882eb68SXin Tian 2868882eb68SXin Tian wire_ready_result(i) := !reg_encdec_valid(i) || (reg_encdec_valid(i) && (if (i == MemencPipes - 1) io.out_w.ready else wire_ready_result(i+1))) 2878882eb68SXin Tian 2888882eb68SXin Tian val module: OnePipeEncBase = if (HasDelayNoencryption) Module(new OnePipeForEncNoEnc()) else Module(new OnePipeForEnc()) 2898882eb68SXin Tian module.io.onepipe_in.keyid := keyId 2908882eb68SXin Tian module.io.onepipe_in.data_in := dataIn 2918882eb68SXin Tian module.io.onepipe_in.tweak_in := tweakIn 2928882eb68SXin Tian module.io.onepipe_in.axi4_other := axi4In 2938882eb68SXin Tian for (i <- 0 until 32/MemencPipes) { 2948882eb68SXin Tian module.io.onepipe_in.round_key_in(i) := roundKeys(i * 32 + 31, i * 32) 2958882eb68SXin Tian } 2968882eb68SXin Tian when((if (i == 0) io.in_w.valid else reg_encdec_valid(i-1)) && wire_ready_result(i)) { 2978882eb68SXin Tian if (flag) { 2988882eb68SXin Tian reg_encdec_result_0(i) := module.io.onepipe_out.result_out 2998882eb68SXin Tian reg_tweak_result_0(i) := module.io.onepipe_out.tweak_out 3008882eb68SXin Tian reg_axi4_other_result(i) := module.io.onepipe_out.axi4_other_out 3018882eb68SXin Tian reg_keyid(i) := module.io.onepipe_out.keyid_out 3028882eb68SXin Tian } else { 3038882eb68SXin Tian reg_encdec_result_1(i) := module.io.onepipe_out.result_out 3048882eb68SXin Tian reg_tweak_result_1(i) := module.io.onepipe_out.tweak_out 3058882eb68SXin Tian } 3068882eb68SXin Tian } 3078882eb68SXin Tian io.enc_keyids(i) := module.io.onepipe_out.keyid_out 3088882eb68SXin Tian module 3098882eb68SXin Tian } 3108882eb68SXin Tian val modules_0 = (0 until MemencPipes).map { i => 3118882eb68SXin Tian if (i == 0) { 3128882eb68SXin Tian configureModule(true, i, io.in_w.bits.keyid, pipes_first_data_0, io.in_w.bits.tweak(127, 0), wire_axi4_other, io.enc_round_keys(i)) 3138882eb68SXin Tian } else { 3148882eb68SXin Tian configureModule(true, i, reg_keyid(i-1), reg_encdec_result_0(i-1), reg_tweak_result_0(i-1), reg_axi4_other_result(i-1), io.enc_round_keys(i)) 3158882eb68SXin Tian } 3168882eb68SXin Tian } 3178882eb68SXin Tian val modules_1 = (0 until MemencPipes).map { i => 3188882eb68SXin Tian if (i == 0) { 3198882eb68SXin Tian configureModule(false, i, io.in_w.bits.keyid, pipes_first_data_1, io.in_w.bits.tweak(255,128), wire_axi4_other, io.enc_round_keys(i)) 3208882eb68SXin Tian } else { 3218882eb68SXin Tian configureModule(false, i, reg_keyid(i-1), reg_encdec_result_1(i-1), reg_tweak_result_1(i-1), reg_axi4_other_result(i-1), io.enc_round_keys(i)) 3228882eb68SXin Tian } 3238882eb68SXin Tian } 3248882eb68SXin Tian if (HasDelayNoencryption) { 3258882eb68SXin Tian io.out_w.bits.data := Cat(reg_encdec_result_1.last, reg_encdec_result_0.last) 3268882eb68SXin Tian } else { 3278882eb68SXin Tian val enc_0_out = Cat( 3288882eb68SXin Tian reg_encdec_result_0.last(31, 0), 3298882eb68SXin Tian reg_encdec_result_0.last(63, 32), 3308882eb68SXin Tian reg_encdec_result_0.last(95, 64), 3318882eb68SXin Tian reg_encdec_result_0.last(127, 96) 3328882eb68SXin Tian ) 3338882eb68SXin Tian val enc_1_out = Cat( 3348882eb68SXin Tian reg_encdec_result_1.last(31, 0), 3358882eb68SXin Tian reg_encdec_result_1.last(63, 32), 3368882eb68SXin Tian reg_encdec_result_1.last(95, 64), 3378882eb68SXin Tian reg_encdec_result_1.last(127, 96) 3388882eb68SXin Tian ) 3398882eb68SXin Tian io.out_w.bits.data := Cat(enc_1_out ^ reg_tweak_result_1.last, enc_0_out ^ reg_tweak_result_0.last) 3408882eb68SXin Tian } 3418882eb68SXin Tian 3428882eb68SXin Tian io.out_w.bits.strb := reg_axi4_other_result.last.strb 3438882eb68SXin Tian io.out_w.bits.last := reg_axi4_other_result.last.last 3448882eb68SXin Tian io.out_w.bits.user := reg_axi4_other_result.last.user 3458882eb68SXin Tian io.out_w.valid := reg_encdec_valid.last 3468882eb68SXin Tian io.in_w.ready := wire_ready_result(0) 3478882eb68SXin Tian} 3488882eb68SXin Tian 3498882eb68SXin Tianclass TweakEncrptyTable(implicit p: Parameters) extends MemEncryptModule 3508882eb68SXin Tian{ 3518882eb68SXin Tian val io = IO(new Bundle { 3528882eb68SXin Tian val enq = Flipped(DecoupledIO(new Bundle { 3538882eb68SXin Tian val addr = UInt(PAddrBits.W) 3548882eb68SXin Tian val len = UInt(MemcedgeOut.bundle.lenBits.W) // number of beats - 1 3558882eb68SXin Tian val id = UInt(MemcedgeOut.bundle.idBits.W) // 7 bits 3568882eb68SXin Tian })) 3578882eb68SXin Tian val req = Flipped(DecoupledIO(new Bundle { 3588882eb68SXin Tian val id = UInt(MemcedgeOut.bundle.idBits.W) 3598882eb68SXin Tian })) 3608882eb68SXin Tian val resp = DecoupledIO(new Bundle { 3618882eb68SXin Tian val keyid = UInt(KeyIDBits.W) 3628882eb68SXin Tian val tweak = UInt(MemcedgeOut.bundle.dataBits.W) 3638882eb68SXin Tian }) 3648882eb68SXin Tian val dec_r = new Bundle { 3658882eb68SXin Tian val id = Input(UInt(MemcedgeOut.bundle.idBits.W)) 3668882eb68SXin Tian val mode = Output(Bool()) 3678882eb68SXin Tian } 3688882eb68SXin Tian val dec_keyid = Output(UInt(KeyIDBits.W)) 3698882eb68SXin Tian val dec_mode = Input(Bool()) 3708882eb68SXin Tian val tweak_round_keys = Input(Vec(32, UInt(32.W))) 3718882eb68SXin Tian val memenc_enable = Input(Bool()) 3728882eb68SXin Tian }) 3738882eb68SXin Tian 3748882eb68SXin Tian val tweak_in = Cat(0.U((128 - PAddrBits).W), Cat(io.enq.bits.addr(PAddrBits-1, 6), 0.U(6.W))) 3758882eb68SXin Tian // query the dec_mode from the round key 3768882eb68SXin Tian io.dec_keyid := io.enq.bits.addr(PAddrBits - 1, PAddrBits - KeyIDBits) 3778882eb68SXin Tian 3788882eb68SXin Tian val tweak_enc_module = Module(new TweakEncrypt(opt = false)) 3798882eb68SXin Tian val tweak_table = Module(new TweakTable()) 3808882eb68SXin Tian val tweak_gf128 = Module(new GF128()) 3818882eb68SXin Tian 3828882eb68SXin Tian // updata mode table 3838882eb68SXin Tian tweak_table.io.w_mode.bits.id := io.enq.bits.id 3848882eb68SXin Tian tweak_table.io.w_mode.bits.dec_mode := io.dec_mode && io.memenc_enable 3858882eb68SXin Tian tweak_table.io.w_mode.valid := io.enq.fire 3868882eb68SXin Tian 3878882eb68SXin Tian tweak_enc_module.io.tweak_enc_resp.ready := tweak_table.io.write.ready // always true 3888882eb68SXin Tian tweak_enc_module.io.tweak_enc_req.bits.tweak := tweak_in 3898882eb68SXin Tian tweak_enc_module.io.tweak_enc_req.bits.addr_in := io.enq.bits.addr 3908882eb68SXin Tian tweak_enc_module.io.tweak_enc_req.bits.len_in := io.enq.bits.len 3918882eb68SXin Tian tweak_enc_module.io.tweak_enc_req.bits.id_in := io.enq.bits.id 3928882eb68SXin Tian tweak_enc_module.io.tweak_enc_req.bits.tweak_round_keys := io.tweak_round_keys 3938882eb68SXin Tian tweak_enc_module.io.tweak_enc_req.valid := io.enq.valid && io.dec_mode && io.memenc_enable 3948882eb68SXin Tian 3958882eb68SXin Tian io.enq.ready := tweak_enc_module.io.tweak_enc_req.ready 3968882eb68SXin Tian 3978882eb68SXin Tian // write signal in tweak table 3988882eb68SXin Tian tweak_table.io.write.valid := tweak_enc_module.io.tweak_enc_resp.valid 3998882eb68SXin Tian tweak_table.io.write.bits.id := tweak_enc_module.io.tweak_enc_resp.bits.id_out 4008882eb68SXin Tian tweak_table.io.write.bits.addr := tweak_enc_module.io.tweak_enc_resp.bits.addr_out 4018882eb68SXin Tian tweak_table.io.write.bits.len := tweak_enc_module.io.tweak_enc_resp.bits.len_out 4028882eb68SXin Tian tweak_table.io.write.bits.tweak_encrpty := tweak_enc_module.io.tweak_enc_resp.bits.tweak_encrpty 4038882eb68SXin Tian 4048882eb68SXin Tian // read signal in tweak table 4058882eb68SXin Tian tweak_table.io.req.valid := io.req.valid 4068882eb68SXin Tian tweak_table.io.resp.ready := io.resp.ready 4078882eb68SXin Tian 4088882eb68SXin Tian tweak_table.io.req.bits.read_id := io.req.bits.id 4098882eb68SXin Tian 4108882eb68SXin Tian val tweak_encrpty = tweak_table.io.resp.bits.read_tweak 4118882eb68SXin Tian val tweak_counter = tweak_table.io.resp.bits.read_sel_counter 4128882eb68SXin Tian val keyid = tweak_table.io.resp.bits.read_keyid 4138882eb68SXin Tian 4148882eb68SXin Tian tweak_table.io.r_mode.id := io.dec_r.id 4158882eb68SXin Tian val mode = tweak_table.io.r_mode.dec_mode 4168882eb68SXin Tian io.dec_r.mode := mode 4178882eb68SXin Tian 4188882eb68SXin Tian tweak_gf128.io.tweak_in := tweak_encrpty 4198882eb68SXin Tian io.resp.bits.tweak := Mux(tweak_counter, tweak_gf128.io.tweak_out(511, 256), tweak_gf128.io.tweak_out(255, 0)) 4208882eb68SXin Tian io.resp.bits.keyid := keyid 4218882eb68SXin Tian io.resp.valid := tweak_table.io.resp.valid 4228882eb68SXin Tian io.req.ready := tweak_table.io.req.ready 4238882eb68SXin Tian 4248882eb68SXin Tian} 4258882eb68SXin Tian 4268882eb68SXin Tianclass AXI4R_KT(opt:Boolean)(implicit val p: Parameters) extends Bundle with Memconsts 4278882eb68SXin Tian{ 4288882eb68SXin Tian val edgeUse = if (opt) MemcedgeIn else MemcedgeOut 4298882eb68SXin Tian val axi4 = new AXI4BundleR(edgeUse.bundle) 4308882eb68SXin Tian val keyid = UInt(KeyIDBits.W) 4318882eb68SXin Tian val tweak = UInt(edgeUse.bundle.dataBits.W) 4328882eb68SXin Tian} 4338882eb68SXin Tian 4348882eb68SXin Tianclass AXI4ReadMachine(implicit p: Parameters) extends MemEncryptModule 4358882eb68SXin Tian{ 4368882eb68SXin Tian val io = IO(new Bundle { 4378882eb68SXin Tian val in_r = Flipped(Irrevocable(new AXI4BundleR(MemcedgeOut.bundle))) 4388882eb68SXin Tian val kt_req = DecoupledIO(new Bundle { 4398882eb68SXin Tian val id = UInt(MemcedgeOut.bundle.idBits.W) 4408882eb68SXin Tian }) 4418882eb68SXin Tian val in_kt = Flipped(DecoupledIO(new Bundle { 4428882eb68SXin Tian val keyid = UInt(KeyIDBits.W) 4438882eb68SXin Tian val tweak = UInt(MemcedgeOut.bundle.dataBits.W) 4448882eb68SXin Tian })) 4458882eb68SXin Tian val out_r = DecoupledIO(new AXI4R_KT(false)) 4468882eb68SXin Tian }) 4478882eb68SXin Tian val s1_r_val = RegInit(false.B) 4488882eb68SXin Tian val s1_r_req = RegEnable(io.in_r.bits, io.in_r.fire) 4498882eb68SXin Tian val s1_r_out_rdy = Wire(Bool()) 4508882eb68SXin Tian 4518882eb68SXin Tian val s2_r_val = RegInit(false.B) 4528882eb68SXin Tian val s2_r_in_rdy = Wire(Bool()) 4538882eb68SXin Tian val s2_r_req = RegEnable(s1_r_req, s1_r_val && s2_r_in_rdy) 4548882eb68SXin Tian 4558882eb68SXin Tian // ---------------- 4568882eb68SXin Tian // s0 stage 4578882eb68SXin Tian // ---------------- 4588882eb68SXin Tian io.in_r.ready := !s1_r_val || (s1_r_val && s1_r_out_rdy) 4598882eb68SXin Tian 4608882eb68SXin Tian // ---------------- 4618882eb68SXin Tian // s1 stage 4628882eb68SXin Tian // ---------------- 4638882eb68SXin Tian when(io.in_r.fire) { 4648882eb68SXin Tian s1_r_val := true.B 4658882eb68SXin Tian }.elsewhen(s1_r_val && s1_r_out_rdy) { 4668882eb68SXin Tian s1_r_val := false.B 4678882eb68SXin Tian }.otherwise { 4688882eb68SXin Tian s1_r_val := s1_r_val 4698882eb68SXin Tian } 4708882eb68SXin Tian 4718882eb68SXin Tian s1_r_out_rdy := s2_r_in_rdy && io.kt_req.ready 4728882eb68SXin Tian io.kt_req.valid := s1_r_val && s2_r_in_rdy 4738882eb68SXin Tian io.kt_req.bits.id := s1_r_req.id 4748882eb68SXin Tian 4758882eb68SXin Tian // ---------------- 4768882eb68SXin Tian // s2 stage 4778882eb68SXin Tian // ---------------- 4788882eb68SXin Tian when(s1_r_val && s1_r_out_rdy) { 4798882eb68SXin Tian s2_r_val := true.B 4808882eb68SXin Tian }.elsewhen(s2_r_val && io.out_r.fire) { 4818882eb68SXin Tian s2_r_val := false.B 4828882eb68SXin Tian }.otherwise { 4838882eb68SXin Tian s2_r_val := s2_r_val 4848882eb68SXin Tian } 4858882eb68SXin Tian s2_r_in_rdy := !s2_r_val || io.out_r.fire 4868882eb68SXin Tian 4878882eb68SXin Tian io.in_kt.ready := io.out_r.fire 4888882eb68SXin Tian 4898882eb68SXin Tian io.out_r.valid := s2_r_val && io.in_kt.valid 4908882eb68SXin Tian io.out_r.bits.axi4 := s2_r_req 4918882eb68SXin Tian io.out_r.bits.keyid := io.in_kt.bits.keyid 4928882eb68SXin Tian io.out_r.bits.tweak := io.in_kt.bits.tweak 4938882eb68SXin Tian} 4948882eb68SXin Tian 4958882eb68SXin Tianclass RdataDecrptyPipe(implicit p: Parameters) extends MemEncryptModule 4968882eb68SXin Tian{ 4978882eb68SXin Tian val io = IO(new Bundle { 4988882eb68SXin Tian val in_r = Flipped(DecoupledIO(new AXI4R_KT(false))) 4998882eb68SXin Tian val out_r = Irrevocable(new AXI4BundleR(MemcedgeOut.bundle)) 5008882eb68SXin Tian val dec_keyids = Output(Vec(MemencPipes, UInt(KeyIDBits.W))) 5018882eb68SXin Tian val dec_round_keys = Input(Vec(MemencPipes, UInt((32*32/MemencPipes).W))) 5028882eb68SXin Tian }) 5038882eb68SXin Tian 5048882eb68SXin Tian val reg_encdec_result_0 = Reg(Vec(MemencPipes, UInt(128.W))) 5058882eb68SXin Tian val reg_encdec_result_1 = Reg(Vec(MemencPipes, UInt(128.W))) 5068882eb68SXin Tian val reg_axi4_other_result = Reg(Vec(MemencPipes, new AXI4BundleRWithoutData(MemcedgeOut.bundle))) 5078882eb68SXin Tian val reg_tweak_result_0 = Reg(Vec(MemencPipes, UInt(128.W))) 5088882eb68SXin Tian val reg_tweak_result_1 = Reg(Vec(MemencPipes, UInt(128.W))) 5098882eb68SXin Tian val reg_keyid = Reg(Vec(MemencPipes, UInt(KeyIDBits.W))) 5108882eb68SXin Tian val reg_encdec_valid = RegInit(VecInit(Seq.fill(MemencPipes)(false.B))) 5118882eb68SXin Tian val wire_ready_result = WireInit(VecInit(Seq.fill(MemencPipes)(false.B))) 5128882eb68SXin Tian 5138882eb68SXin Tian 5148882eb68SXin Tian val wire_axi4_other = Wire(new AXI4BundleRWithoutData(MemcedgeOut.bundle)) 5158882eb68SXin Tian wire_axi4_other.id := io.in_r.bits.axi4.id 5168882eb68SXin Tian wire_axi4_other.resp := io.in_r.bits.axi4.resp 5178882eb68SXin Tian wire_axi4_other.user := io.in_r.bits.axi4.user 5188882eb68SXin Tian wire_axi4_other.echo := io.in_r.bits.axi4.echo 5198882eb68SXin Tian wire_axi4_other.last := io.in_r.bits.axi4.last 5208882eb68SXin Tian 5218882eb68SXin Tian val pipes_first_data_0 = Wire(UInt(128.W)) 5228882eb68SXin Tian val pipes_first_data_1 = Wire(UInt(128.W)) 5238882eb68SXin Tian 5248882eb68SXin Tian if (HasDelayNoencryption) { 5258882eb68SXin Tian pipes_first_data_0 := io.in_r.bits.axi4.data(127,0) 5268882eb68SXin Tian pipes_first_data_1 := io.in_r.bits.axi4.data(255,128) 5278882eb68SXin Tian } else { 5288882eb68SXin Tian pipes_first_data_0 := io.in_r.bits.axi4.data(127,0) ^ io.in_r.bits.tweak(127, 0) 5298882eb68SXin Tian pipes_first_data_1 := io.in_r.bits.axi4.data(255,128) ^ io.in_r.bits.tweak(255,128) 5308882eb68SXin Tian } 5318882eb68SXin Tian def configureModule(flag: Boolean, i: Int, keyId: UInt, dataIn: UInt, tweakIn: UInt, axi4In: AXI4BundleRWithoutData, roundKeys: UInt): OnePipeDecBase = { 5328882eb68SXin Tian 5338882eb68SXin Tian when(wire_ready_result(i) && (if (i == 0) io.in_r.valid else reg_encdec_valid(i-1))) { 5348882eb68SXin Tian reg_encdec_valid(i) := true.B 5358882eb68SXin Tian }.elsewhen(reg_encdec_valid(i) && (if (i == MemencPipes - 1) io.out_r.ready else wire_ready_result(i+1))) { 5368882eb68SXin Tian reg_encdec_valid(i) := false.B 5378882eb68SXin Tian }.otherwise { 5388882eb68SXin Tian reg_encdec_valid(i) := reg_encdec_valid(i) 5398882eb68SXin Tian } 5408882eb68SXin Tian 5418882eb68SXin Tian wire_ready_result(i) := !reg_encdec_valid(i) || (reg_encdec_valid(i) && (if (i == MemencPipes - 1) io.out_r.ready else wire_ready_result(i+1))) 5428882eb68SXin Tian 5438882eb68SXin Tian val module: OnePipeDecBase = if (HasDelayNoencryption) Module(new OnePipeForDecNoDec()) else Module(new OnePipeForDec()) 5448882eb68SXin Tian module.io.onepipe_in.keyid := keyId 5458882eb68SXin Tian module.io.onepipe_in.data_in := dataIn 5468882eb68SXin Tian module.io.onepipe_in.tweak_in := tweakIn 5478882eb68SXin Tian module.io.onepipe_in.axi4_other := axi4In 5488882eb68SXin Tian for (i <- 0 until 32/MemencPipes) { 5498882eb68SXin Tian module.io.onepipe_in.round_key_in(i) := roundKeys(i * 32 + 31, i * 32) 5508882eb68SXin Tian } 5518882eb68SXin Tian when((if (i == 0) io.in_r.valid else reg_encdec_valid(i-1)) && wire_ready_result(i)) { 5528882eb68SXin Tian if (flag) { 5538882eb68SXin Tian reg_encdec_result_0(i) := module.io.onepipe_out.result_out 5548882eb68SXin Tian reg_tweak_result_0(i) := module.io.onepipe_out.tweak_out 5558882eb68SXin Tian reg_axi4_other_result(i) := module.io.onepipe_out.axi4_other_out 5568882eb68SXin Tian reg_keyid(i) := module.io.onepipe_out.keyid_out 5578882eb68SXin Tian } else { 5588882eb68SXin Tian reg_encdec_result_1(i) := module.io.onepipe_out.result_out 5598882eb68SXin Tian reg_tweak_result_1(i) := module.io.onepipe_out.tweak_out 5608882eb68SXin Tian } 5618882eb68SXin Tian } 5628882eb68SXin Tian io.dec_keyids(i) := module.io.onepipe_out.keyid_out 5638882eb68SXin Tian module 5648882eb68SXin Tian } 5658882eb68SXin Tian val modules_0 = (0 until MemencPipes).map { i => 5668882eb68SXin Tian if (i == 0) { 5678882eb68SXin Tian configureModule(true, i, io.in_r.bits.keyid, pipes_first_data_0, io.in_r.bits.tweak(127, 0), wire_axi4_other, io.dec_round_keys(i)) 5688882eb68SXin Tian } else { 5698882eb68SXin Tian configureModule(true, i, reg_keyid(i-1), reg_encdec_result_0(i-1), reg_tweak_result_0(i-1), reg_axi4_other_result(i-1), io.dec_round_keys(i)) 5708882eb68SXin Tian } 5718882eb68SXin Tian } 5728882eb68SXin Tian 5738882eb68SXin Tian val modules_1 = (0 until MemencPipes).map { i => 5748882eb68SXin Tian if (i == 0) { 5758882eb68SXin Tian configureModule(false, i, io.in_r.bits.keyid, pipes_first_data_1, io.in_r.bits.tweak(255,128), wire_axi4_other, io.dec_round_keys(i)) 5768882eb68SXin Tian } else { 5778882eb68SXin Tian configureModule(false, i, reg_keyid(i-1),reg_encdec_result_1(i-1), reg_tweak_result_1(i-1), reg_axi4_other_result(i-1), io.dec_round_keys(i)) 5788882eb68SXin Tian } 5798882eb68SXin Tian } 5808882eb68SXin Tian if (HasDelayNoencryption) { 5818882eb68SXin Tian io.out_r.bits.data := Cat(reg_encdec_result_1.last, reg_encdec_result_0.last) 5828882eb68SXin Tian } else { 5838882eb68SXin Tian val enc_0_out = Cat( 5848882eb68SXin Tian reg_encdec_result_0.last(31, 0), 5858882eb68SXin Tian reg_encdec_result_0.last(63, 32), 5868882eb68SXin Tian reg_encdec_result_0.last(95, 64), 5878882eb68SXin Tian reg_encdec_result_0.last(127, 96) 5888882eb68SXin Tian ) 5898882eb68SXin Tian val enc_1_out = Cat( 5908882eb68SXin Tian reg_encdec_result_1.last(31, 0), 5918882eb68SXin Tian reg_encdec_result_1.last(63, 32), 5928882eb68SXin Tian reg_encdec_result_1.last(95, 64), 5938882eb68SXin Tian reg_encdec_result_1.last(127, 96) 5948882eb68SXin Tian ) 5958882eb68SXin Tian io.out_r.bits.data := Cat(enc_1_out ^ reg_tweak_result_1.last, enc_0_out ^ reg_tweak_result_0.last) 5968882eb68SXin Tian } 5978882eb68SXin Tian 5988882eb68SXin Tian io.out_r.bits.id := reg_axi4_other_result.last.id 5998882eb68SXin Tian io.out_r.bits.resp := reg_axi4_other_result.last.resp 6008882eb68SXin Tian io.out_r.bits.user := reg_axi4_other_result.last.user 6018882eb68SXin Tian io.out_r.bits.echo := reg_axi4_other_result.last.echo 6028882eb68SXin Tian io.out_r.bits.last := reg_axi4_other_result.last.last 6038882eb68SXin Tian io.out_r.valid := reg_encdec_valid.last 6048882eb68SXin Tian io.in_r.ready := wire_ready_result(0) 6058882eb68SXin Tian 6068882eb68SXin Tian} 6078882eb68SXin Tian 6088882eb68SXin Tianclass RdataRoute(implicit p: Parameters) extends MemEncryptModule 6098882eb68SXin Tian{ 6108882eb68SXin Tian val io = IO(new Bundle { 6118882eb68SXin Tian val in_r = Flipped(Irrevocable(new AXI4BundleR(MemcedgeOut.bundle))) 6128882eb68SXin Tian val out_r0 = Irrevocable(new AXI4BundleR(MemcedgeIn.bundle)) 6138882eb68SXin Tian val out_r1 = Irrevocable(new AXI4BundleR(MemcedgeIn.bundle)) 6148882eb68SXin Tian }) 6158882eb68SXin Tian 6168882eb68SXin Tian val r_sel = io.in_r.bits.id(MemcedgeOut.bundle.idBits - 1).asBool 6178882eb68SXin Tian 6188882eb68SXin Tian io.out_r0.bits <> io.in_r.bits 6198882eb68SXin Tian io.out_r1.bits <> io.in_r.bits 6208882eb68SXin Tian 6218882eb68SXin Tian io.out_r0.valid := io.in_r.valid && !r_sel 6228882eb68SXin Tian io.out_r1.valid := io.in_r.valid && r_sel 6238882eb68SXin Tian io.in_r.ready := Mux(r_sel, io.out_r1.ready, io.out_r0.ready) 6248882eb68SXin Tian} 6258882eb68SXin Tian 6268882eb68SXin Tianclass MemEncryptCSR(implicit p: Parameters) extends MemEncryptModule 6278882eb68SXin Tian{ 6288882eb68SXin Tian val io = IO(new Bundle { 6298882eb68SXin Tian val en = Input(Bool()) 6308882eb68SXin Tian val wmode = Input(Bool()) 6318882eb68SXin Tian val addr = Input(UInt(12.W)) 6328882eb68SXin Tian val wdata = Input(UInt(64.W)) 6338882eb68SXin Tian val wmask = Input(UInt(8.W)) 6348882eb68SXin Tian val rdata = Output(UInt(64.W)) // get rdata next cycle after en 6358882eb68SXin Tian val memenc_enable = Output(Bool()) 6368882eb68SXin Tian val keyextend_req = DecoupledIO(new Bundle { 6378882eb68SXin Tian val key = UInt(128.W) 6388882eb68SXin Tian val keyid = UInt(KeyIDBits.W) 6398882eb68SXin Tian val enc_mode = Bool() // 1:this keyid open enc 0:this keyid close enc 6408882eb68SXin Tian val tweak_flage = Bool() // 1:extend tweak key 0:extend keyid key 6418882eb68SXin Tian }) 6428882eb68SXin Tian val randomio = new Bundle { 6438882eb68SXin Tian val random_req = Output(Bool()) 6448882eb68SXin Tian val random_val = Input(Bool()) 6458882eb68SXin Tian val random_data = Input(Bool()) 6468882eb68SXin Tian } 6478882eb68SXin Tian }) 6488882eb68SXin Tian // CSR 6498882eb68SXin Tian val key_id = RegInit(0.U(5.W)) // [4:0] 6508882eb68SXin Tian val mode = RegInit(0.U(2.W)) // [6:5] 6518882eb68SXin Tian val tweak_flage = RegInit(0.U(1.W)) // [7] 6528882eb68SXin Tian val memenc_enable = if (HasDelayNoencryption) RegInit(true.B) else RegInit(false.B) // [8] 6538882eb68SXin Tian val memenc_enable_lock = RegInit(false.B) 6548882eb68SXin Tian val random_ready_flag = Wire(Bool()) // [32] 6558882eb68SXin Tian val key_expansion_idle = Wire(Bool()) // [33] 6568882eb68SXin Tian val last_req_accepted = RegInit(false.B) // [34] 6578882eb68SXin Tian val cfg_succesd = Wire(Bool()) // [35] 6588882eb68SXin Tian val key_init_req = RegInit(false.B) // [63] 6598882eb68SXin Tian // KEY0&1 6608882eb68SXin Tian val key0 = RegInit(0.U(64.W)) 6618882eb68SXin Tian val key1 = RegInit(0.U(64.W)) 6628882eb68SXin Tian // RelPaddrBitsMap 6638882eb68SXin Tian val relpaddrbitsmap = ~0.U((PAddrBits - KeyIDBits).W) 6648882eb68SXin Tian // KeyIDBitsMap 6658882eb68SXin Tian val keyidbitsmap = ~0.U(PAddrBits.W) - ~0.U((PAddrBits - KeyIDBits).W) 6668882eb68SXin Tian // Version 6678882eb68SXin Tian val memenc_version_p0 = (0x0001).U(16.W) 6688882eb68SXin Tian val memenc_version_p1 = (0x0001).U(16.W) 6698882eb68SXin Tian val memenc_version_p2 = (0x00000002).U(32.W) 6708882eb68SXin Tian val memenc_version = Cat(memenc_version_p0, memenc_version_p1, memenc_version_p2) 6718882eb68SXin Tian 6728882eb68SXin Tian // READ 6738882eb68SXin Tian val rdata_reg = RegInit(0.U(64.W)) 6748882eb68SXin Tian when(io.en && !io.wmode && (io.addr(11,3) === 0.U)) { 6758882eb68SXin Tian rdata_reg := Cat(0.U(28.W), cfg_succesd, last_req_accepted, key_expansion_idle, random_ready_flag, 0.U(23.W), memenc_enable, tweak_flage, mode, key_id) 6768882eb68SXin Tian }.elsewhen(io.en && !io.wmode && (io.addr(11,3) === 3.U)) { 6778882eb68SXin Tian rdata_reg := relpaddrbitsmap 6788882eb68SXin Tian }.elsewhen(io.en && !io.wmode && (io.addr(11,3) === 4.U)) { 6798882eb68SXin Tian rdata_reg := keyidbitsmap 6808882eb68SXin Tian }.elsewhen(io.en && !io.wmode && (io.addr(11,3) === 5.U)) { 6818882eb68SXin Tian rdata_reg := memenc_version 6828882eb68SXin Tian }.otherwise { 6838882eb68SXin Tian rdata_reg := 0.U 6848882eb68SXin Tian } 6858882eb68SXin Tian 6868882eb68SXin Tian io.rdata := rdata_reg 6878882eb68SXin Tian 6888882eb68SXin Tian // WRITE 6898882eb68SXin Tian val wmask_legal = (io.wmask === (0xff).U) 6908882eb68SXin Tian 6918882eb68SXin Tian when(io.en && io.wmode && wmask_legal && (io.addr(11,3) === 0.U)) { 6928882eb68SXin Tian key_id := io.wdata(4,0) 6938882eb68SXin Tian mode := io.wdata(6,5) 6948882eb68SXin Tian tweak_flage := io.wdata(7) 6958882eb68SXin Tian key_init_req := io.wdata(63).asBool 6968882eb68SXin Tian }.otherwise { 6978882eb68SXin Tian key_init_req := false.B 6988882eb68SXin Tian } 6998882eb68SXin Tian when(io.en && io.wmode && wmask_legal && (io.addr(11,3) === 0.U) && (!memenc_enable_lock)) { 7008882eb68SXin Tian memenc_enable := io.wdata(8) 7018882eb68SXin Tian memenc_enable_lock := true.B 7028882eb68SXin Tian } 7038882eb68SXin Tian when(io.en && io.wmode && wmask_legal && (io.addr(11,3) === 1.U)) { 7048882eb68SXin Tian key0 := io.wdata 7058882eb68SXin Tian } 7068882eb68SXin Tian when(io.en && io.wmode && wmask_legal && (io.addr(11,3) === 2.U)) { 7078882eb68SXin Tian key1 := io.wdata 7088882eb68SXin Tian } 7098882eb68SXin Tian io.memenc_enable := memenc_enable 7108882eb68SXin Tian 7118882eb68SXin Tian // RANDOM COLLECT 7128882eb68SXin Tian val random_vec_data = RegInit(0.U(128.W)) 7138882eb68SXin Tian val random_cnt = RegInit(0.U(8.W)) 7148882eb68SXin Tian val random_key_init_done = Wire(Bool()) 7158882eb68SXin Tian io.randomio.random_req := random_cnt =/= 128.U(8.W) 7168882eb68SXin Tian random_ready_flag := random_cnt === 128.U(8.W) 7178882eb68SXin Tian 7188882eb68SXin Tian when(io.randomio.random_req && io.randomio.random_val) { 7198882eb68SXin Tian random_vec_data := Cat(random_vec_data(127,1), io.randomio.random_data) 7208882eb68SXin Tian } 7218882eb68SXin Tian 7228882eb68SXin Tian when(random_ready_flag && random_key_init_done) { 7238882eb68SXin Tian random_cnt := 0.U 7248882eb68SXin Tian }.elsewhen(io.randomio.random_req && io.randomio.random_val) { 7258882eb68SXin Tian random_cnt := random_cnt + 1.U 7268882eb68SXin Tian } 7278882eb68SXin Tian 7288882eb68SXin Tian // KEY Extend Req 7298882eb68SXin Tian key_expansion_idle := io.keyextend_req.ready 7308882eb68SXin Tian cfg_succesd := io.keyextend_req.ready 7318882eb68SXin Tian 7328882eb68SXin Tian val keyextend_req_valid = RegInit(false.B) 7338882eb68SXin Tian val req_leagl = Wire(Bool()) 7348882eb68SXin Tian req_leagl := (mode =/= 3.U(2.W)) && key_expansion_idle && ((mode =/= 2.U(2.W)) || random_ready_flag) 7358882eb68SXin Tian 7368882eb68SXin Tian when(key_init_req && req_leagl) { 7378882eb68SXin Tian keyextend_req_valid := true.B 7388882eb68SXin Tian }.elsewhen(io.keyextend_req.fire) { 7398882eb68SXin Tian keyextend_req_valid := false.B 7408882eb68SXin Tian }.otherwise { 7418882eb68SXin Tian keyextend_req_valid := keyextend_req_valid 7428882eb68SXin Tian } 7438882eb68SXin Tian 7448882eb68SXin Tian when(key_init_req && req_leagl) { 7458882eb68SXin Tian last_req_accepted := true.B 7468882eb68SXin Tian }.elsewhen(key_init_req) { 7478882eb68SXin Tian last_req_accepted := false.B 7488882eb68SXin Tian }.otherwise { 7498882eb68SXin Tian last_req_accepted := last_req_accepted 7508882eb68SXin Tian } 7518882eb68SXin Tian 7528882eb68SXin Tian random_key_init_done := io.keyextend_req.fire && (mode === 2.U(2.W)) 7538882eb68SXin Tian 7548882eb68SXin Tian io.keyextend_req.valid := keyextend_req_valid 7558882eb68SXin Tian io.keyextend_req.bits.key := Mux(mode === 1.U(2.W), Cat(key1, key0), random_vec_data) 7568882eb68SXin Tian io.keyextend_req.bits.keyid := key_id 7578882eb68SXin Tian io.keyextend_req.bits.enc_mode := mode =/= 0.U(2.W) 7588882eb68SXin Tian io.keyextend_req.bits.tweak_flage := tweak_flage.asBool 7598882eb68SXin Tian} 7608882eb68SXin Tian 7618882eb68SXin Tianclass KeyTableEntry extends Bundle { 7628882eb68SXin Tian val round_key_data = Vec(32, UInt(32.W)) 7638882eb68SXin Tian val encdec_mode = Bool() 7648882eb68SXin Tian} 7658882eb68SXin Tianclass KeyTable(implicit p: Parameters) extends MemEncryptModule { 7668882eb68SXin Tian val io = IO(new Bundle { 7678882eb68SXin Tian val write_req = Input(new Bundle { 7688882eb68SXin Tian val keyid = UInt(KeyIDBits.W) 7698882eb68SXin Tian val keyid_valid = Input(Bool()) 7708882eb68SXin Tian val enc_mode = Input(Bool()) // 1: this keyid open enc, 0: this keyid close enc 7718882eb68SXin Tian val round_id = UInt(5.W) 7728882eb68SXin Tian val data = Input(UInt(32.W)) 7738882eb68SXin Tian }) 7748882eb68SXin Tian 7758882eb68SXin Tian val enc_keyids = Input(Vec(MemencPipes, UInt(KeyIDBits.W))) 7768882eb68SXin Tian val enc_round_keys = Output(Vec(MemencPipes, UInt((32*32/MemencPipes).W))) 7778882eb68SXin Tian val dec_keyids = Input(Vec(MemencPipes, UInt(KeyIDBits.W))) 7788882eb68SXin Tian val dec_round_keys = Output(Vec(MemencPipes, UInt((32*32/MemencPipes).W))) 7798882eb68SXin Tian val dec = new Bundle { 7808882eb68SXin Tian val keyid = Input(UInt(KeyIDBits.W)) // query dec_mode in advance in the AR channel 7818882eb68SXin Tian val mode = Output(Bool()) 7828882eb68SXin Tian } 7838882eb68SXin Tian val enc = new Bundle { 7848882eb68SXin Tian val keyid = Input(UInt(KeyIDBits.W)) // query enc_mode in advance in the AW channel 7858882eb68SXin Tian val mode = Output(Bool()) 7868882eb68SXin Tian } 7878882eb68SXin Tian}) 7888882eb68SXin Tian 7898882eb68SXin Tian val init_entry = Wire(new KeyTableEntry) 7908882eb68SXin Tian init_entry.round_key_data := DontCare // Keep round_key_data as default (uninitialized) 7918882eb68SXin Tian if (HasDelayNoencryption) { 7928882eb68SXin Tian init_entry.encdec_mode := true.B 7938882eb68SXin Tian } else { 7948882eb68SXin Tian init_entry.encdec_mode := false.B 7958882eb68SXin Tian } 7968882eb68SXin Tian val table = RegInit(VecInit(Seq.fill(1 << KeyIDBits)(init_entry))) 7978882eb68SXin Tian val wire_enc_round_keys = Wire(Vec(MemencPipes, UInt((32*32/MemencPipes).W))) 7988882eb68SXin Tian val wire_dec_round_keys = Wire(Vec(MemencPipes, UInt((32*32/MemencPipes).W))) 7998882eb68SXin Tian 8008882eb68SXin Tian // write and updata mode 8018882eb68SXin Tian when(io.write_req.keyid_valid && io.write_req.enc_mode) { 8028882eb68SXin Tian val entry = table(io.write_req.keyid) 8038882eb68SXin Tian entry.encdec_mode := io.write_req.enc_mode 8048882eb68SXin Tian entry.round_key_data(io.write_req.round_id) := io.write_req.data 8058882eb68SXin Tian } 8068882eb68SXin Tian when(io.write_req.keyid_valid && !io.write_req.enc_mode) { 8078882eb68SXin Tian val entry = table(io.write_req.keyid) 8088882eb68SXin Tian entry.encdec_mode := io.write_req.enc_mode 8098882eb68SXin Tian } 8108882eb68SXin Tian 8118882eb68SXin Tian// read logic 8128882eb68SXin Tian for (i <- 0 until MemencPipes) { 8138882eb68SXin Tian val enc_entry = table(io.enc_keyids(i)) 8148882eb68SXin Tian val enc_round_key_parts = VecInit(Seq.fill(32 / MemencPipes)(0.U(32.W))) 8158882eb68SXin Tian for (j <- 0 until (32 / MemencPipes)) { 8168882eb68SXin Tian enc_round_key_parts((32 / MemencPipes) - 1 - j) := enc_entry.round_key_data(i.U * (32 / MemencPipes).U + j.U) 8178882eb68SXin Tian } 8188882eb68SXin Tian wire_enc_round_keys(i) := enc_round_key_parts.reduce(Cat(_, _)) 8198882eb68SXin Tian 8208882eb68SXin Tian val dec_entry = table(io.dec_keyids(i)) 8218882eb68SXin Tian val dec_round_key_parts = VecInit(Seq.fill(32 / MemencPipes)(0.U(32.W))) 8228882eb68SXin Tian for (j <- 0 until (32 / MemencPipes)) { 8238882eb68SXin Tian dec_round_key_parts((32 / MemencPipes) - 1 - j) := dec_entry.round_key_data(31.U - (i.U * (32 / MemencPipes).U + j.U)) 8248882eb68SXin Tian } 8258882eb68SXin Tian wire_dec_round_keys(i) := dec_round_key_parts.reduce(Cat(_, _)) 8268882eb68SXin Tian } 8278882eb68SXin Tian // output read data(round keys, enc/dec_mode, ar_mode, aw_mode) 8288882eb68SXin Tian val dec_mode_entry = table(io.dec.keyid) 8298882eb68SXin Tian io.dec.mode := dec_mode_entry.encdec_mode 8308882eb68SXin Tian 8318882eb68SXin Tian val enc_mode_entry = table(io.enc.keyid) 8328882eb68SXin Tian io.enc.mode := enc_mode_entry.encdec_mode 8338882eb68SXin Tian 8348882eb68SXin Tian io.enc_round_keys := wire_enc_round_keys 8358882eb68SXin Tian io.dec_round_keys := wire_dec_round_keys 8368882eb68SXin Tian 8378882eb68SXin Tian} 8388882eb68SXin Tian 8398882eb68SXin Tianclass KeyExtender(implicit p: Parameters) extends MemEncryptModule{ 8408882eb68SXin Tian val io = IO(new Bundle { 8418882eb68SXin Tian val keyextend_req = Flipped(DecoupledIO(new Bundle { 8428882eb68SXin Tian val key = UInt(128.W) 8438882eb68SXin Tian val keyid = UInt(KeyIDBits.W) 8448882eb68SXin Tian val enc_mode = Bool() // 1:this keyid open enc 0:this keyid close enc 8458882eb68SXin Tian val tweak_flage = Bool() // 1:extend tweak key 0:extend keyid key 8468882eb68SXin Tian })) 8478882eb68SXin Tian val tweak_round_keys = Output(Vec(32, UInt(32.W))) 8488882eb68SXin Tian val enc_keyids = Input(Vec(MemencPipes, UInt(KeyIDBits.W))) 8498882eb68SXin Tian val enc_round_keys = Output(Vec(MemencPipes, UInt((32*32/MemencPipes).W))) 8508882eb68SXin Tian val dec_keyids = Input(Vec(MemencPipes, UInt(KeyIDBits.W))) 8518882eb68SXin Tian val dec_round_keys = Output(Vec(MemencPipes, UInt((32*32/MemencPipes).W))) 8528882eb68SXin Tian val dec = new Bundle { 8538882eb68SXin Tian val keyid = Input(UInt(KeyIDBits.W)) // query dec_mode in advance in the AR channel 8548882eb68SXin Tian val mode = Output(Bool()) 8558882eb68SXin Tian } 8568882eb68SXin Tian val enc = new Bundle { 8578882eb68SXin Tian val keyid = Input(UInt(KeyIDBits.W)) // query enc_mode in advance in the AW channel 8588882eb68SXin Tian val mode = Output(Bool()) 8598882eb68SXin Tian } 8608882eb68SXin Tian }) 8618882eb68SXin Tian 8628882eb68SXin Tian val idle :: keyExpansion :: Nil = Enum(2) 8638882eb68SXin Tian val current = RegInit(idle) 8648882eb68SXin Tian val next = WireDefault(idle) 8658882eb68SXin Tian current := next 8668882eb68SXin Tian 8678882eb68SXin Tian val count_round = RegInit(0.U(5.W)) 8688882eb68SXin Tian val reg_count_round = RegNext(count_round) 8698882eb68SXin Tian val reg_user_key = RegInit(0.U(128.W)) 8708882eb68SXin Tian val data_for_round = Wire(UInt(128.W)) 8718882eb68SXin Tian val data_after_round = Wire(UInt(128.W)) 8728882eb68SXin Tian val reg_data_after_round = RegInit(0.U(128.W)) 8738882eb68SXin Tian val key_exp_finished_out = RegInit(1.U) 8748882eb68SXin Tian val reg_key_valid = RegNext(io.keyextend_req.valid, false.B) 8758882eb68SXin Tian val reg_tweak_round_keys = Reg(Vec(32, UInt(32.W))) 8768882eb68SXin Tian 8778882eb68SXin Tian 8788882eb68SXin Tian switch(current) { 8798882eb68SXin Tian is(idle) { 8808882eb68SXin Tian when(!reg_key_valid && io.keyextend_req.valid && io.keyextend_req.bits.enc_mode) { 8818882eb68SXin Tian next := keyExpansion 8828882eb68SXin Tian } 8838882eb68SXin Tian } 8848882eb68SXin Tian is(keyExpansion) { 8858882eb68SXin Tian when(reg_count_round === 31.U) { 8868882eb68SXin Tian next := idle 8878882eb68SXin Tian }.otherwise { 8888882eb68SXin Tian next := keyExpansion 8898882eb68SXin Tian } 8908882eb68SXin Tian } 8918882eb68SXin Tian } 8928882eb68SXin Tian 8938882eb68SXin Tian when(next === keyExpansion) { 8948882eb68SXin Tian count_round := count_round + 1.U 8958882eb68SXin Tian }.otherwise { 8968882eb68SXin Tian count_round := 0.U 8978882eb68SXin Tian } 8988882eb68SXin Tian 8998882eb68SXin Tian when(!reg_key_valid && io.keyextend_req.valid && io.keyextend_req.bits.enc_mode) { 9008882eb68SXin Tian reg_user_key := io.keyextend_req.bits.key 9018882eb68SXin Tian } 9028882eb68SXin Tian 9038882eb68SXin Tian when(current === keyExpansion && next === idle) { 9048882eb68SXin Tian key_exp_finished_out := true.B 9058882eb68SXin Tian }.elsewhen(io.keyextend_req.valid && io.keyextend_req.bits.enc_mode) { 9068882eb68SXin Tian key_exp_finished_out := false.B 9078882eb68SXin Tian } 9088882eb68SXin Tian io.keyextend_req.ready := key_exp_finished_out 9098882eb68SXin Tian 9108882eb68SXin Tian // Data for round calculation 9118882eb68SXin Tian data_for_round := Mux(reg_count_round =/= 0.U, reg_data_after_round, reg_user_key) 9128882eb68SXin Tian val cki = Module(new GetCKI) 9138882eb68SXin Tian cki.io.countRoundIn := count_round 9148882eb68SXin Tian val one_round = Module(new OneRoundForKeyExp) 9158882eb68SXin Tian one_round.io.countRoundIn := reg_count_round 9168882eb68SXin Tian one_round.io.dataIn := data_for_round 9178882eb68SXin Tian one_round.io.ckParameterIn := cki.io.ckiOut 9188882eb68SXin Tian data_after_round := one_round.io.resultOut 9198882eb68SXin Tian 9208882eb68SXin Tian when(current === keyExpansion) { 9218882eb68SXin Tian reg_data_after_round := data_after_round 9228882eb68SXin Tian } 9238882eb68SXin Tian 9248882eb68SXin Tian val keyTable = Module(new KeyTable()) 9258882eb68SXin Tian keyTable.io.write_req.keyid := io.keyextend_req.bits.keyid 9268882eb68SXin Tian keyTable.io.write_req.enc_mode := io.keyextend_req.bits.enc_mode 9278882eb68SXin Tian keyTable.io.write_req.round_id := reg_count_round 9288882eb68SXin Tian keyTable.io.write_req.data := data_after_round(31, 0) 9298882eb68SXin Tian 9308882eb68SXin Tian keyTable.io.enc_keyids := io.enc_keyids 9318882eb68SXin Tian keyTable.io.dec_keyids := io.dec_keyids 9328882eb68SXin Tian keyTable.io.dec.keyid := io.dec.keyid 9338882eb68SXin Tian keyTable.io.enc.keyid := io.enc.keyid 9348882eb68SXin Tian io.dec.mode := keyTable.io.dec.mode 9358882eb68SXin Tian io.enc.mode := keyTable.io.enc.mode 9368882eb68SXin Tian io.enc_round_keys := keyTable.io.enc_round_keys 9378882eb68SXin Tian io.dec_round_keys := keyTable.io.dec_round_keys 9388882eb68SXin Tian 9398882eb68SXin Tian 9408882eb68SXin Tian when(io.keyextend_req.bits.tweak_flage) { 9418882eb68SXin Tian reg_tweak_round_keys(reg_count_round) := data_after_round(31, 0) 9428882eb68SXin Tian keyTable.io.write_req.keyid_valid := false.B 9438882eb68SXin Tian }.otherwise { 9448882eb68SXin Tian keyTable.io.write_req.keyid_valid := current 9458882eb68SXin Tian } 9468882eb68SXin Tian io.tweak_round_keys := reg_tweak_round_keys 9478882eb68SXin Tian} 9488882eb68SXin Tian 9498882eb68SXin Tianclass AXI4MemEncrypt(address: AddressSet)(implicit p: Parameters) extends LazyModule with Memconsts 9508882eb68SXin Tian{ 9518882eb68SXin Tian require (isPow2(MemencPipes), s"AXI4MemEncrypt: MemencPipes must be a power of two, not $MemencPipes") 9528882eb68SXin Tian require (PAddrBits > KeyIDBits, s"AXI4MemEncrypt: PAddrBits must be greater than KeyIDBits") 9538882eb68SXin Tian 9548882eb68SXin Tian val node = AXI4AdapterNode( 9558882eb68SXin Tian masterFn = { mp => 9568882eb68SXin Tian val new_idbits = log2Ceil(mp.endId) + 1 9578882eb68SXin Tian // Create one new "master" per ID 9588882eb68SXin Tian val masters = Array.tabulate(1 << new_idbits) { i => AXI4MasterParameters( 9598882eb68SXin Tian name = "", 9608882eb68SXin Tian id = IdRange(i, i+1), 9618882eb68SXin Tian aligned = true, 9628882eb68SXin Tian maxFlight = Some(0)) 9638882eb68SXin Tian } 9648882eb68SXin Tian // Accumulate the names of masters we squish 9658882eb68SXin Tian val names = Array.fill(1 << new_idbits) { new scala.collection.mutable.HashSet[String]() } 9668882eb68SXin Tian // Squash the information from original masters into new ID masters 9678882eb68SXin Tian mp.masters.foreach { m => 9688882eb68SXin Tian for (i <- 0 until (1 << new_idbits)) { 9698882eb68SXin Tian val accumulated = masters(i) 9708882eb68SXin Tian names(i) += m.name 9718882eb68SXin Tian masters(i) = accumulated.copy( 9728882eb68SXin Tian aligned = accumulated.aligned && m.aligned, 9738882eb68SXin Tian maxFlight = accumulated.maxFlight.flatMap { o => m.maxFlight.map { n => o+n } }) 9748882eb68SXin Tian } 9758882eb68SXin Tian } 9768882eb68SXin Tian val finalNameStrings = names.map { n => if (n.isEmpty) "(unused)" else n.toList.mkString(", ") } 977*11269ca7STang Haojin mp.copy(masters = masters.toIndexedSeq.zip(finalNameStrings.toIndexedSeq).map { case (m, n) => m.copy(name = n) }) 9788882eb68SXin Tian }, 9798882eb68SXin Tian slaveFn = { sp => sp }) 9808882eb68SXin Tian 9818882eb68SXin Tian val device = new SimpleDevice("mem-encrypt-unit", Seq("iie,memencrypt0")) 9828882eb68SXin Tian val ctrl_node = APBSlaveNode(Seq(APBSlavePortParameters( 9838882eb68SXin Tian Seq(APBSlaveParameters( 9848882eb68SXin Tian address = List(address), 9858882eb68SXin Tian resources = device.reg, 9868882eb68SXin Tian device = Some(device), 9878882eb68SXin Tian regionType = RegionType.IDEMPOTENT)), 9888882eb68SXin Tian beatBytes = 8))) 9898882eb68SXin Tian 9908882eb68SXin Tian lazy val module = new Impl 9918882eb68SXin Tian class Impl extends LazyModuleImp(this) { 9928882eb68SXin Tian val io = IO(new Bundle { 9938882eb68SXin Tian val random_req = Output(Bool()) 9948882eb68SXin Tian val random_val = Input(Bool()) 9958882eb68SXin Tian val random_data = Input(Bool()) 9968882eb68SXin Tian }) 9978882eb68SXin Tian 9988882eb68SXin Tian val en = Wire(Bool()) 9998882eb68SXin Tian val wmode = Wire(Bool()) 10008882eb68SXin Tian val addr = Wire(UInt(12.W)) 10018882eb68SXin Tian val wdata = Wire(UInt(64.W)) 10028882eb68SXin Tian val wmask = Wire(UInt(8.W)) 10038882eb68SXin Tian val rdata = Wire(UInt(64.W)) // get rdata next cycle after en 10048882eb68SXin Tian 10058882eb68SXin Tian (ctrl_node.in) foreach { case (ctrl_in, _) => 10068882eb68SXin Tian en := ctrl_in.psel && !ctrl_in.penable 10078882eb68SXin Tian wmode := ctrl_in.pwrite 10088882eb68SXin Tian addr := ctrl_in.paddr(11, 0) 10098882eb68SXin Tian wdata := ctrl_in.pwdata 10108882eb68SXin Tian wmask := ctrl_in.pstrb 10118882eb68SXin Tian ctrl_in.pready := true.B 10128882eb68SXin Tian ctrl_in.pslverr := false.B 10138882eb68SXin Tian ctrl_in.prdata := rdata 10148882eb68SXin Tian } 10158882eb68SXin Tian 10168882eb68SXin Tian (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => 10178882eb68SXin Tian require (edgeIn.bundle.dataBits == 256, s"AXI4MemEncrypt: edgeIn dataBits must be 256") 10188882eb68SXin Tian require (edgeOut.bundle.dataBits == 256, s"AXI4MemEncrypt: edgeOut dataBits must be 256") 10198882eb68SXin Tian 10208882eb68SXin Tian val memencParams: Parameters = p.alterPartial { 10218882eb68SXin Tian case MemcEdgeInKey => edgeIn 10228882eb68SXin Tian case MemcEdgeOutKey => edgeOut 10238882eb68SXin Tian } 10248882eb68SXin Tian // ------------------------------------- 10258882eb68SXin Tian // MemEncrypt Config and State Registers 10268882eb68SXin Tian // ------------------------------------- 10278882eb68SXin Tian val memenc_enable = Wire(Bool()) 10288882eb68SXin Tian val memencrypt_csr = Module(new MemEncryptCSR()(memencParams)) 10298882eb68SXin Tian memencrypt_csr.io.en := en 10308882eb68SXin Tian memencrypt_csr.io.wmode := wmode 10318882eb68SXin Tian memencrypt_csr.io.addr := addr 10328882eb68SXin Tian memencrypt_csr.io.wdata := wdata 10338882eb68SXin Tian memencrypt_csr.io.wmask := wmask 10348882eb68SXin Tian memenc_enable := memencrypt_csr.io.memenc_enable 10358882eb68SXin Tian rdata := memencrypt_csr.io.rdata 10368882eb68SXin Tian 10378882eb68SXin Tian io.random_req := memencrypt_csr.io.randomio.random_req 10388882eb68SXin Tian memencrypt_csr.io.randomio.random_val := io.random_val 10398882eb68SXin Tian memencrypt_csr.io.randomio.random_data := io.random_data 10408882eb68SXin Tian 10418882eb68SXin Tian // ------------------------------------- 10428882eb68SXin Tian // Key Extender & Round Key Lookup Table 10438882eb68SXin Tian // ------------------------------------- 10448882eb68SXin Tian val key_extender = Module(new KeyExtender()(memencParams)) 10458882eb68SXin Tian key_extender.io.keyextend_req :<>= memencrypt_csr.io.keyextend_req 10468882eb68SXin Tian 10478882eb68SXin Tian // ------------------- 10488882eb68SXin Tian // AXI4 chanel B 10498882eb68SXin Tian // ------------------- 10508882eb68SXin Tian Connectable.waiveUnmatched(in.b, out.b) match { 10518882eb68SXin Tian case (lhs, rhs) => lhs.squeezeAll :<>= rhs.squeezeAll 10528882eb68SXin Tian } 10538882eb68SXin Tian 10548882eb68SXin Tian val write_route = Module(new WriteChanelRoute()(memencParams)) 10558882eb68SXin Tian val aw_tweakenc = Module(new TweakEncrptyQueue()(memencParams)) 10568882eb68SXin Tian val waddr_q = Module(new IrrevocableQueue(chiselTypeOf(in.aw.bits), entries = MemencPipes+1)) 10578882eb68SXin Tian val wdata_q = Module(new IrrevocableQueue(chiselTypeOf(in.w.bits), entries = MemencPipes+1)) 10588882eb68SXin Tian val write_machine = Module(new AXI4WriteMachine()(memencParams)) 10598882eb68SXin Tian val axi4w_kt_q = Module(new Queue(new AXI4W_KT(false)(memencParams), entries = 2, flow = true)) 10608882eb68SXin Tian val wdata_encpipe = Module(new WdataEncrptyPipe()(memencParams)) 10618882eb68SXin Tian val write_arb = Module(new WriteChanelArbiter()(memencParams)) 10628882eb68SXin Tian 10638882eb68SXin Tian // ------------------- 10648882eb68SXin Tian // AXI4 Write Route 10658882eb68SXin Tian // Unencrypt & Encrypt 10668882eb68SXin Tian // ------------------- 10678882eb68SXin Tian write_route.io.memenc_enable := memenc_enable 10688882eb68SXin Tian key_extender.io.enc.keyid := write_route.io.enc_keyid 10698882eb68SXin Tian write_route.io.enc_mode := key_extender.io.enc.mode 10708882eb68SXin Tian 10718882eb68SXin Tian write_route.io.in.aw :<>= in.aw 10728882eb68SXin Tian write_route.io.in.w :<>= in.w 10738882eb68SXin Tian 10748882eb68SXin Tian val unenc_aw = write_route.io.out0.aw 10758882eb68SXin Tian val unenc_w = write_route.io.out0.w 10768882eb68SXin Tian val pre_enc_aw = write_route.io.out1.aw 10778882eb68SXin Tian val pre_enc_w = write_route.io.out1.w 10788882eb68SXin Tian 10798882eb68SXin Tian // ------------------- 10808882eb68SXin Tian // AXI4 chanel AW 10818882eb68SXin Tian // ------------------- 10828882eb68SXin Tian pre_enc_aw.ready := waddr_q.io.enq.ready && aw_tweakenc.io.enq.ready 10838882eb68SXin Tian waddr_q.io.enq.valid := pre_enc_aw.valid && aw_tweakenc.io.enq.ready 10848882eb68SXin Tian aw_tweakenc.io.enq.valid := pre_enc_aw.valid && waddr_q.io.enq.ready 10858882eb68SXin Tian 10868882eb68SXin Tian waddr_q.io.enq.bits := pre_enc_aw.bits 10878882eb68SXin Tian waddr_q.io.enq.bits.addr := pre_enc_aw.bits.addr(PAddrBits-KeyIDBits-1, 0) 10888882eb68SXin Tian aw_tweakenc.io.enq.bits.addr := pre_enc_aw.bits.addr 10898882eb68SXin Tian aw_tweakenc.io.enq.bits.len := pre_enc_aw.bits.len 10908882eb68SXin Tian aw_tweakenc.io.tweak_round_keys := key_extender.io.tweak_round_keys 10918882eb68SXin Tian 10928882eb68SXin Tian // ------------------- 10938882eb68SXin Tian // AXI4 chanel W 10948882eb68SXin Tian // ------------------- 10958882eb68SXin Tian wdata_q.io.enq :<>= pre_enc_w 10968882eb68SXin Tian write_machine.io.in_w :<>= wdata_q.io.deq 10978882eb68SXin Tian write_machine.io.in_kt :<>= aw_tweakenc.io.deq 10988882eb68SXin Tian axi4w_kt_q.io.enq :<>= write_machine.io.out_w 10998882eb68SXin Tian wdata_encpipe.io.in_w :<>= axi4w_kt_q.io.deq 11008882eb68SXin Tian key_extender.io.enc_keyids := wdata_encpipe.io.enc_keyids 11018882eb68SXin Tian wdata_encpipe.io.enc_round_keys := key_extender.io.enc_round_keys 11028882eb68SXin Tian 11038882eb68SXin Tian // ------------------- 11048882eb68SXin Tian // AXI4 Write Arbiter 11058882eb68SXin Tian // Unencrypt & Encrypt 11068882eb68SXin Tian // ------------------- 11078882eb68SXin Tian write_arb.io.in0.aw :<>= unenc_aw 11088882eb68SXin Tian write_arb.io.in0.aw.bits.addr := unenc_aw.bits.addr(PAddrBits-KeyIDBits-1, 0) 11098882eb68SXin Tian write_arb.io.in0.w :<>= unenc_w 11108882eb68SXin Tian 11118882eb68SXin Tian write_arb.io.in1.aw.valid := waddr_q.io.deq.valid && (waddr_q.io.deq.bits.len =/=0.U || write_machine.io.uncache_en) 11128882eb68SXin Tian waddr_q.io.deq.ready := write_arb.io.in1.aw.ready && (waddr_q.io.deq.bits.len =/=0.U || write_machine.io.uncache_en) 11138882eb68SXin Tian write_machine.io.uncache_commit := write_arb.io.in1.aw.fire 11148882eb68SXin Tian write_arb.io.in1.aw.bits := waddr_q.io.deq.bits 11158882eb68SXin Tian write_arb.io.in1.w :<>= wdata_encpipe.io.out_w 11168882eb68SXin Tian 11178882eb68SXin Tian out.aw :<>= write_arb.io.out.aw 11188882eb68SXin Tian out.w :<>= write_arb.io.out.w 11198882eb68SXin Tian 11208882eb68SXin Tian val ar_arb = Module(new IrrevocableArbiter(chiselTypeOf(out.ar.bits), 2)) 11218882eb68SXin Tian val ar_tweakenc = Module(new TweakEncrptyTable()(memencParams)) 11228882eb68SXin Tian val read_machine = Module(new AXI4ReadMachine()(memencParams)) 11238882eb68SXin Tian val axi4r_kt_q = Module(new Queue(new AXI4R_KT(false)(memencParams), entries = 2, flow = true)) 11248882eb68SXin Tian val pre_dec_rdata_route = Module(new RdataChanelRoute()(memencParams)) 11258882eb68SXin Tian val rdata_decpipe = Module(new RdataDecrptyPipe()(memencParams)) 11268882eb68SXin Tian val r_arb = Module(new IrrevocableArbiter(chiselTypeOf(out.r.bits), 2)) 11278882eb68SXin Tian val post_dec_rdata_route = Module(new RdataRoute()(memencParams)) 11288882eb68SXin Tian 11298882eb68SXin Tian // ------------------- 11308882eb68SXin Tian // AXI4 chanel AR 11318882eb68SXin Tian // ------------------- 11328882eb68SXin Tian ar_arb.io.in(0) :<>= write_machine.io.out_ar 11338882eb68SXin Tian // DecoupledIO connect IrrevocableIO 11348882eb68SXin Tian ar_arb.io.in(1).valid := in.ar.valid 11358882eb68SXin Tian ar_arb.io.in(1).bits := in.ar.bits 11368882eb68SXin Tian in.ar.ready := ar_arb.io.in(1).ready 11378882eb68SXin Tian 11388882eb68SXin Tian ar_arb.io.out.ready := out.ar.ready && ar_tweakenc.io.enq.ready 11398882eb68SXin Tian 11408882eb68SXin Tian ar_tweakenc.io.enq.valid := ar_arb.io.out.valid && out.ar.ready 11418882eb68SXin Tian ar_tweakenc.io.enq.bits.addr := ar_arb.io.out.bits.addr 11428882eb68SXin Tian ar_tweakenc.io.enq.bits.len := ar_arb.io.out.bits.len 11438882eb68SXin Tian ar_tweakenc.io.enq.bits.id := ar_arb.io.out.bits.id 11448882eb68SXin Tian ar_tweakenc.io.tweak_round_keys := key_extender.io.tweak_round_keys 11458882eb68SXin Tian ar_tweakenc.io.memenc_enable := memenc_enable 11468882eb68SXin Tian key_extender.io.dec.keyid := ar_tweakenc.io.dec_keyid 11478882eb68SXin Tian ar_tweakenc.io.dec_mode := key_extender.io.dec.mode 11488882eb68SXin Tian 11498882eb68SXin Tian out.ar.valid := ar_arb.io.out.valid && ar_tweakenc.io.enq.ready 11508882eb68SXin Tian out.ar.bits := ar_arb.io.out.bits 11518882eb68SXin Tian out.ar.bits.addr := ar_arb.io.out.bits.addr(PAddrBits-KeyIDBits-1, 0) 11528882eb68SXin Tian 11538882eb68SXin Tian // ------------------- 11548882eb68SXin Tian // AXI4 Rdata Route 11558882eb68SXin Tian // Unencrypt & Encrypt 11568882eb68SXin Tian // ------------------- 11578882eb68SXin Tian pre_dec_rdata_route.io.in_r :<>= out.r 11588882eb68SXin Tian ar_tweakenc.io.dec_r.id := pre_dec_rdata_route.io.dec_rid 11598882eb68SXin Tian pre_dec_rdata_route.io.dec_mode := ar_tweakenc.io.dec_r.mode 11608882eb68SXin Tian 11618882eb68SXin Tian val undec_r = pre_dec_rdata_route.io.out_r0 11628882eb68SXin Tian val pre_dec_r = pre_dec_rdata_route.io.out_r1 11638882eb68SXin Tian 11648882eb68SXin Tian // ------------------- 11658882eb68SXin Tian // AXI4 chanel R 11668882eb68SXin Tian // ------------------- 11678882eb68SXin Tian read_machine.io.in_r :<>= pre_dec_r 11688882eb68SXin Tian ar_tweakenc.io.req :<>= read_machine.io.kt_req 11698882eb68SXin Tian read_machine.io.in_kt :<>= ar_tweakenc.io.resp 11708882eb68SXin Tian axi4r_kt_q.io.enq :<>= read_machine.io.out_r 11718882eb68SXin Tian rdata_decpipe.io.in_r :<>= axi4r_kt_q.io.deq 11728882eb68SXin Tian key_extender.io.dec_keyids := rdata_decpipe.io.dec_keyids 11738882eb68SXin Tian rdata_decpipe.io.dec_round_keys := key_extender.io.dec_round_keys 11748882eb68SXin Tian 11758882eb68SXin Tian // ------------------- 11768882eb68SXin Tian // AXI4 Rdata Arbiter 11778882eb68SXin Tian // Unencrypt & Encrypt 11788882eb68SXin Tian // ------------------- 11798882eb68SXin Tian r_arb.io.in(0) :<>= undec_r 11808882eb68SXin Tian r_arb.io.in(1) :<>= rdata_decpipe.io.out_r 11818882eb68SXin Tian 11828882eb68SXin Tian post_dec_rdata_route.io.in_r :<>= r_arb.io.out 11838882eb68SXin Tian write_machine.io.in_r :<>= post_dec_rdata_route.io.out_r1 11848882eb68SXin Tian in.r :<>= post_dec_rdata_route.io.out_r0 11858882eb68SXin Tian } 11868882eb68SXin Tian } 11878882eb68SXin Tian} 11888882eb68SXin Tian 11898882eb68SXin Tianobject AXI4MemEncrypt 11908882eb68SXin Tian{ 11918882eb68SXin Tian def apply(address: AddressSet)(implicit p: Parameters): AXI4Node = 11928882eb68SXin Tian { 11938882eb68SXin Tian val axi4memenc = LazyModule(new AXI4MemEncrypt(address)) 11948882eb68SXin Tian axi4memenc.node 11958882eb68SXin Tian } 11968882eb68SXin Tian} 1197