From 7ea464dc906eb629db1df7deb67ca9641ce01298 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Tue, 14 Jul 2020 12:49:36 -0700 Subject: [PATCH] 4th revision --- docs/Customization/Custom-Core.rst | 26 ++++++++++++++----- .../src/main/scala/example/TutorialTile.scala | 25 ++++++++++++++++++ 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/docs/Customization/Custom-Core.rst b/docs/Customization/Custom-Core.rst index 16d19f27..4a7f57f1 100644 --- a/docs/Customization/Custom-Core.rst +++ b/docs/Customization/Custom-Core.rst @@ -224,9 +224,9 @@ Connect Interrupt Chipyard allows a tile to either receive interrupts from other devices or initiate interrupts to notify other cores/devices. In the tile that inherited ``SinksExternalInterrupts``, one can create a ``TileInterrupts`` object (a Chisel bundle) and -call ``decodeCoreInterrupts`` with the object as the argument. Note that you should call this function in the implementation -class since it returns a Chisel bundle used by RTL code. You can then read the interrupt bits from the resulting object. -The definition of ``TileInterrupts`` is +call ``decodeCoreInterrupts()`` with the object as the argument. Note that you should call this function in the implementation +class since it returns a Chisel bundle used by RTL code. You can then read the interrupt bits from the ``TileInterrupts`` bundle +we create above. The definition of ``TileInterrupts`` is .. code-block:: scala @@ -239,15 +239,29 @@ The definition of ``TileInterrupts`` is val lip = Vec(coreParams.nLocalInterrupts, Bool()) // Local interrupts } +Here is an example on how to connect these signals in the implementation class: + +.. literalinclude:: ../../generators/chipyard/src/main/scala/example/TutorialTile.scala + :language: scala + :start-after: DOC include start: connect interrupt + :end-before: DOC include end: connect interrupt + Also, the tile can also notify other cores or devices for some events by calling following functions in ``SourcesExternalNotifications`` from the implementation class: .. code-block:: scala def reportHalt(could_halt: Option[Bool]) // Triggered when there is an unrecoverable hardware error (halt the machine) - def reportHalt(errors: Seq[CanHaveErrors]) // Varient for standard error bundle (used only by cache when there's an ECC error) - reportCease(could_cease: Option[Bool], quiescenceCycles: Int = 8) // Triggered when the core stop retiring instructions (like clock gating) - reportWFI(could_wfi: Option[Bool]) // Triggered when a WFI instruction is executed + def reportHalt(errors: Seq[CanHaveErrors]) // Varient for standard error bundle (Rocket specific: used only by cache when there's an ECC error) + def reportCease(could_cease: Option[Bool], quiescenceCycles: Int = 8) // Triggered when the core stop retiring instructions (like clock gating) + def reportWFI(could_wfi: Option[Bool]) // Triggered when a WFI instruction is executed + +Here is an example on how to use these functions to raise interrupt. + +.. literalinclude:: ../../generators/chipyard/src/main/scala/example/TutorialTile.scala + :language: scala + :start-after: DOC include start: raise interrupt + :end-before: DOC include end: raise interrupt Create Config Fragments to Integrate the Core --------------------------------------------- diff --git a/generators/chipyard/src/main/scala/example/TutorialTile.scala b/generators/chipyard/src/main/scala/example/TutorialTile.scala index 75ff1e5b..c8f71b85 100644 --- a/generators/chipyard/src/main/scala/example/TutorialTile.scala +++ b/generators/chipyard/src/main/scala/example/TutorialTile.scala @@ -163,6 +163,31 @@ class MyTileModuleImp(outer: MyTile) extends BaseTileModuleImp(outer){ //} // DOC include end: Implementation class + // DOC include start: connect interrupt + // For example, our core support debug interrupt and machine-level interrupt, and suppose the following two signals + // are the interrupt inputs to the core. (DO NOT COPY this code - if your core treat each type of interrupt differently, + // you need to connect them to different interrupt ports of your core) + val debug_i = Wire(Bool()) + val mtip_i = Wire(Bool()) + // We create a bundle here and decode the interrupt. + val int_bundle = new TileInterrupts() + outer.decodeCoreInterrupts(int_bundle) + debug_i := int_bundle.debug + mtip_i := int_bundle.meip & int_bundle.msip & int_bundle.mtip + // DOC include end: connect interrupt + + // DOC include start: raise interrupt + // This is a demo. You should call these function according to your core + // Suppose that the following signal is from the decoder indicating a WFI instruction is received. + val wfi_o = Wire(Bool()) + outer.reportWFI(Some(wfi_o)) + // Suppose that the following signal indicate an unreconverable hardware error. + val halt_o = Wire(Bool()) + outer.reportHalt(Some(halt_o)) + // Suppose that our core never stall for a long time / stop retiring. Use None to indicate that this interrupt never fires. + outer.reportCease(None) + // DOC include end: raise interrupt + // DOC include start: AXI4 connect outer.memAXI4Node.out foreach { case (out, edgeOut) => // Connect your module IO port to "out"