├── src ├── exclude │ ├── LSU │ │ └── LSUConfig.scala │ └── IU │ │ ├── Csr │ │ └── Define │ │ │ ├── Exceptions.scala │ │ │ └── Interrupts.scala │ │ ├── Bju │ │ ├── BjuBundle.scala │ │ └── PcFifo.scala │ │ ├── Rbus.scala │ │ ├── IntegeUnit.scala │ │ ├── Alu.scala │ │ ├── Special.scala │ │ └── Cbus.scala ├── main │ ├── scala │ │ ├── Utils │ │ │ ├── Bits │ │ │ │ ├── BinaryConst.scala │ │ │ │ ├── RingShiftLeft.scala │ │ │ │ ├── DropBit.scala │ │ │ │ └── Ext.scala │ │ │ ├── RAMHelper.scala │ │ │ ├── BasicIOType.scala │ │ │ ├── utils.scala │ │ │ ├── CircularQueuePtr.scala │ │ │ └── ParallelMux.scala │ │ ├── ISA │ │ │ ├── Common.scala │ │ │ ├── RV64Diff.scala │ │ │ ├── RV64Pri.scala │ │ │ ├── RV64Zifencei.scala │ │ │ ├── RV64V.scala │ │ │ ├── RV64Zfh.scala │ │ │ ├── RV64D.scala │ │ │ ├── RV64F.scala │ │ │ ├── RV64Zicsr.scala │ │ │ ├── RV64Pseudo.scala │ │ │ ├── RV64M.scala │ │ │ ├── RV64C.scala │ │ │ ├── RV64A.scala │ │ │ └── RV64I.scala │ │ ├── Core │ │ │ ├── IDU │ │ │ │ ├── Opcode │ │ │ │ │ ├── Opcode.scala │ │ │ │ │ ├── OpClass.scala │ │ │ │ │ ├── SpecialOpcode.scala │ │ │ │ │ ├── DivOpcode.scala │ │ │ │ │ ├── BjuOpcode.scala │ │ │ │ │ ├── MulOpcode.scala │ │ │ │ │ ├── AluOpcode.scala │ │ │ │ │ ├── StoreOpcode.scala │ │ │ │ │ └── LoadOpcode.scala │ │ │ │ ├── DecodeTable │ │ │ │ │ ├── DefaultInst.scala │ │ │ │ │ ├── BjuDecodeTable.scala │ │ │ │ │ └── AluDecodeTable.scala │ │ │ │ ├── FuncUnit.scala │ │ │ │ ├── IS │ │ │ │ │ └── VfiqEntry.scala │ │ │ │ ├── IDUBundle.scala │ │ │ │ ├── RF │ │ │ │ │ └── Prf.scala │ │ │ │ └── IQBundle.scala │ │ │ ├── IFU │ │ │ │ ├── RAMHelper.scala │ │ │ │ ├── IPDecode.scala │ │ │ │ ├── BTB.scala │ │ │ │ ├── indBTB.scala │ │ │ │ ├── uBTB.scala │ │ │ │ ├── ct_ifu_icache_refill.scala │ │ │ │ ├── CacheConfig.scala │ │ │ │ ├── prefetch_buffer.scala │ │ │ │ ├── PCGen.scala │ │ │ │ ├── sram_c910.scala │ │ │ │ ├── RAS.scala │ │ │ │ └── icache_predec.scala │ │ │ ├── IU │ │ │ │ ├── MDu │ │ │ │ │ └── MDUbit.scala │ │ │ │ ├── Cp0 │ │ │ │ │ └── Define │ │ │ │ │ │ ├── Exceptions.scala │ │ │ │ │ │ └── Interrupts.scala │ │ │ │ ├── Bju │ │ │ │ │ └── BjuBundle.scala │ │ │ │ ├── Rbus.scala │ │ │ │ ├── Alu.scala │ │ │ │ └── Special.scala │ │ │ ├── RTU │ │ │ │ └── CompareIid.scala │ │ │ ├── LSU │ │ │ │ ├── RotData128.scala │ │ │ │ ├── RotData.scala │ │ │ │ ├── DCache │ │ │ │ │ ├── DCacheSram.scala │ │ │ │ │ └── DCacheTop.scala │ │ │ │ ├── IdFifo8.scala │ │ │ │ ├── StoreExStage │ │ │ │ │ └── StoreEx1.scala │ │ │ │ └── Lq │ │ │ │ │ └── LQ.scala │ │ │ └── SimpleIFU.scala │ │ └── Top │ │ │ └── SimTopIO.scala │ └── resources │ │ ├── gated_clk_cell.v │ │ ├── fpga_ram.v │ │ ├── ct_spsram_512x52.v │ │ ├── ct_spsram_512x54.v │ │ ├── ct_spsram_512x7.v │ │ ├── ct_spsram_2048x32.v │ │ ├── ct_spsram_2048x32_split.v │ │ └── ct_f_spsram_2048x32.v └── test │ └── scala │ ├── Core │ ├── IFU │ │ ├── IFUMain.scala │ │ └── PCfifoMain.scala │ ├── RTU │ │ ├── RobMain.scala │ │ ├── RtuTopMain.scala │ │ ├── PstPregMain.scala │ │ ├── RetireMain.scala │ │ ├── RobRetireMain.scala │ │ ├── RobEntryMain.scala │ │ ├── RobExceptMain.scala │ │ └── PstPregEntryMain.scala │ ├── LSU │ │ ├── BusArbMain.scala │ │ ├── IdFifo8.scala │ │ ├── LSUMain.scala │ │ ├── LQMain.scala │ │ ├── WmbMain.scala │ │ ├── RbMain.scala │ │ ├── BiuRamHelperMain.scala │ │ ├── LQEntryMain.scala │ │ ├── LoadDAMain.scala │ │ ├── LoadWBMain.scala │ │ ├── WmbCeMain.scala │ │ ├── WmbEntryMain.scala │ │ ├── DCacheArbMain.scala │ │ ├── RbEntryMain.scala │ │ └── SqMain.scala │ └── IDU │ │ ├── ISStageMain.scala │ │ ├── RF │ │ ├── PrfMain.scala │ │ └── RFStageMain.scala │ │ ├── IDStageMain.scala │ │ ├── IRStageMain.scala │ │ ├── IS │ │ ├── LsiqMain.scala │ │ ├── SdiqMain.scala │ │ ├── AiqEntryMain.scala │ │ ├── BiqEntryMain.scala │ │ ├── LsiqEntryMain.scala │ │ ├── SdiqEntryMain.scala │ │ ├── DepRegEntryMain.scala │ │ ├── ArithInstQueueMain.scala │ │ └── BiqMain.scala │ │ ├── RenameTableMain.scala │ │ ├── DepRegSrc2EntryMain.scala │ │ └── IDUMain.scala │ └── Top │ └── TopMain.scala ├── project ├── build.properties └── plugins.sbt ├── .gitmodules ├── utils ├── lsu_idu.txt └── IOcvt.py ├── .github └── workflows │ └── test.yml └── README.md /src/exclude/LSU/LSUConfig.scala: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version = 1.6.2 2 | -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | logLevel := Level.Warn 2 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "difftest"] 2 | path = difftest 3 | url = https://github.com/OpenXiangShan/difftest.git 4 | -------------------------------------------------------------------------------- /src/main/scala/Utils/Bits/BinaryConst.scala: -------------------------------------------------------------------------------- 1 | package Utils.Bits 2 | 3 | import chisel3._ 4 | 5 | object BinaryConst { 6 | def T : Bool = true.B 7 | def F : Bool = false.B 8 | } 9 | -------------------------------------------------------------------------------- /src/main/scala/ISA/Common.scala: -------------------------------------------------------------------------------- 1 | package ISA 2 | 3 | trait DecoderBase 4 | trait Decoder32Bits extends DecoderBase 5 | trait Decoder16Bits extends DecoderBase 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/main/scala/Core/IDU/Opcode/Opcode.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU.Opcode 2 | 3 | import chisel3._ 4 | 5 | trait Opcode { 6 | def width = 7 7 | def NOP : UInt = "b0000000".U 8 | } 9 | 10 | object Opcode extends Opcode 11 | -------------------------------------------------------------------------------- /src/main/scala/ISA/RV64Diff.scala: -------------------------------------------------------------------------------- 1 | package ISA 2 | 3 | import chisel3.util.BitPat 4 | 5 | object RV64Diff extends Decoder32Bits { 6 | // Todo: Configurable 7 | def trapInst: BitPat = BitPat("b0000000_00000_00000_000_1101011") 8 | } 9 | -------------------------------------------------------------------------------- /src/main/scala/ISA/RV64Pri.scala: -------------------------------------------------------------------------------- 1 | package ISA 2 | 3 | import chisel3.util.BitPat 4 | 5 | object RV64Pri extends Decoder32Bits { 6 | // Todo: 7 | // mret, sret, wfi 8 | def mret = BitPat("b0011000_?????_?????___000____?????_11100") 9 | } 10 | -------------------------------------------------------------------------------- /src/main/scala/Top/SimTopIO.scala: -------------------------------------------------------------------------------- 1 | package Top 2 | 3 | import chisel3._ 4 | import difftest._ 5 | 6 | class SimTopIO extends Bundle { 7 | val logCtrl = new LogCtrlIO 8 | val perfInfo = new PerfInfoIO 9 | val uart = new UARTIO 10 | } 11 | 12 | -------------------------------------------------------------------------------- /src/main/scala/Core/IDU/Opcode/OpClass.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU.Opcode 2 | 3 | import chisel3._ 4 | 5 | trait OpClass { 6 | def ADDER : UInt = "b00001".U 7 | def SHIFTER : UInt = "b00010".U 8 | def LOGIC : UInt = "b00011".U 9 | def MISC : UInt = "b00100".U 10 | } 11 | -------------------------------------------------------------------------------- /src/main/scala/ISA/RV64Zifencei.scala: -------------------------------------------------------------------------------- 1 | package ISA 2 | 3 | import chisel3.util.BitPat 4 | 5 | object RV64Zifencei extends Decoder32Bits { 6 | // fence |-func7-|-rs2-|-rs1-|-funct3-|--rd-|opcode| 7 | def fence_i = BitPat("b???????_?????_?????___001____?????_00011") 8 | } 9 | -------------------------------------------------------------------------------- /src/test/scala/Core/IFU/IFUMain.scala: -------------------------------------------------------------------------------- 1 | package Core.IFU 2 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 3 | object IFUMain extends App { 4 | (new ChiselStage).execute( 5 | args, 6 | Seq( 7 | ChiselGeneratorAnnotation(() => new IFU) 8 | ) 9 | ) 10 | } -------------------------------------------------------------------------------- /src/test/scala/Core/IFU/PCfifoMain.scala: -------------------------------------------------------------------------------- 1 | package Core.IFU 2 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 3 | object PCfifoMain extends App { 4 | (new ChiselStage).execute( 5 | args, 6 | Seq( 7 | ChiselGeneratorAnnotation(() => new PCfifo) 8 | ) 9 | ) 10 | } -------------------------------------------------------------------------------- /src/test/scala/Top/TopMain.scala: -------------------------------------------------------------------------------- 1 | package Top 2 | 3 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 4 | 5 | object TopMain extends App { 6 | (new ChiselStage).execute( 7 | args, 8 | Seq( 9 | ChiselGeneratorAnnotation(() => new SimTop) 10 | ) 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/Core/RTU/RobMain.scala: -------------------------------------------------------------------------------- 1 | package Core.RTU 2 | 3 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 4 | 5 | object RobMain extends App { 6 | (new ChiselStage).execute( 7 | args, 8 | Seq( 9 | ChiselGeneratorAnnotation(() => new Rob) 10 | ) 11 | ) 12 | } -------------------------------------------------------------------------------- /src/test/scala/Core/LSU/BusArbMain.scala: -------------------------------------------------------------------------------- 1 | package Core.LSU 2 | 3 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 4 | 5 | object BusArbMain extends App { 6 | (new ChiselStage).execute( 7 | args, 8 | Seq( 9 | ChiselGeneratorAnnotation(() => new BusArb) 10 | ) 11 | ) 12 | } -------------------------------------------------------------------------------- /src/test/scala/Core/LSU/IdFifo8.scala: -------------------------------------------------------------------------------- 1 | package Core.LSU 2 | 3 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 4 | 5 | object IdFifo8Main extends App { 6 | (new ChiselStage).execute( 7 | args, 8 | Seq( 9 | ChiselGeneratorAnnotation(() => new IdFifo8) 10 | ) 11 | ) 12 | } -------------------------------------------------------------------------------- /src/test/scala/Core/LSU/LSUMain.scala: -------------------------------------------------------------------------------- 1 | package Core.LSU 2 | 3 | 4 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 5 | 6 | object LSUMain extends App { 7 | (new ChiselStage).execute( 8 | args, 9 | Seq( 10 | ChiselGeneratorAnnotation(() => new LSU) 11 | ) 12 | ) 13 | } -------------------------------------------------------------------------------- /src/test/scala/Core/RTU/RtuTopMain.scala: -------------------------------------------------------------------------------- 1 | package Core.RTU 2 | 3 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 4 | 5 | object RtuTopMain extends App { 6 | (new ChiselStage).execute( 7 | args, 8 | Seq( 9 | ChiselGeneratorAnnotation(() => new RtuTop) 10 | ) 11 | ) 12 | } -------------------------------------------------------------------------------- /src/main/scala/Core/IDU/DecodeTable/DefaultInst.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU.DecodeTable 2 | 3 | import Core.IDU.FuncUnit 4 | import Core.IDU.Opcode.Opcode 5 | import Utils.Bits.BinaryConst.{F, T} 6 | import chisel3._ 7 | 8 | object DefaultInst { 9 | def inst = List(FuncUnit.NON, Opcode.NOP, F, F, F) 10 | } 11 | -------------------------------------------------------------------------------- /src/test/scala/Core/IDU/ISStageMain.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU 2 | 3 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 4 | 5 | object ISStageMain extends App { 6 | (new ChiselStage).execute( 7 | args, 8 | Seq( 9 | ChiselGeneratorAnnotation(() => new ISStage) 10 | ) 11 | ) 12 | } -------------------------------------------------------------------------------- /src/test/scala/Core/IDU/RF/PrfMain.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU.RF 2 | 3 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 4 | 5 | object PrfMain extends App { 6 | (new ChiselStage).execute( 7 | args, 8 | Seq( 9 | ChiselGeneratorAnnotation(() => new Prf) 10 | ) 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/Core/IDU/IDStageMain.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU 2 | 3 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 4 | 5 | object IDStageMain extends App { 6 | (new ChiselStage).execute( 7 | args, 8 | Seq( 9 | ChiselGeneratorAnnotation(() => new IDStage) 10 | ) 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/Core/IDU/IRStageMain.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU 2 | 3 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 4 | 5 | object IRStageMain extends App { 6 | (new ChiselStage).execute( 7 | args, 8 | Seq( 9 | ChiselGeneratorAnnotation(() => new IRStage) 10 | ) 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/Core/IDU/IS/LsiqMain.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU.IS 2 | 3 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 4 | 5 | object LsiqMain extends App { 6 | (new ChiselStage).execute( 7 | args, 8 | Seq( 9 | ChiselGeneratorAnnotation(() => new Lsiq) 10 | ) 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/Core/IDU/IS/SdiqMain.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU.IS 2 | 3 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 4 | 5 | object SdiqMain extends App { 6 | (new ChiselStage).execute( 7 | args, 8 | Seq( 9 | ChiselGeneratorAnnotation(() => new Sdiq) 10 | ) 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/Core/RTU/PstPregMain.scala: -------------------------------------------------------------------------------- 1 | package Core.RTU 2 | 3 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 4 | 5 | object PstPregMain extends App { 6 | (new ChiselStage).execute( 7 | args, 8 | Seq( 9 | ChiselGeneratorAnnotation(() => new PstPreg) 10 | ) 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/Core/RTU/RetireMain.scala: -------------------------------------------------------------------------------- 1 | package Core.RTU 2 | 3 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 4 | 5 | object RetireMain extends App { 6 | (new ChiselStage).execute( 7 | args, 8 | Seq( 9 | ChiselGeneratorAnnotation(() => new Retire) 10 | ) 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/Core/RTU/RobRetireMain.scala: -------------------------------------------------------------------------------- 1 | package Core.RTU 2 | 3 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 4 | 5 | object RobRetireMain extends App { 6 | (new ChiselStage).execute( 7 | args, 8 | Seq( 9 | ChiselGeneratorAnnotation(() => new RobRetire) 10 | ) 11 | ) 12 | } -------------------------------------------------------------------------------- /src/test/scala/Core/IDU/RF/RFStageMain.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU.RF 2 | 3 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 4 | 5 | object RFStageMain extends App { 6 | (new ChiselStage).execute( 7 | args, 8 | Seq( 9 | ChiselGeneratorAnnotation(() => new RFStage) 10 | ) 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/Core/LSU/LQMain.scala: -------------------------------------------------------------------------------- 1 | package Core.LSU 2 | 3 | import Core.LSU.Lq.LQ 4 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 5 | 6 | object LQMain extends App { 7 | (new ChiselStage).execute( 8 | args, 9 | Seq( 10 | ChiselGeneratorAnnotation(() => new LQ) 11 | ) 12 | ) 13 | } -------------------------------------------------------------------------------- /src/test/scala/Core/RTU/RobEntryMain.scala: -------------------------------------------------------------------------------- 1 | package Core.RTU 2 | 3 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 4 | 5 | object RobEntryMain extends App { 6 | (new ChiselStage).execute( 7 | args, 8 | Seq( 9 | ChiselGeneratorAnnotation(() => new RobEntry) 10 | ) 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/Core/RTU/RobExceptMain.scala: -------------------------------------------------------------------------------- 1 | package Core.RTU 2 | 3 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 4 | 5 | object RobExceptMain extends App { 6 | (new ChiselStage).execute( 7 | args, 8 | Seq( 9 | ChiselGeneratorAnnotation(() => new RobExcept) 10 | ) 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/Core/IDU/IS/AiqEntryMain.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU.IS 2 | 3 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 4 | 5 | object AiqEntryMain extends App { 6 | (new ChiselStage).execute( 7 | args, 8 | Seq( 9 | ChiselGeneratorAnnotation(() => new AiqEntry) 10 | ) 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/Core/IDU/IS/BiqEntryMain.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU.IS 2 | 3 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 4 | 5 | object BiqEntryMain extends App { 6 | (new ChiselStage).execute( 7 | args, 8 | Seq( 9 | ChiselGeneratorAnnotation(() => new BiqEntry) 10 | ) 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/Core/LSU/WmbMain.scala: -------------------------------------------------------------------------------- 1 | package Core.LSU 2 | 3 | import Core.LSU.Wmb.Wmb 4 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 5 | 6 | object WmbMain extends App { 7 | (new ChiselStage).execute( 8 | args, 9 | Seq( 10 | ChiselGeneratorAnnotation(() => new Wmb) 11 | ) 12 | ) 13 | } -------------------------------------------------------------------------------- /src/test/scala/Core/IDU/IS/LsiqEntryMain.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU.IS 2 | 3 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 4 | 5 | object LsiqEntryMain extends App { 6 | (new ChiselStage).execute( 7 | args, 8 | Seq( 9 | ChiselGeneratorAnnotation(() => new LsiqEntry) 10 | ) 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/Core/IDU/IS/SdiqEntryMain.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU.IS 2 | 3 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 4 | 5 | object SdiqEntryMain extends App { 6 | (new ChiselStage).execute( 7 | args, 8 | Seq( 9 | ChiselGeneratorAnnotation(() => new SdiqEntry) 10 | ) 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/Core/IDU/RenameTableMain.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU 2 | 3 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 4 | 5 | object RenameTableMain extends App { 6 | (new ChiselStage).execute( 7 | args, 8 | Seq( 9 | ChiselGeneratorAnnotation(() => new RenameTable) 10 | ) 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/Core/LSU/RbMain.scala: -------------------------------------------------------------------------------- 1 | package Core.LSU 2 | 3 | 4 | import Core.LSU.Rb.Rb 5 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 6 | 7 | object RbMain extends App { 8 | (new ChiselStage).execute( 9 | args, 10 | Seq( 11 | ChiselGeneratorAnnotation(() => new Rb) 12 | ) 13 | ) 14 | } -------------------------------------------------------------------------------- /src/test/scala/Core/RTU/PstPregEntryMain.scala: -------------------------------------------------------------------------------- 1 | package Core.RTU 2 | 3 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 4 | 5 | object PstPregEntryMain extends App { 6 | (new ChiselStage).execute( 7 | args, 8 | Seq( 9 | ChiselGeneratorAnnotation(() => new PstPregEntry) 10 | ) 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/Core/IDU/IS/DepRegEntryMain.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU.IS 2 | 3 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 4 | 5 | object DepRegEntryMain extends App { 6 | (new ChiselStage).execute( 7 | args, 8 | Seq( 9 | ChiselGeneratorAnnotation(() => new DepRegEntry) 10 | ) 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/Core/LSU/BiuRamHelperMain.scala: -------------------------------------------------------------------------------- 1 | package Core.LSU 2 | 3 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 4 | 5 | 6 | object BiuRamHelperMain extends App { 7 | (new ChiselStage).execute( 8 | args, 9 | Seq( 10 | ChiselGeneratorAnnotation(() => new BiuRamHelper) 11 | ) 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /src/test/scala/Core/IDU/DepRegSrc2EntryMain.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU 2 | 3 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 4 | 5 | object DepRegSrc2EntryMain extends App { 6 | (new ChiselStage).execute( 7 | args, 8 | Seq( 9 | ChiselGeneratorAnnotation(() => new DepRegSrc2Entry) 10 | ) 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/Core/LSU/LQEntryMain.scala: -------------------------------------------------------------------------------- 1 | package Core.LSU 2 | 3 | import Core.LSU.Lq.LQEntry 4 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 5 | 6 | object LQEntryMain extends App { 7 | (new ChiselStage).execute( 8 | args, 9 | Seq( 10 | ChiselGeneratorAnnotation(() => new LQEntry) 11 | ) 12 | ) 13 | } -------------------------------------------------------------------------------- /src/test/scala/Core/IDU/IDUMain.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU 2 | 3 | import Core.LSU.LoadExStage.LoadDC 4 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 5 | 6 | object IDUMain extends App { 7 | (new ChiselStage).execute( 8 | args, 9 | Seq( 10 | ChiselGeneratorAnnotation(() => new IDU) 11 | ) 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /src/test/scala/Core/IDU/IS/ArithInstQueueMain.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU.IS 2 | 3 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 4 | 5 | object ArithInstQueueMain extends App { 6 | (new ChiselStage).execute( 7 | args, 8 | Seq( 9 | ChiselGeneratorAnnotation(() => new ArithInstQueue) 10 | ) 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/Core/LSU/LoadDAMain.scala: -------------------------------------------------------------------------------- 1 | package Core.LSU 2 | 3 | import Core.LSU.LoadExStage.LoadDA 4 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 5 | 6 | object LoadDAMain extends App { 7 | (new ChiselStage).execute( 8 | args, 9 | Seq( 10 | ChiselGeneratorAnnotation(() => new LoadDA) 11 | ) 12 | ) 13 | } -------------------------------------------------------------------------------- /src/test/scala/Core/LSU/LoadWBMain.scala: -------------------------------------------------------------------------------- 1 | package Core.LSU 2 | 3 | import Core.LSU.LoadExStage.LoadWB 4 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 5 | 6 | object LoadWBMain extends App { 7 | (new ChiselStage).execute( 8 | args, 9 | Seq( 10 | ChiselGeneratorAnnotation(() => new LoadWB) 11 | ) 12 | ) 13 | } -------------------------------------------------------------------------------- /src/test/scala/Core/LSU/WmbCeMain.scala: -------------------------------------------------------------------------------- 1 | package Core.LSU 2 | 3 | import Core.LSU.Wmb.WmbCe 4 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 5 | 6 | object WmbCeMain extends App { 7 | (new ChiselStage).execute( 8 | args, 9 | Seq( 10 | ChiselGeneratorAnnotation(() => new WmbCe) 11 | ) 12 | ) 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/test/scala/Core/LSU/WmbEntryMain.scala: -------------------------------------------------------------------------------- 1 | package Core.LSU 2 | 3 | import Core.LSU.Wmb.WmbEntry 4 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 5 | 6 | object WmbEntryMain extends App { 7 | (new ChiselStage).execute( 8 | args, 9 | Seq( 10 | ChiselGeneratorAnnotation(() => new WmbEntry) 11 | ) 12 | ) 13 | } -------------------------------------------------------------------------------- /src/test/scala/Core/IDU/IS/BiqMain.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU.IS 2 | 3 | import Core.LSU.LoadExStage.LoadAG 4 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 5 | 6 | object BiqMain extends App { 7 | (new ChiselStage).execute( 8 | args, 9 | Seq( 10 | ChiselGeneratorAnnotation(() => new Biq) 11 | ) 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /src/test/scala/Core/LSU/DCacheArbMain.scala: -------------------------------------------------------------------------------- 1 | package Core.LSU 2 | 3 | import Core.LSU.DCache.DCacheArb 4 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 5 | 6 | object DCacheArbMain extends App { 7 | (new ChiselStage).execute( 8 | args, 9 | Seq( 10 | ChiselGeneratorAnnotation(() => new DCacheArb) 11 | ) 12 | ) 13 | } -------------------------------------------------------------------------------- /src/test/scala/Core/LSU/RbEntryMain.scala: -------------------------------------------------------------------------------- 1 | package Core.LSU 2 | 3 | 4 | import Core.LSU.Rb.RbEntry 5 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 6 | 7 | object RbEntryMain extends App { 8 | (new ChiselStage).execute( 9 | args, 10 | Seq( 11 | ChiselGeneratorAnnotation(() => new RbEntry) 12 | ) 13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /src/test/scala/Core/LSU/SqMain.scala: -------------------------------------------------------------------------------- 1 | package Core.LSU 2 | 3 | import Core.LSU.Sq 4 | import Core.LSU.Sq.Sq 5 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} 6 | 7 | object SqMain extends App { 8 | (new ChiselStage).execute( 9 | args, 10 | Seq( 11 | ChiselGeneratorAnnotation(() => new Sq) 12 | ) 13 | ) 14 | } 15 | 16 | -------------------------------------------------------------------------------- /src/main/scala/Utils/RAMHelper.scala: -------------------------------------------------------------------------------- 1 | package Utils 2 | import chisel3._ 3 | 4 | class RAMHelper extends BlackBox { 5 | val io = IO(new Bundle { 6 | val clk = Input(Clock()) 7 | val en = Input(Bool()) 8 | 9 | val rIdx = Input(UInt(64.W)) 10 | val rdata = Output(UInt(64.W)) 11 | 12 | val wIdx = Input(UInt(64.W)) 13 | val wdata = Input(UInt(64.W)) 14 | val wmask = Input(UInt(64.W)) 15 | val wen = Input(Bool()) 16 | }) 17 | } 18 | -------------------------------------------------------------------------------- /src/main/scala/Core/IFU/RAMHelper.scala: -------------------------------------------------------------------------------- 1 | package Core.IFU 2 | 3 | import chisel3._ 4 | 5 | class RAMHelper extends BlackBox { 6 | val io = IO(new Bundle { 7 | val clk = Input(Clock()) 8 | val en = Input(Bool()) 9 | 10 | val rIdx = Input(UInt(64.W)) 11 | val rdata = Output(UInt(64.W)) 12 | 13 | val wIdx = Input(UInt(64.W)) 14 | val wdata = Input(UInt(64.W)) 15 | val wmask = Input(UInt(64.W)) 16 | val wen = Input(Bool()) 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /src/main/scala/Utils/Bits/RingShiftLeft.scala: -------------------------------------------------------------------------------- 1 | package Utils.Bits 2 | 3 | import chisel3.util.Cat 4 | import chisel3.{UInt, assert} 5 | 6 | object RingShiftLeft { 7 | def apply(src : UInt, offset : Int) : UInt = { 8 | assert(offset >= 0 && offset <= src.getWidth) 9 | if (offset == 0) 10 | src 11 | else { 12 | Cat( 13 | src(src.getWidth - offset - 1, 0), 14 | src(src.getWidth - 1, src.getWidth - offset) 15 | ) 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/scala/Core/IDU/Opcode/SpecialOpcode.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU.Opcode 2 | 3 | import chisel3._ 4 | 5 | trait SpecialOpcode extends Opcode { 6 | def ECALL : UInt = "b0000010".U 7 | def EBREAK : UInt = "b0000011".U 8 | def AUIPC : UInt = "b0000100".U 9 | def PSEUDO_AUIPC : UInt = "b0000101".U 10 | def VSETVLI : UInt = "b0000100".U 11 | def VSETVL : UInt = "b0000111".U 12 | } 13 | 14 | object SpecialOpcode extends SpecialOpcode 15 | 16 | -------------------------------------------------------------------------------- /src/main/scala/ISA/RV64V.scala: -------------------------------------------------------------------------------- 1 | package ISA 2 | 3 | import chisel3.util.BitPat 4 | 5 | object RV64V extends Decoder32Bits { 6 | // RV32/RV64 Vector Standard Extension 7 | // |-----imm-----|-rs1-|-funct3-|--rd-|opcode| 8 | def vmv_v_x = BitPat("b0101111_?????_?????___100____?????_10101") 9 | def vmv_s_x = BitPat("b0011011_?????_?????___110____?????_10101") 10 | def vsetvli = BitPat("b0??????_?????_?????___111____?????_10101") 11 | def vsetvl = BitPat("b1000000_?????_?????___111____?????_10101") 12 | } 13 | -------------------------------------------------------------------------------- /src/main/scala/Utils/BasicIOType.scala: -------------------------------------------------------------------------------- 1 | package Utils 2 | import chisel3._ 3 | import chisel3.internal.firrtl.Width 4 | 5 | object OutUInt { 6 | def apply(w : Int) : UInt = Output(UInt(w.W)) 7 | def apply(w : Width) : UInt = Output(UInt(w)) 8 | } 9 | 10 | object InUInt { 11 | def apply(w: Int) : UInt = Input(UInt(w.W)) 12 | def apply(w: Width) : UInt = Input(UInt(w)) 13 | } 14 | 15 | object OutBool { 16 | def apply() : Bool = Output(Bool()) 17 | } 18 | 19 | object InBool { 20 | def apply() : Bool = Input(Bool()) 21 | } 22 | -------------------------------------------------------------------------------- /src/main/scala/Core/IDU/Opcode/DivOpcode.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU.Opcode 2 | 3 | import chisel3._ 4 | 5 | trait DivOpcode extends Opcode { 6 | def DIV : UInt = "b1000101".U 7 | def DIVU : UInt = "b1000100".U 8 | def REM : UInt = "b1001001".U 9 | def REMU : UInt = "b1001000".U 10 | def DIVW : UInt = "b1000111".U 11 | def DIVUW : UInt = "b1000110".U 12 | def REMW : UInt = "b1001011".U 13 | def REMUW : UInt = "b1001010".U 14 | def isDu(opcode: UInt) : Bool = opcode(6,5) === "b10".U 15 | } 16 | 17 | object DivOpcode extends DivOpcode 18 | -------------------------------------------------------------------------------- /src/main/scala/Core/IDU/Opcode/BjuOpcode.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU.Opcode 2 | 3 | import chisel3._ 4 | 5 | trait BjuOpcode extends Opcode { 6 | def JAL : UInt = "b1000000".U 7 | def JALR : UInt = "b1000001".U 8 | def BEQ : UInt = "b0100000".U 9 | def BNE : UInt = "b0100001".U 10 | def BLT : UInt = "b0100010".U 11 | def BLTU : UInt = "b0100011".U 12 | def BGE : UInt = "b0100100".U 13 | def BGEU : UInt = "b0100101".U 14 | def isJmp(op: UInt): Bool = op(6) 15 | def isBr(op: UInt): Bool = op(5) 16 | } 17 | 18 | object BjuOpcode extends BjuOpcode 19 | -------------------------------------------------------------------------------- /src/main/scala/Core/IU/MDu/MDUbit.scala: -------------------------------------------------------------------------------- 1 | package Core.IU.Du 2 | 3 | import Core.Config.XLEN 4 | import Core.IUConfig 5 | import Utils.ZeroExt 6 | import chisel3._ 7 | 8 | class MDUbit(val src: UInt) extends Bundle with IUConfig { 9 | def abs(a: UInt,lenx: Int): UInt = { 10 | val s = a(lenx - 1) 11 | val temp = Wire(UInt((lenx+1).W)) 12 | temp := Mux(s, -a, a) 13 | temp(lenx-1, 0) 14 | } //取得绝对值 15 | def single(x: UInt, lenx: Int):UInt = ZeroExt(abs(x,lenx),XLEN) 16 | def half(x: UInt, lenx: Int) = ZeroExt(abs(x,lenx),32) 17 | } 18 | 19 | -------------------------------------------------------------------------------- /utils/lsu_idu.txt: -------------------------------------------------------------------------------- 1 | input 2 | lsu_idu_ag IduFromLsuAgStageBundle ag 3 | lsu_idu_da IduFromLsuDaStageBundle da 4 | lsu_idu_dc IduFromLsuDcStageBundle dc 5 | lsu_idu_ex1 IduFromLsuEx1StageBundle ex1 6 | lsu_idu_lq IduFromLsuLqBundle lq 7 | lsu_idu_rb IduFromLsuRbBundle rb 8 | lsu_idu_sq IduFromLsuSqBundle sq 9 | lsu_idu_tlb IduFromLsuTlbBundle tlb 10 | lsu_idu_vmb IduFromLsuVmbBundle vwb 11 | lsu_idu_wb IduFromLsuWbStageBundle wb 12 | lsu_idu IduFromLsu top_class 13 | -------------------------------------------------------------------------------- /src/main/scala/ISA/RV64Zfh.scala: -------------------------------------------------------------------------------- 1 | package ISA 2 | 3 | import chisel3.util.BitPat 4 | 5 | object RV64Zfh extends Decoder32Bits { 6 | // RV32Zfh Standard Extension 7 | // I-type |-----imm-----|-rs1-|-funct3-|--rd-|opcode| 8 | def flh = BitPat("b???????_?????_?????___001____?????_00001") 9 | 10 | // S-type |--imm--|-rs2-|-rs1-|-funct3-|-imm-|opcode| 11 | def fsh = BitPat("b???????_?????_?????___001____?????_01001") 12 | 13 | // R-type |-func7-|-rs2-|-rs1-|-funct3-|--rd-|opcode| 14 | def fmv_h_x = BitPat("b1111010_?????_?????___000____?????_10100") 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/Core/IDU/FuncUnit.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU 2 | 3 | import chisel3._ 4 | import chisel3.util._ 5 | 6 | object FuncUnit { 7 | def OH = true 8 | def size = 8 9 | def width : Int = size 10 | def NON : UInt = 0.U(width.W) 11 | def ALU : UInt = UIntToOH(0.U, width) 12 | def SPECIAL : UInt = UIntToOH(1.U, width) 13 | def CP0 : UInt = UIntToOH(2.U, width) 14 | def MU : UInt = UIntToOH(3.U, width) 15 | def DU : UInt = UIntToOH(4.U, width) 16 | def BJU : UInt = UIntToOH(5.U, width) 17 | def LU : UInt = UIntToOH(6.U, width) 18 | def SU : UInt = UIntToOH(7.U, width) 19 | } 20 | -------------------------------------------------------------------------------- /src/main/scala/Utils/Bits/DropBit.scala: -------------------------------------------------------------------------------- 1 | package Utils.Bits 2 | 3 | import chisel3._ 4 | import chisel3.util._ 5 | 6 | object DropBit { 7 | def apply (src: UInt, idx: Int) : UInt = { 8 | val width = src.getWidth 9 | if (idx == 0) 10 | src(width-1, 1) 11 | else if(idx == width - 1) 12 | src(width-2, 0) 13 | else if(idx > 0 && idx < width - 1) 14 | Cat(src(width-1, idx+1), src(idx-1, 0)) 15 | else { 16 | assert(cond = false, "idx out of width of src") 17 | 0.U 18 | } 19 | } 20 | def apply(src: Vec[Bool], idx: Int) : UInt = { 21 | this.apply(src.asUInt, idx) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/scala/ISA/RV64D.scala: -------------------------------------------------------------------------------- 1 | package ISA 2 | 3 | import chisel3.util.BitPat 4 | 5 | object RV64D extends Decoder32Bits { 6 | // RV32D Standard Extension 7 | // I-type |-----imm-----|-rs1-|-funct3-|--rd-|opcode| 8 | def fld = BitPat("b???????_?????_?????___011____?????_00001") 9 | 10 | // S-type |--imm--|-rs2-|-rs1-|-funct3-|-imm-|opcode| 11 | def fsd = BitPat("b???????_?????_?????___011____?????_01001") 12 | 13 | // RV64D Standard Extension (in addition to RV32D) 14 | // R-type |-func7-|-rs2-|-rs1-|-funct3-|--rd-|opcode| 15 | def fmv_d_x = BitPat("b1111001_?????_?????___000____?????_10100") 16 | } 17 | -------------------------------------------------------------------------------- /src/main/scala/Core/IDU/Opcode/MulOpcode.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU.Opcode 2 | 3 | import chisel3._ 4 | 5 | trait MulOpcode extends Opcode { 6 | def MUL : UInt = "b0001100".U 7 | def MULH : UInt = "b0000100".U 8 | def MULHU : UInt = "b0000101".U 9 | def MULHSU : UInt = "b0000111".U 10 | def MULW : UInt = "b0001000".U 11 | // for vector 12 | def MULA : UInt = "b0101100".U 13 | def MULS : UInt = "b0101101".U 14 | def MULAW : UInt = "b0101000".U 15 | def MULSW : UInt = "b0101001".U 16 | def MULAH : UInt = "b0100100".U 17 | def MULSH : UInt = "b0100101".U 18 | } 19 | 20 | object MulOpcode extends MulOpcode 21 | -------------------------------------------------------------------------------- /src/main/scala/ISA/RV64F.scala: -------------------------------------------------------------------------------- 1 | package ISA 2 | 3 | import chisel3.util.BitPat 4 | 5 | object RV64F extends Decoder32Bits { 6 | // RV32F Standard Extension 7 | // I-type |-----imm-----|-rs1-|-funct3-|--rd-|opcode| 8 | def flw = BitPat("b???????_?????_?????___010____?????_00001") 9 | 10 | // S-type |--imm--|-rs2-|-rs1-|-funct3-|-imm-|opcode| 11 | def fsw = BitPat("b???????_?????_?????___010____?????_01001") 12 | 13 | // R-type |-func7-|-rs2-|-rs1-|-funct3-|--rd-|opcode| 14 | def fmv_w_x = BitPat("b1111000_?????_?????___000____?????_10100") 15 | // RV64F Standard Extension (in addition to RV32F) 16 | 17 | } 18 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Continuous Integration 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | ci: 7 | name: ci 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Checkout 11 | uses: actions/checkout@v2 12 | - name: Cleanup 13 | run: sed -i "s/%NAME%/test/g" build.sc 14 | - name: Update Submodule 15 | run: git submodule update --init --recursive 16 | - name: Setup Scala 17 | uses: olafurpg/setup-scala@v10 18 | with: 19 | java-version: adopt@1.8 20 | - name: Cache Scala 21 | uses: coursier/cache-action@v5 22 | - name: SBT Test 23 | run: sbt test 24 | 25 | -------------------------------------------------------------------------------- /src/main/scala/Utils/Bits/Ext.scala: -------------------------------------------------------------------------------- 1 | package Utils.Bits 2 | 3 | import chisel3._ 4 | import chisel3.util._ 5 | 6 | object msb { 7 | def apply(src: UInt): Bool = src(src.getWidth - 1).asBool 8 | } 9 | 10 | object sext { 11 | def apply(width: Int, src: UInt) : UInt = { 12 | assert(width > 0) 13 | if (width - src.getWidth == 0) 14 | src 15 | else 16 | Cat(Fill(width - src.getWidth, msb(src).asUInt), src) 17 | } 18 | } 19 | 20 | object zext { 21 | def apply(width: Int, src: UInt) : UInt = { 22 | assert(width > 0) 23 | if (width - src.getWidth == 0) 24 | src 25 | else 26 | Cat(Fill(width - src.getWidth, 0.U(1.W)), src) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/exclude/IU/Csr/Define/Exceptions.scala: -------------------------------------------------------------------------------- 1 | package Core.IU.Csr.Define 2 | 3 | import chisel3._ 4 | object Exceptions { 5 | object ExceptionVec { 6 | def apply(): Vec[Bool] = Vec(16, Bool()) 7 | } 8 | 9 | def InstAddressMisaligned = 0 10 | 11 | def InstAccessFault = 1 12 | 13 | def IllegalInst = 2 14 | 15 | def Breakpoint = 3 16 | 17 | def LoadAddrMisaligned = 4 18 | 19 | def LoadAccessFault = 5 20 | 21 | def StoreAddrMisaligned = 6 22 | 23 | def StoreAccessFault = 7 24 | 25 | def UECall = 8 26 | 27 | def SECall = 9 28 | 29 | def MECall = 11 30 | 31 | def InstPageFault = 12 32 | 33 | def LoadPageFault = 13 34 | 35 | def StorePageFault = 15 36 | } 37 | -------------------------------------------------------------------------------- /src/main/scala/Core/IU/Cp0/Define/Exceptions.scala: -------------------------------------------------------------------------------- 1 | package Core.IU.Cp0.Define 2 | 3 | import chisel3._ 4 | object Exceptions { 5 | object ExceptionVec { 6 | def apply(): Vec[Bool] = Vec(16, Bool()) 7 | } 8 | 9 | def InstAddressMisaligned = 0 10 | 11 | def InstAccessFault = 1 12 | 13 | def IllegalInst = 2 14 | 15 | def Breakpoint = 3 16 | 17 | def LoadAddrMisaligned = 4 18 | 19 | def LoadAccessFault = 5 20 | 21 | def StoreAddrMisaligned = 6 22 | 23 | def StoreAccessFault = 7 24 | 25 | def UECall = 8 26 | 27 | def SECall = 9 28 | 29 | def MECall = 11 30 | 31 | def InstPageFault = 12 32 | 33 | def LoadPageFault = 13 34 | 35 | def StorePageFault = 15 36 | } 37 | -------------------------------------------------------------------------------- /src/main/scala/ISA/RV64Zicsr.scala: -------------------------------------------------------------------------------- 1 | package ISA 2 | 3 | import chisel3.util.BitPat 4 | 5 | object RV64Zicsr extends Decoder32Bits { 6 | // RV32/RV64 Zicsr Standard Extension 7 | // |---csrimm----|-rs1-|-funct3-|--rd-|opcode| 8 | def csrrw = BitPat("b???????_?????_?????___001____?????_11100") 9 | def csrrs = BitPat("b???????_?????_?????___010____?????_11100") 10 | def csrrc = BitPat("b???????_?????_?????___011____?????_11100") 11 | // |---csrimm----|-uimm|-funct3-|--rd-|opcode| 12 | def csrrwi = BitPat("b???????_?????_?????___101____?????_11100") 13 | def csrrsi = BitPat("b???????_?????_?????___110____?????_11100") 14 | def csrrci = BitPat("b???????_?????_?????___111____?????_11100") 15 | } 16 | -------------------------------------------------------------------------------- /src/exclude/IU/Bju/BjuBundle.scala: -------------------------------------------------------------------------------- 1 | package Core.IU.Bju 2 | 3 | import Core.AddrConfig.PcWidth 4 | import chisel3._ 5 | 6 | class BhtPredDataForward extends Bundle{ // @ct_iu_bju_pcfifo @1677-1684 7 | var curPc = UInt(PcWidth.W) 8 | var tarPc = UInt(PcWidth.W) 9 | var jal = Bool() 10 | var jalr = Bool() 11 | var dstVld = Bool() 12 | val predStore = new IfuPredStore 13 | } 14 | 15 | class IfuPredStore extends Bundle{ 16 | val pc = UInt(PcWidth.W) 17 | val bhtPred = Bool() 18 | val chkIdx = UInt(25.W) 19 | val jmpMispred = Bool() 20 | } 21 | 22 | class PredCheckRes extends Bundle{ 23 | val length = Bool() 24 | val bhtMispred = Bool() 25 | val jmp = Bool() 26 | val condbr = Bool() 27 | val pcall = Bool() 28 | val pret = Bool() 29 | val pc = UInt(PcWidth.W) 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/main/scala/Core/RTU/CompareIid.scala: -------------------------------------------------------------------------------- 1 | package Core.RTU 2 | import Core.ROBConfig.{IidWidth, NumRobEntryBits} 3 | import chisel3._ 4 | import chisel3.util._ 5 | class CompareIid extends Module{ 6 | val io = IO(new Bundle() { 7 | val iid0 = Input(UInt(IidWidth.W)) 8 | val iid1 = Input(UInt(IidWidth.W)) 9 | val older = Output(Bool()) 10 | }) 11 | //========================================================== 12 | // Compare order of two 7 bits IIDs 13 | //========================================================== 14 | val mis_match = io.iid0(IidWidth-1) ^ io.iid1(IidWidth-1) 15 | val (ptr0,ptr1) = (io.iid0(NumRobEntryBits-1,0),io.iid1(NumRobEntryBits-1,0)) 16 | val match_0_older = ptr0 < ptr1 17 | val mis_match_0_older = ptr0 < ptr1 18 | io.older := Mux(mis_match,mis_match_0_older,match_0_older) 19 | } 20 | -------------------------------------------------------------------------------- /src/main/scala/Core/IDU/DecodeTable/BjuDecodeTable.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU.DecodeTable 2 | 3 | import Utils.Bits.BinaryConst.{F, T} 4 | import chisel3._ 5 | import chisel3.util.BitPat 6 | import ISA.RV64I._ 7 | import Core.IDU.Opcode.BjuOpcode._ 8 | import Core.IDU.FuncUnit._ 9 | 10 | object BjuDecodeTable { 11 | val table : Array[(BitPat, List[UInt])] = Array( 12 | // Fu opcode rs2 13 | // | | rs1| 14 | // | | rd | | 15 | jal -> List(BJU, JAL , F, F, F), 16 | jalr -> List(BJU, JALR, F, T, F), 17 | beq -> List(BJU, BEQ , F, T, T), 18 | bne -> List(BJU, BNE , F, T, T), 19 | blt -> List(BJU, BLT , F, T, T), 20 | bge -> List(BJU, BGE , F, T, T), 21 | bltu -> List(BJU, BLTU , F, T, T), 22 | bgeu -> List(BJU, BGEU , F, T, T), 23 | ) 24 | } 25 | -------------------------------------------------------------------------------- /src/main/scala/ISA/RV64Pseudo.scala: -------------------------------------------------------------------------------- 1 | package ISA 2 | 3 | import chisel3.util.BitPat 4 | 5 | object RV64Pseudo extends Decoder32Bits { 6 | // I-type |-func7-|-rs2-|-rs1-|-funct3-|--rd-|opcode| 7 | def PseudoAuipc = BitPat("b???????_?????_?????____???___?????_00111") 8 | def PseudoMin = BitPat("b0100000_?????_?????____010___?????_01100") 9 | def PseudoMax = BitPat("b0110000_?????_?????____010___?????_01100") 10 | def PseudoMinw = BitPat("b0110000_?????_?????____010___?????_01100") 11 | def PseudoMaxw = BitPat("b0110000_?????_?????____010___?????_01100") 12 | def PseudoMinu = BitPat("b0110000_?????_?????____010___?????_01100") 13 | def PseudoMaxu = BitPat("b0110000_?????_?????____010___?????_01100") 14 | def PseudoMinuw = BitPat("b0110000_?????_?????____010___?????_01100") 15 | def PseudoMaxuw = BitPat("b0110000_?????_?????____010___?????_01100") 16 | } 17 | -------------------------------------------------------------------------------- /src/main/scala/Core/IU/Bju/BjuBundle.scala: -------------------------------------------------------------------------------- 1 | package Core.IU.Bju 2 | 3 | import Core.AddrConfig.PcWidth 4 | import chisel3._ 5 | 6 | class ifuDataForward extends Bundle{ // @ct_iu_bju_pcfifo @1677-1684 7 | var curPc = UInt((PcWidth).W) // TODO why 40 bits? 8 | var dstVld = Bool() 9 | val en = Bool() 10 | var tarPc = UInt((PcWidth).W) 11 | var jal = Bool() 12 | var jalr = Bool() 13 | val predStore = new IfuPredStore 14 | } 15 | 16 | class IfuPredStore extends Bundle{ 17 | val bhtPred = Bool() 18 | val chkIdx = UInt(25.W) 19 | val jmpMispred = Bool() 20 | val pc = UInt((PcWidth).W) // pc ignore in forward, but use in store fifo 21 | } 22 | 23 | class PredCheckRes extends Bundle{ 24 | val instVld = Bool() 25 | val bhtMispred = Bool() 26 | val jmp = Bool() 27 | val pcall = Bool() 28 | val pret = Bool() 29 | val pc = UInt((PcWidth).W) 30 | val condbr = Bool() 31 | val length = Bool() 32 | val bhtPred = Bool() 33 | } 34 | 35 | -------------------------------------------------------------------------------- /src/exclude/IU/Csr/Define/Interrupts.scala: -------------------------------------------------------------------------------- 1 | package Core.IU.Csr.Define 2 | 3 | import chisel3.{Bool, UInt, Vec, fromStringToLiteral} 4 | 5 | object Interrupts { 6 | 7 | object InterruptVec { 8 | def apply(): Vec[Bool] = Vec(12, Bool()) 9 | } 10 | def UserSoft = 0 11 | 12 | def SupervisorSoft = 1 13 | 14 | def MachineSoft = 3 15 | 16 | def UserTime = 4 17 | 18 | def SupervisorTime = 5 19 | 20 | def MachineTime = 7 21 | 22 | def UserExtern = 8 23 | 24 | def SupervisorExtern = 9 25 | 26 | def MachineExtern = 11 27 | 28 | def isUser(cause : UInt) : Bool = cause(1, 0) === "b00".U 29 | 30 | def isSupervisor(cause : UInt) : Bool = cause(1, 0) === "b01".U 31 | 32 | def isMachine(cause : UInt) : Bool = cause(1, 0) === "b11".U 33 | 34 | def isSoft(cause : UInt) : Bool = cause(3, 2) === "b00".U 35 | 36 | def isTime(cause : UInt) : Bool = cause(3, 2) === "b01".U 37 | 38 | def isExtern(cause : UInt) : Bool = cause(3, 2) === "b10".U 39 | } 40 | -------------------------------------------------------------------------------- /src/main/scala/Core/IU/Cp0/Define/Interrupts.scala: -------------------------------------------------------------------------------- 1 | package Core.IU.Cp0.Define 2 | 3 | import chisel3.{Bool, UInt, Vec, fromStringToLiteral} 4 | 5 | object Interrupts { 6 | 7 | object InterruptVec { 8 | def apply(): Vec[Bool] = Vec(12, Bool()) 9 | } 10 | def UserSoft = 0 11 | 12 | def SupervisorSoft = 1 13 | 14 | def MachineSoft = 3 15 | 16 | def UserTime = 4 17 | 18 | def SupervisorTime = 5 19 | 20 | def MachineTime = 7 21 | 22 | def UserExtern = 8 23 | 24 | def SupervisorExtern = 9 25 | 26 | def MachineExtern = 11 27 | 28 | def isUser(cause : UInt) : Bool = cause(1, 0) === "b00".U 29 | 30 | def isSupervisor(cause : UInt) : Bool = cause(1, 0) === "b01".U 31 | 32 | def isMachine(cause : UInt) : Bool = cause(1, 0) === "b11".U 33 | 34 | def isSoft(cause : UInt) : Bool = cause(3, 2) === "b00".U 35 | 36 | def isTime(cause : UInt) : Bool = cause(3, 2) === "b01".U 37 | 38 | def isExtern(cause : UInt) : Bool = cause(3, 2) === "b10".U 39 | } 40 | -------------------------------------------------------------------------------- /src/main/scala/Utils/utils.scala: -------------------------------------------------------------------------------- 1 | package Utils 2 | 3 | import chisel3._ 4 | import chisel3.util._ 5 | 6 | object LookupTree { 7 | def apply[T <: Data](key: UInt, mapping: Iterable[(UInt, T)]): T = 8 | Mux1H(mapping.map(p => (p._1 === key, p._2))) 9 | } // mux select 10 | 11 | object SignExt { 12 | def apply(a: UInt, len: Int) : UInt = { 13 | val aLen = a.getWidth 14 | val signBit = a(aLen-1) 15 | if (aLen >= len) a(len-1,0) else Cat(Fill(len - aLen, signBit), a) 16 | } 17 | } //bread says it is buqi weishu 18 | 19 | object ZeroExt { 20 | def apply(a: UInt, len: Int) : UInt = { 21 | val aLen = a.getWidth 22 | if (aLen >= len) a(len-1,0) else Cat(0.U((len - aLen).W), a) 23 | } 24 | } 25 | object UIntToMask { 26 | def apply(ptr: UInt, length: Integer) = leftmask(ptr, length) 27 | def reverseUInt(input: UInt): UInt = { 28 | VecInit(input.asBools.reverse).asUInt 29 | } 30 | def leftmask(ptr: UInt, length: Integer) = UIntToOH(ptr)(length - 1, 0) - 1.U 31 | def rightmask(ptr: UInt, length: Integer) = reverseUInt(reverseUInt(UIntToOH(ptr)(length - 1, 0)) - 1.U) 32 | } 33 | 34 | -------------------------------------------------------------------------------- /src/main/scala/ISA/RV64M.scala: -------------------------------------------------------------------------------- 1 | package ISA 2 | 3 | import chisel3.util.BitPat 4 | 5 | object RV64M extends Decoder32Bits { 6 | // RV32M Standard Extension 7 | // R-type |-func7-|-rs2-|-rs1-|-funct3-|--rd-|opcode| 8 | def mul = BitPat("b0000001_?????_?????___000____?????_01100") 9 | def mulh = BitPat("b0000001_?????_?????___001____?????_01100") 10 | def mulhsu = BitPat("b0000001_?????_?????___010____?????_01100") 11 | def mulhu = BitPat("b0000001_?????_?????___011____?????_01100") 12 | def div = BitPat("b0000001_?????_?????___100____?????_01100") 13 | def divu = BitPat("b0000001_?????_?????___101____?????_01100") 14 | def rem = BitPat("b0000001_?????_?????___110____?????_01100") 15 | def remu = BitPat("b0000001_?????_?????___111____?????_01100") 16 | // RV64M Standard Extension (in addition to RV32M) 17 | def mulw = BitPat("b0000001_?????_?????___000____?????_01110") 18 | def divw = BitPat("b0000001_?????_?????___100____?????_01110") 19 | def divuw = BitPat("b0000001_?????_?????___101____?????_01110") 20 | def remw = BitPat("b0000001_?????_?????___110____?????_01110") 21 | def remuw = BitPat("b0000001_?????_?????___111____?????_01110") 22 | } 23 | -------------------------------------------------------------------------------- /src/main/scala/Core/IDU/Opcode/AluOpcode.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU.Opcode 2 | 3 | import chisel3._ 4 | 5 | trait AluOpcode extends Opcode { 6 | // alu 7 | def AUI_PC = "b1011111".U 8 | def ADD : UInt = "b0000000".U 9 | def SUB : UInt = "b0000001".U 10 | def SLT : UInt = "b0000011".U 11 | def LUI : UInt = "b0101100".U 12 | def ADDW : UInt = "b0100000".U 13 | def SUBW : UInt = "b0100001".U 14 | def SLTU : UInt = "b1000011".U 15 | // shift 16 | def SLL : UInt = "b0001000".U 17 | def SRL : UInt = "b0001010".U 18 | def SRA : UInt = "b0001011".U 19 | def SLLW : UInt = "b0101000".U 20 | def SRLW : UInt = "b0101010".U 21 | def SRAW : UInt = "b0101011".U 22 | // logic 23 | def AND : UInt = "b0010000".U 24 | def OR : UInt = "b0010001".U 25 | def XOR : UInt = "b0010010".U 26 | // pseudo 27 | def MIN : UInt = "b0010000".U 28 | def MINU : UInt = "b1010000".U 29 | def MINW : UInt = "b0110000".U 30 | def MINUW : UInt = "b1110000".U 31 | def MAX : UInt = "b0010001".U 32 | def MAXU : UInt = "b1010001".U 33 | def MAXW : UInt = "b0110001".U 34 | def MAXUW : UInt = "b1110001".U 35 | 36 | def isWordOp(op: UInt) : Bool = op(5) 37 | def isUnsigned(op: UInt) : Bool = op(6) 38 | } 39 | 40 | object AluOpcode extends AluOpcode -------------------------------------------------------------------------------- /src/main/scala/Core/LSU/RotData128.scala: -------------------------------------------------------------------------------- 1 | package Core.LSU 2 | 3 | import Core.Config.XLEN 4 | import Core.LsuConfig 5 | import chisel3._ 6 | import chisel3.util._ 7 | 8 | class RotData128 extends Module with LsuConfig { 9 | val io = IO(new Bundle() { 10 | val dataIn = Input(UInt((XLEN*2).W)) 11 | val rotSel = Input(UInt(ROT_SEL_WIDTH_8.W)) 12 | val dataSettle = Output(UInt((XLEN*2).W)) 13 | }) 14 | val data = io.dataIn(XLEN-1,0) | io.dataIn(2*XLEN-1,XLEN) 15 | val data_rot = Seq.fill(8)(Wire(UInt(XLEN.W))) 16 | data_rot(0) := data(63,0) 17 | data_rot(1) := Cat(data(7,0) ,data(63,8)) 18 | data_rot(2) := Cat(data(15,0) ,data(63,16)) 19 | data_rot(3) := Cat(data(23,0) ,data(63,24)) 20 | data_rot(4) := Cat(data(31,0) ,data(63,32)) 21 | data_rot(5) := Cat(data(39,0) ,data(63,40)) 22 | data_rot(6) := Cat(data(47,0) ,data(63,48)) 23 | data_rot(7) := Cat(data(55,0) ,data(63,56)) 24 | 25 | io.dataSettle := Cat(0.U(XLEN.W), 26 | MuxLookup(io.rotSel, 0.U(XLEN.W), Seq( 27 | "b0000_0001".U -> data_rot(0), 28 | "b0000_0010".U -> data_rot(1), 29 | "b0000_0100".U -> data_rot(2), 30 | "b0000_1000".U -> data_rot(3), 31 | "b0001_0000".U -> data_rot(4), 32 | "b0010_0000".U -> data_rot(5), 33 | "b0100_0000".U -> data_rot(6), 34 | "b1000_0000".U -> data_rot(7) 35 | )) 36 | ) 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/scala/Core/LSU/RotData.scala: -------------------------------------------------------------------------------- 1 | //package Core.LSU 2 | // 3 | //import Core.Config.XLEN 4 | //import Core.LsuConfig 5 | //import chisel3._ 6 | //import chisel3.util._ 7 | // 8 | //class RotData extends Module with LsuConfig { 9 | // val io = IO(new Bundle() { 10 | // val dataIn = Input(UInt((XLEN).W)) 11 | // val rotSel = Input(UInt(ROT_SEL_WIDTH_8.W)) 12 | // val dataSettle = Output(UInt((XLEN).W)) 13 | // }) 14 | // val data = io.dataIn//io.dataIn(XLEN-1,0) | io.dataIn(2*XLEN-1,XLEN) 15 | // val data_rot = Seq.fill(8)(Wire(UInt(XLEN.W))) 16 | // data_rot(0) := data(63,0) 17 | // data_rot(1) := Cat(data(7,0) ,data(63,8)) 18 | // data_rot(2) := Cat(data(15,0) ,data(63,16)) 19 | // data_rot(3) := Cat(data(23,0) ,data(63,24)) 20 | // data_rot(4) := Cat(data(31,0) ,data(63,32)) 21 | // data_rot(5) := Cat(data(39,0) ,data(63,40)) 22 | // data_rot(6) := Cat(data(47,0) ,data(63,48)) 23 | // data_rot(7) := Cat(data(55,0) ,data(63,56)) 24 | // 25 | // io.dataSettle := MuxLookup(io.rotSel, 0.U(XLEN.W), Seq( 26 | // "b0000_0001".U -> data_rot(0), 27 | // "b0000_0010".U -> data_rot(1), 28 | // "b0000_0100".U -> data_rot(2), 29 | // "b0000_1000".U -> data_rot(3), 30 | // "b0001_0000".U -> data_rot(4), 31 | // "b0010_0000".U -> data_rot(5), 32 | // "b0100_0000".U -> data_rot(6), 33 | // "b1000_0000".U -> data_rot(7) 34 | // )) 35 | // 36 | // 37 | // 38 | //} 39 | -------------------------------------------------------------------------------- /src/main/scala/Core/IDU/IS/VfiqEntry.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU.IS 2 | 3 | import Core.ExceptionConfig._ 4 | import Core.IntConfig._ 5 | import Core.VectorUnitConfig._ 6 | import chisel3._ 7 | import chisel3.util._ 8 | 9 | trait VfiqConfig { 10 | def NumSrcVf = 4 11 | def NumEntryVfiq = 8 12 | } 13 | 14 | object VfiqConfig extends VfiqConfig 15 | 16 | class VfiqEntryData extends Bundle with VfiqConfig { 17 | val vl = UInt(VlmaxBits.W) 18 | val vsew = UInt(VsewBits.W) 19 | val vlmul = UInt(VlmulBits.W) 20 | val vmul = Bool() 21 | val vmulUnsplit = Bool() 22 | val vmlaShort = Bool() // 136 23 | val vdiv = Bool() // 135 24 | val launchReadyViq1 = Vec(NumEntryVfiq, Bool()) // 134 25 | val launchReadyViq0 = Vec(NumEntryVfiq, Bool()) // 126 26 | // Todo: imm 27 | val vmlaType = UInt(3.W) // 118 28 | val splitNum = UInt(7.W) // 115 29 | val splitLast = Bool() // 108 30 | val mfvr = Bool() // 107 31 | val vmla = Bool() // 106 32 | // Todo: Replace with DepVregEntryData 33 | val srcVec = Vec(NumSrcVf, new DepRegEntryData) // 105 ~ 65 34 | val dstEreg = UInt(NumEregsBits.W) // 64 35 | val dstVreg = UInt(NumVPregsBits.W) // 59 36 | val dstPreg = UInt(NumPhysicRegsBits.W) // 52 37 | val dstEregValid = Bool() 38 | val dstVregValid = Bool() 39 | val dstPregValid = Bool() 40 | val srcValidVec = Vec(NumSrcVf, Bool()) 41 | val iid = UInt(InstructionIdWidth.W) 42 | val inst = UInt(InstBits.W) 43 | } 44 | -------------------------------------------------------------------------------- /src/main/resources/gated_clk_cell.v: -------------------------------------------------------------------------------- 1 | /*Copyright 2019-2021 T-Head Semiconductor Co., Ltd. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | 16 | module gated_clk_cell( 17 | clk_in, 18 | global_en, 19 | module_en, 20 | local_en, 21 | external_en, 22 | pad_yy_icg_scan_en, 23 | clk_out 24 | ); 25 | 26 | input clk_in; 27 | input global_en; 28 | input module_en; 29 | input local_en; 30 | input external_en; 31 | input pad_yy_icg_scan_en; 32 | output clk_out; 33 | 34 | wire clk_en_bf_latch; 35 | wire SE; 36 | 37 | assign clk_en_bf_latch = (global_en && (module_en || local_en)) || external_en ; 38 | 39 | // SE driven from primary input, held constant 40 | assign SE = pad_yy_icg_scan_en; 41 | 42 | // // &Connect( .clk_in (clk_in), @50 43 | // // .SE (SE), @51 44 | // // .external_en (clk_en_bf_latch), @52 45 | // // .clk_out (clk_out) @53 46 | // // ) ; @54 47 | assign clk_out = clk_in; 48 | 49 | endmodule 50 | -------------------------------------------------------------------------------- /src/main/scala/ISA/RV64C.scala: -------------------------------------------------------------------------------- 1 | package ISA 2 | 3 | import chisel3.util.BitPat 4 | 5 | object RV64C extends Decoder16Bits { 6 | // RVC Instruction Set 7 | // Quadrant 0 8 | def c_addi4spn = BitPat("b000_???_???_??_???_00") 9 | // Quadrant 1 10 | def c_addi = BitPat("b000_?_?????_?????_01") 11 | def c_addiw = BitPat("b001_?_?????_?????_01") 12 | def c_li = BitPat("b010_?_?????_?????_01") 13 | def c_addi16sp = BitPat("b011_?_00010_?????_01") 14 | def c_lui = BitPat("b011_?_?????_?????_01") 15 | def c_srli = BitPat("b100_?_00_???_?????_01") 16 | def c_srai = BitPat("b100_?_01_???_?????_01") 17 | def c_andi = BitPat("b100_?_10_???_?????_01") 18 | def c_sub = BitPat("b100_0_11_???_00_???_01") 19 | def c_xor = BitPat("b100_0_11_???_01_???_01") 20 | def c_or = BitPat("b100_0_11_???_10_???_01") 21 | def c_and = BitPat("b100_0_11_???_11_???_01") 22 | def c_subw = BitPat("b100_1_11_???_00_???_01") 23 | def c_addw = BitPat("b100_1_11_???_01_???_01") 24 | // Quadrant 1 25 | def c_slli = BitPat("b000_?_?????_?????_10") 26 | def c_mv = BitPat("b100_0_?????_?????_10") 27 | def c_add = BitPat("b100_1_?????_?????_10") 28 | def c_ebreak = BitPat("b100_1_00000_00000_10") 29 | def c_j = BitPat("b101_?_??_???_??_???_01") 30 | def c_beqz = BitPat("b110_?_??_???_??_???_01") 31 | def c_bnez = BitPat("b111_?_??_???_??_???_01") 32 | def c_jr = BitPat("b100_0_??_???_??_???_10") 33 | def c_jalr = BitPat("b100_1_??_???_00_000_10") 34 | } 35 | -------------------------------------------------------------------------------- /src/main/scala/Core/LSU/DCache/DCacheSram.scala: -------------------------------------------------------------------------------- 1 | package Core.LSU.DCache 2 | import chisel3._ 3 | import chisel3.experimental.ExtModule 4 | import chisel3.util._ 5 | 6 | 7 | class ct_spsram_2048x32 extends ExtModule with HasExtModuleResource { 8 | val A = IO(Input(UInt(11.W))) 9 | val CEN = IO(Input(Bool())) 10 | val CLK = IO(Input(Clock())) 11 | val D = IO(Input(UInt(32.W))) 12 | val GWEN = IO(Input(Bool())) 13 | val Q = IO(Output(UInt(32.W))) 14 | val WEN = IO(Input(UInt(32.W))) 15 | 16 | addResource("/ct_spsram_2048x32.v") 17 | } 18 | 19 | class ct_spsram_512x54 extends ExtModule with HasExtModuleResource { 20 | val A = IO(Input(UInt(9.W))) 21 | val CEN = IO(Input(Bool())) 22 | val CLK = IO(Input(Clock())) 23 | val D = IO(Input(UInt(54.W))) 24 | val GWEN = IO(Input(Bool())) 25 | val Q = IO(Output(UInt(54.W))) 26 | val WEN = IO(Input(UInt(54.W))) 27 | 28 | addResource("/ct_spsram_512x54.v") 29 | } 30 | 31 | class ct_spsram_512x52 extends ExtModule with HasExtModuleResource { 32 | val A = IO(Input(UInt(9.W))) 33 | val CEN = IO(Input(Bool())) 34 | val CLK = IO(Input(Clock())) 35 | val D = IO(Input(UInt(52.W))) 36 | val GWEN = IO(Input(Bool())) 37 | val Q = IO(Output(UInt(52.W))) 38 | val WEN = IO(Input(UInt(52.W))) 39 | 40 | addResource("/ct_spsram_512x52.v") 41 | } 42 | 43 | class ct_spsram_512x7 extends ExtModule with HasExtModuleResource { 44 | val A = IO(Input(UInt(9.W))) 45 | val CEN = IO(Input(Bool())) 46 | val CLK = IO(Input(Clock())) 47 | val D = IO(Input(UInt(7.W))) 48 | val GWEN = IO(Input(Bool())) 49 | val Q = IO(Output(UInt(7.W))) 50 | val WEN = IO(Input(UInt(7.W))) 51 | 52 | addResource("/ct_spsram_512x7.v") 53 | } 54 | 55 | -------------------------------------------------------------------------------- /src/main/resources/fpga_ram.v: -------------------------------------------------------------------------------- 1 | /*Copyright 2019-2021 T-Head Semiconductor Co., Ltd. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | module fpga_ram( 16 | PortAClk, 17 | PortAAddr, 18 | PortADataIn, 19 | PortAWriteEnable, 20 | // PortAChipEnable, 21 | PortADataOut 22 | ); 23 | 24 | parameter DATAWIDTH = 2; 25 | parameter ADDRWIDTH = 2; 26 | 27 | input PortAClk; 28 | input [(ADDRWIDTH-1):0] PortAAddr; 29 | input [(DATAWIDTH-1):0] PortADataIn; 30 | input PortAWriteEnable; 31 | //input PortAChipEnable; 32 | output [(DATAWIDTH-1):0] PortADataOut; 33 | 34 | parameter MEMDEPTH = 2**(ADDRWIDTH); 35 | 36 | reg [(DATAWIDTH-1):0] mem [(MEMDEPTH-1):0] /* synthesis syn_ramstyle = "no_rw_check" */; 37 | reg [(DATAWIDTH-1):0] PortADataOut; 38 | 39 | always @(posedge PortAClk) 40 | begin 41 | if(PortAWriteEnable) 42 | begin 43 | mem[PortAAddr] <= PortADataIn; 44 | PortADataOut <= PortADataIn; 45 | end 46 | else 47 | begin 48 | PortADataOut <= mem[PortAAddr]; 49 | end 50 | end 51 | 52 | //wire [(DATAWIDTH-1):0] tt; 53 | //assign t = mem[PortAAddr]; 54 | //always @(posedge PortAClk) 55 | //begin 56 | // if(PortAWriteEnable) 57 | // begin 58 | // PortADataOut <= PortADataIn; 59 | // end 60 | // else 61 | // begin 62 | // PortADataOut <= mem[PortAAddr]; 63 | // end 64 | //end 65 | 66 | endmodule 67 | -------------------------------------------------------------------------------- /src/main/scala/Core/IDU/DecodeTable/AluDecodeTable.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU.DecodeTable 2 | 3 | import Core.IDU.FuncUnit._ 4 | import Core.IDU.Opcode.AluOpcode._ 5 | import Core.IDU.Opcode.SpecialOpcode._ 6 | import ISA.RV64Diff.trapInst 7 | import ISA.RV64I._ 8 | import Utils.Bits.BinaryConst.{F, T} 9 | import chisel3._ 10 | import chisel3.util.BitPat 11 | 12 | object AluDecodeTable { 13 | 14 | val table : Array[(BitPat, List[UInt])] = Array( 15 | // Fu opcode rs2 16 | // | | rs1| 17 | // | | rd | | 18 | lui -> List(ALU, LUI, T, F, F), 19 | auipc -> List(ALU, AUI_PC, T, F, F), // todo auipc -> List(ALU, SPECIAL, T, F, F), 20 | addi -> List(ALU, ADD, T, T, F), 21 | slti -> List(ALU, SLT, T, T, F), 22 | sltiu -> List(ALU, SLT, T, T, F), 23 | xori -> List(ALU, XOR, T, T, F), 24 | ori -> List(ALU, OR , T, T, F), 25 | andi -> List(ALU, AND, T, T, F), 26 | slli -> List(ALU, SLL, T, T, F), 27 | srli -> List(ALU, SRL, T, T, F), 28 | srai -> List(ALU, SRA, T, T, F), 29 | addiw -> List(ALU, ADDW,T, T, F), 30 | slliw -> List(ALU, SLLW,T, T, F), 31 | srliw -> List(ALU, SRLW,T, T, F), 32 | sraiw -> List(ALU, SRAW,T, T, F), 33 | addw -> List(ALU, ADDW,T, T, T), 34 | subw -> List(ALU, SUBW,T, T, T), 35 | sllw -> List(ALU, SLLW,T, T, T), 36 | srlw -> List(ALU, SRLW,T, T, T), 37 | sraw -> List(ALU, SRAW,T, T, T), 38 | add -> List(ALU, ADD, T, T, T), 39 | sub -> List(ALU, SUB, T, T, T), 40 | sll -> List(ALU, SLL, T, T, T), 41 | slt -> List(ALU, SLT, T, T, T), 42 | sltu -> List(ALU, SLTU,T, T, T), 43 | xor -> List(ALU, XOR, T, T, T), 44 | srl -> List(ALU, SRL, T, T, T), 45 | sra -> List(ALU, SRA, T, T, T), 46 | or -> List(ALU, OR, T, T, T), 47 | and -> List(ALU, AND, T, T, T), 48 | trapInst -> List(ALU, ADD, F, T, T), 49 | pseudo_auipc -> List(SPECIAL, PSEUDO_AUIPC, T, F, F), 50 | ) 51 | } 52 | -------------------------------------------------------------------------------- /src/main/scala/ISA/RV64A.scala: -------------------------------------------------------------------------------- 1 | package ISA 2 | 3 | import chisel3.util.BitPat 4 | 5 | object RV64A extends Decoder32Bits { 6 | // RV32A Standard Extension 7 | // |func5|aq|rl|-rs2-|-rs1-|-funct3-|--rd-|opcode| 8 | def lr_w = BitPat("b00010__?__?_00000_?????___010____?????_01011") 9 | def sc_w = BitPat("b00011__?__?_?????_?????___010____?????_01011") 10 | def amoswap_w = BitPat("b00001__?__?_?????_?????___010____?????_01011") 11 | def amoadd_w = BitPat("b00000__?__?_?????_?????___010____?????_01011") 12 | def amoxor_w = BitPat("b00100__?__?_?????_?????___010____?????_01011") 13 | def amoand_w = BitPat("b01100__?__?_?????_?????___010____?????_01011") 14 | def amoor_w = BitPat("b01000__?__?_?????_?????___010____?????_01011") 15 | def amomin_w = BitPat("b10000__?__?_?????_?????___010____?????_01011") 16 | def amomax_w = BitPat("b10100__?__?_?????_?????___010____?????_01011") 17 | def amominu_w = BitPat("b11000__?__?_?????_?????___010____?????_01011") 18 | def amomaxu_w = BitPat("b11100__?__?_?????_?????___010____?????_01011") 19 | // RV64A Standard Extension (in addition to RV32A) 20 | def lr_d = BitPat("b00010__?__?_00000_?????___011____?????_01011") 21 | def sc_d = BitPat("b00011__?__?_?????_?????___011____?????_01011") 22 | def amoswap_d = BitPat("b00001__?__?_?????_?????___011____?????_01011") 23 | def amoadd_d = BitPat("b00000__?__?_?????_?????___011____?????_01011") 24 | def amoxor_d = BitPat("b00100__?__?_?????_?????___011____?????_01011") 25 | def amoand_d = BitPat("b01100__?__?_?????_?????___011____?????_01011") 26 | def amoor_d = BitPat("b01000__?__?_?????_?????___011____?????_01011") 27 | def amomin_d = BitPat("b10000__?__?_?????_?????___011____?????_01011") 28 | def amomax_d = BitPat("b10100__?__?_?????_?????___011____?????_01011") 29 | def amominu_d = BitPat("b11000__?__?_?????_?????___011____?????_01011") 30 | def amomaxu_d = BitPat("b11100__?__?_?????_?????___011____?????_01011") 31 | } 32 | -------------------------------------------------------------------------------- /src/main/scala/Core/IDU/Opcode/StoreOpcode.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU.Opcode 2 | 3 | import chisel3._ 4 | 5 | trait StoreOpcode extends Opcode { 6 | def SB : UInt = "b0000000".U 7 | def SH : UInt = "b0000001".U 8 | def SW : UInt = "b0000010".U 9 | def SD : UInt = "b0000011".U 10 | def FSH : UInt = "b0010001".U 11 | def FSW : UInt = "b0010010".U 12 | def FSD : UInt = "b0010011".U 13 | def SRB : UInt = "b0100000".U 14 | def SRH : UInt = "b0100001".U 15 | def SRW : UInt = "b0100010".U 16 | def SRD : UInt = "b0100011".U 17 | def FSRW : UInt = "b0101010".U 18 | def FSRD : UInt = "b0101011".U 19 | def SURB : UInt = "b0110000".U 20 | def SURH : UInt = "b0110001".U 21 | def SURW : UInt = "b0110010".U 22 | def SURD : UInt = "b0110011".U 23 | def FSURW : UInt = "b0111010".U 24 | def FSURD : UInt = "b0111011".U 25 | def AMOSWAP_W : UInt = "b1000010".U 26 | def AMOADD_W : UInt = "b1001010".U 27 | def AMOAND_W : UInt = "b1010010".U 28 | def AMOOR_W : UInt = "b1011010".U 29 | def AMOXOR_W : UInt = "b1100010".U 30 | def AMOMIN_W : UInt = "b1101010".U 31 | def AMOMAX_W : UInt = "b1110010".U 32 | def AMOMINU_W : UInt = "b1101110".U 33 | def AMOMAXU_W : UInt = "b1110110".U 34 | def SC_W : UInt = "b1111010".U 35 | def AMOSWAP_D : UInt = "b1000011".U 36 | def AMOADD_D : UInt = "b1001011".U 37 | def AMOAND_D : UInt = "b1010011".U 38 | def AMOOR_D : UInt = "b1011011".U 39 | def AMOXOR_D : UInt = "b1100011".U 40 | def AMOMIN_D : UInt = "b1101011".U 41 | def AMOMAX_D : UInt = "b1110011".U 42 | def AMOMINU_D : UInt = "b1101111".U 43 | def AMOMAXU_D : UInt = "b1110111".U 44 | def SC_D : UInt = "b1111011".U 45 | // Todo: fsrw, fsrd, fsurw, fsurd 46 | def isAmo(op: UInt) : Bool = op(6, 6) === "b1".U 47 | def isSr(op: UInt) : Bool = op(6, 5) === "b01".U 48 | def isFloat(op: UInt) : Bool = op(6, 4) === "b0001".U || op(6, 4) === "b0101".U || op(6, 4) === "b0111".U 49 | def isNormal(op: UInt): Bool = op(6, 3) === "b0000".U 50 | def isUnsign(op: UInt): Bool = op(2) 51 | def maSize(op: UInt) : UInt = op(1, 0) 52 | } 53 | 54 | object StoreOpcode extends StoreOpcode 55 | -------------------------------------------------------------------------------- /src/main/scala/Core/IFU/IPDecode.scala: -------------------------------------------------------------------------------- 1 | package Core.IFU 2 | import Core.{Config, CoreBundle} 3 | import chisel3._ 4 | import chisel3.util._ 5 | import Utils._ 6 | 7 | class IPDecodeOutput extends CoreBundle { 8 | val auipc = Output(Vec(8+1,Bool())) 9 | val branch = Output(Vec(8+1,Bool())) 10 | val chgflw = Output(Vec(8+1,Bool())) 11 | val con_br = Output(Vec(8+1,Bool())) 12 | val dst_vld = Output(Vec(8+1,Bool())) 13 | val ind_br = Output(Vec(8+1,Bool())) 14 | val jal = Output(Vec(8+1,Bool())) 15 | val jalr = Output(Vec(8+1,Bool())) 16 | val call = Output(Vec(8+1,Bool())) 17 | val ret = Output(Vec(8+1,Bool())) 18 | val offset = Output(Vec(8+1,UInt(21.W))) 19 | val pc_oper = Output(Vec(8+1,Bool())) 20 | } 21 | 22 | class IPDecodeIO extends CoreBundle { 23 | val half_inst = Input(Vec(8+1,UInt(16.W))) 24 | val icache_br = Input(Vec(8+1,Bool())) 25 | 26 | val decode_info = new IPDecodeOutput 27 | } 28 | 29 | class IPDecode extends Module with Config { 30 | val io = IO(new IPDecodeIO) 31 | 32 | val inst = Wire(Vec(8+1,UInt(32.W))) 33 | for(i <- 0 until 8){ 34 | inst(i) := Cat(io.half_inst(i+1),io.half_inst(i)) 35 | } 36 | inst(8) := Cat(0.U(16.W),io.half_inst(8)) 37 | 38 | val ifu_decode = Seq.fill(8+1)(Module(new IFUDecode)) 39 | for(i <- 0 until 8+1){ 40 | ifu_decode(i).io.inst := inst(i) 41 | ifu_decode(i).io.icache_br := io.icache_br(i) 42 | } 43 | 44 | for(i <- 0 until 8+1){ 45 | io.decode_info.auipc(i) := ifu_decode(i).io.is_auipc 46 | io.decode_info.branch(i) := ifu_decode(i).io.is_branch 47 | io.decode_info.chgflw(i) := ifu_decode(i).io.is_chgflw 48 | io.decode_info.con_br(i) := ifu_decode(i).io.is_con_br 49 | io.decode_info.dst_vld(i) := ifu_decode(i).io.dst_valid 50 | io.decode_info.ind_br(i) := ifu_decode(i).io.is_ind_br 51 | io.decode_info.jal(i) := ifu_decode(i).io.is_jal 52 | io.decode_info.jalr(i) := ifu_decode(i).io.is_jalr 53 | io.decode_info.call(i) := ifu_decode(i).io.is_call 54 | io.decode_info.ret(i) := ifu_decode(i).io.is_return 55 | io.decode_info.offset(i) := ifu_decode(i).io.offset 56 | io.decode_info.pc_oper(i) := ifu_decode(i).io.is_pc_oper 57 | } 58 | // pc mask && changeflow mask 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/resources/ct_spsram_512x52.v: -------------------------------------------------------------------------------- 1 | /*Copyright 2019-2021 T-Head Semiconductor Co., Ltd. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | 16 | // &ModuleBeg; @22 17 | module ct_spsram_512x52( 18 | A, 19 | CEN, 20 | CLK, 21 | D, 22 | GWEN, 23 | Q, 24 | WEN 25 | ); 26 | 27 | // &Ports; @23 28 | input [8 :0] A; 29 | input CEN; 30 | input CLK; 31 | input [51:0] D; 32 | input GWEN; 33 | input [51:0] WEN; 34 | output [51:0] Q; 35 | 36 | // &Regs; @24 37 | 38 | // &Wires; @25 39 | wire [8 :0] A; 40 | wire CEN; 41 | wire CLK; 42 | wire [51:0] D; 43 | wire GWEN; 44 | wire [51:0] Q; 45 | wire [51:0] WEN; 46 | 47 | 48 | //********************************************************** 49 | // Parameter Definition 50 | //********************************************************** 51 | parameter ADDR_WIDTH = 9; 52 | parameter DATA_WIDTH = 52; 53 | parameter WE_WIDTH = 52; 54 | 55 | // &Force("bus","Q",DATA_WIDTH-1,0); @34 56 | // &Force("bus","WEN",WE_WIDTH-1,0); @35 57 | // &Force("bus","A",ADDR_WIDTH-1,0); @36 58 | // &Force("bus","D",DATA_WIDTH-1,0); @37 59 | 60 | //******************************************************** 61 | //* FPGA memory * 62 | //******************************************************** 63 | //{WEN[35:18],WEN[17:0]} 64 | // &Instance("ct_f_spsram_512x52"); @44 65 | ct_f_spsram_512x52 x_ct_f_spsram_512x52 ( 66 | .A (A ), 67 | .CEN (CEN ), 68 | .CLK (CLK ), 69 | .D (D ), 70 | .GWEN (GWEN), 71 | .Q (Q ), 72 | .WEN (WEN ) 73 | ); 74 | 75 | // &Instance("ct_tsmc_spsram_512x52"); @50 76 | 77 | // &ModuleEnd; @66 78 | endmodule 79 | 80 | 81 | -------------------------------------------------------------------------------- /src/main/resources/ct_spsram_512x54.v: -------------------------------------------------------------------------------- 1 | /*Copyright 2019-2021 T-Head Semiconductor Co., Ltd. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | 16 | // &ModuleBeg; @22 17 | module ct_spsram_512x54( 18 | A, 19 | CEN, 20 | CLK, 21 | D, 22 | GWEN, 23 | Q, 24 | WEN 25 | ); 26 | 27 | // &Ports; @23 28 | input [8 :0] A; 29 | input CEN; 30 | input CLK; 31 | input [53:0] D; 32 | input GWEN; 33 | input [53:0] WEN; 34 | output [53:0] Q; 35 | 36 | // &Regs; @24 37 | 38 | // &Wires; @25 39 | wire [8 :0] A; 40 | wire CEN; 41 | wire CLK; 42 | wire [53:0] D; 43 | wire GWEN; 44 | wire [53:0] Q; 45 | wire [53:0] WEN; 46 | 47 | 48 | //********************************************************** 49 | // Parameter Definition 50 | //********************************************************** 51 | parameter ADDR_WIDTH = 9; 52 | parameter DATA_WIDTH = 54; 53 | parameter WE_WIDTH = 54; 54 | 55 | // &Force("bus","Q",DATA_WIDTH-1,0); @34 56 | // &Force("bus","WEN",WE_WIDTH-1,0); @35 57 | // &Force("bus","A",ADDR_WIDTH-1,0); @36 58 | // &Force("bus","D",DATA_WIDTH-1,0); @37 59 | 60 | //******************************************************** 61 | //* FPGA memory * 62 | //******************************************************** 63 | //{WEN[37:19],WEN[18:0]} 64 | // &Instance("ct_f_spsram_512x54"); @44 65 | ct_f_spsram_512x54 x_ct_f_spsram_512x54 ( 66 | .A (A ), 67 | .CEN (CEN ), 68 | .CLK (CLK ), 69 | .D (D ), 70 | .GWEN (GWEN), 71 | .Q (Q ), 72 | .WEN (WEN ) 73 | ); 74 | 75 | // &Instance("ct_tsmc_spsram_512x54"); @50 76 | 77 | // &ModuleEnd; @66 78 | endmodule 79 | 80 | 81 | -------------------------------------------------------------------------------- /src/main/resources/ct_spsram_512x7.v: -------------------------------------------------------------------------------- 1 | /*Copyright 2019-2021 T-Head Semiconductor Co., Ltd. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | 16 | // &ModuleBeg; @22 17 | module ct_spsram_512x7( 18 | A, 19 | CEN, 20 | CLK, 21 | D, 22 | GWEN, 23 | Q, 24 | WEN 25 | ); 26 | 27 | // &Ports; @23 28 | input [8:0] A; 29 | input CEN; 30 | input CLK; 31 | input [6:0] D; 32 | input GWEN; 33 | input [6:0] WEN; 34 | output [6:0] Q; 35 | 36 | // &Regs; @24 37 | 38 | // &Wires; @25 39 | wire [8:0] A; 40 | wire CEN; 41 | wire CLK; 42 | wire [6:0] D; 43 | wire GWEN; 44 | wire [6:0] Q; 45 | wire [6:0] WEN; 46 | 47 | 48 | //********************************************************** 49 | // Parameter Definition 50 | //********************************************************** 51 | parameter ADDR_WIDTH = 9; 52 | parameter DATA_WIDTH = 7; 53 | parameter WE_WIDTH = 7; 54 | 55 | // &Force("bus","Q",DATA_WIDTH-1,0); @34 56 | // &Force("bus","WEN",WE_WIDTH-1,0); @35 57 | // &Force("bus","A",ADDR_WIDTH-1,0); @36 58 | // &Force("bus","D",DATA_WIDTH-1,0); @37 59 | 60 | //******************************************************** 61 | //* FPGA memory * 62 | //******************************************************** 63 | //{WEN[6],WEN[5],WEN[4],WEN[3],WEN[2],WEN[1],WEN[0]} 64 | // &Instance("ct_f_spsram_512x7"); @44 65 | ct_f_spsram_512x7 x_ct_f_spsram_512x7 ( 66 | .A (A ), 67 | .CEN (CEN ), 68 | .CLK (CLK ), 69 | .D (D ), 70 | .GWEN (GWEN), 71 | .Q (Q ), 72 | .WEN (WEN ) 73 | ); 74 | 75 | // &Instance("ct_tsmc_spsram_512x7"); @50 76 | 77 | // &ModuleEnd; @66 78 | endmodule 79 | 80 | 81 | -------------------------------------------------------------------------------- /src/main/resources/ct_spsram_2048x32.v: -------------------------------------------------------------------------------- 1 | /*Copyright 2019-2021 T-Head Semiconductor Co., Ltd. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | 16 | // &ModuleBeg; @22 17 | module ct_spsram_2048x32( 18 | A, 19 | CEN, 20 | CLK, 21 | D, 22 | GWEN, 23 | Q, 24 | WEN 25 | ); 26 | 27 | // &Ports; @23 28 | input [10:0] A; 29 | input CEN; 30 | input CLK; 31 | input [31:0] D; 32 | input GWEN; 33 | input [31:0] WEN; 34 | output [31:0] Q; 35 | 36 | // &Regs; @24 37 | 38 | // &Wires; @25 39 | wire [10:0] A; 40 | wire CEN; 41 | wire CLK; 42 | wire [31:0] D; 43 | wire GWEN; 44 | wire [31:0] Q; 45 | wire [31:0] WEN; 46 | 47 | 48 | //********************************************************** 49 | // Parameter Definition 50 | //********************************************************** 51 | parameter ADDR_WIDTH = 11; 52 | parameter DATA_WIDTH = 32; 53 | parameter WE_WIDTH = 32; 54 | 55 | // &Force("bus","Q",DATA_WIDTH-1,0); @34 56 | // &Force("bus","WEN",WE_WIDTH-1,0); @35 57 | // &Force("bus","A",ADDR_WIDTH-1,0); @36 58 | // &Force("bus","D",DATA_WIDTH-1,0); @37 59 | 60 | //******************************************************** 61 | //* FPGA memory * 62 | //******************************************************** 63 | //{WEN[31:24],WEN[23:16],WEN[15:8],WEN[7:0]} 64 | // &Instance("ct_f_spsram_2048x32"); @44 65 | ct_f_spsram_2048x32 x_ct_f_spsram_2048x32 ( 66 | .A (A ), 67 | .CEN (CEN ), 68 | .CLK (CLK ), 69 | .D (D ), 70 | .GWEN (GWEN), 71 | .Q (Q ), 72 | .WEN (WEN ) 73 | ); 74 | 75 | // &Instance("ct_tsmc_spsram_2048x32"); @50 76 | 77 | // &ModuleEnd; @66 78 | endmodule 79 | 80 | 81 | -------------------------------------------------------------------------------- /src/main/resources/ct_spsram_2048x32_split.v: -------------------------------------------------------------------------------- 1 | /*Copyright 2019-2021 T-Head Semiconductor Co., Ltd. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | 16 | // &ModuleBeg; @22 17 | module ct_spsram_2048x32_split( 18 | A, 19 | CEN, 20 | CLK, 21 | D, 22 | GWEN, 23 | Q, 24 | WEN 25 | ); 26 | 27 | // &Ports; @23 28 | input [10:0] A; 29 | input CEN; 30 | input CLK; 31 | input [31:0] D; 32 | input GWEN; 33 | input [31:0] WEN; 34 | output [31:0] Q; 35 | 36 | // &Regs; @24 37 | 38 | // &Wires; @25 39 | wire [10:0] A; 40 | wire CEN; 41 | wire CLK; 42 | wire [31:0] D; 43 | wire GWEN; 44 | wire [31:0] Q; 45 | wire [31:0] WEN; 46 | 47 | 48 | //********************************************************** 49 | // Parameter Definition 50 | //********************************************************** 51 | parameter ADDR_WIDTH = 11; 52 | parameter DATA_WIDTH = 32; 53 | parameter WE_WIDTH = 32; 54 | 55 | // &Force("bus","Q",DATA_WIDTH-1,0); @34 56 | // &Force("bus","WEN",WE_WIDTH-1,0); @35 57 | // &Force("bus","A",ADDR_WIDTH-1,0); @36 58 | // &Force("bus","D",DATA_WIDTH-1,0); @37 59 | 60 | //******************************************************** 61 | //* FPGA memory * 62 | //******************************************************** 63 | //{WEN[31:24],WEN[23:16],WEN[15:8],WEN[7:0]} 64 | // &Instance("ct_f_spsram_2048x32"); @44 65 | ct_f_spsram_2048x32 x_ct_f_spsram_2048x32 ( 66 | .A (A ), 67 | .CEN (CEN ), 68 | .CLK (CLK ), 69 | .D (D ), 70 | .GWEN (GWEN), 71 | .Q (Q ), 72 | .WEN (WEN ) 73 | ); 74 | 75 | // &Instance("ct_tsmc_spsram_2048x32_split"); @50 76 | 77 | // &ModuleEnd; @66 78 | endmodule 79 | 80 | 81 | -------------------------------------------------------------------------------- /src/main/scala/Utils/CircularQueuePtr.scala: -------------------------------------------------------------------------------- 1 | package Utils 2 | 3 | import chisel3._ 4 | import chisel3.util._ 5 | 6 | class CircularQueuePtr[T <: CircularQueuePtr[T]](val entries: Int) extends Bundle { 7 | 8 | val PTR_WIDTH = log2Up(entries) 9 | val flag = Bool() 10 | val value = UInt(PTR_WIDTH.W) 11 | 12 | override def toPrintable: Printable = { 13 | p"$flag:$value" 14 | } 15 | 16 | final def +(v: UInt): T = { 17 | val entries = this.entries 18 | val new_ptr = Wire(this.asInstanceOf[T].cloneType) 19 | if(isPow2(entries)){ 20 | new_ptr := (Cat(this.flag, this.value) + v).asTypeOf(new_ptr) 21 | } else { 22 | val new_value = this.value +& v 23 | val diff = Cat(0.U(1.W), new_value).asSInt() - Cat(0.U(1.W), entries.U.asTypeOf(new_value)).asSInt() 24 | val reverse_flag = diff >= 0.S 25 | new_ptr.flag := Mux(reverse_flag, !this.flag, this.flag) 26 | new_ptr.value := Mux(reverse_flag, 27 | diff.asUInt(), 28 | new_value 29 | ) 30 | } 31 | new_ptr 32 | } 33 | 34 | final def -(v: UInt): T = { 35 | val flipped_new_ptr = this + (this.entries.U - v) 36 | val new_ptr = Wire(this.asInstanceOf[T].cloneType) 37 | new_ptr.flag := !flipped_new_ptr.flag 38 | new_ptr.value := flipped_new_ptr.value 39 | new_ptr 40 | } 41 | 42 | final def === (that_ptr: T): Bool = this.asUInt()===that_ptr.asUInt() 43 | 44 | final def =/= (that_ptr: T): Bool = this.asUInt()=/=that_ptr.asUInt() 45 | } 46 | 47 | trait HasCircularQueuePtrHelper { 48 | 49 | def isEmpty[T <: CircularQueuePtr[T]](enq_ptr: T, deq_ptr: T): Bool = { 50 | enq_ptr === deq_ptr 51 | } 52 | 53 | def isFull[T <: CircularQueuePtr[T]](enq_ptr: T, deq_ptr: T): Bool = { 54 | (enq_ptr.flag =/= deq_ptr.flag) && (enq_ptr.value === deq_ptr.value) 55 | } 56 | 57 | def distanceBetween[T <: CircularQueuePtr[T]](enq_ptr: T, deq_ptr: T): UInt = { 58 | assert(enq_ptr.entries == deq_ptr.entries) 59 | Mux(enq_ptr.flag === deq_ptr.flag, 60 | enq_ptr.value - deq_ptr.value, 61 | enq_ptr.entries.U + enq_ptr.value - deq_ptr.value) 62 | } 63 | 64 | def isAfter[T <: CircularQueuePtr[T]](left: T, right: T): Bool = { 65 | Mux(left.flag === right.flag, left.value > right.value, left.value < right.value) 66 | } 67 | 68 | def isBefore[T <: CircularQueuePtr[T]](left: T, right: T): Bool = { 69 | Mux(left.flag === right.flag, left.value < right.value, left.value > right.value) 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/scala/Core/IDU/Opcode/LoadOpcode.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU.Opcode 2 | 3 | import chisel3._ 4 | 5 | trait LoadOpcode extends Opcode { 6 | def LB : UInt = "b0000000".U 7 | def LH : UInt = "b0000001".U 8 | def LW : UInt = "b0000010".U 9 | def LD : UInt = "b0000011".U 10 | def LBU : UInt = "b0000100".U 11 | def LHU : UInt = "b0000101".U 12 | def LWU : UInt = "b0000110".U 13 | def FLH : UInt = "b0001001".U 14 | def FLW : UInt = "b0001010".U 15 | def FLD : UInt = "b0001011".U 16 | def LRB : UInt = "b0100000".U 17 | def LRH : UInt = "b0100001".U 18 | def LRW : UInt = "b0100010".U 19 | def LRD : UInt = "b0100011".U 20 | def LRBU : UInt = "b0100100".U 21 | def LRHU : UInt = "b0100101".U 22 | def LRWU : UInt = "b0100110".U 23 | def FLRW : UInt = "b0101010".U 24 | def FLRD : UInt = "b0101011".U 25 | def LURB : UInt = "b0110000".U 26 | def LURH : UInt = "b0110001".U 27 | def LURW : UInt = "b0110010".U 28 | def LURD : UInt = "b0110011".U 29 | def LURBU : UInt = "b0110100".U 30 | def LURHU : UInt = "b0110101".U 31 | def LURWU : UInt = "b0110110".U 32 | def FLURW : UInt = "b0111010".U 33 | def FLURD : UInt = "b0111011".U 34 | def AMOSWAP_W : UInt = "b1000010".U 35 | def AMOADD_W : UInt = "b1001010".U 36 | def AMOAND_W : UInt = "b1010010".U 37 | def AMOOR_W : UInt = "b1011010".U 38 | def AMOXOR_W : UInt = "b1100010".U 39 | def AMOMIN_W : UInt = "b1101010".U 40 | def AMOMAX_W : UInt = "b1110010".U 41 | def AMOMINU_W : UInt = "b1101110".U 42 | def AMOMAXU_W : UInt = "b1110110".U 43 | def LR_W : UInt = "b1111010".U 44 | def AMOSWAP_D : UInt = "b1000011".U 45 | def AMOADD_D : UInt = "b1001011".U 46 | def AMOAND_D : UInt = "b1010011".U 47 | def AMOOR_D : UInt = "b1011011".U 48 | def AMOXOR_D : UInt = "b1100011".U 49 | def AMOMIN_D : UInt = "b1101011".U 50 | def AMOMAX_D : UInt = "b1110011".U 51 | def AMOMINU_D : UInt = "b1101111".U 52 | def AMOMAXU_D : UInt = "b1110111".U 53 | def LR_D : UInt = "b1111011".U 54 | def isAmo(op: UInt) : Bool = op(6, 6) === "b1".U 55 | def isLr(op: UInt) : Bool = op(6, 5) === "b01".U 56 | def isFloat(op: UInt) : Bool = op(6, 4) === "b0001".U || op(6, 4) === "b0101".U || op(6, 4) === "b0111".U 57 | def isNormal(op: UInt): Bool = op(6, 3) === "b0000".U 58 | def isUnsign(op: UInt): Bool = op(2) 59 | def maSize(op: UInt) : UInt = op(1, 0) 60 | } 61 | 62 | object LoadOpcode extends LoadOpcode 63 | -------------------------------------------------------------------------------- /src/main/scala/Core/IFU/BTB.scala: -------------------------------------------------------------------------------- 1 | package Core.IFU 2 | import Core.{Config, CoreBundle} 3 | import chisel3._ 4 | import chisel3.util._ 5 | 6 | class BTBUpdate extends CoreBundle { 7 | val btb_index = UInt(10.W) 8 | val btb_tag = UInt(10.W) 9 | val btb_data = UInt(20.W) 10 | } 11 | 12 | class BTBIO extends CoreBundle { 13 | val pc = Input(UInt(VAddrBits.W)) 14 | val btb_target = Vec(4,Valid(UInt(20.W))) 15 | val btb_update = Flipped(Valid(new BTBUpdate)) 16 | val ib_btb_mispred = Input(Bool()) 17 | } 18 | 19 | class BTB extends Module with Config { 20 | val io = IO(new BTBIO) 21 | 22 | //TODO: SRAM 23 | // val btb_valid = RegInit(VecInit(Seq.fill(1024)(VecInit(Seq.fill(4)(false.B))))) 24 | // val btb_tag = RegInit(VecInit(Seq.fill(1024)(VecInit(Seq.fill(4)(0.U(10.W)))))) 25 | val btb_valid = SyncReadMem(1024,Vec(4, Bool())) 26 | val btb_tag = SyncReadMem(1024,Vec(4, UInt(10.W))) 27 | val btb_data = SyncReadMem(1024,Vec(4, UInt(20.W))) 28 | // val btb_data = RegInit(VecInit(Seq.fill(1024)(VecInit(Seq.fill(4)(0.U(20.W)))))) 29 | 30 | val if_index = io.pc(13,4) 31 | val if_tag = WireInit(VecInit(Seq.fill(4)(0.U(10.W)))) 32 | for(i <- 0 until 4){ 33 | if_tag(i) := Cat(io.pc(20,14), 0.U(3.W)) + (i.U << 1.U) 34 | } 35 | 36 | 37 | for(i <- 0 until 4){ 38 | val tag = RegNext(if_tag(i)) 39 | io.btb_target(i).bits := btb_data.read(if_index)(tag(2,1)) 40 | io.btb_target(i).valid := btb_valid.read(if_index)(tag(2,1)) && btb_tag.read(if_index)(tag(2,1)) === tag 41 | } 42 | 43 | //btb_update 44 | val update_info = RegInit(0.U.asTypeOf(new BTBUpdate)) 45 | val update_valid = RegInit(false.B) 46 | when(io.btb_update.valid){ 47 | update_info := io.btb_update.bits 48 | update_valid := true.B 49 | } 50 | val update_wmask = Wire(Vec(4,Bool())) 51 | val update_write_data = Wire(Vec(4,UInt(20.W))) 52 | val update_write_tag = Wire(Vec(4,UInt(10.W))) 53 | for(i <- 0 until 4){ 54 | update_wmask(i) := update_info.btb_tag(2,1) === i.U 55 | update_write_data(i) := update_info.btb_data 56 | update_write_tag(i) := update_info.btb_tag 57 | } 58 | 59 | when(io.ib_btb_mispred && update_valid){ 60 | // btb_valid(update_info.btb_index)(update_info.btb_tag(2,1)) := true.B 61 | btb_valid.write(update_info.btb_index, VecInit(Seq.fill(4)(true.B)), update_wmask) 62 | btb_tag.write(update_info.btb_index, update_write_tag, update_wmask) 63 | btb_data.write(update_info.btb_index, update_write_data, update_wmask) 64 | // btb_tag(update_info.btb_index)(update_info.btb_tag(2,1) === ) := update_info.btb_tag 65 | // btb_data(update_info.btb_index)(update_info.btb_tag(2,1)) := update_info.btb_data 66 | update_valid := false.B 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/scala/Core/IFU/indBTB.scala: -------------------------------------------------------------------------------- 1 | package Core.IFU 2 | import Core.{Config, CoreBundle} 3 | import chisel3._ 4 | import chisel3.util._ 5 | 6 | class indBTBIO extends CoreBundle { 7 | val commit_jmp_path = Vec(3,Flipped(Valid(UInt(8.W))))//valid排序依次进入 8 | val rtu_jmp_mispred = Input(Bool()) 9 | val rtu_jmp_pc = Input(UInt(VAddrBits.W))//pc(21,1) 10 | val rtu_flush = Input(Bool()) 11 | 12 | val rtu_ghr = Input(UInt(8.W)) 13 | val bht_ghr = Input(UInt(8.W)) 14 | val ind_btb_path = Input(UInt(8.W))//pc(11,4) 15 | val ib_jmp_valid = Input(Bool()) 16 | 17 | val ind_btb_target = Output(UInt(20.W)) 18 | } 19 | 20 | class indBTB extends Module with Config { 21 | val io = IO(new indBTBIO) 22 | 23 | val target = RegInit(VecInit(Seq.fill(256)(0.U(20.W)))) 24 | val path_reg = RegInit(VecInit(Seq.fill(4)(0.U(8.W)))) 25 | val rtu_path_reg = RegInit(VecInit(Seq.fill(4)(0.U(8.W)))) 26 | 27 | val path_reg_pre = WireInit(VecInit(Seq.fill(4)(0.U(8.W)))) 28 | val rtu_path_reg_pre = WireInit(VecInit(Seq.fill(4)(0.U(8.W)))) 29 | 30 | val commit_jmp_cnt = PopCount(io.commit_jmp_path.map(_.valid)) 31 | for(i <- 0 until 4){ 32 | rtu_path_reg_pre(i) := Mux(i.U < commit_jmp_cnt, io.commit_jmp_path(commit_jmp_cnt-(i+1).U).bits, rtu_path_reg(i.U-commit_jmp_cnt)) 33 | } 34 | when(commit_jmp_cnt > 0.U){ 35 | rtu_path_reg := rtu_path_reg_pre 36 | } 37 | 38 | val path_reg_update = io.rtu_flush || io.rtu_jmp_mispred 39 | for(i <- 1 until 4){ 40 | path_reg_pre(i) := Mux(path_reg_update, rtu_path_reg_pre(i), Mux(io.ib_jmp_valid, path_reg(i-1), path_reg(i))) 41 | } 42 | path_reg_pre(0) := Mux(path_reg_update, rtu_path_reg_pre(0), Mux(io.ib_jmp_valid, io.ind_btb_path, path_reg(0))) 43 | 44 | path_reg := path_reg_pre 45 | 46 | val wr_idx = WireInit(0.U(8.W)) 47 | val rd_idx = WireInit(0.U(8.W)) 48 | // for(i <- 0 until 4){ 49 | // wr_idx(2*i+1,2*i) := rtu_path_reg_pre(i)(2*i+1,2*i) ^ io.rtu_ghr(2*i+1,2*i) 50 | // rd_idx(2*i+1,2*i) := path_reg_pre(i)(2*i+1,2*i) ^ io.bht_ghr(2*i+1,2*i) 51 | // } 52 | val wr_0 = rtu_path_reg_pre(0)(2*0+1,2*0) ^ io.rtu_ghr(2*0+1,2*0) 53 | val rd_0 = path_reg_pre(0)(2*0+1,2*0) ^ io.bht_ghr(2*0+1,2*0) 54 | val wr_1 = rtu_path_reg_pre(1)(2*1+1,2*1) ^ io.rtu_ghr(2*1+1,2*1) 55 | val rd_1 = path_reg_pre(1)(2*1+1,2*1) ^ io.bht_ghr(2*1+1,2*1) 56 | val wr_2 = rtu_path_reg_pre(2)(2*2+1,2*2) ^ io.rtu_ghr(2*2+1,2*2) 57 | val rd_2 = path_reg_pre(2)(2*2+1,2*2) ^ io.bht_ghr(2*2+1,2*2) 58 | val wr_3 = rtu_path_reg_pre(3)(2*3+1,2*3) ^ io.rtu_ghr(2*3+1,2*3) 59 | val rd_3 = path_reg_pre(3)(2*3+1,2*3) ^ io.bht_ghr(2*3+1,2*3) 60 | 61 | wr_idx := Cat(wr_0,wr_1,wr_2,wr_3) 62 | rd_idx := Cat(rd_0,rd_1,rd_2,rd_3) 63 | 64 | when(io.rtu_jmp_mispred){ 65 | target(wr_idx) := io.rtu_jmp_pc(21,1) 66 | } 67 | 68 | io.ind_btb_target := target(rd_idx) 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/scala/Core/IFU/uBTB.scala: -------------------------------------------------------------------------------- 1 | package Core.IFU 2 | import Utils.{CircularQueuePtr, HasCircularQueuePtrHelper, ParallelPriorityMux} 3 | import Core.{Config, CoreBundle} 4 | import chisel3._ 5 | import chisel3.util._ 6 | 7 | class uBTBPtr extends CircularQueuePtr[uBTBPtr](Config.uBTBSize) with HasCircularQueuePtrHelper 8 | 9 | class uBTBResp extends CoreBundle { 10 | val target_pc = UInt(VAddrBits.W) 11 | val hit_index = UInt(16.W) 12 | val is_ret = Bool() 13 | } 14 | 15 | class uBTBUpdateData extends CoreBundle { 16 | val entry_valid = Bool() 17 | val target = UInt(20.W) 18 | val tag = UInt(15.W) 19 | val ras = Bool() 20 | } 21 | 22 | class uBTBIO extends CoreBundle { 23 | val pc = Input(UInt(VAddrBits.W)) 24 | val ubtb_resp = Valid(new uBTBResp) 25 | val ras_pc = Input(UInt(VAddrBits.W)) //forward ras pc 26 | //update 27 | val update_data = Flipped(Valid(new uBTBUpdateData)) 28 | val update_idx = Flipped(Valid(UInt(16.W))) 29 | } 30 | 31 | class uBTB extends Module with Config with HasCircularQueuePtrHelper { 32 | val io = IO(new uBTBIO) 33 | 34 | val enqPtr = RegInit(0.U.asTypeOf(new uBTBPtr)) 35 | val ubtb_valid = RegInit(VecInit(Seq.fill(uBTBSize)(false.B))) 36 | val ubtb_target = RegInit(VecInit(Seq.fill(uBTBSize)(0.U(20.W)))) 37 | val ubtb_tag = RegInit(VecInit(Seq.fill(uBTBSize)(0.U(15.W)))) 38 | val ubtb_ras = RegInit(VecInit(Seq.fill(uBTBSize)(false.B))) 39 | 40 | val tag = io.pc(15,1) 41 | val hit_vec = WireInit(VecInit(Seq.fill(uBTBSize)(false.B))) 42 | for(i <- 0 until uBTBSize){ 43 | hit_vec(i) := ubtb_valid(i) && ubtb_tag(i) === tag 44 | } 45 | 46 | val bypass_hit = io.update_data.valid && io.update_data.bits.entry_valid && io.update_data.bits.tag === tag 47 | 48 | val entry_hit_target = ParallelPriorityMux(hit_vec.zip(ubtb_target)) 49 | val entry_hit_ras = ParallelPriorityMux(hit_vec.zip(ubtb_ras)) 50 | 51 | val target_pc = Mux(entry_hit_ras, io.ras_pc, Cat(io.pc(VAddrBits-1,21), entry_hit_target, 0.U(1.W))) 52 | val bypass_target = Cat(io.pc(VAddrBits-1,21), io.update_data.bits.target, 0.U(1.W)) 53 | 54 | io.ubtb_resp.valid := hit_vec.asUInt.orR || bypass_hit 55 | io.ubtb_resp.bits.target_pc := Mux(bypass_hit, bypass_target, target_pc) 56 | io.ubtb_resp.bits.hit_index := hit_vec.asUInt() 57 | io.ubtb_resp.bits.is_ret := entry_hit_ras 58 | 59 | //ubtb update 60 | val idx_OH2UInt = WireInit(0.U(5.W)) 61 | for(i <- 0 until 16){ 62 | when(io.update_idx.bits(i)){ 63 | idx_OH2UInt := i.U 64 | } 65 | } 66 | val update_index = WireInit(0.U(log2Up(uBTBSize).W)) 67 | when(io.update_data.valid && io.update_idx.valid){ 68 | update_index := idx_OH2UInt 69 | }.elsewhen(io.update_data.valid && !io.update_idx.valid){ 70 | update_index := enqPtr.value 71 | enqPtr := enqPtr + 1.U 72 | } 73 | 74 | when(io.update_data.valid){ 75 | ubtb_valid(update_index) := io.update_data.bits.entry_valid 76 | ubtb_target(update_index) := io.update_data.bits.target 77 | ubtb_tag (update_index) := io.update_data.bits.tag 78 | ubtb_ras(update_index) := io.update_data.bits.ras 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/scala/Core/IFU/ct_ifu_icache_refill.scala: -------------------------------------------------------------------------------- 1 | package Core.IFU 2 | 3 | import Core.Config 4 | import chisel3._ 5 | import chisel3.util._ 6 | 7 | 8 | // 9 | class ct_ifu_icache_refill extends Module with Config with CacheConfig { 10 | val io = IO(new icache_RefillIO) 11 | 12 | val paddr = Cat(0.U((XLEN-PAddrBits).W),io.req.bits.paddr) - PcStart.U(XLEN.W)//todo: change addr width 13 | val paddrReg = RegEnable(paddr,0.U(XLEN.W),io.req.valid) 14 | 15 | 16 | 17 | 18 | 19 | val ram = Module(new RAMHelper) 20 | ram.io.clk := clock 21 | ram.io.en := !reset.asBool() 22 | ram.io.rIdx := DontCare 23 | ram.io.wIdx := DontCare 24 | ram.io.wen := false.B 25 | ram.io.wdata := DontCare 26 | ram.io.wmask := DontCare 27 | 28 | 29 | val s_pf0 :: s_pf0_done :: s_pf1 :: s_pf1_done :: s_pf2 :: s_pf2_done :: s_pf3 :: s_pf3_done :: Nil = Enum(8) 30 | val state: UInt = RegInit(s_pf0) 31 | //replace等待axi4响应,如果是ramhelper一次64bit数据,一个缓存块64byte需要8次传输 32 | 33 | val SRam_write =RegInit(VecInit(Seq.fill(RefillTimes)(0.U(RamhelperBits.W)))) //往法 34 | 35 | 36 | //L2测试可先用ramhelper 37 | when(state === s_pf0 && io.req.valid) { 38 | ram.io.rIdx := (paddr ) >> 3.U//64bit一跳转//第一拍直接以请求当拍的paddr读,第二拍开始是用寄存器地址 39 | SRam_write(0) := ram.io.rdata 40 | }.elsewhen(state === s_pf0_done){ 41 | ram.io.rIdx := (paddrReg + 8.U) >> 3.U//64bit一跳转 //pc_reset(PC_WIDTH - 1, 0) 42 | SRam_write(1) := ram.io.rdata 43 | }.elsewhen(state === s_pf1){ 44 | ram.io.rIdx := (paddrReg + 16.U) >> 3.U 45 | SRam_write(0) := ram.io.rdata 46 | }.elsewhen(state === s_pf1_done){ 47 | ram.io.rIdx := (paddrReg + 24.U) >> 3.U 48 | SRam_write(1) := ram.io.rdata 49 | }.elsewhen(state === s_pf2){ 50 | ram.io.rIdx := (paddrReg + 32.U) >> 3.U 51 | SRam_write(0) := ram.io.rdata 52 | }.elsewhen(state === s_pf2_done){ 53 | ram.io.rIdx := (paddrReg + 40.U) >> 3.U 54 | SRam_write(1) := ram.io.rdata 55 | }.elsewhen(state === s_pf3){ 56 | ram.io.rIdx := (paddrReg + 48.U) >> 3.U 57 | SRam_write(0) := ram.io.rdata 58 | }.elsewhen(state === s_pf3_done){ 59 | ram.io.rIdx := (paddrReg + 56.U) >> 3.U 60 | SRam_write(1) := ram.io.rdata 61 | } 62 | 63 | io.resp.rdata := Cat(SRam_write(1),SRam_write(0)) 64 | io.resp.rvalid := 65 | (RegNext(state === s_pf0_done)) || 66 | (RegNext(state === s_pf1_done)) || 67 | (RegNext(state === s_pf2_done)) || 68 | (RegNext(state === s_pf3_done)) 69 | 70 | //-------------------------------------状态机------------------------------------------------ 71 | switch(state) { 72 | is(s_pf0) { 73 | when(io.req.valid) { 74 | state := s_pf0_done 75 | } 76 | } 77 | is(s_pf0_done) { 78 | state := s_pf1 79 | } 80 | is(s_pf1) { 81 | state := s_pf1_done 82 | } 83 | is(s_pf1_done) { 84 | state := s_pf2 85 | } 86 | is(s_pf2) { 87 | state := s_pf2_done 88 | } 89 | is(s_pf2_done) { 90 | state := s_pf3 91 | } 92 | is(s_pf3) { 93 | state := s_pf3_done 94 | } 95 | is(s_pf3_done) { 96 | state := s_pf0 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/scala/Core/IFU/CacheConfig.scala: -------------------------------------------------------------------------------- 1 | package Core.IFU 2 | 3 | import chisel3._ 4 | import chisel3.util._ 5 | import Core.{Config} 6 | 7 | trait CacheConfig extends Config { 8 | def AddrWidth = XLEN.W 9 | def pc_reset = PcStart.U(AddrWidth) 10 | def PC_WIDTH = 40 11 | def ICacheRead_WIDTH = 4 12 | def TotalSize = 64 //Kb //c910 parameter 13 | def Ways: Int = 2 14 | def LineSize = 64 // byte, 块大小 15 | def CacheDataBits = LineSize*8 //1字节是8比特 16 | def CacheCatNum = 4 //Cache读取次数 17 | def CacheCatBits = LineSize * 8/CacheCatNum //128 18 | def Sets = TotalSize * 1024 / LineSize / Ways //512 sets 19 | // def OffsetBits = log2Up(LineSize) //对应的是字节标号,= 6 20 | // def IndexBits = log2Up(Sets) //=9 21 | // def AddrHighBits = 64 - PC_WIDTH 22 | // def TagBits = PC_WIDTH - IndexBits - OffsetBits // = 25, C910里pc_width=40, tagbits=28, 采用虚拟地址作为index 23 | def TagBits = 28 24 | def TagHighdex = 39 25 | def TagLowdex = 12 26 | def IndexPCBits = 16 27 | def IndexHighdex = 14//13 28 | def IndexLowdex = 6//5 //目前暂假定就是实地址Index 29 | // (0 5), (6 13) 30 | // 1 6 , 7 14 31 | def DIndexLowdex = 4//3 32 | //def IndexBits = 9//todo:目前Icache和dcache存在共用定义,注意区分 33 | def DIndexBits = 11 34 | def axiDataBits = 128 //C910里似乎128bits 35 | def ICacheRespBits = 128 36 | def ICachePredecBits = 32 37 | def RetTimes = CacheDataBits/axiDataBits //=4*128/128=4 38 | def cacheUseTabCnt = 32 //是计数器? 39 | def sram_width = 32 //2048*32 bit 40 | def Banks = 4 41 | def MSHRSize = 4 42 | def RamhelperBits = 64 43 | def RefillTimes = CacheCatBits/RamhelperBits //=128/64=2 44 | // def addrBundle = new Bundle { 45 | // val addrhigh = UInt(AddrHighBits.W) 46 | // val tag = UInt(TagBits.W) 47 | // val index = UInt(IndexBits.W) 48 | // val Offset = UInt(OffsetBits.W) 49 | // } 50 | // def tag(addr: IndexedSeq[UInt]): IndexedSeq[UInt] = { 51 | // addr.map(_(TagHighdex,TagLowdex)) 52 | // } 53 | // def index(addr:IndexedSeq[UInt]): IndexedSeq[UInt] = { 54 | // addr.map(_(IndexHighdex,IndexLowdex)) 55 | // } 56 | def ftag(addr: UInt): UInt = { 57 | addr(TagHighdex,TagLowdex) 58 | } 59 | def findex(addr:UInt): UInt = { 60 | addr(IndexHighdex,IndexLowdex) 61 | } 62 | def fDindex(addr:UInt): UInt = { 63 | addr(IndexHighdex,DIndexLowdex) 64 | } 65 | } 66 | 67 | trait ifuConfig { 68 | def btb_index_bits = 10 69 | def btb_tag_bits = 10 70 | def btb_taget_pc_width = 20 71 | def l0_btb_update_entry_width = 16 72 | def l0_btb_wen_width = 4 73 | def pcgen_pc_width = 39 74 | def way_pred_width = 2 75 | def mmu_va_width = 63 76 | } 77 | 78 | class icache_RefillReq extends Bundle with CacheConfig { 79 | val paddr = Output(UInt(PC_WIDTH.W)) 80 | } 81 | 82 | class icache_RefillResp extends Bundle with CacheConfig { 83 | val rdata = Output(UInt(CacheCatBits.W)) 84 | val rvalid = Output(Bool()) 85 | } 86 | 87 | class icache_RefillIO extends Bundle with CacheConfig{ 88 | val req = Flipped(ValidIO(new icache_RefillReq)) 89 | val resp = new icache_RefillResp 90 | } 91 | 92 | class cohResp extends Bundle with CacheConfig { 93 | val forward = Vec(CacheCatNum,UInt((LineSize/CacheCatNum*8).W)) 94 | val needforward = Bool() 95 | } -------------------------------------------------------------------------------- /src/main/scala/Core/IFU/prefetch_buffer.scala: -------------------------------------------------------------------------------- 1 | package Core.IFU 2 | 3 | import Core.Config 4 | import chisel3._ 5 | import chisel3.util._ 6 | 7 | //todo:这里只考虑64位ramhelper 8 | class prefetch_bufferIO extends Bundle with Config with CacheConfig{ 9 | // val tag = Input(UInt(TagBits.W)) // 10 | // val offset = Input(UInt(2.W)) 11 | val vaddr = Input(UInt(PC_WIDTH.W)) 12 | val paddr = Input(UInt(PC_WIDTH.W)) 13 | val prefetch_valid = Input(Bool()) 14 | //val prefetch_data = Input(Vec(4,UInt(128.W))) 15 | val prefetch_addr = Input(UInt(TagBits.W)) 16 | val dout = ValidIO(Output(UInt(ICacheRespBits.W))) 17 | } 18 | 19 | class prefetch_buffer extends Module with Config with CacheConfig { 20 | def ramhelper_width = 64 21 | val io = IO(new prefetch_bufferIO) 22 | val tag_array = Seq.fill(Ways)(RegInit(0.U(TagBits.W))) 23 | val valid_array = Seq.fill(Ways)(RegInit(false.B)) 24 | val data_array = Seq.fill(Ways)(RegInit(Vec(CacheCatNum,0.U(CacheCatBits.W)))) 25 | val fifo = RegInit(0.U(1.W)) 26 | //计划设计为两行2*64byte,否则逻辑麻烦点 27 | val tagHitVec = Wire(Vec(Ways,Bool())) 28 | val tag = ftag(io.paddr) 29 | val index = findex(io.vaddr) 30 | val offset = index(2,1)//相当于PC前四位不看,从第5位开始,每变1 offset,就是下个128bit 31 | 32 | val prefetch_idx = Wire(UInt(PC_WIDTH.W)) 33 | val prefetch_tag = ftag(io.prefetch_addr) 34 | 35 | val icache_refill = Module(new ct_ifu_icache_refill) 36 | 37 | 38 | val refill_ready = Wire(Bool()) 39 | val refill_data = WireInit(Vec(CacheCatNum,0.U(CacheCatBits.W))) 40 | 41 | val state: UInt = RegInit(s_idle) 42 | val s_idle :: s_wait_refill :: s_refill :: Nil = Enum(3) 43 | //replace等待axi4响应,如果是ramhelper一次64bit数据,一个缓存块64byte需要8次传输 44 | 45 | icache_refill.io.req.valid := io.prefetch_valid 46 | icache_refill.io.req.bits.paddr := io.prefetch_addr 47 | refill_ready := icache_refill.io.resp.rvalid 48 | refill_data := icache_refill.io.resp.rdata 49 | 50 | 51 | for (i <- 0 until Ways) { 52 | tagHitVec(i) := io.dout.valid && valid_array(i) && tag_array(i) === tag 53 | } 54 | val hit = Wire(Bool()) 55 | hit := Mux(fifo===0.U(1.W),tagHitVec(0),tagHitVec(1)) //因为是逐路读写 56 | 57 | when(state===s_idle && hit){ 58 | io.dout.valid := true.B 59 | }.otherwise{ 60 | io.dout.valid := false.B 61 | } 62 | io.dout.bits := Mux(fifo===0.U(1.W),data_array(0).asUInt() >> (offset << 7.U),data_array(1).asUInt() >> (offset << 7.U))//<<7.U即 *128.U 63 | 64 | for( i<- 0 until CacheCatNum){//这里先按C910考虑sram一次读写128bit 65 | when(state === s_refill){ 66 | when(fifo===0.U){ 67 | tag_array(0) := prefetch_tag //下一拍生效,生效同时转为idle 68 | valid_array(0) := true.B 69 | data_array(0) := refill_data.asTypeOf(data_array(0))//下一拍生效,生效同时转为idle 70 | }.otherwise{ 71 | tag_array(1) := prefetch_tag 72 | valid_array(1) := true.B 73 | data_array(1) := refill_data.asTypeOf(data_array(1)) 74 | } 75 | } 76 | } 77 | 78 | 79 | //-------------------------------------状态机------------------------------------------------ 80 | switch(state) { 81 | is(s_idle) { 82 | when(io.prefetch_valid) { 83 | state := s_wait_refill 84 | } 85 | } 86 | is(s_wait_refill) { 87 | when(refill_ready) { //什么是非阻塞式缓存,是否有必要每拍写入一部分数据,ans:应该不用,因为tag没变。 88 | state := s_refill 89 | } 90 | } 91 | is(s_refill) { 92 | state := s_idle 93 | fifo := ~fifo 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/exclude/IU/Bju/PcFifo.scala: -------------------------------------------------------------------------------- 1 | package Core.IU.Bju 2 | 3 | import Core.AddrConfig.PcWidth 4 | import Core.IUConfig.PcFifoLen 5 | import Utils.{CircularQueuePtr, HasCircularQueuePtrHelper} 6 | import chisel3._ 7 | import chisel3.util._ 8 | 9 | class PcFifoPtr extends CircularQueuePtr[PcFifoPtr](PcFifoLen){ 10 | override def cloneType = (new PcFifoPtr).asInstanceOf[this.type] 11 | } 12 | 13 | object PcFifoPtr { 14 | def apply(f: Bool, v:UInt): PcFifoPtr = { 15 | val ptr = Wire(new PcFifoPtr) 16 | ptr.flag := f 17 | ptr.value := v 18 | ptr 19 | } 20 | } 21 | 22 | class IduWriteIO extends Bundle{ 23 | val writePcfifo = Vec(2,Input(new IfuPredStore)) 24 | val alloPid = Vec(2, Output(UInt(5.W))) 25 | } 26 | class PidIO extends Bundle{ 27 | val read = Input(UInt(5.W)) 28 | val write = Output(UInt(5.W)) 29 | } 30 | class BjuRwIO extends Bundle { 31 | val readPcfifo = Output(new IfuPredStore) 32 | val pid = new PidIO 33 | val writePcfifo = Valid(Input(new PredCheckRes)) 34 | 35 | val specialPid = Input(UInt(5.W)) 36 | val specialPc = Output(UInt(PcWidth.W)) 37 | } 38 | class RobReadIO extends Bundle{ 39 | val ifu_pred = Output(new IfuPredStore) 40 | val bht_check = Output(new PredCheckRes) 41 | val dealloPid = Input(Bool()) 42 | } 43 | class PcFifoIO extends Bundle{ 44 | val iduWrite = Valid(new IduWriteIO) // valid to out - pcfifo is full ? bht can not in : bht can in 45 | val bjuRw = new BjuRwIO 46 | val robRead = new RobReadIO 47 | } 48 | 49 | class PcFifo extends Module with HasCircularQueuePtrHelper{ 50 | // PcFifo storage 3 data: chk_idx, bht_pred, jmp_mispred 51 | val io = IO(new PcFifoIO()) 52 | val ifu_forward_data = io.iduWrite.bits.writePcfifo // how to name this data? just use same name whit XT910, ct_io_bju_fio.v @1677 - 1693 53 | 54 | var fifo_tab_pred = RegInit(VecInit(Seq.fill(PcFifoLen)( 0.U.asTypeOf(new IfuPredStore) ))) 55 | var fifo_tab_check = RegInit(VecInit(Seq.fill(PcFifoLen)( 0.U.asTypeOf(new PredCheckRes) ))) 56 | 57 | val headPtr = RegInit(PcFifoPtr(false.B, 0.U)) 58 | val tailPtr = RegInit(PcFifoPtr(true.B, 0.U)) 59 | val is_full = distanceBetween(tailPtr, headPtr) < 2.U 60 | io.iduWrite.valid := is_full 61 | // idu write in & allocate ptr 62 | val allocatePtrs = (0 until 2).map(i => headPtr + i.U) // is_full to control allo_ptr 63 | for(i <- 0 until 2){ 64 | io.iduWrite.bits.alloPid(i) := allocatePtrs(i).value 65 | } 66 | for(i <- 0 until 2){ 67 | val offset = i.U //if(i == 0) 0.U else PopCount(ifu_forward_data(i).en ) // TODO ? 68 | val ptr = tailPtr + offset 69 | val idx = ptr.value 70 | fifo_tab_pred(idx) := ifu_forward_data(i) 71 | } 72 | // bju read by pid 73 | val bju_read_pid = io.bjuRw.pid.read 74 | val readData = fifo_tab_pred(bju_read_pid) // VecInit(bju_read_pid.map(addr => fifo_tab_pred(addr))) 75 | // bju write by pid 76 | val bju_write_pid = io.bjuRw.pid.write 77 | when(io.bjuRw.writePcfifo.valid){ 78 | fifo_tab_check(bju_write_pid) := io.bjuRw.writePcfifo.bits 79 | } 80 | // rob read & deallocate ptr 81 | when(io.robRead.dealloPid){ 82 | io.robRead.bht_check := fifo_tab_check(tailPtr.value) 83 | io.robRead.ifu_pred := fifo_tab_pred(tailPtr.value) 84 | val tailPtrNext = tailPtr + 1.U 85 | tailPtr := tailPtrNext 86 | } 87 | 88 | // Speical read, to Special Unit, auipc inst 89 | io.bjuRw.specialPc := fifo_tab_pred(io.bjuRw.specialPc).pc 90 | 91 | 92 | } 93 | -------------------------------------------------------------------------------- /src/main/scala/Core/IFU/PCGen.scala: -------------------------------------------------------------------------------- 1 | package Core.IFU 2 | import Core.Config 3 | import chisel3._ 4 | import chisel3.util._ 5 | 6 | 7 | class PCGen extends Module with Config { 8 | val io = IO(new PCGenIO) 9 | 10 | val pcReg = RegInit(PcStart.U(VAddrBits.W)) 11 | val pcWire = WireInit(PcStart.U(VAddrBits.W)) 12 | val ifpc_chgflw_pre = Wire(UInt(VAddrBits.W)) 13 | val inc_pc = WireInit(PcStart.U(VAddrBits.W)) 14 | val rtu_cur_pc = WireInit(PcStart.U(VAddrBits.W)) 15 | val rtu_cur_pc_load = WireInit(false.B) 16 | val ifu_rtu_cur_pcReg = RegInit(PcStart.U(VAddrBits.W)) 17 | val ifu_rtu_cur_pc_loadReg = WireInit(false.B) 18 | val pcgen_chgflw = io.redirect.map(_.valid).reduce(_||_) //|| io.rtu_ifu_chgflw_vld 19 | // &Force("bus","ipctrl_pcgen_taken_pc",38,0); @28 20 | //========================================================== 21 | // PC MUX of Change Flow 22 | //========================================================== 23 | //The Priority of PC is as following: 24 | // PC from Had 25 | // PC from Vector 26 | // PC from RTU 27 | // PC from IU 28 | // PC from Addrgen 29 | // PC from IFU IB Stage Change Flow 30 | // PC from IFU IP Stage Reissue 31 | // PC from IFU IP Stage Change Flow 32 | // PC from IFU IF Stage Reissue 33 | // PC Increase 34 | // &CombBeg; @43 35 | ifpc_chgflw_pre := PriorityMux(Seq( 36 | //io.rtu_ifu_chgflw_vld -> io.rtu_ifu_chgflw_pc,//todo: complete it in future 37 | io.redirect(3).valid -> io.redirect(3).bits,//io.redirect(3).bits, 38 | io.redirect(2).valid -> io.redirect(2).bits,//io.redirect(2).bits, 39 | io.redirect(1).valid -> io.redirect(1).bits,//io.redirect(1).bits, 40 | io.redirect(0).valid -> io.redirect(0).bits,//io.redirect(0).bits, 41 | //io.redirect(0).valid -> io.redirect(0).bits, 42 | true.B -> "h80000000".U 43 | )) 44 | 45 | inc_pc := Cat(pcReg(VAddrBits-1,4), 0.U(4.W)) + 16.U 46 | //true.B, io.redirect(0).bits can ? 47 | //false.B, io.redirect(0).bits can be compiled !!! 48 | //io.redirect(0).valid, io.redirect(0).bits can not be compiled !!! 49 | //io.redirect(1).valid can be compiled !!! 50 | //io.redirect(0).valid can be compiled !!! 51 | //false.B can be compiled 52 | //pc := Mux(io.redirect(3).valid,io.redirect(3).bits,Mux(io.redirect(2).valid,io.redirect(2).bits,Mux(io.redirect(1).valid,io.redirect(1).bits,Mux(io.redirect(0).valid,io.redirect(0).bits,(Cat(pcReg(VAddrBits-1,4), 0.U(4.W)) + 16.U))))) 53 | //pcWire := Mux(io.continue,Cat(pcReg(VAddrBits-1,4), 0.U(4.W)) + 16.U,pcReg) 54 | when(io.continue){ 55 | pcReg := Mux(pcgen_chgflw,ifpc_chgflw_pre,Mux(io.continue,inc_pc,pcReg)) 56 | } 57 | 58 | io.pc := pcReg 59 | 60 | //========================================================== 61 | // Interface with RTU 62 | //========================================================== 63 | rtu_cur_pc_load := io.had_ifu_pcload || io.vector_pcgen_pcload 64 | rtu_cur_pc := Mux(io.had_ifu_pcload, io.had_ifu_pc, io.vector_pcgen_pc) 65 | 66 | ifu_rtu_cur_pc_loadReg := rtu_cur_pc_load 67 | ifu_rtu_cur_pcReg := Mux(io.continue, pcReg, Mux(rtu_cur_pc_load, rtu_cur_pc, ifu_rtu_cur_pcReg)) //////todo: fix this logic 68 | 69 | io.ifu_rtu_cur_pc_load := ifu_rtu_cur_pc_loadReg 70 | io.ifu_rtu_cur_pc := ifu_rtu_cur_pcReg 71 | 72 | //-----------------------IB Cancel-------------------------- 73 | io.ibctrl_cancel := io.had_ifu_pcload || 74 | io.vector_pcgen_pcload || 75 | io.rtu_ifu_chgflw_vld || 76 | io.redirect(3).valid 77 | //|| io.rtu_ifu_xx_expt_vld todo 78 | //|| dbg_cancel 79 | 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/scala/Core/IDU/IDUBundle.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU 2 | import chisel3._ 3 | import chisel3.util._ 4 | 5 | class ir_srcMatch extends Bundle{ 6 | val srcv2 = Bool() 7 | val src2 = Bool() 8 | val src1 = Bool() 9 | val src0 = Bool() 10 | } 11 | 12 | class rt_srcMatch extends Bundle{ 13 | val src2 = Bool() 14 | val src1 = Bool() 15 | val src0 = Bool() 16 | } 17 | 18 | class srcData9 extends Bundle{ 19 | val preg = UInt(7.W) 20 | val wb = Bool() 21 | val rdy = Bool() 22 | } 23 | 24 | class srcData10 extends Bundle{ 25 | val rdy = Bool() 26 | val preg = UInt(7.W) 27 | val wb = Bool() 28 | val mla_rdy = Bool() 29 | } 30 | 31 | //rename table 32 | class rtInstReq extends Bundle{ 33 | val dst_preg = UInt(7.W) 34 | val dst_reg = UInt(6.W) 35 | val dst_vld = Bool() 36 | val mla = Bool() 37 | val mov = Bool() 38 | val src_reg = Vec(2, UInt(6.W)) 39 | val src_vld = Vec(3, Bool()) 40 | } 41 | 42 | class rtInstResp extends Bundle{ 43 | val rel_preg = UInt(7.W) 44 | val src0_data = new srcData9 45 | val src1_data = new srcData9 46 | val src2_data = new srcData10 47 | } 48 | 49 | class RT_Req extends Bundle{ 50 | val depInfo = new DepInfo 51 | val instInfo = Vec(4, Flipped(Valid(new rtInstReq))) 52 | } 53 | 54 | class RT_Resp extends Bundle{ 55 | // 0 depends on 1, 02 03 12 13 23 56 | val srcMatch = Vec(6, new rt_srcMatch) // 同一拍的指令关联性 57 | val instInfo = Vec(4, new rtInstResp) // 和 58 | } 59 | 60 | //float rename table 61 | class frtInstReq extends Bundle{ 62 | val dst_ereg = UInt(5.W) 63 | val dst_freg = UInt(6.W) 64 | val dste_vld = Bool() 65 | val dstf_reg = UInt(6.W) 66 | val dstf_vld = Bool() 67 | 68 | val fmla = Bool() 69 | val fmov = Bool() 70 | val srcf_reg = Vec(3, UInt(6.W)) 71 | val srcf_vld = Vec(3, Bool()) 72 | } 73 | 74 | class frtInstResp extends Bundle{ 75 | val rel_ereg = UInt(5.W) 76 | val rel_freg = UInt(7.W) 77 | val srcf0_data = new srcData9 78 | val srcf1_data = new srcData9 79 | val srcf2_data = new srcData10 80 | } 81 | 82 | class FRT_Req extends Bundle{ 83 | val depInfo = new DepInfo 84 | val instInfo = Vec(4, Flipped(Valid(new frtInstReq))) 85 | } 86 | 87 | class FRT_Resp extends Bundle{ 88 | val srcf2Match = Vec(6, new Bool()) 89 | val instInfo = Vec(4, new frtInstResp) 90 | } 91 | 92 | //vector rename table 93 | class vrtInstReq extends Bundle{ 94 | val dst_vreg = UInt(6.W) 95 | val dstv_reg = UInt(6.W) 96 | val dstv_vld = Bool() 97 | 98 | val vmla = Bool() 99 | val srcv_reg = Vec(2, UInt(6.W)) 100 | val srcv_vld = Vec(3, Bool()) 101 | val srcvm_vld = Bool() 102 | } 103 | 104 | class vrtInstResp extends Bundle{ 105 | val rel_vreg = UInt(7.W) 106 | val srcv0_data = new srcData9 107 | val srcv1_data = new srcData9 108 | val srcv2_data = new srcData10 109 | val srcvm_data = new srcData9 110 | } 111 | 112 | class VRT_Req extends Bundle{ 113 | val instInfo = Vec(4, new vrtInstReq) 114 | } 115 | 116 | class VRT_Resp extends Bundle{ 117 | val srcv2Match = Vec(6, new Bool()) 118 | val instInfo = Vec(4, new vrtInstResp) 119 | } 120 | 121 | 122 | class IR_preDispatch extends Bundle{ 123 | val inst_vld = Vec(4, Bool()) 124 | //aiq0 aiq1 biq lsiq sdiq viq0 viq1 vmb 125 | val iq_create_sel = Vec(8 ,Vec(2, Valid(UInt(2.W)))) 126 | val pipedown2 = Bool() 127 | val pst_create_iid_sel = Vec(3, UInt(3.W)) 128 | val rob_create = new Bundle{ 129 | val sel0 = UInt(2.W) 130 | val en1 = Bool() 131 | val sel1 = UInt(3.W) 132 | val en2 = Bool() 133 | val sel2 = UInt(2.W) 134 | val en3 = Bool() 135 | } 136 | } 137 | 138 | 139 | //ISStage 140 | class IQCntInfo extends Bundle { 141 | val left_1_updt = Bool() 142 | val empty = Bool() 143 | val full = Bool() 144 | val full_updt = Bool() 145 | val full_updt_clk_en = Bool() 146 | } 147 | 148 | 149 | -------------------------------------------------------------------------------- /src/exclude/IU/Rbus.scala: -------------------------------------------------------------------------------- 1 | package Core.IU 2 | import Core.IU.Du.DuOut 3 | import Core.IntConfig 4 | import chisel3._ 5 | import chisel3.util.{is, _} 6 | 7 | class RbusIn extends Bundle { 8 | val aluIn = (Vec(2,new AluOut)) 9 | val muIn = new MuOut 10 | val duIn = new DuOut 11 | val specialIn = new SpecialOut // althoug only need (data, dataVld, preg) 12 | } 13 | class RbusOut extends Bundle { 14 | val wbPreg = UInt(7.W) 15 | val wbData = UInt(XLEN.W) 16 | val wbPregVld = Bool() 17 | } 18 | 19 | class RbusIO extends Bundle { 20 | val in = Input(new RbusIn) 21 | val flush = Input(Bool()) 22 | val out = Output(Vec(3, new RbusOut)) 23 | } 24 | class Rbus extends Module with IUConfig { 25 | val io = IO(new RbusIO) 26 | val pipe_rslt_vld = Seq.fill(IuPipeNum)(Wire(Bool())) 27 | pipe_rslt_vld.head := io.in.aluIn(0).dataVld || io.in.duIn.pipe0DataVld || io.in.specialIn.dataVld 28 | pipe_rslt_vld(1) := io.in.aluIn(1).dataVld || io.in.muIn.dataVld 29 | //---------------------------------------------------------- 30 | // Write Back Valid 31 | //---------------------------------------------------------- 32 | val pipe_wb_vld = Seq.fill(IuPipeNum)(RegInit(false.B)) 33 | for(i<- 0 until IuPipeNum){ 34 | when(io.flush){ 35 | pipe_wb_vld(i) := false.B 36 | }otherwise{ 37 | pipe_wb_vld(i) := pipe_rslt_vld(i) 38 | } 39 | } 40 | //---------------------------------------------------------- 41 | // Write Back Data Selection 42 | //---------------------------------------------------------- 43 | //---------------------------------------------------------- 44 | // Pipe 0 45 | //---------------------------------------------------------- 46 | val pipe0_select = Cat(io.in.aluIn(0).dataVld ,io.in.duIn.pipe0DataVld ,io.in.specialIn.dataVld) // TODO add CP0 47 | val pipe0_rslt_preg = RegInit(0.U(7.W)) 48 | switch(pipe0_select){ 49 | is("b100".U){ 50 | pipe0_rslt_preg := io.in.aluIn(0).preg 51 | } 52 | is("b010".U){ 53 | pipe0_rslt_preg := io.in.duIn.preg 54 | } 55 | is("b001".U){ 56 | pipe0_rslt_preg := io.in.specialIn.preg 57 | } 58 | } 59 | val pipe0_rslt_data = RegInit(0.U(XLEN.W)) 60 | switch(pipe0_select){ 61 | is("b100".U){ 62 | pipe0_rslt_data := io.in.aluIn(0).data 63 | } 64 | is("b010".U){ 65 | pipe0_rslt_data := io.in.duIn.data 66 | } 67 | is("b001".U){ 68 | pipe0_rslt_data := io.in.specialIn.data 69 | } 70 | } 71 | val pipe0_wb_rslt_preg = RegEnable(pipe0_rslt_preg, pipe_rslt_vld.head) 72 | val pipe0_wb_rslt_data = RegEnable(pipe0_rslt_data, pipe_rslt_vld.head) 73 | io.out(0).wbPreg := pipe0_wb_rslt_preg 74 | io.out(0).wbData := pipe0_wb_rslt_data 75 | io.out(0).wbPregVld := pipe_wb_vld(0) 76 | //---------------------------------------------------------- 77 | // Pipe 1 78 | //---------------------------------------------------------- 79 | val pipe1_select = Cat(io.in.aluIn(1).dataVld ,io.in.muIn.dataVld) // TODO add CP0 80 | val pipe1_rslt_preg = RegInit(0.U(7.W)) 81 | switch(pipe1_select){ 82 | is("b10".U){ 83 | pipe1_rslt_preg := io.in.aluIn(1).preg 84 | } 85 | is("b01".U){ 86 | pipe1_rslt_preg := io.in.muIn.preg 87 | } 88 | } 89 | val pipe1_rslt_data = RegInit(0.U(XLEN.W)) 90 | switch(pipe1_select){ 91 | is("b10".U){ 92 | pipe1_rslt_data := io.in.aluIn(1).data 93 | } 94 | is("b01".U){ 95 | pipe1_rslt_data := io.in.muIn.data 96 | } 97 | } 98 | val pipe1_wb_rslt_preg = RegEnable(pipe1_rslt_preg, pipe_rslt_vld(1)) 99 | val pipe1_wb_rslt_data = RegEnable(pipe1_rslt_data, pipe_rslt_vld(1)) 100 | io.out(1).wbPreg := pipe1_wb_rslt_preg 101 | io.out(1).wbData := pipe1_wb_rslt_data 102 | io.out(1).wbPregVld := pipe_wb_vld(1) 103 | 104 | } 105 | -------------------------------------------------------------------------------- /src/exclude/IU/IntegeUnit.scala: -------------------------------------------------------------------------------- 1 | package Core.IU 2 | import Core.FuncOpType 3 | import Core.IU.Bju.{BhtPredDataForward, Bju} 4 | import Core.IU.Du.Du 5 | import chisel3._ 6 | import chisel3.util._ 7 | 8 | class CtrlSignalIO extends Bundle{ 9 | val src0 = UInt(64.W) 10 | val src1 = UInt(64.W) 11 | val func = FuncOpType.uwidth 12 | val iid = UInt(5.W) // ROB PTR 13 | } 14 | 15 | class CtrlSignalHasDestIO extends CtrlSignalIO{ 16 | val aluShort = Bool() 17 | val dstPreg = UInt(7.W) 18 | val dstVld = Bool() 19 | val src1NoImm = UInt(64.W) 20 | val src2 = UInt(64.W) 21 | val imm = UInt(7.W) 22 | val sel = Bool() 23 | } 24 | class IduRfPipe0 extends CtrlSignalHasDestIO{ 25 | val opcode = UInt(32.W) 26 | val specialImm = UInt(20.W) 27 | val exptVec = UInt(5.W) 28 | val exptVld = Bool() 29 | val highHwExpt = Bool() 30 | val divSel = Input(Bool()) 31 | } 32 | class IduRfPipe1 extends CtrlSignalHasDestIO{ 33 | val multFunc = UInt(8.W) 34 | val mlaSrc2Preg = UInt(7.W) 35 | val mlaSrc2Vld = Bool() 36 | val mulSel = Input(Bool()) 37 | } 38 | class IduRfPipe2 extends CtrlSignalIO{ 39 | val pid = UInt(5.W) 40 | val specialPid = UInt(5.W) 41 | val length = Bool() 42 | val offset = UInt(21.W) 43 | val pcall = Bool() 44 | val rts = Bool() 45 | } 46 | 47 | class IntegerUnitIO extends Bundle{ 48 | // to alu0, special, div 49 | val idu_iu_rf_pipe0 = Flipped(ValidIO(new IduRfPipe0)) 50 | // to alu1&mult 51 | val idu_iu_rf_pipe1 = Input(new IduRfPipe1) 52 | // to BJU 53 | val idu_iu_rf_pipe2 = Input(new IduRfPipe2) 54 | val ifuForward = Flipped(DecoupledIO(Vec(2,new BhtPredDataForward))) 55 | } 56 | 57 | class IntegeUnit extends Module{ 58 | val io = IO(new IntegerUnitIO) 59 | //========================================================== 60 | // Pipeline 0 - alu0, special, div 61 | //========================================================== 62 | val alu0 = Module(new Alu) 63 | val special = Module(new Special) 64 | val du = Module(new Du) 65 | alu0.io.in := io.idu_iu_rf_pipe0 66 | special.io.in := io.idu_iu_rf_pipe0 67 | du.io.in := io.idu_iu_rf_pipe0 68 | //========================================================== 69 | // Pipeline 1 - alu1, mult 70 | //========================================================== 71 | val alu1 = Module(new Alu) 72 | val mu = Module(new Mu) 73 | alu1.io.in := io.idu_iu_rf_pipe1 74 | mu.io.in := io.idu_iu_rf_pipe1 75 | //========================================================== 76 | // Pipeline 2 - bju 77 | //========================================================== 78 | val bju = Module(new Bju) 79 | bju.io.in.ifuForward := io.ifuForward 80 | bju.io.in.rfPipe2 := io.idu_iu_rf_pipe2 81 | // special pc io should be below Module 'bju' & 'special', because 'Suspicious forward reference' 82 | special.io.bjuSpecialPc := bju.io.out.specialPc 83 | //========================================================== 84 | // Cbus - Iu pipes complete signal process 85 | //========================================================== 86 | val cbus = Module(new Cbus) 87 | cbus.io.normIn.divSel := io.idu_iu_rf_pipe0.bits.divSel 88 | cbus.io.normIn.pipe0Sel := io.idu_iu_rf_pipe0.bits.sel 89 | cbus.io.normIn.pipe0Iid := io.idu_iu_rf_pipe0.bits.iid 90 | cbus.io.normIn.multSel := io.idu_iu_rf_pipe1.mulSel 91 | cbus.io.normIn.pipe1Sel := io.idu_iu_rf_pipe1.sel 92 | cbus.io.normIn.pipe1Iid := io.idu_iu_rf_pipe1.iid 93 | cbus.io.bjuIn := bju.io.out.toCbus 94 | 95 | //========================================================== 96 | // Rbus - Iu pipes data process 97 | //========================================================== 98 | val rbus = Module(new Rbus) 99 | rbus.io.in.aluIn(0) := alu0.io.out 100 | rbus.io.in.aluIn(1) := alu1.io.out 101 | rbus.io.in.duIn := du.io.out 102 | rbus.io.in.muIn := mu.io.out 103 | 104 | } 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /src/main/scala/Core/IU/Rbus.scala: -------------------------------------------------------------------------------- 1 | package Core.IU 2 | 3 | import Core.Config.XLEN 4 | import Core.IU.MDu.{DuRegData, MuRegData} 5 | import Core.IUConfig 6 | import chisel3._ 7 | import chisel3.util.{is, _} 8 | 9 | class RbusIn extends Bundle { 10 | val aluIn = Vec(2,new AluRegData) 11 | val muIn = new MuRegData 12 | val duIn = new DuRegData 13 | val specialIn = new SpecialRegData // althoug only need (data, dataVld, preg) 14 | val cp0In = new Cp0ToRbus 15 | } 16 | class RbusOut extends Bundle with IUConfig{ 17 | val wbPreg = UInt(7.W) 18 | val wbData = UInt(XLEN.W) 19 | val wbPregVld = Bool() 20 | } 21 | 22 | class RbusIO extends Bundle with IUConfig { 23 | val in = Input(new RbusIn) 24 | val flush = Input(Bool()) 25 | val out = Output(Vec(IuPipeNum-1, new RbusOut)) 26 | } 27 | class Rbus extends Module with IUConfig { 28 | val io = IO(new RbusIO) 29 | val pipe_rslt_vld = Seq.fill(IuPipeNum-1)(Wire(Bool())) 30 | val special_in = io.in.specialIn 31 | val cp0_in = io.in.cp0In 32 | val alu_in = io.in.aluIn 33 | val mu_in = io.in.muIn 34 | val du_in = io.in.duIn 35 | pipe_rslt_vld.head := alu_in(0).dataVld || du_in.pipe0DataVld || special_in.dataVld || special_in.dataVld 36 | pipe_rslt_vld(1) := alu_in(1).dataVld || mu_in.dataVld 37 | 38 | //---------------------------------------------------------- 39 | // Write Back Valid 40 | //---------------------------------------------------------- 41 | val pipe_wb_vld = Seq.fill(IuPipeNum-1)(RegInit(false.B)) 42 | for(i<- 0 until (IuPipeNum-1)){ 43 | when(io.flush){ 44 | pipe_wb_vld(i) := false.B 45 | }otherwise{ 46 | pipe_wb_vld(i) := pipe_rslt_vld(i) 47 | } 48 | } 49 | //---------------------------------------------------------- 50 | // Write Back Data Selection 51 | //---------------------------------------------------------- 52 | //---------------------------------------------------------- 53 | // Pipe 0 54 | //---------------------------------------------------------- 55 | val pipe0_select = Cat(alu_in(0).dataVld ,du_in.pipe0DataVld ,special_in.dataVld, cp0_in.rsltVld) // TODO add CP0 56 | val pipe0_rslt_preg = RegInit(0.U(7.W)) 57 | switch(pipe0_select){ 58 | is("b1000".U){ 59 | pipe0_rslt_preg := alu_in(0).preg 60 | } 61 | is("b0100".U){ 62 | pipe0_rslt_preg := du_in.preg 63 | } 64 | is("b0010".U){ 65 | pipe0_rslt_preg := special_in.preg 66 | } 67 | is("b0001".U){ 68 | pipe0_rslt_preg := cp0_in.rsltPreg 69 | } 70 | } 71 | val pipe0_rslt_data = RegInit(0.U(XLEN.W)) 72 | switch(pipe0_select){ 73 | is("b1000".U){ 74 | pipe0_rslt_data := alu_in(0).data 75 | } 76 | is("b0100".U){ 77 | pipe0_rslt_data := du_in.data 78 | } 79 | is("b0010".U){ 80 | pipe0_rslt_data := special_in.data 81 | } 82 | is("b0001".U){ 83 | pipe0_rslt_data := cp0_in.rsltData 84 | } 85 | } 86 | 87 | io.out(0).wbPreg := pipe0_rslt_preg 88 | io.out(0).wbData := pipe0_rslt_data 89 | io.out(0).wbPregVld := pipe_wb_vld(0) 90 | //---------------------------------------------------------- 91 | // Pipe 1 92 | //---------------------------------------------------------- 93 | val pipe1_select = Cat(alu_in(1).dataVld ,mu_in.dataVld) // TODO add CP0 94 | val pipe1_rslt_preg = RegInit(0.U(7.W)) 95 | switch(pipe1_select){ 96 | is("b10".U){ 97 | pipe1_rslt_preg := alu_in(1).preg 98 | } 99 | is("b01".U){ 100 | pipe1_rslt_preg := mu_in.preg 101 | } 102 | } 103 | val pipe1_rslt_data = RegInit(0.U(XLEN.W)) 104 | switch(pipe1_select){ 105 | is("b10".U){ 106 | pipe1_rslt_data := alu_in(1).data 107 | } 108 | is("b01".U){ 109 | pipe1_rslt_data := mu_in.data 110 | } 111 | } 112 | 113 | io.out(1).wbPreg := pipe1_rslt_preg 114 | io.out(1).wbData := pipe1_rslt_data 115 | io.out(1).wbPregVld := pipe_wb_vld(1) 116 | 117 | } 118 | -------------------------------------------------------------------------------- /src/exclude/IU/Alu.scala: -------------------------------------------------------------------------------- 1 | package Core.IU 2 | 3 | 4 | import Core.IntConfig._ 5 | import Utils.{LookupTree, SignExt} 6 | import chisel3._ 7 | import chisel3.util._ 8 | 9 | object ALUOpType { 10 | def add = "b1000000".U 11 | def sll = "b0000001".U 12 | def slt = "b0000010".U 13 | def sltu = "b0000011".U 14 | def xor = "b0000100".U 15 | def srl = "b0000101".U 16 | def or = "b0000110".U 17 | def and = "b0000111".U 18 | def sub = "b0001000".U 19 | def sra = "b0001101".U 20 | def lui = "b0001111".U 21 | 22 | def addw = "b1100000".U 23 | def subw = "b0101000".U 24 | def sllw = "b0100001".U 25 | def srlw = "b0100101".U 26 | def sraw = "b0101101".U 27 | def isWordOp(func: UInt) = func(5) //if 32bit 28 | } 29 | 30 | class AluOut extends Bundle { 31 | val data = UInt(64.W) 32 | val dataVld = Bool() 33 | val fwdData = UInt(64.W) 34 | val fwdVld = Bool() 35 | val preg = UInt(7.W) 36 | } 37 | 38 | class AluIO extends Bundle{ 39 | val in = Input(new IduRfPipe0) 40 | val flush = Input(Bool()) 41 | val out = Output(new AluOut) 42 | } 43 | 44 | class Alu extends Module { 45 | val io = IO(new AluIO) 46 | //---------------------------------------------------------- 47 | // Pipe2 EX1 Instruction valid 48 | //---------------------------------------------------------- 49 | val alu_ex1_inst_vld = RegInit(false.B) 50 | val alu_ex1_fwd_vld = RegInit(false.B) 51 | val flush = io.flush 52 | val fwd_vld = io.in.aluShort && io.in.sel && io.in.dstVld 53 | when(flush){ 54 | alu_ex1_inst_vld := false.B 55 | alu_ex1_fwd_vld := false.B 56 | }.otherwise{ 57 | alu_ex1_inst_vld := io.in.sel 58 | alu_ex1_fwd_vld := fwd_vld 59 | } 60 | //---------------------------------------------------------- 61 | // Pipe2 EX1 Instruction Data 62 | //---------------------------------------------------------- 63 | val pipe1_en = WireInit(true.B) // TODO add gate_sel 64 | val ex1_pipe = RegEnable(io.in, pipe1_en) 65 | 66 | val (src1, src2, op) = (io.in.src0,io.in.src1, io.in.opcode) 67 | //---------------------------------------------------------- 68 | // add && shift TODO misc 69 | //---------------------------------------------------------- 70 | val shamt = Mux(ALUOpType.isWordOp(op), src2(4, 0), src2(5, 0)) 71 | val res = LookupTree(op, List( 72 | ALUOpType.add -> (src1 + src2), 73 | ALUOpType.sll -> (src1 << shamt), 74 | ALUOpType.slt -> Cat(0.U((XLEN - 1).W), src1.asSInt < src2.asSInt), 75 | ALUOpType.sltu -> (src1 < src2), 76 | ALUOpType.xor -> (src1 ^ src2), 77 | ALUOpType.srl -> (src1 >> shamt), 78 | ALUOpType.or -> (src1 | src2), 79 | ALUOpType.and -> (src1 & src2), 80 | ALUOpType.sub -> (src1 - src2), 81 | ALUOpType.sra -> (src1.asSInt >> shamt).asUInt, 82 | ALUOpType.addw -> (src1 + src2), 83 | ALUOpType.subw -> (src1 - src2), 84 | ALUOpType.sllw -> (src1 << shamt), 85 | ALUOpType.srlw -> (src1(31,0) >> shamt), 86 | ALUOpType.sraw -> (src1(31,0).asSInt >> shamt).asUInt, 87 | ALUOpType.lui -> src2 88 | )) 89 | //========================================================== 90 | // Complete Bus signals 91 | //========================================================== 92 | // deal alu complete bus signal in cbus : ATTENSION alu sel is en, means alu complete 93 | 94 | //========================================================== 95 | // Result Bus signals 96 | //========================================================== 97 | //---------------------------------------------------------- 98 | // Result Bus 99 | //---------------------------------------------------------- 100 | io.out.dataVld := ex1_pipe.dstVld && alu_ex1_inst_vld 101 | io.out.fwdVld := alu_ex1_fwd_vld 102 | io.out.fwdData := Mux(ALUOpType.isWordOp(op), SignExt(res(31,0), 64), res) 103 | io.out.preg := ex1_pipe.dstPreg 104 | io.out.data := Mux(ALUOpType.isWordOp(op), SignExt(res(31,0), 64), res) 105 | } 106 | 107 | -------------------------------------------------------------------------------- /src/exclude/IU/Special.scala: -------------------------------------------------------------------------------- 1 | package Core.IU 2 | 3 | import Core.AddrConfig.PcWidth 4 | import chisel3._ 5 | import chisel3.util._ 6 | import Utils.LookupTree 7 | 8 | object SpecialOpType { 9 | def NOP = "b00000".U 10 | def ECALL = "b00010".U 11 | def EBREAK = "b00011".U 12 | def AUIPC = "b00100".U 13 | def PSEUDO_AUIPC = "b00101".U 14 | def VSETVLI = "b00110".U 15 | } 16 | 17 | class SpecialOut extends Bundle { 18 | val abnormal = Bool() 19 | val bkpt = Bool() 20 | val exptVec = UInt(5.W) 21 | val exptVld = Bool() 22 | val flush = Bool() 23 | val highHwExpt = Bool() 24 | val iid = UInt(7.W) 25 | val immuExpt = Bool() 26 | val instVld = Bool() 27 | val mtval = UInt(32.W) 28 | val data = UInt(64.W) 29 | val dataVld = Bool() 30 | val preg = UInt(7.W) 31 | } 32 | 33 | class SpecialIO extends Bundle{ 34 | val in = Input(new IduRfPipe0) 35 | val bjuSpecialPc = Input(UInt(PcWidth.W)) 36 | val flush = Input(Bool()) 37 | val bju_special_pc = UInt(PcWidth.W) 38 | val cp0_yy_priv_mode = UInt(2.W) 39 | val out = Output(new SpecialOut) 40 | } 41 | 42 | class Special extends Module{ 43 | val io = IO(new SpecialIO) 44 | // Special unit is aim to process: 1. exception 2. pseudo auipc - pc + imm(un-shifted) 3. vec-inst - vsetvl (Dontcare) 45 | //---------------------------------------------------------- 46 | // Pipe2 EX1 Instruction valid 47 | //---------------------------------------------------------- 48 | val flush = io.flush 49 | val special_ex1_inst_vld = RegInit(false.B) 50 | when(flush){ 51 | special_ex1_inst_vld := false.B 52 | }.otherwise { 53 | special_ex1_inst_vld := io.in.sel 54 | } 55 | //---------------------------------------------------------- 56 | // Pipe2 EX1 Instruction Data 57 | //---------------------------------------------------------- 58 | val pipe1_en = WireInit(true.B) // TODO add gate_sel 59 | val ex1_pipe = RegEnable(io.in, pipe1_en) 60 | val ex1_pipe_pc = io.bjuSpecialPc 61 | //========================================================== 62 | // Instruction Selection 63 | //========================================================== 64 | // 1. exception vec process 65 | val special_ex1_ecall_expt_vec = LookupTree(io.cp0_yy_priv_mode, List( 66 | "b00".U -> "b01000".U, 67 | "b01".U -> "b01001".U, 68 | "b11".U -> "b01011".U, 69 | )) 70 | // 2. auipc 71 | //========================================================== 72 | // AUIPC result 73 | //========================================================== 74 | val special_ex1_offset = ex1_pipe.specialImm << 12.U // auipc , left shift 12bits for jalr 75 | val special_auipc_rslt = ex1_pipe_pc + special_ex1_offset 76 | // 3. vector inst 77 | //========================================================== 78 | // RF stage Complete Bus signals 79 | //========================================================== 80 | io.out.instVld := special_ex1_inst_vld 81 | io.out.abnormal := special_ex1_inst_vld && (io.in.opcode === SpecialOpType.NOP) || (io.in.opcode === SpecialOpType.ECALL) || (io.in.opcode === SpecialOpType.EBREAK) 82 | io.out.bkpt := (io.in.opcode === SpecialOpType.EBREAK) 83 | io.out.iid := ex1_pipe.iid 84 | //---------------------------------------------------------- 85 | // Exception 86 | //---------------------------------------------------------- 87 | io.out.exptVec := LookupTree(io.in.opcode, List( 88 | SpecialOpType.NOP -> io.in.exptVec, 89 | SpecialOpType.ECALL -> special_ex1_ecall_expt_vec, 90 | SpecialOpType.EBREAK -> "b00011".U, 91 | )) 92 | io.out.exptVld := special_ex1_inst_vld && (io.in.opcode === SpecialOpType.NOP) || (io.in.opcode === SpecialOpType.ECALL) || (io.in.opcode === SpecialOpType.EBREAK) 93 | //========================================================== 94 | // Result Bus signals 95 | //========================================================== 96 | io.out.dataVld := special_ex1_inst_vld 97 | io.out.preg := ex1_pipe.dstPreg 98 | io.out.data := special_auipc_rslt 99 | } 100 | -------------------------------------------------------------------------------- /src/main/scala/Core/IU/Alu.scala: -------------------------------------------------------------------------------- 1 | package Core.IU 2 | 3 | import Core.Config.XLEN 4 | import Core.FuncOpType.width 5 | import Core.IDU.Opcode 6 | import Core.IUConfig 7 | import Core.IntConfig.NumPhysicRegsBits 8 | import Utils.{LookupTree, SignExt} 9 | import chisel3._ 10 | import chisel3.util._ 11 | import Core.IDU.Opcode.AluOpcode 12 | 13 | class AluRegData extends Bundle with IUConfig { 14 | val data = UInt(XLEN.W) 15 | val dataVld = Bool() 16 | val fwdData = UInt(XLEN.W) 17 | val fwdVld = Bool() 18 | val preg = UInt(NumPhysicRegsBits.W) 19 | } 20 | 21 | class AluIO extends Bundle{ 22 | val in = Input(new CtrlSignalHasDestIO) 23 | val flush = Input(Bool()) 24 | val toRbus = Output(new AluRegData) 25 | val sel = Input(new unitSel) 26 | } 27 | 28 | class Alu extends Module with IUConfig{ 29 | val io = IO(new AluIO) 30 | //---------------------------------------------------------- 31 | // Pipe2 EX1 Instruction valid 32 | //---------------------------------------------------------- 33 | val alu_ex1_inst_vld = RegInit(false.B) 34 | val alu_ex1_fwd_vld = RegInit(false.B) 35 | val flush = io.flush 36 | val fwd_vld = io.in.aluShort && io.sel.sel && io.in.dstVld 37 | when(flush){ 38 | alu_ex1_inst_vld := false.B 39 | alu_ex1_fwd_vld := false.B 40 | }.otherwise{ 41 | alu_ex1_inst_vld := io.sel.sel 42 | alu_ex1_fwd_vld := fwd_vld 43 | } 44 | //---------------------------------------------------------- 45 | // Pipe2 EX1 Instruction Data 46 | //---------------------------------------------------------- 47 | val pipe1_en = io.sel.gateSel // TODO add gate_sel 48 | val ex1_pipe = RegInit(0.U.asTypeOf(io.in)) 49 | val res = RegInit(0.U(XLEN.W)) 50 | val src1 = WireInit(0.U(XLEN.W)) 51 | val src2 = WireInit(0.U(XLEN.W)) 52 | val op = WireInit(0.U(width)) 53 | val opReg = RegInit(0.U(width)) 54 | 55 | //---------------------------------------------------------- 56 | // add && shift TODO misc 57 | //---------------------------------------------------------- 58 | op := io.in.opcode 59 | src1 := io.in.src0 60 | src2 := io.in.src1 61 | val shamt = Mux(AluOpcode.isWordOp(op), src2(4, 0), src2(5, 0)) 62 | when(pipe1_en) { 63 | ex1_pipe := io.in 64 | opReg := io.in.opcode 65 | res := LookupTree(op, List( 66 | AluOpcode.ADD -> (src1 + src2), 67 | AluOpcode.SLL -> (src1 << shamt), 68 | AluOpcode.SLT -> Cat(0.U((XLEN - 1).W), src1.asSInt < src2.asSInt), 69 | AluOpcode.SLTU -> (src1 < src2), 70 | AluOpcode.XOR -> (src1 ^ src2), 71 | AluOpcode.SRL -> (src1 >> shamt), 72 | AluOpcode.OR -> (src1 | src2), 73 | AluOpcode.AND -> (src1 & src2), 74 | AluOpcode.SUB -> (src1 - src2), 75 | AluOpcode.SRA -> (src1.asSInt >> shamt).asUInt, 76 | AluOpcode.ADDW -> (src1 + src2), 77 | AluOpcode.SUBW -> (src1 - src2), 78 | AluOpcode.SLLW -> (src1 << shamt), 79 | AluOpcode.SRLW -> (src1(31, 0) >> shamt), 80 | AluOpcode.SRAW -> (src1(31, 0).asSInt >> shamt).asUInt, 81 | AluOpcode.LUI -> (src2 << 12.U), 82 | AluOpcode.AUI_PC -> (src1 + src2) 83 | )) 84 | } 85 | //========================================================== 86 | // Complete Bus signals 87 | //========================================================== 88 | // deal alu complete bus signal in cbus : ATTENSION alu sel is en, means alu complete 89 | 90 | //========================================================== 91 | // Result Bus signals 92 | //========================================================== 93 | //---------------------------------------------------------- 94 | // Result Bus 95 | //---------------------------------------------------------- 96 | io.toRbus.dataVld := ex1_pipe.dstVld && alu_ex1_inst_vld 97 | io.toRbus.fwdVld := alu_ex1_fwd_vld 98 | io.toRbus.fwdData := Mux(AluOpcode.isWordOp(opReg), SignExt(res(31,0), 64), res) //////ex1 pipe Reg 99 | io.toRbus.preg := ex1_pipe.dstPreg 100 | io.toRbus.data := Mux(AluOpcode.isWordOp(opReg), SignExt(res(31,0), 64), res) //////todo: check isWordOp 101 | } 102 | 103 | -------------------------------------------------------------------------------- /src/main/scala/Core/IDU/RF/Prf.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU.RF 2 | 3 | import Core.Config.XLEN 4 | import chisel3._ 5 | import chisel3.util._ 6 | import Core.ROBConfig._ 7 | import Core.VectorUnitConfig._ 8 | import Core.PipelineConfig._ 9 | import Core.IntConfig._ 10 | import chisel3.util.experimental.BoringUtils 11 | import difftest.DifftestArchIntRegState 12 | 13 | trait PrfConfig { 14 | def NumPregReadPort = 11 15 | def NumPregWritePort = 3 16 | } 17 | 18 | object PrfConfig extends PrfConfig 19 | 20 | class PrfFromCp0Bundle extends Bundle { 21 | val iduIcgEn : Bool = Bool() 22 | val yyClkEn : Bool = Bool() 23 | } 24 | 25 | class PrfFromPadBundle extends Bundle { 26 | val yyIcgScanEn : Bool = Bool() 27 | } 28 | 29 | class PrfFromRtuBundle extends Bundle { 30 | val yyXxDebugOn : Bool = Bool() 31 | } 32 | 33 | class PrfToHadBundle extends Bundle { 34 | val wb = new Bundle { 35 | val data : UInt = UInt(XLEN.W) 36 | val valid : Bool = Bool() 37 | } 38 | } 39 | 40 | /** 41 | * Elements has different direction 42 | */ 43 | class PrfReadBundle extends Bundle { 44 | val preg : UInt = Input(UInt(NumPhysicRegsBits.W)) 45 | val data : UInt = Output(UInt(XLEN.W)) 46 | } 47 | 48 | class PrfWriteBundle extends Bundle { 49 | val en : Bool = Bool() 50 | val preg : UInt = UInt(NumPhysicRegsBits.W) 51 | val data : UInt = UInt(XLEN.W) 52 | } 53 | 54 | class PrfInput extends Bundle { 55 | val fromCp0 = new PrfFromCp0Bundle 56 | val fromPad = new PrfFromPadBundle 57 | val fromRtu = new PrfFromRtuBundle 58 | } 59 | 60 | class PrfOutput extends Bundle { 61 | val toHad = new PrfToHadBundle 62 | } 63 | 64 | class PrfIO extends Bundle with PrfConfig { 65 | val in : PrfInput = Input(new PrfInput) 66 | val out : PrfOutput = Output(new PrfOutput) 67 | val r : Vec[PrfReadBundle] = Vec(NumPregReadPort, new PrfReadBundle) 68 | val w : Vec[PrfWriteBundle] = Input(Vec(NumPregWritePort, new PrfWriteBundle)) 69 | } 70 | 71 | /** 72 | * Physical regfile 73 | */ 74 | class Prf extends Module with PrfConfig{ 75 | val io : PrfIO = IO(new PrfIO) 76 | 77 | /** 78 | * Input rename 79 | */ 80 | val wenVec : Vec[Bool] = VecInit(io.w.map(_.en)) 81 | val wdataVec : Vec[UInt] = VecInit(io.w.map(_.data)) 82 | val wPregVec : Vec[UInt] = VecInit(io.w.map(_.preg)) 83 | val rPregVec : Vec[UInt] = VecInit(io.r.map(_.preg)) 84 | /** 85 | * Regs 86 | */ 87 | private val data = RegInit(VecInit(Seq.fill(NumPhysicRegs)(0.U(XLEN.W)))) 88 | 89 | val wen : Bool = wenVec.reduce(_||_) 90 | val wenCnt : UInt = wenVec.count(b => b) 91 | // Only one wen high is permitted 92 | val fault : Bool = !(wenCnt === 0.U || wenCnt === 1.U) 93 | val wdata : UInt = wdataVec(OHToUInt(wenVec)) 94 | val wPreg : UInt = wPregVec(OHToUInt(wenVec)) 95 | 96 | // Todo: gated clk 97 | 98 | // when(!fault && wen) { 99 | // when(wPreg =/= 0.U) { 100 | // data(wPreg) := wdata 101 | // } 102 | // } 103 | 104 | for(i <- 0 until NumPregWritePort){ 105 | when(wenVec(i)){ 106 | when(wPregVec(i) === 0.U((NumPhysicRegsBits.W))){ 107 | data(wPregVec(i)) := 0.U(XLEN.W) 108 | }.otherwise{ 109 | data(wPregVec(i)) := wdataVec(i) 110 | } 111 | } 112 | } 113 | 114 | io.r.zip(rPregVec).foreach{ 115 | case (r, preg) => r.data := data(preg) 116 | } 117 | 118 | io.out.toHad.wb.valid := io.in.fromRtu.yyXxDebugOn && wen 119 | io.out.toHad.wb.data := Mux(wen, wdata, 0.U) 120 | 121 | 122 | //========================================================== 123 | // to Difftest 124 | //========================================================== 125 | val difftestIntPreg = WireInit(VecInit(Seq.fill(NumLogicRegs)(0.U(NumPhysicRegsBits.W)))) 126 | BoringUtils.addSink(difftestIntPreg, "difftestIntPreg") 127 | 128 | val commitGpr = Wire(Vec(NumLogicRegs, UInt(XLEN.W))) 129 | commitGpr.zipWithIndex.foreach { 130 | case (rdata, i) => 131 | rdata := data(difftestIntPreg(i)) 132 | } 133 | 134 | val difftestArchIntRegState = Module(new DifftestArchIntRegState) 135 | difftestArchIntRegState.io.clock := clock 136 | difftestArchIntRegState.io.coreid := 0.U 137 | difftestArchIntRegState.io.gpr := commitGpr 138 | 139 | BoringUtils.addSource(commitGpr(0xa), "difftestTrapCode") 140 | } 141 | -------------------------------------------------------------------------------- /src/main/scala/Core/LSU/IdFifo8.scala: -------------------------------------------------------------------------------- 1 | package Core.LSU 2 | import chisel3._ 3 | import chisel3.util._ 4 | 5 | 6 | class IdFifo8Input extends Bundle{ 7 | val cp0_lsu_icg_en = Bool() 8 | val cp0_yy_clk_en = Bool() 9 | val idfifo_create_id = UInt(3.W) 10 | val idfifo_create_id_oh = UInt(8.W) 11 | val idfifo_create_vld = Bool() 12 | val idfifo_pop_vld = Bool() 13 | val pad_yy_icg_scan_en = Bool() 14 | } 15 | 16 | class IdFifo8Output extends Bundle{ 17 | val idfifo_empty = Bool() 18 | val idfifo_pop_id_oh = UInt(8.W) 19 | } 20 | 21 | class IdFifo8IO extends Bundle{ 22 | val in = Input(new IdFifo8Input) 23 | val out = Output(new IdFifo8Output) 24 | } 25 | 26 | 27 | class IdFifo8 extends Module { 28 | val io = IO(new IdFifo8IO) 29 | 30 | //Regs 31 | val idfifo_create_ptr = RegInit(0.U(4.W)) 32 | val idfifo_pop_id_oh = RegInit(0.U(8.W)) 33 | val idfifo_pop_ptr = RegInit(0.U(4.W)) 34 | val idfifo_pop_ptr_next = RegInit(1.U(4.W)) 35 | 36 | //Wires 37 | val idfifo_entry_create_vld = Wire(UInt(8.W)) 38 | 39 | val idfifo_pe_clr_vld = Wire(Bool()) 40 | val idfifo_pe_sel_create_ptr_vld = Wire(Bool()) 41 | val idfifo_pop_id_next_oh = Wire(UInt(8.W)) 42 | 43 | val idfifo_1vld = Wire(Bool()) 44 | val idfifo_empty = Wire(Bool()) 45 | val idfifo_create_ptr_oh = Wire(UInt(8.W)) 46 | //========================================================== 47 | // Instance FIFO 48 | //========================================================== 49 | val idfifo_entry = RegInit(VecInit(Seq.fill(8)(0.U(3.W)))) 50 | 51 | for(i <- 0 until 8){ 52 | when(idfifo_entry_create_vld(i)){ 53 | idfifo_entry(i) := io.in.idfifo_create_id 54 | } 55 | 56 | } 57 | 58 | //========================================================== 59 | // Register 60 | //========================================================== 61 | //------------------pointer--------------------------------- 62 | when(io.in.idfifo_create_vld){ 63 | idfifo_create_ptr := idfifo_create_ptr + 1.U(4.W) 64 | } 65 | 66 | when(io.in.idfifo_pop_vld){ 67 | idfifo_pop_ptr := idfifo_pop_ptr_next 68 | idfifo_pop_ptr_next := idfifo_pop_ptr_next + 1.U(4.W) 69 | } 70 | 71 | when(idfifo_pe_clr_vld){ 72 | idfifo_pop_id_oh := 0.U(8.W) 73 | }.elsewhen(idfifo_pe_sel_create_ptr_vld){ 74 | idfifo_pop_id_oh := io.in.idfifo_create_id_oh 75 | }.elsewhen(io.in.idfifo_pop_vld){ 76 | idfifo_pop_id_oh := idfifo_pop_id_next_oh 77 | } 78 | 79 | io.out.idfifo_pop_id_oh := idfifo_pop_id_oh 80 | //========================================================== 81 | // Wires 82 | //========================================================== 83 | //------------------pop entry signal------------------------ 84 | idfifo_pe_clr_vld := io.in.idfifo_pop_vld && !io.in.idfifo_create_vld && idfifo_1vld 85 | 86 | idfifo_pe_sel_create_ptr_vld := io.in.idfifo_create_vld && (idfifo_empty || idfifo_1vld && io.in.idfifo_pop_vld) 87 | 88 | //------------------entry signal---------------------------- 89 | idfifo_entry_create_vld := idfifo_create_ptr_oh & VecInit(Seq.fill(8)(io.in.idfifo_create_vld)).asUInt 90 | 91 | //------------------pointer--------------------------------- 92 | //expand to one hot code 93 | idfifo_create_ptr_oh := UIntToOH(idfifo_create_ptr(2,0))(7,0) 94 | 95 | val idfifo_pop_ptr_next_oh = UIntToOH(idfifo_pop_ptr_next(2,0))(7,0) 96 | 97 | //-------------------entry valid signal--------------------- 98 | idfifo_empty := idfifo_create_ptr === idfifo_pop_ptr 99 | io.out.idfifo_empty := idfifo_empty 100 | 101 | //only 1 entry is valid 102 | idfifo_1vld := idfifo_create_ptr === idfifo_pop_ptr_next 103 | 104 | //-------------------next pop id---------------------------- 105 | val idfifo_pop_id_next = Mux1H(Seq( 106 | idfifo_pop_ptr_next_oh(0) -> idfifo_entry(0), 107 | idfifo_pop_ptr_next_oh(1) -> idfifo_entry(1), 108 | idfifo_pop_ptr_next_oh(2) -> idfifo_entry(2), 109 | idfifo_pop_ptr_next_oh(3) -> idfifo_entry(3), 110 | idfifo_pop_ptr_next_oh(4) -> idfifo_entry(4), 111 | idfifo_pop_ptr_next_oh(5) -> idfifo_entry(5), 112 | idfifo_pop_ptr_next_oh(6) -> idfifo_entry(6), 113 | idfifo_pop_ptr_next_oh(7) -> idfifo_entry(7) 114 | )) 115 | 116 | idfifo_pop_id_next_oh := UIntToOH(idfifo_pop_id_next(2,0))(7,0) 117 | 118 | } 119 | -------------------------------------------------------------------------------- /src/main/scala/Core/IFU/sram_c910.scala: -------------------------------------------------------------------------------- 1 | package Core.IFU 2 | 3 | import chisel3._ 4 | import chisel3.util._ 5 | import chisel3.experimental._ 6 | import Utils._ 7 | 8 | trait SramConfig { 9 | def Bits32 = 32; 10 | def WordDepth = 64; 11 | def AddrWidth = 11//6; 12 | def WenWidth32 = 32; 13 | 14 | def BitsArray = 128; 15 | def WenWidthArray = 128; 16 | } 17 | 18 | class ct_spsram_2048x32_split extends ExtModule with HasExtModuleResource with SramConfig { 19 | val A = IO(Input(UInt(AddrWidth.W))) 20 | val CEN = IO(Input(Bool())) 21 | val CLK = IO(Input(Clock())) 22 | val D = IO(Input(UInt(Bits32.W))) 23 | val GWEN = IO(Input(Bool())) 24 | val Q = IO(Output(UInt(Bits32.W))) 25 | val WEN = IO(Input(UInt(WenWidth32.W))) 26 | 27 | 28 | addResource("/ct_spsram_2048x32_split.v") 29 | } 30 | 31 | 32 | 33 | class SramIO extends Bundle with SramConfig { 34 | val rData: UInt = OutUInt(BitsArray) 35 | 36 | val en: Bool = InBool() 37 | val idx: UInt = InUInt(AddrWidth) 38 | val wen: Bool = InBool() 39 | val wMask: UInt = InUInt(WenWidthArray) 40 | val wData: UInt = InUInt(BitsArray) 41 | } 42 | 43 | //class sram_c910 extends Module { 44 | // val io = IO(new SramIO) 45 | // // val bank0: ct_spsram_2048x32_split = Module(new ct_spsram_2048x32_split) 46 | // // val bank1: ct_spsram_2048x32_split = Module(new ct_spsram_2048x32_split) 47 | // // val bank2: ct_spsram_2048x32_split = Module(new ct_spsram_2048x32_split) 48 | // // val bank3: ct_spsram_2048x32_split = Module(new ct_spsram_2048x32_split) 49 | // val bank0:sram_2048x32 = Module(new sram_2048x32) 50 | // val bank1:sram_2048x32 = Module(new sram_2048x32) 51 | // val bank2:sram_2048x32 = Module(new sram_2048x32) 52 | // val bank3:sram_2048x32 = Module(new sram_2048x32) 53 | // io.rData := Cat(bank3.Q(31,0),bank2.Q(31,0),bank1.Q(31,0),bank0.Q(31,0)) 54 | // bank0.CLK := clock 55 | // bank0.CEN := !io.en 56 | // bank0.A := io.idx 57 | // bank0.GWEN := !io.wen 58 | // bank0.WEN := ~io.wMask(31,0) 59 | // bank0.D := io.wData(31,0) 60 | // bank1.CLK := clock 61 | // bank1.CEN := !io.en 62 | // bank1.A := io.idx 63 | // bank1.GWEN := !io.wen 64 | // bank1.WEN := ~io.wMask(63,32) 65 | // bank1.D := io.wData(63,32) 66 | // bank2.CLK := clock 67 | // bank2.CEN := !io.en 68 | // bank2.A := io.idx 69 | // bank2.GWEN := !io.wen 70 | // bank2.WEN := ~io.wMask(95,64) 71 | // bank2.D := io.wData(95,64) 72 | // bank3.CLK := clock 73 | // bank3.CEN := !io.en 74 | // bank3.A := io.idx 75 | // bank3.GWEN := !io.wen 76 | // bank3.WEN := ~io.wMask(127,96) 77 | // bank3.D := io.wData(127,96) 78 | //} 79 | 80 | class SramIO_2048x32 extends Bundle with SramConfig { 81 | val rData: UInt = OutUInt(Bits32) 82 | 83 | val en: Bool = InBool() 84 | val idx: UInt = InUInt(AddrWidth) 85 | val wen: Bool = InBool() 86 | val wMask: UInt = InUInt(WenWidth32) 87 | val wData: UInt = InUInt(Bits32) 88 | } 89 | class sram_2048x32 extends Module { 90 | val io = IO(new SramIO_2048x32) 91 | val sram_2048x32: ct_spsram_2048x32_split = Module(new ct_spsram_2048x32_split) 92 | io.rData := sram_2048x32.Q 93 | sram_2048x32.CLK := clock 94 | sram_2048x32.CEN := !io.en 95 | sram_2048x32.A := io.idx 96 | sram_2048x32.WEN := ~io.wMask 97 | sram_2048x32.GWEN := !io.wen 98 | sram_2048x32.D := io.wData 99 | } 100 | 101 | class sram_c910 extends Module { 102 | val io = IO(new SramIO) 103 | val bank0:sram_2048x32 = Module(new sram_2048x32) 104 | val bank1:sram_2048x32 = Module(new sram_2048x32) 105 | val bank2:sram_2048x32 = Module(new sram_2048x32) 106 | val bank3:sram_2048x32 = Module(new sram_2048x32) 107 | io.rData := Cat(bank3.io.rData,bank2.io.rData,bank1.io.rData,bank0.io.rData) 108 | bank0.io.en := io.en 109 | bank0.io.idx := io.idx 110 | bank0.io.wen := io.wen 111 | bank0.io.wMask := io.wMask(31,0) 112 | bank0.io.wData := io.wData(31,0) 113 | bank1.io.en := io.en 114 | bank1.io.idx := io.idx 115 | bank1.io.wen := io.wen 116 | bank1.io.wMask := io.wMask(63,32) 117 | bank1.io.wData := io.wData(63,32) 118 | bank2.io.en := io.en 119 | bank2.io.idx := io.idx 120 | bank2.io.wen := io.wen 121 | bank2.io.wMask := io.wMask(95,64) 122 | bank2.io.wData := io.wData(95,64) 123 | bank3.io.en := io.en 124 | bank3.io.idx := io.idx 125 | bank3.io.wen := io.wen 126 | bank3.io.wMask := io.wMask(127,96) 127 | bank3.io.wData := io.wData(127,96) 128 | } -------------------------------------------------------------------------------- /utils/IOcvt.py: -------------------------------------------------------------------------------- 1 | 2 | import sys 3 | import re 4 | 5 | def usage(): 6 | print("Usage: ") 7 | print(" %s .v file, config file" % sys.argv[0]) 8 | print("Example:") 9 | print(" python3 %s 1.v, lsu_idu.txt" % sys.argv[0]) 10 | 11 | def snake2camel(name:str): 12 | name_list = name.lstrip("_").split("_") 13 | res = name_list[0] + ''.join(elem.title() for elem in name_list[1:]) 14 | return res 15 | 16 | re_io = { 17 | "input" : r"input\s+\[([0-9]+)\s*:\s*([0-9]+)\]\s*(\w+)\s*;", 18 | "output": r"output\s+\[([0-9]+)\s*:\s*([0-9]+)\]\s*(\w+)\s*;" 19 | } 20 | re_io_no_width = { 21 | "input" : r"input\s+(\w+)\s*;", 22 | "output": r"output\s+(\w+)\s*;" 23 | } 24 | 25 | def get_bundle_class(lines, prefixes:list, io:str, camel = True): 26 | if io not in ["input", "output"]: 27 | print("get_class_bundle's arg io must in ['input', 'output']") 28 | exit() 29 | bundle_class = dict() 30 | for prefix in prefixes: 31 | bundle_class[prefix] = [] 32 | for line in lines: 33 | res = re.findall(re_io[io], line) 34 | width = 1 35 | signal = "" 36 | selected = False 37 | if len(res) != 0: 38 | width = int(res[0][0]) - int(res[0][1]) + 1 39 | signal = res[0][2] 40 | selected = True 41 | else: 42 | res = re.findall(re_io_no_width[io], line) 43 | if len(res) != 0: 44 | selected = True 45 | signal = res[0] 46 | if (selected): 47 | for prefix in prefixes: 48 | if signal.find(prefix) != -1: 49 | bundle_class[prefix].append((snake2camel(signal[len(prefix):]), width)) 50 | break 51 | return bundle_class 52 | 53 | def get_prefixes_class_names(line): 54 | prefix_re = "(\w+)" 55 | prefixes = [] 56 | class_names = [] 57 | field_names = [] 58 | top_class = "" 59 | for line in prefix_lines: 60 | res = re.findall(prefix_re, line) 61 | prefixes.append(res[0]) 62 | class_names.append(res[1]) 63 | field_names.append(res[2]) 64 | if "top_class" == res[2]: 65 | top_class = res[0] 66 | return (prefixes, class_names, field_names, top_class) 67 | 68 | def generate_scala(bundle_class: dict, class_names: list, field_names: list, need_top=True, top_class="", file=sys.stdout, extends=[]): 69 | class_head_template = r"class %s extends Bundle %s {" 70 | class_tail_template = r"}" 71 | field_template = r" val %s : %s = new %s" 72 | value_def_template = r" val %s : UInt = UInt(%d.W)" 73 | extends_str = "".join(" with"+elem for elem in extends) 74 | top_idx = -1 75 | for i, item in enumerate(bundle_class.items()): 76 | if need_top and item[0] == top_class: 77 | top_idx = i 78 | continue 79 | print(class_head_template % (class_names[i], extends_str), file = file) 80 | for signal, width in item[1]: 81 | print(value_def_template % (signal, width), file = file) 82 | print(class_tail_template, file = file) 83 | print(file = file) 84 | if need_top: 85 | print(class_head_template % (class_names[top_idx], extends_str), file = file) 86 | for i, field in enumerate(field_names): 87 | if field == "top_class": 88 | continue 89 | print(field_template % (field, class_names[i], class_names[i]), file = file) 90 | for signal, width in bundle_class[top_class]: 91 | print(value_def_template % (signal, width), file = file) 92 | print(class_tail_template, file = file) 93 | print(file = file) 94 | 95 | if len(sys.argv) < 3: 96 | usage() 97 | exit() 98 | 99 | prefix_file_obj = open(sys.argv[2], "r") 100 | direction = prefix_file_obj.readline().strip() 101 | prefix_lines = prefix_file_obj.readlines() 102 | # print("direction: ", direction) 103 | prefix_file_obj.close() 104 | prefixes, class_names, field_names, top_class = get_prefixes_class_names(prefix_lines) 105 | need_top = top_class != "" 106 | 107 | file = sys.argv[1] 108 | file_name, _ = file.split(".") 109 | out_file = file_name + ".scala" 110 | fobj = open(file, "r") 111 | 112 | lines = fobj.readlines() 113 | fobj.close() 114 | 115 | bundle_class = get_bundle_class(lines, prefixes, direction, camel = True) 116 | 117 | 118 | generate_scala(bundle_class, class_names, field_names, file=open(out_file, "w"), need_top=need_top, top_class=top_class) 119 | 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /src/main/resources/ct_f_spsram_2048x32.v: -------------------------------------------------------------------------------- 1 | /*Copyright 2019-2021 T-Head Semiconductor Co., Ltd. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | 16 | // &Depend("fpga_ram.v"); @23 17 | 18 | // &ModuleBeg; @25 19 | module ct_f_spsram_2048x32( 20 | A, 21 | CEN, 22 | CLK, 23 | D, 24 | GWEN, 25 | Q, 26 | WEN 27 | ); 28 | 29 | // &Ports; @26 30 | input [10:0] A; 31 | input CEN; 32 | input CLK; 33 | input [31:0] D; 34 | input GWEN; 35 | input [31:0] WEN; 36 | output [31:0] Q; 37 | 38 | // &Regs; @27 39 | reg [10:0] addr_holding; 40 | 41 | // &Wires; @28 42 | wire [10:0] A; 43 | wire CEN; 44 | wire CLK; 45 | wire [31:0] D; 46 | wire GWEN; 47 | wire [31:0] Q; 48 | wire [31:0] WEN; 49 | wire [10:0] addr; 50 | wire [7 :0] ram0_din; 51 | wire [7 :0] ram0_dout; 52 | wire ram0_wen; 53 | wire [7 :0] ram1_din; 54 | wire [7 :0] ram1_dout; 55 | wire ram1_wen; 56 | wire [7 :0] ram2_din; 57 | wire [7 :0] ram2_dout; 58 | wire ram2_wen; 59 | wire [7 :0] ram3_din; 60 | wire [7 :0] ram3_dout; 61 | wire ram3_wen; 62 | 63 | 64 | parameter ADDR_WIDTH = 11; 65 | parameter WRAP_SIZE = 8; 66 | 67 | //write enable 68 | // &Force("nonport","ram0_wen"); @34 69 | // &Force("nonport","ram1_wen"); @35 70 | // &Force("nonport","ram2_wen"); @36 71 | // &Force("nonport","ram3_wen"); @37 72 | // &Force("bus","WEN",31,0); @38 73 | assign ram0_wen = !CEN && !WEN[ 7] && !GWEN; 74 | assign ram1_wen = !CEN && !WEN[15] && !GWEN; 75 | assign ram2_wen = !CEN && !WEN[23] && !GWEN; 76 | assign ram3_wen = !CEN && !WEN[31] && !GWEN; 77 | 78 | //din 79 | // &Force("nonport","ram0_din"); @45 80 | // &Force("nonport","ram1_din"); @46 81 | // &Force("nonport","ram2_din"); @47 82 | // &Force("nonport","ram3_din"); @48 83 | // &Force("bus","D",4*WRAP_SIZE-1,0); @49 84 | assign ram0_din[WRAP_SIZE-1:0] = D[WRAP_SIZE-1:0]; 85 | assign ram1_din[WRAP_SIZE-1:0] = D[2*WRAP_SIZE-1:WRAP_SIZE]; 86 | assign ram2_din[WRAP_SIZE-1:0] = D[3*WRAP_SIZE-1:2*WRAP_SIZE]; 87 | assign ram3_din[WRAP_SIZE-1:0] = D[4*WRAP_SIZE-1:3*WRAP_SIZE]; 88 | //address 89 | // &Force("nonport","addr"); @55 90 | always@(posedge CLK) 91 | begin 92 | if(!CEN) begin 93 | addr_holding[ADDR_WIDTH-1:0] <= A[ADDR_WIDTH-1:0]; 94 | end 95 | end 96 | 97 | assign addr[ADDR_WIDTH-1:0] = CEN ? addr_holding[ADDR_WIDTH-1:0] 98 | : A[ADDR_WIDTH-1:0]; 99 | //dout 100 | // &Force("nonport","ram0_dout"); @66 101 | // &Force("nonport","ram1_dout"); @67 102 | // &Force("nonport","ram2_dout"); @68 103 | // &Force("nonport","ram3_dout"); @69 104 | 105 | assign Q[WRAP_SIZE-1:0] = ram0_dout[WRAP_SIZE-1:0]; 106 | assign Q[2*WRAP_SIZE-1:WRAP_SIZE] = ram1_dout[WRAP_SIZE-1:0]; 107 | assign Q[3*WRAP_SIZE-1:2*WRAP_SIZE] = ram2_dout[WRAP_SIZE-1:0]; 108 | assign Q[4*WRAP_SIZE-1:3*WRAP_SIZE] = ram3_dout[WRAP_SIZE-1:0]; 109 | 110 | 111 | fpga_ram #(WRAP_SIZE,ADDR_WIDTH) ram0( 112 | .PortAClk (CLK), 113 | .PortAAddr(addr), 114 | .PortADataIn (ram0_din), 115 | .PortAWriteEnable(ram0_wen), 116 | .PortADataOut(ram0_dout)); 117 | 118 | fpga_ram #(WRAP_SIZE,ADDR_WIDTH) ram1( 119 | .PortAClk (CLK), 120 | .PortAAddr(addr), 121 | .PortADataIn (ram1_din), 122 | .PortAWriteEnable(ram1_wen), 123 | .PortADataOut(ram1_dout)); 124 | 125 | fpga_ram #(WRAP_SIZE,ADDR_WIDTH) ram2( 126 | .PortAClk (CLK), 127 | .PortAAddr(addr), 128 | .PortADataIn (ram2_din), 129 | .PortAWriteEnable(ram2_wen), 130 | .PortADataOut(ram2_dout)); 131 | 132 | fpga_ram #(WRAP_SIZE,ADDR_WIDTH) ram3( 133 | .PortAClk (CLK), 134 | .PortAAddr(addr), 135 | .PortADataIn (ram3_din), 136 | .PortAWriteEnable(ram3_wen), 137 | .PortADataOut(ram3_dout)); 138 | 139 | // &ModuleEnd; @105 140 | endmodule 141 | 142 | 143 | 144 | 145 | 146 | -------------------------------------------------------------------------------- /src/main/scala/Core/IFU/RAS.scala: -------------------------------------------------------------------------------- 1 | package Core.IFU 2 | import Core.{Config, CoreBundle} 3 | import Utils._ 4 | import chisel3._ 5 | import chisel3.util._ 6 | 7 | class RASPtr extends CircularQueuePtr[RASPtr](16) with HasCircularQueuePtrHelper 8 | 9 | class RASEntry extends Bundle with Config{ 10 | val retAddr = UInt(VAddrBits.W) 11 | val ctr = UInt(10.W) // layer of nested call functions 12 | } 13 | object RASEntry { 14 | def apply(retAddr: UInt, ctr: UInt): RASEntry = { 15 | val e = Wire(new RASEntry) 16 | e.retAddr := retAddr 17 | e.ctr := ctr 18 | e 19 | } 20 | } 21 | class RASUpdateIO extends CoreBundle { 22 | val iscall = Input(Bool()) 23 | val isret = Input(Bool()) 24 | val target = Input(UInt(VAddrBits.W)) 25 | } 26 | class RASIO extends CoreBundle { 27 | val ifu_update = new RASUpdateIO 28 | val rtu_update = new RASUpdateIO 29 | val target = Output(UInt(VAddrBits.W)) 30 | val flush = Input(Bool()) 31 | val ras_flush = Input(Bool()) 32 | } 33 | class RAS extends Module with Config { 34 | val io = IO(new RASIO) 35 | val stack = RegInit(VecInit(Seq.fill(16)(0.U.asTypeOf(new RASEntry)))) 36 | val sp_ptr = RegInit(0.U.asTypeOf(new RASPtr)) 37 | val top = stack(sp_ptr.value) 38 | io.target := top.retAddr 39 | 40 | when(io.ifu_update.iscall && io.ifu_update.isret){ 41 | when(top.ctr===1.U){ 42 | stack(sp_ptr.value) := RASEntry(io.ifu_update.target, 1.U) 43 | }.elsewhen(top.retAddr=/=io.ifu_update.target){ 44 | stack(sp_ptr.value) := RASEntry(top.retAddr, top.ctr - 1.U) 45 | stack(sp_ptr.value + 1.U) := RASEntry(io.ifu_update.target, 1.U) 46 | sp_ptr.value := sp_ptr.value + 1.U 47 | } 48 | } 49 | when(io.ifu_update.iscall && !io.ifu_update.isret){ 50 | when(top.retAddr===io.ifu_update.target){ 51 | stack(sp_ptr.value) := RASEntry(top.retAddr, top.ctr + 1.U) 52 | }.otherwise{ 53 | stack(sp_ptr.value + 1.U) := RASEntry(io.ifu_update.target, 1.U) 54 | sp_ptr.value := sp_ptr.value + 1.U 55 | } 56 | } 57 | when(io.ifu_update.isret && !io.ifu_update.iscall){ 58 | when(top.ctr===1.U){ 59 | sp_ptr.value := sp_ptr.value - 1.U 60 | }.otherwise{ 61 | stack(sp_ptr.value) := RASEntry(top.retAddr, top.ctr - 1.U) 62 | } 63 | } 64 | 65 | val stack_commit = RegInit(VecInit(Seq.fill(16)(0.U.asTypeOf(new RASEntry))))//新建第二个表 66 | val sp_commit = RegInit(0.U.asTypeOf(new RASPtr)) 67 | val top_commit = stack_commit(sp_commit.value) 68 | 69 | when(io.rtu_update.iscall && io.rtu_update.isret){ 70 | when(top_commit.ctr===1.U){ 71 | stack_commit(sp_commit.value) := RASEntry(io.rtu_update.target, 1.U) 72 | }.elsewhen(top_commit.retAddr=/=io.rtu_update.target){ 73 | stack_commit(sp_commit.value) := RASEntry(top_commit.retAddr, top_commit.ctr - 1.U) 74 | stack_commit(sp_commit.value + 1.U) := RASEntry(io.rtu_update.target, 1.U) 75 | sp_commit.value := sp_commit.value + 1.U 76 | } 77 | } 78 | when(io.rtu_update.iscall && !io.rtu_update.isret){ 79 | when(top_commit.retAddr===io.rtu_update.target){ 80 | stack_commit(sp_commit.value) := RASEntry(top_commit.retAddr, top_commit.ctr + 1.U) 81 | }.otherwise{ 82 | stack_commit(sp_commit.value + 1.U) := RASEntry(io.rtu_update.target, 1.U)//指针+1,计数层置为1 83 | sp_commit.value := sp_commit.value + 1.U 84 | } 85 | } 86 | when(io.rtu_update.isret && !io.rtu_update.iscall){ 87 | when(top_commit.ctr===1.U){ 88 | sp_commit.value := sp_commit.value - 1.U//已调用完毕,指针回退 89 | }.otherwise{ 90 | stack_commit(sp_commit.value) := RASEntry(top_commit.retAddr, top_commit.ctr - 1.U)//不是第一层,地址写入commit表,计数层减1 91 | } 92 | } 93 | 94 | when(io.flush){ 95 | for(i <- 0 until 16){ 96 | stack(i) := stack_commit(i)//冲刷时,stack根据commit更新 97 | } 98 | sp_ptr.value := sp_commit.value 99 | 100 | when(io.rtu_update.iscall){ 101 | when(top_commit.retAddr===io.rtu_update.target){ 102 | stack(sp_commit.value).ctr := stack_commit(sp_commit.value).ctr + 1.U 103 | }.otherwise{ 104 | sp_ptr.value := sp_commit.value + 1.U 105 | stack(sp_commit.value + 1.U).retAddr := io.rtu_update.target 106 | stack(sp_commit.value + 1.U).ctr := 1.U 107 | } 108 | } 109 | } 110 | 111 | when(io.ras_flush){ 112 | sp_ptr.value := 0.U 113 | sp_commit.value := 0.U 114 | for(i <- 0 until 16){ 115 | stack_commit(i).retAddr := 0.U 116 | stack_commit(i).ctr := 0.U 117 | stack(i).retAddr := 0.U 118 | stack(i).ctr := 0.U 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/main/scala/Core/IFU/icache_predec.scala: -------------------------------------------------------------------------------- 1 | package Core.IFU 2 | 3 | //import Core.AXI4.{AXI4IO, AXIParameter} 4 | import Core.{Config} 5 | import chisel3._ 6 | import chisel3.util._ 7 | 8 | 9 | //dontcare:传入4*128 bit数据,每次refill同时返回与data_array一一对应的4次取*4bit*4bank标记数 10 | //4*128太占面积,refill需要4次传输,每次调用一次模块便可 11 | class icache_predecIO extends Bundle with Config with CacheConfig { 12 | val din = Input(UInt(ICacheRespBits.W)) // 13 | val dout = Output(UInt(ICachePredecBits.W)) 14 | } 15 | object pre_type { 16 | def jal = BitPat("b1101111") 17 | def beq = BitPat("b000_1100011") 18 | def bne = BitPat("b001_1100011") 19 | def blt = BitPat("b100_1100011") 20 | def bge = BitPat("b101_1100011") 21 | def bltu = BitPat("b110_1100011") 22 | def bgeu = BitPat("b111_1100011") 23 | def beqz_bnez = BitPat("b1101") 24 | def j = BitPat("b10101") 25 | def instr32 = BitPat("b11") 26 | } 27 | //========================================================== 28 | // Precode Information 29 | //========================================================== 30 | //pre_code[23:21] -- {h1_br, h1_bry1, h1_bry0} -- inst_data[127:112] 31 | //pre_code[20:18] -- {h2_br, h2_bry1, h2_bry0} -- inst_data[111: 96] 32 | //pre_code[17:15] -- {h3_br, h3_bry1, h3_bry0} -- inst_data[ 95: 80] 33 | //pre_code[14:12] -- {h4_br, h4_bry1, h4_bry0} -- inst_data[ 79: 64] 34 | //pre_code[11: 9] -- {h5_br, h5_bry1, h5_bry0} -- inst_data[ 63: 48] 35 | //pre_code[ 8: 6] -- {h6_br, h6_bry1, h6_bry0} -- inst_data[ 47: 32] 36 | //pre_code[ 5: 3] -- {h7_br, h7_bry1, h7_bry0} -- inst_data[ 31: 16] 37 | //pre_code[ 2: 0] -- {h8_br, h8_bry1, h8_bry0} -- inst_data[ 15: 0] 38 | class icache_predec extends Module with Config with CacheConfig { 39 | val io = IO(new icache_predecIO) 40 | val hn_data = WireInit(VecInit(Seq.fill(8)(0.U(16.W)))) 41 | val hn_br = WireInit(VecInit(Seq.fill(8)(false.B))) 42 | val hn_ab_br = WireInit(VecInit(Seq.fill(8)(false.B))) 43 | val hn_bry1_32 = WireInit(VecInit(Seq.fill(8)(false.B))) 44 | val hn_bry1_16 = WireInit(VecInit(Seq.fill(8)(false.B))) 45 | val hn_bry1 = WireInit(VecInit(Seq.fill(8)(false.B))) 46 | val hn_bry0_32 = WireInit(VecInit(Seq.fill(8)(false.B))) 47 | val hn_bry0_16 = WireInit(VecInit(Seq.fill(8)(false.B))) 48 | val hn_bry0 = WireInit(VecInit(Seq.fill(8)(false.B))) 49 | val hn_pre_code = WireInit(VecInit(Seq.fill(8)(0.U(4.W)))) 50 | val pre_code = WireInit(0.U(32.W)) 51 | 52 | for( i<- 0 until 8){ 53 | //////todo: origin code is reverse with now, be careful 54 | hn_data(i) := io.din(16*(i+1) - 1, 16*i) 55 | 56 | val tem_brdata0 = hn_data(i)(6,0) 57 | val tem_brdata1 = Cat(hn_data(i)(14,12),hn_data(i)(6,0)) 58 | val tem_brdata2 = Cat(hn_data(i)(15,14),hn_data(i)(1,0)) 59 | val tem_brdata3 = Cat(hn_data(i)(15,13),hn_data(i)(1,0)) 60 | val tem_brdata4 = hn_data(i)(1,0) 61 | 62 | //hn_br 63 | hn_br(i) := (tem_brdata0 === pre_type.jal) || 64 | (tem_brdata1 === pre_type.beq) || 65 | (tem_brdata1 === pre_type.bne) || 66 | (tem_brdata1 === pre_type.blt) || 67 | (tem_brdata1 === pre_type.bge) || 68 | (tem_brdata1 === pre_type.bltu) || 69 | (tem_brdata1 === pre_type.bgeu) || 70 | (tem_brdata2 === pre_type.beqz_bnez) || 71 | (tem_brdata3 === pre_type.j) 72 | 73 | //hn_ab_br 74 | hn_ab_br(i) := (tem_brdata0 === pre_type.jal) || 75 | (tem_brdata3 === pre_type.j) 76 | 77 | //hn_bry1 : suppose h1 is the start of one inst 78 | if (i==0) { 79 | hn_bry1_32(i) := tem_brdata4 === pre_type.instr32 80 | hn_bry1(i) := true.B 81 | } else { 82 | hn_bry1_32(i) := (tem_brdata4 === pre_type.instr32) && !hn_bry1_32(i-1) 83 | hn_bry1_16(i) := !(tem_brdata4 === pre_type.instr32) && !hn_bry1_32(i-1) 84 | hn_bry1(i) := hn_bry1_32(i) || hn_bry1_16(i) 85 | } 86 | 87 | //hn_bry0 : suppose h1 is not the start of one inst 88 | if (i==0) { 89 | hn_bry0(i) := false.B 90 | } else if (i==1) { 91 | hn_bry0_32(i) := (tem_brdata4 === pre_type.instr32) 92 | hn_bry0(i) := true.B 93 | } else { 94 | hn_bry0_32(i) := (tem_brdata4 === pre_type.instr32) && !hn_bry0_32(i-1) 95 | hn_bry0_16(i) := !(tem_brdata4 === pre_type.instr32) && !hn_bry0_32(i-1) 96 | } 97 | 98 | //Merge 99 | hn_pre_code(i) := Cat(hn_ab_br(i).asUInt(),hn_br(i).asUInt(),hn_bry1(i).asUInt(),hn_bry0(i).asUInt()) 100 | } 101 | 102 | pre_code := Cat(hn_pre_code(7),hn_pre_code(6),hn_pre_code(5),hn_pre_code(4), 103 | hn_pre_code(3),hn_pre_code(2),hn_pre_code(1),hn_pre_code(0)) 104 | //////todo: origin code is reverse with now, be careful 105 | 106 | io.dout := pre_code 107 | } 108 | -------------------------------------------------------------------------------- /src/main/scala/Core/SimpleIFU.scala: -------------------------------------------------------------------------------- 1 | package Core 2 | 3 | import Core.IFU.{BhtPredDataForward, IFUIO} 4 | import Utils.RAMHelper 5 | import chisel3._ 6 | import chisel3.util.ValidIO 7 | 8 | class SimpleIFU extends Module { 9 | val io: IFUIO = IO(new IFUIO) 10 | 11 | private val ram = Seq.fill(2)(Module(new RAMHelper)) 12 | private val pc_update = Wire(UInt(32.W)) 13 | private val pc = RegInit(0.U) 14 | private val data = Wire(Vec(2, UInt(64.W))) 15 | 16 | for (i <- 0 until 2) { 17 | ram(i).io.clk := clock 18 | ram(i).io.en := ~reset.asBool 19 | ram(i).io.wen := false.B 20 | ram(i).io.wIdx := DontCare 21 | ram(i).io.wdata := DontCare 22 | ram(i).io.wmask := DontCare 23 | } 24 | 25 | ram(0).io.rIdx := pc >> 3.U 26 | ram(1).io.rIdx := (pc + 8.U) >> 3.U 27 | data(0) := ram(0).io.rdata 28 | data(1) := ram(1).io.rdata 29 | 30 | for (i <- 0 until 3) { 31 | io.instData(i).pc := (pc + (i * 4).U)(15, 1) // not support compress insts 32 | } 33 | 34 | private val instVec = Wire(Vec(3, UInt(32.W))) 35 | 36 | when(pc(2) === 0.U) { 37 | instVec(0) := data(0)(31,0) 38 | instVec(1) := data(0)(63,32) 39 | instVec(2) := data(1)(31,0) 40 | }.otherwise { 41 | instVec(0) := data(0)(63,32) 42 | instVec(1) := data(1)(31,0) 43 | instVec(2) := data(1)(63,32) 44 | } 45 | 46 | private val cnt: UInt = RegInit(0.U(3.W)) 47 | private val stall: Bool = Wire(Bool()) 48 | 49 | when (cnt === 4.U) { 50 | cnt := 0.U 51 | }.otherwise { 52 | cnt := cnt + 1.U 53 | } 54 | 55 | private val redirect: ValidIO[UInt] = RegInit(0.U.asTypeOf(ValidIO(UInt(32.W)))) 56 | redirect := io.bru_redirect 57 | stall := io.idu_ifu_id_stall || cnt =/= 4.U 58 | when (stall) { 59 | pc_update := pc 60 | }.elsewhen(redirect.valid) { 61 | pc_update := redirect.bits 62 | }.otherwise { 63 | pc_update := pc + (4*3).U 64 | } 65 | 66 | when (!stall) { 67 | pc := pc_update 68 | } 69 | 70 | for (i <- 0 until 3) { 71 | io.instData(i).vl_pred := false.B 72 | io.instData(i).vl := 0.U 73 | io.instData(i).vsew := 0.U 74 | io.instData(i).vlmul := 0.U 75 | 76 | io.instData(i).no_spec := false.B 77 | io.instData(i).bkptb_inst := false.B 78 | io.instData(i).bkpta_inst := false.B 79 | io.instData(i).split_short := false.B 80 | io.instData(i).fence := false.B 81 | io.instData(i).split_long := false.B 82 | io.instData(i).high_hw_expt := false.B 83 | io.instData(i).expt_vec := 0.U 84 | io.instData(i).expt_vld := false.B 85 | io.instVld(i) := !stall 86 | io.instData(i).opcode := instVec(i) 87 | } 88 | 89 | private val ifuForwardVec = Wire(Vec(3, new BhtPredDataForward)) 90 | 91 | private val brVec = Wire(Vec(3, Bool())) 92 | brVec.zip(instVec).foreach { 93 | case (br, inst) => 94 | br := inst(6, 0) === "b1100011".U 95 | } 96 | private val jalVec = Wire(Vec(3, Bool())) 97 | jalVec.zip(instVec).foreach { 98 | case (jal, inst) => 99 | jal := inst(6, 0) === "b1101111".U 100 | } 101 | private val jalrVec = Wire(Vec(3, Bool())) 102 | jalrVec.zip(instVec).foreach { 103 | case (jalr, inst) => 104 | jalr := inst(6, 0) === "b1100111".U && inst(14, 12) === "b000".U 105 | } 106 | 107 | private val pcfifoEnVec = Wire(Vec(3, Bool())) 108 | pcfifoEnVec.zipWithIndex.foreach { 109 | case (pcfifoEn, i) => pcfifoEn := brVec(i) || jalVec(i) || jalrVec(i) 110 | } 111 | 112 | 113 | for (i <- 0 until 3) { 114 | ifuForwardVec(i).en := pcfifoEnVec(i) 115 | ifuForwardVec(i).jal := jalVec(i) 116 | ifuForwardVec(i).jalr := jalrVec(i) 117 | ifuForwardVec(i).dstVld := false.B 118 | ifuForwardVec(i).predStore := 0.U.asTypeOf(chiselTypeOf(ifuForwardVec(i).predStore)) 119 | ifuForwardVec(i).curPc := pc + (4 * i).U 120 | ifuForwardVec(i).tarPc := 0.U 121 | } 122 | 123 | when(ifuForwardVec(0).en) { 124 | io.ifuForward(0) := ifuForwardVec(0) 125 | }.elsewhen(ifuForwardVec(1).en) { 126 | io.ifuForward(0) := ifuForwardVec(1) 127 | }.elsewhen(ifuForwardVec(2).en) { 128 | io.ifuForward(0) := ifuForwardVec(2) 129 | }.otherwise { 130 | io.ifuForward(0) := DontCare 131 | io.ifuForward(0).en := false.B 132 | } 133 | 134 | when(ifuForwardVec(0).en && ifuForwardVec(1).en) { 135 | io.ifuForward(1) := ifuForwardVec(1) 136 | }.elsewhen(ifuForwardVec(0).en && ifuForwardVec(2).en) { 137 | io.ifuForward(1) := ifuForwardVec(2) 138 | }.elsewhen(ifuForwardVec(1).en && ifuForwardVec(2).en) { 139 | io.ifuForward(1) := ifuForwardVec(2) 140 | }.otherwise { 141 | io.ifuForward(1) := DontCare 142 | io.ifuForward(1).en := false.B 143 | } 144 | 145 | io.toROB.curPcLoad := 0.U 146 | io.toROB.curPc := 0.U 147 | io.pc := pc 148 | io.tlb.vaddr.valid := false.B 149 | io.tlb.vaddr.bits := 0.U 150 | 151 | } -------------------------------------------------------------------------------- /src/main/scala/Core/LSU/DCache/DCacheTop.scala: -------------------------------------------------------------------------------- 1 | package Core.LSU.DCache 2 | import chisel3._ 3 | import chisel3.util._ 4 | 5 | class DCacheTopInput extends Bundle{ 6 | val cp0_lsu_icg_en = Bool() 7 | val pad_yy_icg_scan_en = Bool() 8 | 9 | val ld_data = new Bundle{ 10 | val gateclk_en = Vec(8, Bool()) 11 | val gwen_b = Vec(8, Bool()) 12 | val high_din = UInt(128.W) 13 | val high_idx = UInt(11.W) 14 | val low_din = UInt(128.W) 15 | val low_idx = UInt(11.W) 16 | val sel_b = Vec(8, Bool()) 17 | val wen_b = Vec(8, UInt(4.W)) 18 | } 19 | val ld_tag = new Bundle{ 20 | val din = UInt(54.W) 21 | val gateclk_en = Bool() 22 | val gwen_b = Bool() 23 | val idx = UInt(9.W) 24 | val sel_b = Bool() 25 | val wen_b = UInt(2.W) 26 | } 27 | val st_dirty = new Bundle{ 28 | val din = UInt(7.W) 29 | val gateclk_en = Bool() 30 | val gwen_b = Bool() 31 | val idx = UInt(9.W) 32 | val sel_b = Bool() 33 | val wen_b = UInt(7.W) 34 | } 35 | val st_tag = new Bundle{ 36 | val din = UInt(52.W) 37 | val gateclk_en = Bool() 38 | val gwen_b = Bool() 39 | val idx = UInt(9.W) 40 | val sel_b = Bool() 41 | val wen_b = UInt(2.W) 42 | } 43 | } 44 | 45 | class DCacheTopOutput extends Bundle{ 46 | val ld_data_bank_dout = Vec(8, UInt(32.W)) 47 | val ld_tag_dout = UInt(54.W) 48 | val st_dirty_dout = UInt(7.W) 49 | val st_tag_dout = UInt(52.W) 50 | } 51 | 52 | class DCacheIO extends Bundle{ 53 | val in = Input(new DCacheTopInput) 54 | val out = Output(new DCacheTopOutput) 55 | } 56 | 57 | class DCacheTop extends Module { 58 | val io = IO(new DCacheIO) 59 | 60 | //========================================================== 61 | // Instance dcache array 62 | //========================================================== 63 | //---------------------tag and dirty------------------------ 64 | val ld_tag_array = Module(new DCacheLoadTagArray) 65 | ld_tag_array.io.tag_din := io.in.ld_tag.din 66 | ld_tag_array.io.tag_gateclk_en := io.in.ld_tag.gateclk_en 67 | ld_tag_array.io.tag_gwen_b := io.in.ld_tag.gwen_b 68 | ld_tag_array.io.tag_idx := io.in.ld_tag.idx 69 | ld_tag_array.io.tag_sel_b := io.in.ld_tag.sel_b 70 | ld_tag_array.io.tag_wen_b := io.in.ld_tag.wen_b 71 | ld_tag_array.io.pad_yy_icg_scan_en := io.in.pad_yy_icg_scan_en 72 | ld_tag_array.io.cp0_lsu_icg_en := io.in.cp0_lsu_icg_en 73 | io.out.ld_tag_dout := ld_tag_array.io.tag_dout 74 | 75 | 76 | val st_tag_array = Module(new DCacheTagArray) 77 | st_tag_array.io.tag_din := io.in.st_tag.din 78 | st_tag_array.io.tag_gateclk_en := io.in.st_tag.gateclk_en 79 | st_tag_array.io.tag_gwen_b := io.in.st_tag.gwen_b 80 | st_tag_array.io.tag_idx := io.in.st_tag.idx 81 | st_tag_array.io.tag_sel_b := io.in.st_tag.sel_b 82 | st_tag_array.io.tag_wen_b := io.in.st_tag.wen_b 83 | st_tag_array.io.pad_yy_icg_scan_en := io.in.pad_yy_icg_scan_en 84 | st_tag_array.io.cp0_lsu_icg_en := io.in.cp0_lsu_icg_en 85 | io.out.st_tag_dout := st_tag_array.io.tag_dout 86 | 87 | 88 | val st_dirty_array = Module(new DCacheDirtyArray) 89 | st_dirty_array.io.dirty_din := io.in.st_dirty.din 90 | st_dirty_array.io.dirty_gateclk_en := io.in.st_dirty.gateclk_en 91 | st_dirty_array.io.dirty_gwen_b := io.in.st_dirty.gwen_b 92 | st_dirty_array.io.dirty_idx := io.in.st_dirty.idx 93 | st_dirty_array.io.dirty_sel_b := io.in.st_dirty.sel_b 94 | st_dirty_array.io.dirty_wen_b := io.in.st_dirty.wen_b 95 | st_dirty_array.io.pad_yy_icg_scan_en := io.in.pad_yy_icg_scan_en 96 | st_dirty_array.io.cp0_lsu_icg_en := io.in.cp0_lsu_icg_en 97 | io.out.st_dirty_dout := st_dirty_array.io.dirty_dout 98 | 99 | 100 | //-------------------------data----------------------------- 101 | val ld_data_bank_array = Seq.fill(8)(Module(new DCacheDataArray)) 102 | 103 | for(i <- 0 until 4){ 104 | ld_data_bank_array(i).io.data_din := io.in.ld_data.low_din(32*i+31, 32*i) 105 | ld_data_bank_array(i).io.data_idx := io.in.ld_data.low_idx 106 | ld_data_bank_array(i+4).io.data_din := io.in.ld_data.high_din(32*i+31, 32*i) 107 | ld_data_bank_array(i+4).io.data_idx := io.in.ld_data.high_idx 108 | } 109 | 110 | for(i <- 0 until 8){ 111 | ld_data_bank_array(i).io.data_gateclk_en := io.in.ld_data.gateclk_en(i) 112 | ld_data_bank_array(i).io.data_gwen_b := io.in.ld_data.gwen_b(i) 113 | ld_data_bank_array(i).io.data_sel_b := io.in.ld_data.sel_b(i) 114 | ld_data_bank_array(i).io.data_wen_b := io.in.ld_data.wen_b(i) 115 | ld_data_bank_array(i).io.pad_yy_icg_scan_en := io.in.pad_yy_icg_scan_en 116 | ld_data_bank_array(i).io.cp0_lsu_icg_en := io.in.cp0_lsu_icg_en 117 | 118 | io.out.ld_data_bank_dout(i) := ld_data_bank_array(i).io.data_dout 119 | } 120 | 121 | } 122 | -------------------------------------------------------------------------------- /src/main/scala/Utils/ParallelMux.scala: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3 | * 4 | * XiangShan is licensed under Mulan PSL v2. 5 | * You can use this software according to the terms and conditions of the Mulan PSL v2. 6 | * You may obtain a copy of Mulan PSL v2 at: 7 | * http://license.coscl.org.cn/MulanPSL2 8 | * 9 | * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10 | * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11 | * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12 | * 13 | * See the Mulan PSL v2 for more details. 14 | ***************************************************************************************/ 15 | 16 | package Utils 17 | import chisel3._ 18 | import chisel3.util._ 19 | 20 | object ParallelOperation { 21 | def apply[T](xs: Seq[T], func: (T, T) => T): T = { 22 | require(xs.nonEmpty) 23 | xs match { 24 | case Seq(a) => a 25 | case Seq(a, b) => func(a, b) 26 | case _ => 27 | apply(Seq(apply(xs take xs.size/2, func), apply(xs drop xs.size/2, func)), func) 28 | } 29 | } 30 | } 31 | 32 | object ParallelOR { 33 | def apply[T <: Data](xs: Seq[T]): T = { 34 | ParallelOperation(xs, (a: T, b: T) => (a.asUInt() | b.asUInt()).asTypeOf(xs.head)) 35 | } 36 | } 37 | 38 | object ParallelORR { 39 | def apply(in: Seq[Bool]): Bool = ParallelOR(in) 40 | def apply(in: Bits): Bool = apply(in.asBools) 41 | } 42 | 43 | object ParallelAND { 44 | def apply[T <: Data](xs: Seq[T]): T = { 45 | ParallelOperation(xs, (a: T, b:T) => (a.asUInt() & b.asUInt()).asTypeOf(xs.head)) 46 | } 47 | } 48 | 49 | object ParallelANDR { 50 | def apply(in: Seq[Bool]): Bool = ParallelAND(in) 51 | def apply(in: Bits): Bool = apply(in.asBools) 52 | } 53 | 54 | object ParallelXOR { 55 | def apply[T <: Data](xs: Seq[T]): T = { 56 | ParallelOperation(xs, (a: T, b:T) => (a.asUInt() ^ b.asUInt()).asTypeOf(xs.head)) 57 | } 58 | } 59 | 60 | object ParallelMux { 61 | def apply[T<:Data](in: Seq[(Bool, T)]): T = { 62 | val xs = in map { case (cond, x) => (Fill(x.getWidth, cond) & x.asUInt()).asTypeOf(in.head._2) } 63 | ParallelOR(xs) 64 | } 65 | } 66 | 67 | object ParallelLookUp { 68 | def apply[T<:Data](key: UInt, mapping:Seq[(UInt,T)]): T = { 69 | ParallelMux(mapping.map(m => (m._1===key) -> m._2)) 70 | } 71 | } 72 | 73 | object ParallelMax { 74 | def apply[T <: Data](xs: Seq[T]): T = { 75 | ParallelOperation(xs, (a: T, b:T) => Mux(a.asUInt() > b.asUInt(),a, b).asTypeOf(xs.head)) 76 | } 77 | } 78 | 79 | object ParallelMin { 80 | def apply[T <: Data](xs: Seq[T]): T = { 81 | ParallelOperation(xs, (a: T, b:T) => Mux(a.asUInt() < b.asUInt(),a, b).asTypeOf(xs.head)) 82 | } 83 | } 84 | 85 | object ParallelPriorityMux { 86 | def apply[T <: Data](in: Seq[(Bool, T)]): T = { 87 | ParallelOperation(in, (a: (Bool, T), b: (Bool, T)) => (a._1 || b._1, Mux(a._1, a._2, b._2)))._2 88 | } 89 | def apply[T <: Data](sel: Bits, in: Seq[T]): T = apply((0 until in.size).map(sel(_)), in) 90 | def apply[T <: Data](sel: Seq[Bool], in: Seq[T]): T = apply(sel zip in) 91 | } 92 | 93 | object ParallelPriorityEncoder { 94 | def apply(in: Seq[Bool]): UInt = ParallelPriorityMux(in, (0 until in.size).map(_.asUInt)) 95 | def apply(in: Bits): UInt = apply(in.asBools) 96 | } 97 | 98 | object ParallelSingedExpandingAdd { 99 | def apply(in: Seq[SInt]): SInt = ParallelOperation(in, (a: SInt, b: SInt) => a +& b) 100 | } 101 | 102 | class SelectTwoInterRes[T <: Data](gen: T) extends Bundle { 103 | // val valid = Bool() 104 | val hasOne = Bool() 105 | val hasTwo = Bool() 106 | val first = gen.cloneType 107 | val second = gen.cloneType 108 | } 109 | 110 | object SelectTwoInterRes { 111 | def apply[T <: Data](hasOne: Bool, hasTwo: Bool, first: T, second: T): SelectTwoInterRes[T] = { 112 | val res = Wire(new SelectTwoInterRes(first)) 113 | res.hasOne := hasOne 114 | res.hasTwo := hasTwo 115 | res.first := first 116 | res.second := second 117 | res 118 | } 119 | def apply[T <: Data](valid: Bool, data: T): SelectTwoInterRes[T] = { 120 | val res = apply(valid, false.B, data, data) 121 | res 122 | } 123 | } 124 | 125 | 126 | //object ParallelSelectTwo { 127 | // def mergeSelectFirstTwo[T <: Data](a: SelectTwoInterRes[T], b: SelectTwoInterRes[T]): SelectTwoInterRes[T] = { 128 | // SelectTwoInterRes( 129 | // a.hasOne || b.hasOne, 130 | // a.hasTwo || b.hasTwo || a.hasOne && b.hasOne, 131 | // Mux(a.hasOne, a.first, b.first), 132 | // Mux1H(Seq( 133 | // (!a.hasOne, b.second), 134 | // (a.hasOne && !a.hasTwo, b.first), 135 | // (a.hasTwo, a.second) 136 | // )) 137 | // ) 138 | // } 139 | // def apply[T <: Data](xs: Seq[SelectTwoInterRes[T]]): SelectTwoInterRes[T] = { 140 | // ParallelOperation(xs, mergeSelectFirstTwo[T]) 141 | // } 142 | //} 143 | -------------------------------------------------------------------------------- /src/main/scala/ISA/RV64I.scala: -------------------------------------------------------------------------------- 1 | package ISA 2 | 3 | import chisel3.util.BitPat 4 | 5 | object RV64I extends Decoder32Bits { 6 | // RV32I Base Instruction Set 7 | // U-type |-func7-|-rs2-|-rs1-|-funct3-|--rd-|opcode| 8 | def lui = BitPat("b???????_?????_?????___???____?????_0110111") 9 | def auipc = BitPat("b???????_?????_?????___???____?????_0010111") 10 | // J-type 11 | def jal = BitPat("b???????_?????_?????___???____?????_1101111") 12 | // I-type |-func7-|-rs2-|-rs1-|-funct3-|--rd-|opcode| 13 | def jalr = BitPat("b???????_?????_?????___000____?????_1100111") 14 | // B-type |-func7-|-rs2-|-rs1-|-funct3-|--rd-|opcode| 15 | def beq = BitPat("b???????_?????_?????___000____?????_1100011") 16 | def bne = BitPat("b???????_?????_?????___001____?????_1100011") 17 | def blt = BitPat("b???????_?????_?????___100____?????_1100011") 18 | def bge = BitPat("b???????_?????_?????___101____?????_1100011") 19 | def bltu = BitPat("b???????_?????_?????___110____?????_1100011") 20 | def bgeu = BitPat("b???????_?????_?????___111____?????_1100011") 21 | // I-type |-func7-|-rs2-|-rs1-|-funct3-|--rd-|opcode| 22 | def lb = BitPat("b???????_?????_?????___000____?????_0000011") 23 | def lh = BitPat("b???????_?????_?????___001____?????_0000011") 24 | def lw = BitPat("b???????_?????_?????___010____?????_0000011") 25 | def lbu = BitPat("b???????_?????_?????___100____?????_0000011") 26 | def lhu = BitPat("b???????_?????_?????___101____?????_0000011") 27 | // S-type |-func7-|-rs2-|-rs1-|-funct3-|-imm-|opcode| 28 | def sb = BitPat("b???????_?????_?????___000____?????_0100011") 29 | def sh = BitPat("b???????_?????_?????___001____?????_0100011") 30 | def sw = BitPat("b???????_?????_?????___010____?????_0100011") 31 | // I-type |-func7-|-rs2-|-rs1-|-funct3-|--rd-|opcode| 32 | def addi = BitPat("b???????_?????_?????___000____?????_0010011") 33 | def slti = BitPat("b???????_?????_?????___010____?????_0010011") 34 | def sltiu = BitPat("b???????_?????_?????___011____?????_0010011") 35 | def xori = BitPat("b???????_?????_?????___100____?????_0010011") 36 | def ori = BitPat("b???????_?????_?????___110____?????_0010011") 37 | def andi = BitPat("b???????_?????_?????___111____?????_0010011") 38 | // R-type |-func7-|-rs2-|-rs1-|-funct3-|--rd-|opcode| 39 | def add = BitPat("b0000000_?????_?????___000____?????_0110011") 40 | def sub = BitPat("b0100000_?????_?????___000____?????_0110011") 41 | def sll = BitPat("b0000000_?????_?????___001____?????_0110011") 42 | def slt = BitPat("b0000000_?????_?????___010____?????_0110011") 43 | def sltu = BitPat("b0000000_?????_?????___011____?????_0110011") 44 | def xor = BitPat("b0000000_?????_?????___100____?????_0110011") 45 | def srl = BitPat("b0000000_?????_?????___101____?????_0110011") 46 | def sra = BitPat("b0100000_?????_?????___101____?????_0110011") 47 | def or = BitPat("b0000000_?????_?????___110____?????_0110011") 48 | def and = BitPat("b0000000_?????_?????___111____?????_0110011") 49 | def fence = BitPat("b???????_?????_?????___000____?????_0001111") 50 | def ecall = BitPat("b0000000_00000_00000___000____00000_1110011") 51 | def ebreak = BitPat("b0000000_00001_00000___000____00000_1110011") 52 | // RV64I Base Instruction Set(in addition to RV32I) 53 | // I-type |-func7-|-rs2-|-rs1-|-funct3-|--rd-|opcode| 54 | def ld = BitPat("b???????_?????_?????___011____?????_0000011") 55 | def lwu = BitPat("b???????_?????_?????___110____?????_0000011") 56 | // S-type |-func7-|-rs2-|-rs1-|-funct3-|-imm-|opcode| 57 | def sd = BitPat("b???????_?????_?????___011____?????_0100011") 58 | // I-type |-func6|-shamt|-rs1-|-funct3-|--rd-|opcode| 59 | def slli = BitPat("b000000_??????_?????___001____?????_0010011") 60 | def srli = BitPat("b000000_??????_?????___101____?????_0010011") 61 | def srai = BitPat("b010000_??????_?????___101____?????_0010011") 62 | // I-type |-func7-|-rs2-|-rs1-|-funct3-|--rd-|opcode| 63 | def addiw = BitPat("b???????_?????_?????___000____?????_0011011") 64 | // IS-type |-func7-|shamt|-rs1-|-funct3-|--rd-|opcode| 65 | def slliw = BitPat("b0000000_?????_?????___001____?????_0011011") 66 | def srliw = BitPat("b0000000_?????_?????___101____?????_0011011") 67 | def sraiw = BitPat("b0100000_?????_?????___101____?????_0011011") 68 | // R-type |-func7-|-rs2-|-rs1-|-funct3-|--rd-|opcode| 69 | def addw = BitPat("b0000000_?????_?????___000____?????_0111011") 70 | def subw = BitPat("b0100000_?????_?????___000____?????_0111011") 71 | def sllw = BitPat("b0000000_?????_?????___001____?????_0111011") 72 | def srlw = BitPat("b0000000_?????_?????___101____?????_0111011") 73 | def sraw = BitPat("b0100000_?????_?????___101____?????_0111011") 74 | // Pesudo 75 | def pseudo_auipc = BitPat("b???????_?????_?????___???____?????_0011111") 76 | } 77 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Chisel Project Template 2 | ======================= 3 | 4 | You've done the [Chisel Bootcamp](https://github.com/freechipsproject/chisel-bootcamp), and now you 5 | are ready to start your own Chisel project. The following procedure should get you started 6 | with a clean running [Chisel3](https://www.chisel-lang.org/) project. 7 | 8 | ## Make your own Chisel3 project 9 | 10 | ### Dependencies 11 | 12 | #### JDK 8 or newer 13 | 14 | We recommend LTS releases Java 8 and Java 11. You can install the JDK as recommended by your operating system, or use the prebuilt binaries from [AdoptOpenJDK](https://adoptopenjdk.net/). 15 | 16 | #### SBT or mill 17 | 18 | SBT is the most common built tool in the Scala community. You can download it [here](https://www.scala-sbt.org/download.html). 19 | mill is another Scala/Java build tool without obscure DSL like SBT. You can download it [here](https://github.com/com-lihaoyi/mill/releases) 20 | 21 | ### How to get started 22 | 23 | #### Create a repository from the template 24 | 25 | This repository is a Github template. You can create your own repository from it by clicking the green `Use this template` in the top right. 26 | Please leave `Include all branches` **unchecked**; checking it will pollute the history of your new repository. 27 | For more information, see ["Creating a repository from a template"](https://docs.github.com/en/free-pro-team@latest/github/creating-cloning-and-archiving-repositories/creating-a-repository-from-a-template). 28 | 29 | #### Wait for the template cleanup workflow to complete 30 | 31 | After using the template to create your own blank project, please wait a minute or two for the `Template cleanup` workflow to run which will removes some template-specific stuff from the repository (like the LICENSE). 32 | Refresh the repository page in your browser until you see a 2nd commit by `actions-user` titled `Template cleanup`. 33 | 34 | 35 | #### Clone your repository 36 | 37 | Once you have created a repository from this template and the `Template cleanup` workflow has completed, you can click the green button to get a link for cloning your repository. 38 | Note that it is easiest to push to a repository if you set up SSH with Github, please see the [related documentation](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/connecting-to-github-with-ssh). SSH is required for pushing to a Github repository when using two-factor authentication. 39 | 40 | ```sh 41 | git clone git@github.com:huxuan0307/XuanTieC910.git 42 | cd XuanTieC910 43 | ``` 44 | 45 | #### Set project organization and name in build.sbt 46 | 47 | The cleanup workflow will have attempted to provide sensible defaults for `ThisBuild / organization` and `name` in the `build.sbt`. 48 | Feel free to use your text editor of choice to change them as you see fit. 49 | 50 | #### Clean up the README.md file 51 | 52 | Again, use you editor of choice to make the README specific to your project. 53 | 54 | #### Add a LICENSE file 55 | 56 | It is important to have a LICENSE for open source (or closed source) code. 57 | This template repository has the Unlicense in order to allow users to add any license they want to derivative code. 58 | The Unlicense is stripped when creating a repository from this template so that users do not accidentally unlicense their own work. 59 | 60 | For more information about a license, check out the [Github Docs](https://docs.github.com/en/free-pro-team@latest/github/building-a-strong-community/adding-a-license-to-a-repository). 61 | 62 | #### Commit your changes 63 | ```sh 64 | git commit -m 'Starting XuanTieC910' 65 | git push origin main 66 | ``` 67 | 68 | ### Did it work? 69 | 70 | You should now have a working Chisel3 project. 71 | 72 | You can run the included test with: 73 | ```sh 74 | sbt test 75 | ``` 76 | 77 | You should see a whole bunch of output that ends with something like the following lines 78 | ``` 79 | [info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0 80 | [info] All tests passed. 81 | [success] Total time: 5 s, completed Dec 16, 2020 12:18:44 PM 82 | ``` 83 | If you see the above then... 84 | 85 | ### It worked! 86 | 87 | You are ready to go. We have a few recommended practices and things to do. 88 | 89 | * Use packages and following conventions for [structure](https://www.scala-sbt.org/1.x/docs/Directories.html) and [naming](http://docs.scala-lang.org/style/naming-conventions.html) 90 | * Package names should be clearly reflected in the testing hierarchy 91 | * Build tests for all your work 92 | * Read more about testing in SBT in the [SBT docs](https://www.scala-sbt.org/1.x/docs/Testing.html) 93 | * This template includes a [test dependency](https://www.scala-sbt.org/1.x/docs/Library-Dependencies.html#Per-configuration+dependencies) on [chiseltest](https://github.com/ucb-bar/chisel-testers2), this is a reasonable starting point for most tests 94 | * You can remove this dependency in the build.sbt file if you want to 95 | * Change the name of your project in the build.sbt file 96 | * Change your README.md 97 | 98 | ## Problems? Questions? 99 | 100 | Check out the [Chisel Users Community](https://www.chisel-lang.org/community.html) page for links to get in contact! 101 | -------------------------------------------------------------------------------- /src/main/scala/Core/IDU/IQBundle.scala: -------------------------------------------------------------------------------- 1 | package Core.IDU 2 | import chisel3._ 3 | import chisel3.util._ 4 | 5 | 6 | class AIQ0Data extends Bundle { 7 | val VL = UInt(8.W) 8 | val LCH_PREG = Bool() 9 | val SPECIAL = Bool() 10 | val VSEW = UInt(3.W) 11 | val VLMUL = UInt(2.W) 12 | val LCH_RDY_SDIQ = Vec(12, Bool()) 13 | val LCH_RDY_LSIQ = Vec(12, UInt(2.W)) 14 | val LCH_RDY_BIQ = Vec(12, UInt(2.W)) 15 | val LCH_RDY_AIQ1 = Vec(8, UInt(3.W)) 16 | val LCH_RDY_AIQ0 = Vec(8, UInt(3.W)) 17 | val ALU_SHORT = Bool() 18 | val PID = UInt(5.W) 19 | val PCFIFO = Bool() 20 | val MTVR = Bool() 21 | val DIV = Bool() 22 | val HIGH_HW_EXPT = Bool() 23 | val EXPT_VEC = UInt(5.W) 24 | val EXPT_VLD = Bool() 25 | val src_info = Vec(3, new Bundle{ 26 | val lsu_match = Bool() 27 | val src_data = new srcData9 28 | }) 29 | val DST_VREG = UInt(7.W) 30 | val DST_PREG = UInt(7.W)//50 31 | val DSTV_VLD = Bool() 32 | val DST_VLD = Bool() 33 | val src_vld = Vec(3, Bool()) 34 | val IID = UInt(7.W) 35 | val OPCODE = UInt(32.W) 36 | val PC = UInt(15.W) 37 | } 38 | 39 | class AIQ1Data extends Bundle{ 40 | val VL = UInt(8.W) 41 | val LCH_PREG = Bool() 42 | val VSEW = UInt(3.W) 43 | val VLMUL = UInt(2.W) 44 | val LCH_RDY_SDIQ = Vec(12, Bool()) 45 | val LCH_RDY_LSIQ = Vec(12, UInt(2.W)) 46 | val LCH_RDY_BIQ = Vec(12, UInt(2.W)) 47 | val LCH_RDY_AIQ1 = Vec(8, UInt(3.W)) 48 | val LCH_RDY_AIQ0 = Vec(8, UInt(3.W)) 49 | val ALU_SHORT = Bool() 50 | val MLA = Bool() 51 | val MTVR = Bool() 52 | val SRC2_LSU_MATCH = Bool() 53 | val SRC2_DATA = new srcData10 54 | val src_info = Vec(2, new Bundle{ 55 | val lsu_match = Bool() 56 | val src_data = new srcData9 57 | }) 58 | val DST_VREG = UInt(7.W) 59 | val DST_PREG = UInt(7.W)//50 60 | val DSTV_VLD = Bool() 61 | val DST_VLD = Bool() 62 | val src_vld = Vec(3, Bool()) 63 | val IID = UInt(7.W) 64 | val OPCODE = UInt(32.W) 65 | } 66 | 67 | class BIQData extends Bundle { 68 | val VL = UInt(8.W) 69 | val VSEW = UInt(3.W) 70 | val VLMUL = UInt(2.W) 71 | val PCALL = Bool() 72 | val RTS = Bool() 73 | val PID = UInt(5.W) 74 | val LENGTH = Bool() 75 | val src_info = Vec(2, new Bundle{ 76 | val lsu_match = Bool() 77 | val src_data = new srcData9 78 | }) 79 | val src_vld = Vec(2, Bool()) 80 | val IID = UInt(7.W) 81 | val OPCODE = UInt(32.W) 82 | } 83 | 84 | //class LSIQData extends Bundle{ 85 | // val VL = UInt(8.W) 86 | // val VMB = Bool() 87 | // val SPLIT_NUM = UInt(7.W) 88 | // val VSEW = UInt(3.W) 89 | // val VLMUL = UInt(2.W) 90 | // val BKPTB_DATA = Bool() 91 | // val BKPTA_DATA = Bool() 92 | // val AGEVEC_ALL = UInt(11.W) 93 | // val ALREADY_DA = Bool() 94 | // val UNALIGN_2ND = Bool() 95 | // val SPEC_FAIL = Bool() 96 | // val NO_SPEC_EXIST = Bool() 97 | // val NO_SPEC = Bool() 98 | // val SPLIT = Bool() 99 | // val SDIQ_ENTRY = UInt(12.W) 100 | // val STADDR = Bool() 101 | // val PC = UInt(15.W) 102 | // val BAR_TYPE = UInt(4.W) 103 | // val BAR = Bool() 104 | // val STORE = Bool() 105 | // val LOAD = Bool() 106 | // val SRCVM_LSU_MATCH = Bool() 107 | // val SRCVM_DATA = new srcData9 108 | // val src_info = Vec(2, new Bundle{ 109 | // val lsu_match = Bool() 110 | // val src_data = new srcData9 111 | // }) 112 | // val DST_VREG = UInt(7.W) 113 | // val DST_PREG = UInt(7.W) 114 | // val DSTV_VLD = Bool() 115 | // val DST_VLD = Bool() 116 | // val SRCVM_VLD = Bool() 117 | // val src_vld = Vec(2, Bool()) 118 | // val IID = UInt(7.W) 119 | // val OPCODE = UInt(32.W) 120 | //} 121 | 122 | //class SDIQData extends Bundle { 123 | // val LOAD = Bool() 124 | // val STADDR1_IN_STQ = Bool() 125 | // val STADDR0_IN_STQ = Bool() 126 | // val STDATA1_VLD = Bool() 127 | // val UNALIGN = Bool() 128 | // val SRCV0_LSU_MATCH = Bool() 129 | // val SRCV0_DATA = new srcData9 130 | // val SRC0_LSU_MATCH = Bool() 131 | // val SRC0_DATA = new srcData9 132 | // val SRCV0_VLD = Bool() 133 | // val SRC0_VLD = Bool() 134 | //} 135 | 136 | class VIQData extends Bundle { 137 | val VL = UInt(8.W) 138 | val VSEW = UInt(3.W) 139 | val VLMUL = UInt(2.W) 140 | val VMUL = Bool()//VIQ0 141 | val VMUL_UNSPLIT = Bool()//VIQ1 142 | val VMLA_SHORT = Bool() 143 | val VDIV = Bool()//VIQ0 144 | val LCH_RDY_VIQ1 = Vec(8, Bool()) 145 | val LCH_RDY_VIQ0 = Vec(8, Bool()) 146 | val VMLA_TYPE = UInt(3.W) 147 | val SPLIT_NUM = UInt(7.W) 148 | val SPLIT_LAST = Bool() 149 | val MFVR = Bool() 150 | val VMLA = Bool() 151 | val SRCVM_DATA = new srcData9 152 | val SRCVM_LSU_MATCH = Bool() 153 | val SRCV2_DATA = new srcData10 154 | val SRCV2_LSU_MATCH = Bool() 155 | val srcv_info = Vec(2, new Bundle{ 156 | val lsu_match = Bool() 157 | val srcv_data = new srcData9 158 | }) 159 | val DST_EREG = UInt(5.W) 160 | val DST_VREG = UInt(7.W) 161 | val DST_PREG = UInt(7.W) 162 | val DSTE_VLD = Bool() 163 | val DSTV_VLD = Bool() 164 | val DST_VLD = Bool() 165 | val SRCVM_VLD = Bool() 166 | val srcv_vld = Vec(3, Bool()) 167 | val IID = UInt(7.W) 168 | val OPCODE = UInt(32.W) 169 | } 170 | -------------------------------------------------------------------------------- /src/main/scala/Core/IU/Special.scala: -------------------------------------------------------------------------------- 1 | package Core.IU 2 | 3 | import Core.AddrConfig.PcWidth 4 | import Core.Config.XLEN 5 | import Core.ExceptionConfig.{ExceptionVecWidth, MtvalWidth} 6 | import Core.IUConfig 7 | import Core.IUConfig.MPPWidth 8 | import Core.IntConfig.{InstructionIdWidth, NumPhysicRegsBits} 9 | import chisel3._ 10 | import chisel3.util._ 11 | import Utils.LookupTree 12 | 13 | object SpecialOpType { 14 | def NOP = "b00000".U 15 | def ECALL = "b00010".U 16 | def EBREAK = "b00011".U 17 | def AUIPC = "b00100".U 18 | def PSEUDO_AUIPC = "b00101".U 19 | def VSETVLI = "b00110".U 20 | def VSETVL = "b00111".U 21 | } 22 | class SpecialCmpltSignal extends Bundle with IUConfig{ 23 | val abnormal = Bool() 24 | val bkpt = Bool() 25 | val exptVec = UInt(ExceptionVecWidth.W) 26 | val exptVld = Bool() 27 | val flush = Bool() 28 | val highHwExpt = Bool() 29 | val iid = UInt(InstructionIdWidth.W) 30 | val immuExpt = Bool() 31 | val instVld = Bool() 32 | val mtval = UInt(MtvalWidth.W) 33 | } 34 | class SpecialRegData extends Bundle with IUConfig{ 35 | val data = UInt(XLEN.W) 36 | val dataVld = Bool() 37 | val preg = UInt(NumPhysicRegsBits.W) 38 | } 39 | class SpecialOut extends Bundle with IUConfig{ 40 | val toCbus = Output(new SpecialCmpltSignal) 41 | val toRbus = Output(new SpecialRegData) 42 | } 43 | class SpecialIO extends Bundle{ 44 | val bjuSpecialPc = Input(UInt(PcWidth.W)) 45 | val cp0PrivMode = Input(UInt(MPPWidth.W)) // todo add cp0 in 46 | val in = Input(new IduRfPipe0) 47 | val sel = Input(new unitSel) 48 | val flush = Input(Bool()) 49 | val out = Output(new SpecialOut) 50 | } 51 | 52 | class Special extends Module{ 53 | val io = IO(new SpecialIO) 54 | // Special unit is aim to process: 1. exception 2. pseudo auipc - pc + imm(un-shifted) 3. vec-inst - vsetvl (Dontcare) 55 | //---------------------------------------------------------- 56 | // Pipe2 EX1 Instruction valid 57 | //---------------------------------------------------------- 58 | val flush = io.flush 59 | val special_ex1_inst_vld = RegInit(false.B) 60 | when(flush){ 61 | special_ex1_inst_vld := false.B 62 | }.otherwise { 63 | special_ex1_inst_vld := io.sel.sel 64 | } 65 | //---------------------------------------------------------- 66 | // Pipe2 EX1 Instruction Data 67 | //---------------------------------------------------------- 68 | val pipe1_en = io.sel.gateSel 69 | val ex1_pipe = RegEnable(io.in, 0.U.asTypeOf(io.in), pipe1_en) 70 | val ex1_pipe_pc = io.bjuSpecialPc 71 | //========================================================== 72 | // Instruction Selection 73 | //========================================================== 74 | // 1. exception vec process 75 | val special_ex1_ecall_expt_vec = LookupTree(io.cp0PrivMode, List( 76 | "b00".U -> "b01000".U, 77 | "b01".U -> "b01001".U, 78 | "b11".U -> "b01011".U, 79 | )) 80 | // 2. auipc 81 | //========================================================== 82 | // AUIPC result 83 | //========================================================== 84 | val is_pesudo = ex1_pipe.opcode === SpecialOpType.PSEUDO_AUIPC 85 | val special_ex1_offset = Mux(is_pesudo,Cat(ex1_pipe.specialImm ,0.U(1.W)),ex1_pipe.specialImm << 12.U) // auipc , left shift 12bits for jalr 86 | val special_auipc_rslt = ex1_pipe_pc + special_ex1_offset 87 | // 3. vector inst 88 | //========================================================== 89 | // RF stage Complete Bus signals 90 | //========================================================== 91 | io.out.toCbus.instVld := special_ex1_inst_vld 92 | io.out.toCbus.abnormal := special_ex1_inst_vld && (io.in.opcode === SpecialOpType.NOP) || (io.in.opcode === SpecialOpType.ECALL) || (io.in.opcode === SpecialOpType.EBREAK) 93 | io.out.toCbus.bkpt := (io.in.opcode === SpecialOpType.EBREAK) 94 | io.out.toCbus.iid := ex1_pipe.iid 95 | //---------------------------------------------------------- 96 | // Exception 97 | //---------------------------------------------------------- 98 | io.out.toCbus.exptVec := LookupTree(io.in.opcode, List( 99 | SpecialOpType.NOP -> io.in.exptVec, 100 | SpecialOpType.ECALL -> special_ex1_ecall_expt_vec, 101 | SpecialOpType.EBREAK -> "b00011".U, 102 | )) 103 | io.out.toCbus.exptVld := special_ex1_inst_vld && (io.in.opcode === SpecialOpType.NOP) || (io.in.opcode === SpecialOpType.ECALL) || (io.in.opcode === SpecialOpType.EBREAK) 104 | //========================================================== 105 | // Result Bus signals 106 | //========================================================== 107 | io.out.toRbus.dataVld := special_ex1_inst_vld 108 | io.out.toRbus.preg := ex1_pipe.dstPreg 109 | io.out.toRbus.data := special_auipc_rslt 110 | io.out.toCbus.highHwExpt := ex1_pipe.highHwExpt 111 | io.out.toCbus.mtval := DontCare 112 | io.out.toCbus.flush := DontCare // this is vector flush 113 | io.out.toCbus.immuExpt := DontCare 114 | } 115 | -------------------------------------------------------------------------------- /src/exclude/IU/Cbus.scala: -------------------------------------------------------------------------------- 1 | package Core.IU 2 | 3 | import Core.AddrConfig.PcWidth 4 | import Core.IU.Bju.BjuOut 5 | import Core.IUConfig 6 | import chisel3._ 7 | import chisel3.util._ 8 | class CbusOut2Rtu extends Bundle with IUConfig { 9 | val pipe0Abnormal = Bool() 10 | val pipe0Bkpt = Bool() 11 | val pipe0Cmplt = Bool() 12 | val pipe0Efpc = UInt(PcWidth.W) 13 | val pipe0EfpcVld = Bool() 14 | val pipe0ExptVec = UInt(5.W) 15 | val pipe0ExptVld = Bool() 16 | val pipe0Flush = Bool() 17 | val pipe0HighHwExpt = Bool() 18 | val pipe0Iid = UInt(7.W) 19 | val pipe0Mtval = Bool() 20 | val pipe1Cmplt = Bool() 21 | val pipe1Iid = Bool() 22 | val pipe2Abnormal = Bool() 23 | val pipe2BhtMispred = Bool() 24 | val pipe2Cmplt = Bool() 25 | val pipe2Iid = UInt(7.W) 26 | val pipe2JmpMispred = Bool() 27 | } 28 | 29 | class CbusNoEcep extends Bundle with IUConfig{ 30 | val divSel = Bool() 31 | val multSel = Bool() 32 | val pipe0Iid = UInt(7.W) 33 | val pipe0Sel = Bool() 34 | val pipe1Iid = UInt(7.W) 35 | val pipe1Sel = Bool() 36 | } 37 | 38 | class Cp0In extends Bundle with IUConfig{ 39 | val abnormal = Bool() 40 | val efpc = UInt(PcWidth.W) 41 | val efpcVld = Bool() 42 | val exptVec = UInt(5.W) 43 | val exptVld = Bool() 44 | val flush = Bool() 45 | val iid = UInt(7.W) 46 | val instVld = Bool() 47 | val mtval = UInt(32.W) 48 | val en = Bool() 49 | } 50 | 51 | class CbusIO extends Bundle with IUConfig{ 52 | val normIn = Input(new CbusNoEcep) 53 | val specialIn = Input(new SpecialOut) 54 | val cp0In = Input(new Cp0In) 55 | val out = Output(new CbusOut2Rtu) 56 | val bjuIn = Input(new BjuOut) 57 | } 58 | 59 | class Cbus extends Module with IUConfig{ 60 | val io = IO(new CbusIO) 61 | val flush = false.B 62 | val cbus_pipe0_cmplt = io.normIn.pipe0Sel || io.normIn.divSel || io.specialIn.instVld || io.cp0In.instVld 63 | val cbus_pipe0_inst_vld = RegInit(cbus_pipe0_cmplt ,!flush) 64 | 65 | // pipe 0 66 | // Mux the iid - to Rob 67 | val cbus_pipe0_src_iid = (Cat(Fill(7, io.normIn.pipe0Sel)) & io.normIn.pipe0Iid) | 68 | (Cat(Fill(7, io.normIn.divSel)) & io.normIn.pipe0Iid)| 69 | (Cat(Fill(7, io.specialIn.instVld)) & io.specialIn.iid)| 70 | (Cat(Fill(7, io.cp0In.instVld)) & io.cp0In.iid) 71 | 72 | val cbus_pipe0_src_abnormal = (io.specialIn.instVld && io.specialIn.abnormal) || (io.cp0In.abnormal && io.cp0In.instVld) 73 | 74 | val cbus_pipe0_src_expt_vld = (io.specialIn.instVld && io.specialIn.exptVld) || (io.cp0In.exptVld && io.cp0In.instVld) 75 | 76 | val cbus_pipe0_src_expt_vec = (Cat(Fill(7, io.specialIn.instVld)) & io.specialIn.exptVec) | 77 | (Cat(Fill(7, io.cp0In.instVld)) & io.cp0In.exptVec) 78 | 79 | val cbus_pipe0_src_high_hw_expt = io.specialIn.instVld && io.specialIn.highHwExpt 80 | 81 | val cbus_pipe0_src_bkpt = io.specialIn.instVld && io.specialIn.bkpt 82 | 83 | val cbus_pipe0_src_mtval = (Cat(Fill(7, io.specialIn.instVld)) & io.specialIn.mtval)| 84 | (Cat(Fill(7, io.cp0In.instVld)) & io.cp0In.mtval) 85 | 86 | val cbus_pipe0_src_flush = (io.cp0In.instVld && io.cp0In.flush) || (io.specialIn.instVld && io.specialIn.flush) 87 | 88 | val cbus_pipe0_src_efpc_vld = io.cp0In.instVld && io.cp0In.efpcVld 89 | 90 | val cbus_pipe0_src_efpc = Cat(Fill(PcWidth, io.cp0In.instVld)) & io.cp0In.efpc 91 | 92 | 93 | val cbus_pipe0_expt_vld = RegEnable( cbus_pipe0_src_expt_vld, cbus_pipe0_cmplt) 94 | val cbus_pipe0_expt_vec = RegEnable( cbus_pipe0_src_expt_vec, cbus_pipe0_cmplt) 95 | val cbus_pipe0_high_hw_expt = RegEnable( cbus_pipe0_src_high_hw_expt, cbus_pipe0_cmplt) 96 | val cbus_pipe0_bkpt = RegEnable( cbus_pipe0_src_bkpt, cbus_pipe0_cmplt) 97 | val cbus_pipe0_mtval = RegEnable( cbus_pipe0_src_mtval, cbus_pipe0_cmplt) 98 | val cbus_pipe0_flush = RegEnable( cbus_pipe0_src_flush, cbus_pipe0_cmplt) 99 | val cbus_pipe0_efpc_vld = RegEnable( cbus_pipe0_src_efpc_vld, cbus_pipe0_cmplt) 100 | val cbus_pipe0_efpc = RegEnable( cbus_pipe0_src_efpc, cbus_pipe0_cmplt) 101 | val cbus_pipe0_iid = RegEnable( cbus_pipe0_src_iid, cbus_pipe0_cmplt) // TODO CLK is different @ct_iu_cbus @439 102 | val cbus_pipe0_abnormal = RegEnable( cbus_pipe0_abnormal, cbus_pipe0_cmplt) 103 | // out put 104 | io.out.pipe0Cmplt := cbus_pipe0_cmplt 105 | io.out.pipe0Iid := cbus_pipe0_iid 106 | io.out.pipe0Abnormal := cbus_pipe0_abnormal 107 | io.out.pipe0ExptVld := cbus_pipe0_expt_vld 108 | io.out.pipe0ExptVec := cbus_pipe0_expt_vec 109 | io.out.pipe0HighHwExpt := cbus_pipe0_high_hw_expt 110 | io.out.pipe0Bkpt := cbus_pipe0_bkpt 111 | io.out.pipe0Mtval := cbus_pipe0_mtval 112 | io.out.pipe0Flush := cbus_pipe0_flush 113 | io.out.pipe0EfpcVld := cbus_pipe0_efpc_vld 114 | io.out.pipe0Efpc := cbus_pipe0_efpc 115 | 116 | 117 | // pipe 1 118 | 119 | val cbus_pipe1_cmplt = io.normIn.pipe1Sel || io.normIn.multSel 120 | val cbus_pipe1_inst_vld = RegInit(cbus_pipe1_cmplt ,!flush) 121 | val cbus_pipe1_src_iid = io.normIn.pipe1Iid 122 | val cbus_pipe1_iid = RegEnable(cbus_pipe1_src_iid,cbus_pipe1_cmplt) 123 | io.out.pipe1Iid := cbus_pipe1_iid 124 | io.out.pipe2Abnormal := io.bjuIn.toCbus.sel 125 | io.out.pipe2BhtMispred := io.bjuIn.toCbus.abnormal 126 | io.out.pipe2Cmplt := io.bjuIn.toCbus.jmpMispred 127 | io.out.pipe2JmpMispred := io.bjuIn.toCbus.bhtMispred 128 | } 129 | -------------------------------------------------------------------------------- /src/main/scala/Core/LSU/StoreExStage/StoreEx1.scala: -------------------------------------------------------------------------------- 1 | package Core.LSU.StoreExStage 2 | import Core.Config.XLEN 3 | import Core.IDU.RF.{RFStageToFuCtrlBundle, RFStageToLsuPipe5Bundle} 4 | import Core.LsuConfig 5 | import chisel3._ 6 | import chisel3.util._ 7 | 8 | class Cp0ToStEx1 extends Bundle with LsuConfig{ 9 | val lsuIcgEn = Bool() 10 | val clkEn = Bool() 11 | } 12 | class RfPipe5ToStEx1 extends Bundle with LsuConfig{ 13 | val gateclkSel = Bool() 14 | val sel = Bool() 15 | 16 | val sdiqEntry = UInt(LSIQ_ENTRY.W) 17 | val src0 = UInt(XLEN.W) 18 | val srcv0Fr = UInt(XLEN.W) 19 | val srcv0FrVld = Bool() 20 | val srcv0Vld = Bool() 21 | val srcv0Vr0 = UInt(XLEN.W) 22 | val srcv0Vr1 = UInt(XLEN.W) 23 | val stdata1Vld = Bool() 24 | val unalign = Bool() 25 | } 26 | //---------------------------------------------------------- 27 | class StoreEx1In extends Bundle with LsuConfig{ 28 | val cp0In = new Cp0ToStEx1 29 | val pipe5 = new Bundle() { 30 | val data = new RFStageToLsuPipe5Bundle 31 | val selCtrl = new RFStageToFuCtrlBundle 32 | } 33 | 34 | val rtuFlush = Bool() 35 | } 36 | //========================================================== 37 | // Output 38 | //========================================================== 39 | class StExtoIdu extends Bundle with LsuConfig{ 40 | val sdiqEntry = UInt(LSIQ_ENTRY.W) 41 | val sdiqFrzClr = Bool() 42 | val sdiqPopVld = Bool() 43 | } 44 | //---------------------------------------------------------- 45 | class StoreEx1Out extends Bundle with LsuConfig{ 46 | val toIdu = new StExtoIdu 47 | val sdEx1Data = UInt(XLEN.W) 48 | val sdEx1DataBypass = UInt((XLEN*2).W) 49 | val sdEx1InstVld = Bool() 50 | val rfEx1Sdid = UInt(SDID_WIDTH.W) 51 | val rfInstVldShort = Bool() 52 | } 53 | //========================================================== 54 | // IO 55 | //========================================================== 56 | class StoreEx1IO extends Bundle with LsuConfig{ 57 | val in = Input(new StoreEx1In) 58 | val out = Output(new StoreEx1Out) 59 | } 60 | 61 | class StoreEx1 extends Module with LsuConfig{ 62 | val io = IO(new StoreEx1IO) 63 | val sd_ex1_clk_en = io.in.pipe5.selCtrl.gateClkSel 64 | val sd_ex1_data_clk_en = io.in.pipe5.selCtrl.gateClkSel && (!io.in.pipe5.data.srcv0Vld) 65 | val sd_ex1_vdata_clk_en = io.in.pipe5.selCtrl.gateClkSel && (io.in.pipe5.data.srcv0Vld) 66 | //========================================================== 67 | // encode sdid 68 | //========================================================== 69 | io.out.rfEx1Sdid := OHToUInt(io.in.pipe5.data.sdiqEntry) 70 | //========================================================== 71 | // Pipeline Register 72 | //========================================================== 73 | //------------------control part---------------------------- 74 | //+----------+ 75 | //| inst_vld | 76 | //+----------+ 77 | io.out.rfInstVldShort := io.in.pipe5.selCtrl.gateClkSel 78 | val sd_rf_ex1_inst_vld = io.in.pipe5.selCtrl.sel && (!io.in.rtuFlush) 79 | val sd_ex1_inst_vld = RegInit(false.B) 80 | sd_ex1_inst_vld := sd_rf_ex1_inst_vld 81 | io.out.sdEx1InstVld := sd_ex1_inst_vld 82 | //+------+------+----------+------+ 83 | //| sdid | secd | boundary | data | 84 | //+------+------+----------+------+ 85 | val sd_ex1_sdid_oh = RegInit(0.U(LSIQ_ENTRY.W)) 86 | val sd_ex1_secd = RegInit(false.B) 87 | val sd_ex1_boundary = RegInit(false.B) 88 | val sd_ex1_srcv0_vld = RegInit(false.B) 89 | val sd_ex1_srcv0_fr_vld = RegInit(false.B) 90 | when(sd_ex1_clk_en){ 91 | sd_ex1_sdid_oh := io.in.pipe5.data.sdiqEntry 92 | sd_ex1_secd := io.in.pipe5.data.stdata1Vld 93 | sd_ex1_boundary := io.in.pipe5.data.unalign 94 | sd_ex1_srcv0_vld := io.in.pipe5.data.srcv0Vld 95 | sd_ex1_srcv0_fr_vld := io.in.pipe5.data.srcv0FrVld 96 | } 97 | val sd_ex1_src0_data = RegInit(0.U(XLEN.W)) 98 | val sd_ex1_srcv0_vr1_data = RegInit(0.U(XLEN.W)) 99 | val sd_ex1_srcv0_vr0_data = RegInit(0.U(XLEN.W)) 100 | val sd_ex1_srcv0_fr_data = RegInit(0.U(XLEN.W)) 101 | when(sd_ex1_data_clk_en){ 102 | sd_ex1_src0_data := io.in.pipe5.data.src0 103 | } 104 | when(sd_ex1_vdata_clk_en){ 105 | sd_ex1_srcv0_vr1_data := io.in.pipe5.data.srcv0Vr1 106 | sd_ex1_srcv0_vr0_data := io.in.pipe5.data.srcv0Vr0 107 | sd_ex1_srcv0_fr_data := io.in.pipe5.data.srcv0Fr 108 | } 109 | //========================================================== 110 | // data select 111 | //========================================================== 112 | val sd_ex1_data_64 = Wire(UInt(XLEN.W)) 113 | sd_ex1_data_64 := Mux(sd_ex1_srcv0_vld , 114 | Mux(sd_ex1_srcv0_fr_vld, sd_ex1_srcv0_fr_data,sd_ex1_srcv0_vr0_data), 115 | sd_ex1_src0_data) 116 | io.out.sdEx1Data := sd_ex1_data_64 117 | io.out.sdEx1DataBypass := Cat(Cat(Seq.fill(XLEN)("b0".U)) ,sd_ex1_data_64) 118 | //========================================================== 119 | // Generage interface to idu 120 | //========================================================== 121 | io.out.toIdu.sdiqPopVld := sd_ex1_inst_vld && (!sd_ex1_boundary || sd_ex1_secd) 122 | io.out.toIdu.sdiqFrzClr := sd_ex1_inst_vld && sd_ex1_boundary && (!sd_ex1_secd) 123 | io.out.toIdu.sdiqEntry := sd_ex1_sdid_oh 124 | } 125 | -------------------------------------------------------------------------------- /src/main/scala/Core/LSU/Lq/LQ.scala: -------------------------------------------------------------------------------- 1 | package Core.LSU.Lq 2 | 3 | import Core.LsuConfig 4 | import chisel3._ 5 | import chisel3.util._ 6 | 7 | class LQInput extends Bundle{ 8 | val fromCP0 = new Bundle{ 9 | val lsu_corr_dis = Bool() 10 | val lsu_icg_en = Bool() 11 | val yy_clk_en = Bool() 12 | } 13 | val fromLdDC = new Bundle { 14 | val addr = Vec(2, UInt(40.W)) 15 | val bytes_vld = Vec(2, UInt(16.W)) 16 | val chk_ld_addr1_vld = Bool() 17 | val iid = UInt(7.W) 18 | val inst_chk_vld = Bool() 19 | val secd = Bool() 20 | } 21 | val EntryCreate = new Bundle { 22 | val dp_vld = Vec(2, Bool()) 23 | val gateclk_en = Vec(2, Bool()) 24 | val vld = Vec(2, Bool()) 25 | } 26 | val fromPad = new Bundle{ 27 | val yy_icg_scan_en = Bool() 28 | } 29 | val fromRTU = new Bundle{ 30 | val yy_xx_commit = Vec(3, Bool()) 31 | val yy_xx_commit_iid = Vec(3, UInt(7.W)) 32 | val yy_xx_flush = Bool() 33 | } 34 | val fromStDC = new Bundle{ 35 | val addr0 = UInt(40.W) 36 | val bytes_vld = UInt(16.W) 37 | val chk_st_inst_vld = Bool() 38 | val chk_statomic_inst_vld = Bool() 39 | val iid = UInt(7.W) 40 | } 41 | } 42 | 43 | class LQOutput extends Bundle{ 44 | val lq_ld_dc_full = Bool() 45 | val lq_ld_dc_inst_hit = Bool() 46 | val lq_ld_dc_less2 = Bool() 47 | val lq_ld_dc_spec_fail = Bool() 48 | val lq_st_dc_spec_fail = Bool() 49 | val lsu_idu_lq_not_full = Bool() 50 | } 51 | 52 | class LQIO extends Bundle{ 53 | val in = Input(new LQInput) 54 | val out = Output(new LQOutput) 55 | } 56 | 57 | class LQ extends Module with LsuConfig{ 58 | val io = IO(new LQIO) 59 | 60 | //Wire 61 | val lq_empty = Wire(Bool()) 62 | 63 | val entry_create = Wire(Vec(LQ_ENTRY, new Bundle { 64 | val dp_vld = Vec(2, Bool()) 65 | val gateclk_en = Vec(2, Bool()) 66 | val vld = Vec(2, Bool()) 67 | })) 68 | 69 | val lq_entry_inst_hit = Wire(Vec(LQ_ENTRY, Bool())) 70 | val lq_entry_rar_spec_fail = Wire(Vec(LQ_ENTRY, Bool())) 71 | val lq_entry_raw_spec_fail = Wire(Vec(LQ_ENTRY, Bool())) 72 | val lq_entry_vld = Wire(Vec(LQ_ENTRY, Bool())) 73 | 74 | val lq_create_ptr = Wire(Vec(2, Vec(LQ_ENTRY, Bool()))) 75 | lq_create_ptr(0) := VecInit(Seq.fill(LQ_ENTRY)(false.B)) 76 | lq_create_ptr(1) := VecInit(Seq.fill(LQ_ENTRY)(false.B)) 77 | //========================================================== 78 | // Instance of Gated Cell 79 | //========================================================== 80 | val lq_clk_en = !lq_empty || io.in.EntryCreate.gateclk_en(0) 81 | 82 | //========================================================== 83 | // Instance load queue entry 84 | //========================================================== 85 | val lq_entry = Seq.fill(LQ_ENTRY)(Module(new LQEntry)) 86 | for(i <- 0 until LQ_ENTRY){ 87 | lq_entry(i).io.in.fromCP0 := io.in.fromCP0 88 | lq_entry(i).io.in.fromLdDC := io.in.fromLdDC 89 | lq_entry(i).io.in.fromPad := io.in.fromPad 90 | lq_entry(i).io.in.fromRTU := io.in.fromRTU 91 | lq_entry(i).io.in.fromStDC := io.in.fromStDC 92 | lq_entry(i).io.in.EntryCreate := entry_create(i) 93 | 94 | lq_entry_inst_hit(i) := lq_entry(i).io.out.inst_hit 95 | lq_entry_rar_spec_fail(i) := lq_entry(i).io.out.rar_spec_fail 96 | lq_entry_raw_spec_fail(i) := lq_entry(i).io.out.raw_spec_fail 97 | lq_entry_vld(i) := lq_entry(i).io.out.vld 98 | } 99 | 100 | //========================================================== 101 | // Generate create pointer 102 | //========================================================== 103 | when(!lq_entry_vld(0)){ 104 | lq_create_ptr(0)(0) := true.B 105 | } 106 | when(!lq_entry_vld(15)){ 107 | lq_create_ptr(1)(15) := true.B 108 | } 109 | 110 | for(i <- 1 until LQ_ENTRY){ 111 | when(lq_entry_vld.asUInt(i,0) === Cat(0.U(1.W), WireInit(VecInit(Seq.fill(i)(true.B))).asUInt)){lq_create_ptr(0)(i) := true.B} 112 | when(lq_entry_vld.asUInt(LQ_ENTRY-1, LQ_ENTRY-1-i) === Cat(WireInit(VecInit(Seq.fill(i)(true.B))).asUInt, 0.U(1.W))){lq_create_ptr(1)(LQ_ENTRY-1-i) := true.B} 113 | } 114 | 115 | lq_empty := !lq_entry_vld.asUInt.orR 116 | val lq_full = lq_entry_vld.asUInt.andR 117 | 118 | //========================================================== 119 | // Generate create pointer 120 | //========================================================== 121 | val lq_create_success = Wire(Vec(2, Bool())) 122 | lq_create_success(0) := io.in.EntryCreate.vld(0) && !io.in.fromRTU.yy_xx_flush && 123 | (!io.out.lq_ld_dc_less2 || !io.out.lq_ld_dc_full && !io.in.EntryCreate.vld(1)) 124 | 125 | lq_create_success(1) := lq_create_success(0) && io.in.EntryCreate.vld(1) 126 | 127 | for(i <- 0 until LQ_ENTRY){ 128 | for(j <- 0 until 2){ 129 | entry_create(i).vld(j) := lq_create_success(j) && lq_create_ptr(j)(i) 130 | entry_create(i).dp_vld(j) := io.in.EntryCreate.dp_vld(j) && lq_create_ptr(j)(i) 131 | entry_create(i).gateclk_en(j) := io.in.EntryCreate.gateclk_en(j) && lq_create_ptr(j)(i) 132 | } 133 | } 134 | 135 | //========================================================== 136 | // Generate interface 137 | //========================================================== 138 | io.out.lq_ld_dc_full := lq_full 139 | io.out.lq_ld_dc_less2 := (lq_create_ptr(0).asUInt | lq_entry_vld.asUInt).andR 140 | io.out.lq_ld_dc_inst_hit := lq_entry_inst_hit.asUInt.orR 141 | io.out.lq_ld_dc_spec_fail := lq_entry_rar_spec_fail.asUInt.orR 142 | io.out.lq_st_dc_spec_fail := lq_entry_raw_spec_fail.asUInt.orR 143 | io.out.lsu_idu_lq_not_full := !lq_full 144 | 145 | } 146 | --------------------------------------------------------------------------------