Merge branch 'controller_improvements' into 'master'
Channel controller improvements and code cleanup See merge request ems/astdm/dram.sys!244
This commit is contained in:
@@ -47,90 +47,122 @@ set(CMAKE_CXX_STANDARD 11 CACHE STRING "C++ Version")
|
||||
set(DCMAKE_SH="CMAKE_SH-NOTFOUND")
|
||||
|
||||
include_directories(
|
||||
src/simulation
|
||||
src/simulation/dram
|
||||
src/controller
|
||||
src/controller/checker
|
||||
src/controller/cmdmux
|
||||
src/controller/powerdown
|
||||
src/controller/refresh
|
||||
src/controller/scheduler
|
||||
src/common
|
||||
src/common/third_party/DRAMPower/src
|
||||
src/configuration
|
||||
src/configuration/memspec
|
||||
src/error
|
||||
src/error/ECC
|
||||
src/common
|
||||
src/common/third_party/DRAMPower/src
|
||||
src/configuration
|
||||
src/configuration/memspec
|
||||
src/controller
|
||||
src/controller/checker
|
||||
src/controller/cmdmux
|
||||
src/controller/powerdown
|
||||
src/controller/refresh
|
||||
src/controller/respqueue
|
||||
src/controller/scheduler
|
||||
src/error
|
||||
src/error/ECC
|
||||
src/simulation
|
||||
src/simulation/dram
|
||||
)
|
||||
|
||||
add_library(DRAMSysLibrary
|
||||
src/common/third_party/tinyxml2/tinyxml2.cpp
|
||||
src/common/TlmRecorder.cpp
|
||||
src/common/DebugManager.cpp
|
||||
src/configuration/Configuration.cpp
|
||||
src/simulation/MemoryManager.cpp
|
||||
src/simulation/TemperatureController.cpp
|
||||
src/configuration/ConfigurationLoader.cpp
|
||||
src/controller/Command.cpp
|
||||
src/error/errormodel.cpp
|
||||
src/simulation/TracePlayer.cpp
|
||||
src/simulation/TraceSetup.cpp
|
||||
src/simulation/DRAMSys.cpp
|
||||
src/simulation/Setup.cpp
|
||||
src/error/ECC/Bit.cpp
|
||||
src/error/ECC/ECC.cpp
|
||||
src/error/ECC/Word.cpp
|
||||
src/error/eccbaseclass.cpp
|
||||
src/error/ecchamming.cpp
|
||||
src/common/AddressDecoder.cpp
|
||||
src/simulation/dram/Dram.cpp
|
||||
src/simulation/Arbiter.cpp
|
||||
src/common/CongenAddressDecoder.cpp
|
||||
src/common/XmlAddressDecoder.cpp
|
||||
src/common/timingCalculations.cpp
|
||||
src/common/dramExtensions.cpp
|
||||
src/common/utils.cpp
|
||||
src/simulation/dram/DramDDR3.cpp
|
||||
src/simulation/dram/DramDDR4.cpp
|
||||
src/simulation/dram/DramRecordable.cpp
|
||||
src/simulation/dram/DramWideIO.cpp
|
||||
src/configuration/memspec/MemSpec.cpp
|
||||
src/controller/BankMachine.cpp
|
||||
src/controller/Controller.cpp
|
||||
src/controller/scheduler/SchedulerFifo.cpp
|
||||
src/controller/scheduler/SchedulerFrFcfs.cpp
|
||||
src/controller/cmdmux/CmdMuxStrict.cpp
|
||||
src/controller/cmdmux/CmdMuxOldest.cpp
|
||||
src/controller/ControllerRecordable.cpp
|
||||
src/controller/checker/CheckerDDR3.cpp
|
||||
src/controller/refresh/RefreshManager.cpp
|
||||
src/controller/refresh/RefreshManagerDummy.cpp
|
||||
src/controller/refresh/RefreshManagerBankwise.cpp
|
||||
src/controller/checker/CheckerWideIO.cpp
|
||||
src/configuration/memspec/MemSpecDDR3.cpp
|
||||
src/configuration/memspec/MemSpecDDR4.cpp
|
||||
src/configuration/memspec/MemSpecWideIO.cpp
|
||||
src/configuration/memspec/MemSpecLPDDR4.cpp
|
||||
src/controller/checker/CheckerDDR4.cpp
|
||||
src/simulation/dram/DramLPDDR4.cpp
|
||||
src/controller/checker/CheckerLPDDR4.cpp
|
||||
src/configuration/memspec/MemSpecWideIO2.cpp
|
||||
src/simulation/dram/DramWideIO2.cpp
|
||||
src/controller/checker/CheckerWideIO2.cpp
|
||||
src/configuration/memspec/MemSpecHBM2.cpp
|
||||
src/simulation/dram/DramHBM2.cpp
|
||||
src/controller/checker/CheckerHBM2.cpp
|
||||
src/configuration/memspec/MemSpecGDDR5.cpp
|
||||
src/configuration/memspec/MemSpecGDDR5X.cpp
|
||||
src/configuration/memspec/MemSpecGDDR6.cpp
|
||||
src/controller/checker/CheckerGDDR5.cpp
|
||||
src/controller/checker/CheckerGDDR5X.cpp
|
||||
src/controller/checker/CheckerGDDR6.cpp
|
||||
src/simulation/dram/DramGDDR5.cpp
|
||||
src/simulation/dram/DramGDDR5X.cpp
|
||||
src/simulation/dram/DramGDDR6.cpp
|
||||
src/controller/powerdown/PowerDownManagerStaggered.cpp
|
||||
src/controller/powerdown/PowerDownManagerDummy.cpp
|
||||
src/common/AddressDecoder.cpp
|
||||
src/common/CongenAddressDecoder.cpp
|
||||
src/common/DebugManager.cpp
|
||||
src/common/dramExtensions.cpp
|
||||
src/common/tlm2_base_protocol_checker.h
|
||||
src/common/TlmRecorder.cpp
|
||||
src/common/utils.cpp
|
||||
src/common/XmlAddressDecoder.cpp
|
||||
src/common/third_party/tinyxml2/tinyxml2.cpp
|
||||
|
||||
src/configuration/Configuration.cpp
|
||||
src/configuration/ConfigurationLoader.cpp
|
||||
src/configuration/TemperatureSimConfig.h
|
||||
|
||||
src/configuration/memspec/MemSpec.cpp
|
||||
src/configuration/memspec/MemSpecDDR3.cpp
|
||||
src/configuration/memspec/MemSpecDDR4.cpp
|
||||
src/configuration/memspec/MemSpecLPDDR4.cpp
|
||||
src/configuration/memspec/MemSpecWideIO.cpp
|
||||
src/configuration/memspec/MemSpecWideIO2.cpp
|
||||
src/configuration/memspec/MemSpecGDDR5.cpp
|
||||
src/configuration/memspec/MemSpecGDDR5X.cpp
|
||||
src/configuration/memspec/MemSpecGDDR6.cpp
|
||||
src/configuration/memspec/MemSpecHBM2.cpp
|
||||
|
||||
src/controller/BankMachine.cpp
|
||||
src/controller/Command.cpp
|
||||
src/controller/ControllerIF.h
|
||||
src/controller/Controller.cpp
|
||||
src/controller/ControllerRecordable.cpp
|
||||
|
||||
src/controller/checker/CheckerIF.h
|
||||
src/controller/checker/CheckerDDR3.cpp
|
||||
src/controller/checker/CheckerDDR4.cpp
|
||||
src/controller/checker/CheckerLPDDR4.cpp
|
||||
src/controller/checker/CheckerWideIO.cpp
|
||||
src/controller/checker/CheckerWideIO2.cpp
|
||||
src/controller/checker/CheckerGDDR5.cpp
|
||||
src/controller/checker/CheckerGDDR5X.cpp
|
||||
src/controller/checker/CheckerGDDR6.cpp
|
||||
src/controller/checker/CheckerHBM2.cpp
|
||||
|
||||
src/controller/cmdmux/CmdMuxIF.h
|
||||
src/controller/cmdmux/CmdMuxOldest.cpp
|
||||
src/controller/cmdmux/CmdMuxStrict.cpp
|
||||
|
||||
src/controller/powerdown/PowerDownManagerIF.h
|
||||
src/controller/powerdown/PowerDownManagerDummy.cpp
|
||||
src/controller/powerdown/PowerDownManagerStaggered.cpp
|
||||
|
||||
src/controller/refresh/RefreshManagerIF.h
|
||||
src/controller/refresh/RefreshManagerDummy.cpp
|
||||
src/controller/refresh/RefreshManagerRankwise.cpp
|
||||
src/controller/refresh/RefreshManagerBankwise.cpp
|
||||
|
||||
src/controller/respqueue/RespQueueIF.h
|
||||
src/controller/respqueue/RespQueueFifo.cpp
|
||||
src/controller/respqueue/RespQueueReorder.cpp
|
||||
|
||||
src/controller/scheduler/SchedulerIF.h
|
||||
src/controller/scheduler/SchedulerFifo.cpp
|
||||
src/controller/scheduler/SchedulerFrFcfs.cpp
|
||||
src/controller/scheduler/SchedulerFrFcfsGrp.cpp
|
||||
|
||||
src/error/eccbaseclass.cpp
|
||||
src/error/ecchamming.cpp
|
||||
src/error/errormodel.cpp
|
||||
|
||||
src/error/ECC/Bit.cpp
|
||||
src/error/ECC/ECC.cpp
|
||||
src/error/ECC/Word.cpp
|
||||
|
||||
src/simulation/Arbiter.cpp
|
||||
src/simulation/DRAMSys.cpp
|
||||
src/simulation/ExampleInitiator.h
|
||||
src/simulation/IArbiter.h
|
||||
src/simulation/MemoryManager.cpp
|
||||
src/simulation/ReorderBuffer.h
|
||||
src/simulation/Setup.cpp
|
||||
src/simulation/SimpleArbiter.h
|
||||
src/simulation/StlPlayer.h
|
||||
src/simulation/TemperatureController.cpp
|
||||
src/simulation/TraceGenerator.h
|
||||
src/simulation/TracePlayer.cpp
|
||||
src/simulation/TracePlayerListener.h
|
||||
src/simulation/TraceSetup.cpp
|
||||
|
||||
src/simulation/dram/Dram.cpp
|
||||
src/simulation/dram/DramRecordable.cpp
|
||||
src/simulation/dram/DramDDR3.cpp
|
||||
src/simulation/dram/DramDDR4.cpp
|
||||
src/simulation/dram/DramLPDDR4.cpp
|
||||
src/simulation/dram/DramWideIO.cpp
|
||||
src/simulation/dram/DramWideIO2.cpp
|
||||
src/simulation/dram/DramGDDR5.cpp
|
||||
src/simulation/dram/DramGDDR5X.cpp
|
||||
src/simulation/dram/DramGDDR6.cpp
|
||||
src/simulation/dram/DramHBM2.cpp
|
||||
)
|
||||
|
||||
# Build:
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
memconfig.xml
|
||||
@@ -1,43 +1,20 @@
|
||||
<mcconfig>
|
||||
<OpenPagePolicy value="1" />
|
||||
<MaxNrOfTransactions value="8" />
|
||||
<!-- Open, OpenAdaptive, Closed, ClosedAdaptive -->
|
||||
<PagePolicy value="Open" />
|
||||
<!-- Fifo, FrFcfs, FrFcfsGrp -->
|
||||
<Scheduler value="Fifo" />
|
||||
<Capsize value="5" />
|
||||
<!-- 4 Modes: NoPowerDown, Staggered, TimeoutPDN, TimeoutSREF -->
|
||||
<PowerDownMode value="NoPowerDown" />
|
||||
<RequestBufferSize value="8" />
|
||||
<!-- Oldest, Strict -->
|
||||
<CmdMux value="Strict" />
|
||||
<!-- Fifo, Reorder -->
|
||||
<RespQueue value="Fifo" />
|
||||
<!-- NoRefresh, Rankwise, Bankwise -->
|
||||
<RefreshPolicy value="Rankwise" />
|
||||
<!-- 1: 1X, 2: 2X, 4: 4X (e.g., DDR4) -->
|
||||
<RefreshMode value="1" />
|
||||
<RefreshMaxPostponed value="8"/>
|
||||
<RefreshMaxPulledin value="8"/>
|
||||
<!-- NoPowerDown, Staggered, TimeoutPDN, TimeoutSREF -->
|
||||
<PowerDownPolicy value="NoPowerDown" />
|
||||
<PowerDownTimeout value="100" />
|
||||
<!-- Bankwise -->
|
||||
<BankwiseLogic value="0"/>
|
||||
<!-- Refresh yes, no -->
|
||||
<ControllerCoreRefDisable value="0"/>
|
||||
<!-- Refresh Mode. 1: 1X, 2: 2X, 4: 4X (e.g., DDR4) -->
|
||||
<ControllerCoreRefMode value="1"/>
|
||||
<!-- Number of AR commands in a tREFI in 1X mode -->
|
||||
<ControllerCoreRefNumARCmdsIntREFI value="8192"/>
|
||||
<!-- RGR -->
|
||||
<ControllerCoreRGR value="0"/>
|
||||
<ControllerCoreRGRRowInc value="1"/>
|
||||
<!-- Banks to be refreshed in RGR mode. 1: yes, 0: no (max. 16 banks) -->
|
||||
<ControllerCoreRGRB0 value="1"/>
|
||||
<ControllerCoreRGRB1 value="1"/>
|
||||
<ControllerCoreRGRB2 value="1"/>
|
||||
<ControllerCoreRGRB3 value="1"/>
|
||||
<ControllerCoreRGRB4 value="1"/>
|
||||
<ControllerCoreRGRB5 value="1"/>
|
||||
<ControllerCoreRGRB6 value="1"/>
|
||||
<ControllerCoreRGRB7 value="1"/>
|
||||
<ControllerCoreRGRB8 value="0"/>
|
||||
<ControllerCoreRGRB9 value="0"/>
|
||||
<ControllerCoreRGRB10 value="0"/>
|
||||
<ControllerCoreRGRB11 value="0"/>
|
||||
<ControllerCoreRGRB12 value="0"/>
|
||||
<ControllerCoreRGRB13 value="0"/>
|
||||
<ControllerCoreRGRB14 value="0"/>
|
||||
<ControllerCoreRGRB15 value="0"/>
|
||||
<!-- Postpone, pull-in -->
|
||||
<ControllerCoreRefEnablePostpone value="0"/>
|
||||
<ControllerCoreRefEnablePullIn value="0"/>
|
||||
<ControllerCoreRefMaxPostponed value="8"/>
|
||||
<ControllerCoreRefMaxPulledIn value="8"/>
|
||||
<ControllerCoreRefForceMaxPostponeBurst value="0"/>
|
||||
</mcconfig>
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
<mcconfig>
|
||||
<OpenPagePolicy value="1" />
|
||||
<AdaptivePagePolicy value="0" />
|
||||
<MaxNrOfTransactions value="8" />
|
||||
<Scheduler value="FifoStrict" />
|
||||
<Capsize value="5" />
|
||||
<!-- 4 Modes: NoPowerDown, Staggered, TimeoutPDN, TimeoutSREF -->
|
||||
<PowerDownMode value="NoPowerDown" />
|
||||
<PowerDownTimeout value="100" />
|
||||
<!-- Bankwise -->
|
||||
<BankwiseLogic value="0"/>
|
||||
<!-- Refresh yes, no -->
|
||||
<ControllerCoreRefDisable value="0"/>
|
||||
<!-- Refresh Mode. 1: 1X, 2: 2X, 4: 4X (e.g., DDR4) -->
|
||||
<ControllerCoreRefMode value="1"/>
|
||||
<!-- Number of AR commands in a tREFI in 1X mode -->
|
||||
<ControllerCoreRefNumARCmdsIntREFI value="8192"/>
|
||||
<!-- RGR -->
|
||||
<ControllerCoreRGR value="0"/>
|
||||
<ControllerCoreRGRRowInc value="1"/>
|
||||
<!-- Banks to be refreshed in RGR mode. 1: yes, 0: no (max. 16 banks) -->
|
||||
<ControllerCoreRGRB0 value="1"/>
|
||||
<ControllerCoreRGRB1 value="1"/>
|
||||
<ControllerCoreRGRB2 value="1"/>
|
||||
<ControllerCoreRGRB3 value="1"/>
|
||||
<ControllerCoreRGRB4 value="1"/>
|
||||
<ControllerCoreRGRB5 value="1"/>
|
||||
<ControllerCoreRGRB6 value="1"/>
|
||||
<ControllerCoreRGRB7 value="1"/>
|
||||
<ControllerCoreRGRB8 value="0"/>
|
||||
<ControllerCoreRGRB9 value="0"/>
|
||||
<ControllerCoreRGRB10 value="0"/>
|
||||
<ControllerCoreRGRB11 value="0"/>
|
||||
<ControllerCoreRGRB12 value="0"/>
|
||||
<ControllerCoreRGRB13 value="0"/>
|
||||
<ControllerCoreRGRB14 value="0"/>
|
||||
<ControllerCoreRGRB15 value="0"/>
|
||||
<!-- Postpone, pull-in -->
|
||||
<ControllerCoreRefEnablePostpone value="0"/>
|
||||
<ControllerCoreRefEnablePullIn value="0"/>
|
||||
<ControllerCoreRefMaxPostponed value="8"/>
|
||||
<ControllerCoreRefMaxPulledIn value="8"/>
|
||||
<ControllerCoreRefForceMaxPostponeBurst value="0"/>
|
||||
</mcconfig>
|
||||
@@ -1,43 +0,0 @@
|
||||
<mcconfig>
|
||||
<OpenPagePolicy value="1" />
|
||||
<MaxNrOfTransactions value="8" />
|
||||
<Scheduler value="Fifo" />
|
||||
<Capsize value="5" />
|
||||
<!-- 4 Modes: NoPowerDown, Staggered, TimeoutPDN, TimeoutSREF -->
|
||||
<PowerDownMode value="NoPowerDown" />
|
||||
<PowerDownTimeout value="100" />
|
||||
<!-- Bankwise -->
|
||||
<BankwiseLogic value="0"/>
|
||||
<!-- Refresh yes, no -->
|
||||
<ControllerCoreRefDisable value="0"/>
|
||||
<!-- Refresh Mode. 1: 1X, 2: 2X, 4: 4X (e.g., DDR4) -->
|
||||
<ControllerCoreRefMode value="1"/>
|
||||
<!-- Number of AR commands in a tREFI in 1X mode -->
|
||||
<ControllerCoreRefNumARCmdsIntREFI value="8192"/>
|
||||
<!-- RGR -->
|
||||
<ControllerCoreRGR value="0"/>
|
||||
<ControllerCoreRGRRowInc value="1"/>
|
||||
<!-- Banks to be refreshed in RGR mode. 1: yes, 0: no (max. 16 banks) -->
|
||||
<ControllerCoreRGRB0 value="1"/>
|
||||
<ControllerCoreRGRB1 value="1"/>
|
||||
<ControllerCoreRGRB2 value="1"/>
|
||||
<ControllerCoreRGRB3 value="1"/>
|
||||
<ControllerCoreRGRB4 value="1"/>
|
||||
<ControllerCoreRGRB5 value="1"/>
|
||||
<ControllerCoreRGRB6 value="1"/>
|
||||
<ControllerCoreRGRB7 value="1"/>
|
||||
<ControllerCoreRGRB8 value="0"/>
|
||||
<ControllerCoreRGRB9 value="0"/>
|
||||
<ControllerCoreRGRB10 value="0"/>
|
||||
<ControllerCoreRGRB11 value="0"/>
|
||||
<ControllerCoreRGRB12 value="0"/>
|
||||
<ControllerCoreRGRB13 value="0"/>
|
||||
<ControllerCoreRGRB14 value="0"/>
|
||||
<ControllerCoreRGRB15 value="0"/>
|
||||
<!-- Postpone, pull-in -->
|
||||
<ControllerCoreRefEnablePostpone value="0"/>
|
||||
<ControllerCoreRefEnablePullIn value="0"/>
|
||||
<ControllerCoreRefMaxPostponed value="8"/>
|
||||
<ControllerCoreRefMaxPulledIn value="8"/>
|
||||
<ControllerCoreRefForceMaxPostponeBurst value="0"/>
|
||||
</mcconfig>
|
||||
@@ -1,44 +1,20 @@
|
||||
<mcconfig>
|
||||
<OpenPagePolicy value="1" />
|
||||
<AdaptivePagePolicy value="1" />
|
||||
<MaxNrOfTransactions value="8" />
|
||||
<!-- Open, OpenAdaptive, Closed, ClosedAdaptive -->
|
||||
<PagePolicy value="Open" />
|
||||
<!-- Fifo, FrFcfs, FrFcfsGrp -->
|
||||
<Scheduler value="FrFcfs" />
|
||||
<Capsize value="5" />
|
||||
<!-- 4 Modes: NoPowerDown, Staggered, TimeoutPDN, TimeoutSREF -->
|
||||
<PowerDownMode value="NoPowerDown" />
|
||||
<RequestBufferSize value="8" />
|
||||
<!-- Oldest, Strict -->
|
||||
<CmdMux value="Oldest" />
|
||||
<!-- Fifo, Reorder -->
|
||||
<RespQueue value="Fifo" />
|
||||
<!-- NoRefresh, Rankwise, Bankwise -->
|
||||
<RefreshPolicy value="Rankwise" />
|
||||
<!-- 1: 1X, 2: 2X, 4: 4X (e.g., DDR4) -->
|
||||
<RefreshMode value="1" />
|
||||
<RefreshMaxPostponed value="8"/>
|
||||
<RefreshMaxPulledin value="8"/>
|
||||
<!-- NoPowerDown, Staggered, TimeoutPDN, TimeoutSREF -->
|
||||
<PowerDownPolicy value="NoPowerDown" />
|
||||
<PowerDownTimeout value="100" />
|
||||
<!-- Bankwise -->
|
||||
<BankwiseLogic value="0"/>
|
||||
<!-- Refresh yes, no -->
|
||||
<ControllerCoreRefDisable value="0"/>
|
||||
<!-- Refresh Mode. 1: 1X, 2: 2X, 4: 4X (e.g., DDR4) -->
|
||||
<ControllerCoreRefMode value="1"/>
|
||||
<!-- Number of AR commands in a tREFI in 1X mode -->
|
||||
<ControllerCoreRefNumARCmdsIntREFI value="8192"/>
|
||||
<!-- RGR -->
|
||||
<ControllerCoreRGR value="0"/>
|
||||
<ControllerCoreRGRRowInc value="1"/>
|
||||
<!-- Banks to be refreshed in RGR mode. 1: yes, 0: no (max. 16 banks) -->
|
||||
<ControllerCoreRGRB0 value="1"/>
|
||||
<ControllerCoreRGRB1 value="1"/>
|
||||
<ControllerCoreRGRB2 value="1"/>
|
||||
<ControllerCoreRGRB3 value="1"/>
|
||||
<ControllerCoreRGRB4 value="1"/>
|
||||
<ControllerCoreRGRB5 value="1"/>
|
||||
<ControllerCoreRGRB6 value="1"/>
|
||||
<ControllerCoreRGRB7 value="1"/>
|
||||
<ControllerCoreRGRB8 value="0"/>
|
||||
<ControllerCoreRGRB9 value="0"/>
|
||||
<ControllerCoreRGRB10 value="0"/>
|
||||
<ControllerCoreRGRB11 value="0"/>
|
||||
<ControllerCoreRGRB12 value="0"/>
|
||||
<ControllerCoreRGRB13 value="0"/>
|
||||
<ControllerCoreRGRB14 value="0"/>
|
||||
<ControllerCoreRGRB15 value="0"/>
|
||||
<!-- Postpone, pull-in -->
|
||||
<ControllerCoreRefEnablePostpone value="0"/>
|
||||
<ControllerCoreRefEnablePullIn value="0"/>
|
||||
<ControllerCoreRefMaxPostponed value="8"/>
|
||||
<ControllerCoreRefMaxPulledIn value="8"/>
|
||||
<ControllerCoreRefForceMaxPostponeBurst value="0"/>
|
||||
</mcconfig>
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
<mcconfig>
|
||||
<OpenPagePolicy value="1" />
|
||||
<MaxNrOfTransactions value="16" />
|
||||
<Scheduler value="FR_FCFS" />
|
||||
<Capsize value="5" />
|
||||
<PowerDownMode value="NoPowerDown" />
|
||||
<PowerDownTimeout value="100" />
|
||||
<!-- Bankwise -->
|
||||
<BankwiseLogic value="1"/>
|
||||
<!-- Refresh yes, no -->
|
||||
<ControllerCoreRefDisable value="0"/>
|
||||
<!-- Refresh Mode. 1: 1X, 2: 2X, 4: 4X (e.g., DDR4) -->
|
||||
<ControllerCoreRefMode value="1"/>
|
||||
<!-- Number of AR commands in a tREFI in 1X mode -->
|
||||
<ControllerCoreRefNumARCmdsIntREFI value="8192"/>
|
||||
<!-- RGR -->
|
||||
<ControllerCoreRGR value="0"/>
|
||||
<ControllerCoreRGRRowInc value="1"/>
|
||||
<!-- Banks to be refreshed in RGR mode. 1: yes, 0: no (max. 16 banks) -->
|
||||
<ControllerCoreRGRB0 value="1"/>
|
||||
<ControllerCoreRGRB1 value="1"/>
|
||||
<ControllerCoreRGRB2 value="1"/>
|
||||
<ControllerCoreRGRB3 value="1"/>
|
||||
<ControllerCoreRGRB4 value="1"/>
|
||||
<ControllerCoreRGRB5 value="1"/>
|
||||
<ControllerCoreRGRB6 value="1"/>
|
||||
<ControllerCoreRGRB7 value="1"/>
|
||||
<ControllerCoreRGRB8 value="0"/>
|
||||
<ControllerCoreRGRB9 value="0"/>
|
||||
<ControllerCoreRGRB10 value="0"/>
|
||||
<ControllerCoreRGRB11 value="0"/>
|
||||
<ControllerCoreRGRB12 value="0"/>
|
||||
<ControllerCoreRGRB13 value="0"/>
|
||||
<ControllerCoreRGRB14 value="0"/>
|
||||
<ControllerCoreRGRB15 value="0"/>
|
||||
<!-- Postpone, pull-in -->
|
||||
<ControllerCoreRefEnablePostpone value="0"/>
|
||||
<ControllerCoreRefEnablePullIn value="0"/>
|
||||
<ControllerCoreRefMaxPostponed value="8"/>
|
||||
<ControllerCoreRefMaxPulledIn value="8"/>
|
||||
<ControllerCoreRefForceMaxPostponeBurst value="0"/>
|
||||
</mcconfig>
|
||||
@@ -1,42 +0,0 @@
|
||||
<mcconfig>
|
||||
<OpenPagePolicy value="0" />
|
||||
<MaxNrOfTransactions value="16" />
|
||||
<Scheduler value="FR_FCFS" />
|
||||
<Capsize value="5" />
|
||||
<PowerDownMode value="NoPowerDown" />
|
||||
<PowerDownTimeout value="100" />
|
||||
<!-- Bankwise -->
|
||||
<BankwiseLogic value="1"/>
|
||||
<!-- Refresh yes, no -->
|
||||
<ControllerCoreRefDisable value="0"/>
|
||||
<!-- Refresh Mode. 1: 1X, 2: 2X, 4: 4X (e.g., DDR4) -->
|
||||
<ControllerCoreRefMode value="1"/>
|
||||
<!-- Number of AR commands in a tREFI in 1X mode -->
|
||||
<ControllerCoreRefNumARCmdsIntREFI value="8192"/>
|
||||
<!-- RGR -->
|
||||
<ControllerCoreRGR value="0"/>
|
||||
<ControllerCoreRGRRowInc value="1"/>
|
||||
<!-- Banks to be refreshed in RGR mode. 1: yes, 0: no (max. 16 banks) -->
|
||||
<ControllerCoreRGRB0 value="1"/>
|
||||
<ControllerCoreRGRB1 value="1"/>
|
||||
<ControllerCoreRGRB2 value="1"/>
|
||||
<ControllerCoreRGRB3 value="1"/>
|
||||
<ControllerCoreRGRB4 value="1"/>
|
||||
<ControllerCoreRGRB5 value="1"/>
|
||||
<ControllerCoreRGRB6 value="1"/>
|
||||
<ControllerCoreRGRB7 value="1"/>
|
||||
<ControllerCoreRGRB8 value="0"/>
|
||||
<ControllerCoreRGRB9 value="0"/>
|
||||
<ControllerCoreRGRB10 value="0"/>
|
||||
<ControllerCoreRGRB11 value="0"/>
|
||||
<ControllerCoreRGRB12 value="0"/>
|
||||
<ControllerCoreRGRB13 value="0"/>
|
||||
<ControllerCoreRGRB14 value="0"/>
|
||||
<ControllerCoreRGRB15 value="0"/>
|
||||
<!-- Postpone, pull-in -->
|
||||
<ControllerCoreRefEnablePostpone value="0"/>
|
||||
<ControllerCoreRefEnablePullIn value="0"/>
|
||||
<ControllerCoreRefMaxPostponed value="8"/>
|
||||
<ControllerCoreRefMaxPulledIn value="8"/>
|
||||
<ControllerCoreRefForceMaxPostponeBurst value="0"/>
|
||||
</mcconfig>
|
||||
@@ -1,43 +1,20 @@
|
||||
<mcconfig>
|
||||
<OpenPagePolicy value="1" />
|
||||
<MaxNrOfTransactions value="16" />
|
||||
<!-- Open, OpenAdaptive, Closed, ClosedAdaptive -->
|
||||
<PagePolicy value="Open" />
|
||||
<!-- Fifo, FrFcfs, FrFcfsGrp -->
|
||||
<Scheduler value="FrFcfsGrp" />
|
||||
<Capsize value="5" />
|
||||
<!-- 4 Modes: NoPowerDown, Staggered, TimeoutPDN, TimeoutSREF -->
|
||||
<PowerDownMode value="NoPowerDown" />
|
||||
<RequestBufferSize value="8" />
|
||||
<!-- Oldest, Strict -->
|
||||
<CmdMux value="Oldest" />
|
||||
<!-- Fifo, Reorder -->
|
||||
<RespQueue value="Fifo" />
|
||||
<!-- NoRefresh, Rankwise, Bankwise -->
|
||||
<RefreshPolicy value="Rankwise" />
|
||||
<!-- 1: 1X, 2: 2X, 4: 4X (e.g., DDR4) -->
|
||||
<RefreshMode value="1" />
|
||||
<RefreshMaxPostponed value="8"/>
|
||||
<RefreshMaxPulledin value="8"/>
|
||||
<!-- NoPowerDown, Staggered, TimeoutPDN, TimeoutSREF -->
|
||||
<PowerDownPolicy value="NoPowerDown" />
|
||||
<PowerDownTimeout value="100" />
|
||||
<!-- Bankwise -->
|
||||
<BankwiseLogic value="0"/>
|
||||
<!-- Refresh yes, no -->
|
||||
<ControllerCoreRefDisable value="0"/>
|
||||
<!-- Refresh Mode. 1: 1X, 2: 2X, 4: 4X (e.g., DDR4) -->
|
||||
<ControllerCoreRefMode value="1"/>
|
||||
<!-- Number of AR commands in a tREFI in 1X mode -->
|
||||
<ControllerCoreRefNumARCmdsIntREFI value="8192"/>
|
||||
<!-- RGR -->
|
||||
<ControllerCoreRGR value="0"/>
|
||||
<ControllerCoreRGRRowInc value="1"/>
|
||||
<!-- Banks to be refreshed in RGR mode. 1: yes, 0: no (max. 16 banks) -->
|
||||
<ControllerCoreRGRB0 value="1"/>
|
||||
<ControllerCoreRGRB1 value="1"/>
|
||||
<ControllerCoreRGRB2 value="1"/>
|
||||
<ControllerCoreRGRB3 value="1"/>
|
||||
<ControllerCoreRGRB4 value="1"/>
|
||||
<ControllerCoreRGRB5 value="1"/>
|
||||
<ControllerCoreRGRB6 value="1"/>
|
||||
<ControllerCoreRGRB7 value="1"/>
|
||||
<ControllerCoreRGRB8 value="0"/>
|
||||
<ControllerCoreRGRB9 value="0"/>
|
||||
<ControllerCoreRGRB10 value="0"/>
|
||||
<ControllerCoreRGRB11 value="0"/>
|
||||
<ControllerCoreRGRB12 value="0"/>
|
||||
<ControllerCoreRGRB13 value="0"/>
|
||||
<ControllerCoreRGRB14 value="0"/>
|
||||
<ControllerCoreRGRB15 value="0"/>
|
||||
<!-- Postpone, pull-in -->
|
||||
<ControllerCoreRefEnablePostpone value="0"/>
|
||||
<ControllerCoreRefEnablePullIn value="0"/>
|
||||
<ControllerCoreRefMaxPostponed value="8"/>
|
||||
<ControllerCoreRefMaxPulledIn value="8"/>
|
||||
<ControllerCoreRefForceMaxPostponeBurst value="0"/>
|
||||
</mcconfig>
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
<mcconfig>
|
||||
<BankwiseLogic value="1"/>
|
||||
<OpenPagePolicy value="1" />
|
||||
<MaxNrOfTransactions value="16" />
|
||||
<Scheduler value="FR_FCFS" />
|
||||
<Capsize value="5" />
|
||||
<PowerDownMode value="NoPowerDown" />
|
||||
<PowerDownTimeout value="100" />
|
||||
<ControllerCoreRefDisable value="0"/>
|
||||
<ControllerCoreRefForceMaxPostponeBurst value="0"/>
|
||||
<ControllerCoreRefEnablePostpone value="0"/>
|
||||
<ControllerCoreRefEnablePullIn value="0"/>
|
||||
<ControllerCoreRefMaxPostponed value="8"/>
|
||||
<ControllerCoreRefMaxPulledIn value="8"/>
|
||||
|
||||
<ControllerCoreRefDisable value="0"/>
|
||||
<ControllerCoreRGR value="1"/>
|
||||
<ControllerCoreRefNumARCmdsIntREFI value="8192"/>
|
||||
<ControllerCoreRGRRowInc value="1"/>
|
||||
<!-- Select the banks you want to refresh. 1: yes, 0: no (max. 16 banks) -->
|
||||
<ControllerCoreRGRB0 value="1"/>
|
||||
<ControllerCoreRGRB1 value="1"/>
|
||||
<ControllerCoreRGRB2 value="1"/>
|
||||
<ControllerCoreRGRB3 value="1"/>
|
||||
<ControllerCoreRGRB4 value="1"/>
|
||||
<ControllerCoreRGRB5 value="1"/>
|
||||
<ControllerCoreRGRB6 value="1"/>
|
||||
<ControllerCoreRGRB7 value="1"/>
|
||||
<ControllerCoreRGRB8 value="0"/>
|
||||
<ControllerCoreRGRB9 value="0"/>
|
||||
<ControllerCoreRGRB10 value="0"/>
|
||||
<ControllerCoreRGRB11 value="0"/>
|
||||
<ControllerCoreRGRB12 value="0"/>
|
||||
<ControllerCoreRGRB13 value="0"/>
|
||||
<ControllerCoreRGRB14 value="0"/>
|
||||
<ControllerCoreRGRB15 value="0"/>
|
||||
</mcconfig>
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
<mcconfig>
|
||||
<OpenPagePolicy value="0" />
|
||||
<MaxNrOfTransactions value="16" />
|
||||
<Scheduler value="FR_FCFS" />
|
||||
<Capsize value="5" />
|
||||
<PowerDownMode value="NoPowerDown" />
|
||||
<PowerDownTimeout value="100" />
|
||||
<!-- Bankwise -->
|
||||
<BankwiseLogic value="0"/>
|
||||
<!-- Refresh yes, no -->
|
||||
<ControllerCoreRefDisable value="0"/>
|
||||
<!-- Refresh Mode. 1: 1X, 2: 2X, 4: 4X (e.g., DDR4) -->
|
||||
<ControllerCoreRefMode value="1"/>
|
||||
<!-- Number of AR commands in a tREFI in 1X mode -->
|
||||
<ControllerCoreRefNumARCmdsIntREFI value="8192"/>
|
||||
<!-- RGR -->
|
||||
<ControllerCoreRGR value="0"/>
|
||||
<ControllerCoreRGRRowInc value="1"/>
|
||||
<!-- Banks to be refreshed in RGR mode. 1: yes, 0: no (max. 16 banks) -->
|
||||
<ControllerCoreRGRB0 value="1"/>
|
||||
<ControllerCoreRGRB1 value="1"/>
|
||||
<ControllerCoreRGRB2 value="1"/>
|
||||
<ControllerCoreRGRB3 value="1"/>
|
||||
<ControllerCoreRGRB4 value="1"/>
|
||||
<ControllerCoreRGRB5 value="1"/>
|
||||
<ControllerCoreRGRB6 value="1"/>
|
||||
<ControllerCoreRGRB7 value="1"/>
|
||||
<ControllerCoreRGRB8 value="0"/>
|
||||
<ControllerCoreRGRB9 value="0"/>
|
||||
<ControllerCoreRGRB10 value="0"/>
|
||||
<ControllerCoreRGRB11 value="0"/>
|
||||
<ControllerCoreRGRB12 value="0"/>
|
||||
<ControllerCoreRGRB13 value="0"/>
|
||||
<ControllerCoreRGRB14 value="0"/>
|
||||
<ControllerCoreRGRB15 value="0"/>
|
||||
<!-- Postpone, pull-in -->
|
||||
<ControllerCoreRefEnablePostpone value="0"/>
|
||||
<ControllerCoreRefEnablePullIn value="0"/>
|
||||
<ControllerCoreRefMaxPostponed value="8"/>
|
||||
<ControllerCoreRefMaxPulledIn value="8"/>
|
||||
<ControllerCoreRefForceMaxPostponeBurst value="0"/>
|
||||
</mcconfig>
|
||||
@@ -1,43 +0,0 @@
|
||||
<mcconfig>
|
||||
<OpenPagePolicy value="1" />
|
||||
<MaxNrOfTransactions value="16" />
|
||||
<Scheduler value="FrFcfsRp" />
|
||||
<Capsize value="5" />
|
||||
<!-- 4 Modes: NoPowerDown, Staggered, TimeoutPDN, TimeoutSREF -->
|
||||
<PowerDownMode value="NoPowerDown" />
|
||||
<PowerDownTimeout value="100" />
|
||||
<!-- Bankwise -->
|
||||
<BankwiseLogic value="0"/>
|
||||
<!-- Refresh yes, no -->
|
||||
<ControllerCoreRefDisable value="0"/>
|
||||
<!-- Refresh Mode. 1: 1X, 2: 2X, 4: 4X (e.g., DDR4) -->
|
||||
<ControllerCoreRefMode value="1"/>
|
||||
<!-- Number of AR commands in a tREFI in 1X mode -->
|
||||
<ControllerCoreRefNumARCmdsIntREFI value="8192"/>
|
||||
<!-- RGR -->
|
||||
<ControllerCoreRGR value="0"/>
|
||||
<ControllerCoreRGRRowInc value="1"/>
|
||||
<!-- Banks to be refreshed in RGR mode. 1: yes, 0: no (max. 16 banks) -->
|
||||
<ControllerCoreRGRB0 value="1"/>
|
||||
<ControllerCoreRGRB1 value="1"/>
|
||||
<ControllerCoreRGRB2 value="1"/>
|
||||
<ControllerCoreRGRB3 value="1"/>
|
||||
<ControllerCoreRGRB4 value="1"/>
|
||||
<ControllerCoreRGRB5 value="1"/>
|
||||
<ControllerCoreRGRB6 value="1"/>
|
||||
<ControllerCoreRGRB7 value="1"/>
|
||||
<ControllerCoreRGRB8 value="0"/>
|
||||
<ControllerCoreRGRB9 value="0"/>
|
||||
<ControllerCoreRGRB10 value="0"/>
|
||||
<ControllerCoreRGRB11 value="0"/>
|
||||
<ControllerCoreRGRB12 value="0"/>
|
||||
<ControllerCoreRGRB13 value="0"/>
|
||||
<ControllerCoreRGRB14 value="0"/>
|
||||
<ControllerCoreRGRB15 value="0"/>
|
||||
<!-- Postpone, pull-in -->
|
||||
<ControllerCoreRefEnablePostpone value="0"/>
|
||||
<ControllerCoreRefEnablePullIn value="0"/>
|
||||
<ControllerCoreRefMaxPostponed value="8"/>
|
||||
<ControllerCoreRefMaxPulledIn value="8"/>
|
||||
<ControllerCoreRefForceMaxPostponeBurst value="0"/>
|
||||
</mcconfig>
|
||||
@@ -1,43 +0,0 @@
|
||||
<mcconfig>
|
||||
<OpenPagePolicy value="1" />
|
||||
<MaxNrOfTransactions value="32" />
|
||||
<Scheduler value="Grp" />
|
||||
<Capsize value="5" />
|
||||
<!-- 4 Modes: NoPowerDown, Staggered, TimeoutPDN, TimeoutSREF -->
|
||||
<PowerDownMode value="NoPowerDown" />
|
||||
<PowerDownTimeout value="100" />
|
||||
<!-- Bankwise -->
|
||||
<BankwiseLogic value="0"/>
|
||||
<!-- Refresh yes, no -->
|
||||
<ControllerCoreRefDisable value="0"/>
|
||||
<!-- Refresh Mode. 1: 1X, 2: 2X, 4: 4X (e.g., DDR4) -->
|
||||
<ControllerCoreRefMode value="1"/>
|
||||
<!-- Number of AR commands in a tREFI in 1X mode -->
|
||||
<ControllerCoreRefNumARCmdsIntREFI value="8192"/>
|
||||
<!-- RGR -->
|
||||
<ControllerCoreRGR value="0"/>
|
||||
<ControllerCoreRGRRowInc value="1"/>
|
||||
<!-- Banks to be refreshed in RGR mode. 1: yes, 0: no (max. 16 banks) -->
|
||||
<ControllerCoreRGRB0 value="1"/>
|
||||
<ControllerCoreRGRB1 value="1"/>
|
||||
<ControllerCoreRGRB2 value="1"/>
|
||||
<ControllerCoreRGRB3 value="1"/>
|
||||
<ControllerCoreRGRB4 value="1"/>
|
||||
<ControllerCoreRGRB5 value="1"/>
|
||||
<ControllerCoreRGRB6 value="1"/>
|
||||
<ControllerCoreRGRB7 value="1"/>
|
||||
<ControllerCoreRGRB8 value="0"/>
|
||||
<ControllerCoreRGRB9 value="0"/>
|
||||
<ControllerCoreRGRB10 value="0"/>
|
||||
<ControllerCoreRGRB11 value="0"/>
|
||||
<ControllerCoreRGRB12 value="0"/>
|
||||
<ControllerCoreRGRB13 value="0"/>
|
||||
<ControllerCoreRGRB14 value="0"/>
|
||||
<ControllerCoreRGRB15 value="0"/>
|
||||
<!-- Postpone, pull-in -->
|
||||
<ControllerCoreRefEnablePostpone value="0"/>
|
||||
<ControllerCoreRefEnablePullIn value="0"/>
|
||||
<ControllerCoreRefMaxPostponed value="8"/>
|
||||
<ControllerCoreRefMaxPulledIn value="8"/>
|
||||
<ControllerCoreRefForceMaxPostponeBurst value="0"/>
|
||||
</mcconfig>
|
||||
@@ -1,43 +0,0 @@
|
||||
<mcconfig>
|
||||
<OpenPagePolicy value="1" />
|
||||
<MaxNrOfTransactions value="8" />
|
||||
<Scheduler value="PAR_BS" />
|
||||
<Capsize value="5" />
|
||||
<!-- 4 Modes: NoPowerDown, Staggered, TimeoutPDN, TimeoutSREF -->
|
||||
<PowerDownMode value="NoPowerDown" />
|
||||
<PowerDownTimeout value="100" />
|
||||
<!-- Bankwise -->
|
||||
<BankwiseLogic value="0"/>
|
||||
<!-- Refresh yes, no -->
|
||||
<ControllerCoreRefDisable value="0"/>
|
||||
<!-- Refresh Mode. 1: 1X, 2: 2X, 4: 4X (e.g., DDR4) -->
|
||||
<ControllerCoreRefMode value="1"/>
|
||||
<!-- Number of AR commands in a tREFI in 1X mode -->
|
||||
<ControllerCoreRefNumARCmdsIntREFI value="8192"/>
|
||||
<!-- RGR -->
|
||||
<ControllerCoreRGR value="0"/>
|
||||
<ControllerCoreRGRRowInc value="1"/>
|
||||
<!-- Banks to be refreshed in RGR mode. 1: yes, 0: no (max. 16 banks) -->
|
||||
<ControllerCoreRGRB0 value="1"/>
|
||||
<ControllerCoreRGRB1 value="1"/>
|
||||
<ControllerCoreRGRB2 value="1"/>
|
||||
<ControllerCoreRGRB3 value="1"/>
|
||||
<ControllerCoreRGRB4 value="1"/>
|
||||
<ControllerCoreRGRB5 value="1"/>
|
||||
<ControllerCoreRGRB6 value="1"/>
|
||||
<ControllerCoreRGRB7 value="1"/>
|
||||
<ControllerCoreRGRB8 value="0"/>
|
||||
<ControllerCoreRGRB9 value="0"/>
|
||||
<ControllerCoreRGRB10 value="0"/>
|
||||
<ControllerCoreRGRB11 value="0"/>
|
||||
<ControllerCoreRGRB12 value="0"/>
|
||||
<ControllerCoreRGRB13 value="0"/>
|
||||
<ControllerCoreRGRB14 value="0"/>
|
||||
<ControllerCoreRGRB15 value="0"/>
|
||||
<!-- Postpone, pull-in -->
|
||||
<ControllerCoreRefEnablePostpone value="0"/>
|
||||
<ControllerCoreRefEnablePullIn value="0"/>
|
||||
<ControllerCoreRefMaxPostponed value="8"/>
|
||||
<ControllerCoreRefMaxPulledIn value="8"/>
|
||||
<ControllerCoreRefForceMaxPostponeBurst value="0"/>
|
||||
</mcconfig>
|
||||
@@ -1,42 +0,0 @@
|
||||
<mcconfig>
|
||||
<OpenPagePolicy value="1" />
|
||||
<MaxNrOfTransactions value="16" />
|
||||
<Scheduler value="FrFcfs" />
|
||||
<Capsize value="5" />
|
||||
<PowerDownMode value="NoPowerDown" />
|
||||
<PowerDownTimeout value="100" />
|
||||
<!-- Bankwise -->
|
||||
<BankwiseLogic value="0"/>
|
||||
<!-- Refresh yes, no -->
|
||||
<ControllerCoreRefDisable value="0"/>
|
||||
<!-- Refresh Mode. 1: 1X, 2: 2X, 4: 4X (e.g., DDR4) -->
|
||||
<ControllerCoreRefMode value="1"/>
|
||||
<!-- Number of AR commands in a tREFI in 1X mode -->
|
||||
<ControllerCoreRefNumARCmdsIntREFI value="8192"/>
|
||||
<!-- RGR -->
|
||||
<ControllerCoreRGR value="1"/>
|
||||
<ControllerCoreRGRRowInc value="1"/>
|
||||
<!-- Banks to be refreshed in RGR mode. 1: yes, 0: no (max. 16 banks) -->
|
||||
<ControllerCoreRGRB0 value="1"/>
|
||||
<ControllerCoreRGRB1 value="1"/>
|
||||
<ControllerCoreRGRB2 value="1"/>
|
||||
<ControllerCoreRGRB3 value="1"/>
|
||||
<ControllerCoreRGRB4 value="1"/>
|
||||
<ControllerCoreRGRB5 value="1"/>
|
||||
<ControllerCoreRGRB6 value="1"/>
|
||||
<ControllerCoreRGRB7 value="1"/>
|
||||
<ControllerCoreRGRB8 value="0"/>
|
||||
<ControllerCoreRGRB9 value="0"/>
|
||||
<ControllerCoreRGRB10 value="0"/>
|
||||
<ControllerCoreRGRB11 value="0"/>
|
||||
<ControllerCoreRGRB12 value="0"/>
|
||||
<ControllerCoreRGRB13 value="0"/>
|
||||
<ControllerCoreRGRB14 value="0"/>
|
||||
<ControllerCoreRGRB15 value="0"/>
|
||||
<!-- Postpone, pull-in -->
|
||||
<ControllerCoreRefEnablePostpone value="0"/>
|
||||
<ControllerCoreRefEnablePullIn value="0"/>
|
||||
<ControllerCoreRefMaxPostponed value="8"/>
|
||||
<ControllerCoreRefMaxPulledIn value="8"/>
|
||||
<ControllerCoreRefForceMaxPostponeBurst value="0"/>
|
||||
</mcconfig>
|
||||
@@ -1,43 +0,0 @@
|
||||
<mcconfig>
|
||||
<OpenPagePolicy value="1" />
|
||||
<MaxNrOfTransactions value="30" />
|
||||
<Scheduler value="SMS" />
|
||||
<SJFProbability value="50" />
|
||||
<RequestBufferSize value = "10" />
|
||||
<PowerDownMode value="NoPowerDown" /> <!-- 4 Modes: NoPowerDown, Staggered, TimeoutPDN, TimeoutSREF -->
|
||||
<PowerDownTimeout value="100" />
|
||||
<!-- Bankwise -->
|
||||
<BankwiseLogic value="0"/>
|
||||
<!-- Refresh yes, no -->
|
||||
<ControllerCoreRefDisable value="0"/>
|
||||
<!-- Refresh Mode. 1: 1X, 2: 2X, 4: 4X (e.g., DDR4) -->
|
||||
<ControllerCoreRefMode value="1"/>
|
||||
<!-- Number of AR commands in a tREFI in 1X mode -->
|
||||
<ControllerCoreRefNumARCmdsIntREFI value="8192"/>
|
||||
<!-- RGR -->
|
||||
<ControllerCoreRGR value="0"/>
|
||||
<ControllerCoreRGRRowInc value="1"/>
|
||||
<!-- Banks to be refreshed in RGR mode. 1: yes, 0: no (max. 16 banks) -->
|
||||
<ControllerCoreRGRB0 value="1"/>
|
||||
<ControllerCoreRGRB1 value="1"/>
|
||||
<ControllerCoreRGRB2 value="1"/>
|
||||
<ControllerCoreRGRB3 value="1"/>
|
||||
<ControllerCoreRGRB4 value="1"/>
|
||||
<ControllerCoreRGRB5 value="1"/>
|
||||
<ControllerCoreRGRB6 value="1"/>
|
||||
<ControllerCoreRGRB7 value="1"/>
|
||||
<ControllerCoreRGRB8 value="0"/>
|
||||
<ControllerCoreRGRB9 value="0"/>
|
||||
<ControllerCoreRGRB10 value="0"/>
|
||||
<ControllerCoreRGRB11 value="0"/>
|
||||
<ControllerCoreRGRB12 value="0"/>
|
||||
<ControllerCoreRGRB13 value="0"/>
|
||||
<ControllerCoreRGRB14 value="0"/>
|
||||
<ControllerCoreRGRB15 value="0"/>
|
||||
<!-- Postpone, pull-in -->
|
||||
<ControllerCoreRefEnablePostpone value="0"/>
|
||||
<ControllerCoreRefEnablePullIn value="0"/>
|
||||
<ControllerCoreRefMaxPostponed value="8"/>
|
||||
<ControllerCoreRefMaxPulledIn value="8"/>
|
||||
<ControllerCoreRefForceMaxPostponeBurst value="0"/>
|
||||
</mcconfig>
|
||||
@@ -8,9 +8,9 @@
|
||||
<!-- Memory Device Specification: Which Device is on the DDR3 DIMM -->
|
||||
<memspec src="MICRON_1Gb_DDR3-1600_8bit_G.xml"></memspec>
|
||||
<!-- Addressmapping Configuration of the Memory Controller -->
|
||||
<addressmapping src="am_ddr3_8x1Gbx8_dimm_p1KB_brc.xml"></addressmapping>
|
||||
<addressmapping src="am_ddr3_8x1Gbx8_dimm_p1KB_rbc.xml"></addressmapping>
|
||||
<!-- Memory Controller Configuration: -->
|
||||
<mcconfig src="fifoStrict.xml"/>
|
||||
<mcconfig src="fifo.xml"/>
|
||||
<!--
|
||||
The following trace setup is only used in standalone mode.
|
||||
In library mode e.g. in Platform Architect the trace setup is ignored.
|
||||
@@ -20,6 +20,6 @@
|
||||
This device mimics an image processing application
|
||||
running on an FPGA with 200 Mhz.
|
||||
-->
|
||||
<device clkMhz="200">ddr3_example.stl</device>
|
||||
<device clkMhz="800">ddr3_example.stl</device>
|
||||
</tracesetup>
|
||||
</simulation>
|
||||
|
||||
@@ -37,14 +37,15 @@
|
||||
#include "utils.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <set>
|
||||
|
||||
using std::ifstream;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
#include <set>
|
||||
|
||||
using std::set;
|
||||
using std::pair;
|
||||
using std::map;
|
||||
using std::deque;
|
||||
|
||||
tinyxml2::XMLElement *CongenAddressDecoder::GetXMLNode(tinyxml2::XMLElement
|
||||
*pRoot, std::string strName)
|
||||
|
||||
@@ -43,10 +43,6 @@
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
using std::vector;
|
||||
using std::pair;
|
||||
using std::map;
|
||||
|
||||
class CongenAddressDecoder : private AddressDecoder
|
||||
{
|
||||
// Friendship needed so that the AddressDecoder can access the
|
||||
@@ -80,13 +76,13 @@ private:
|
||||
m_nByteBits; // Number of Byte bits used by this mapping
|
||||
|
||||
|
||||
vector<XOR>
|
||||
std::vector<XOR>
|
||||
m_vXor; // This container stores for each used xor gate a pair which consists of "First/Number of an address bit which corresponds to a bank" and "Second/Number of an address bit which corresponds to a row"
|
||||
vector<pair<unsigned, unsigned>>
|
||||
std::vector<std::pair<unsigned, unsigned>>
|
||||
m_vBankBits; // This container stores for each bank bit a pair which consists of "First/Number of the bank bit" and "Second/Number of the address bit"
|
||||
vector<pair<unsigned, unsigned>>
|
||||
std::vector<std::pair<unsigned, unsigned>>
|
||||
m_vRowBits; // This container stores for each row bit a pair which consists of "First/Number of the row bit" and "Second/Number of the address bit"
|
||||
vector<pair<unsigned, unsigned>>
|
||||
std::vector<std::pair<unsigned, unsigned>>
|
||||
m_vColumnBits; // This container stores for each column bit a pair which consists of "First/Number of the column bit" and "Second/Number of the address bit"
|
||||
|
||||
//Methods
|
||||
|
||||
@@ -36,17 +36,16 @@
|
||||
|
||||
#include "DebugManager.h"
|
||||
|
||||
#ifdef DEBUGGING
|
||||
#ifndef NDEBUG
|
||||
|
||||
#include "../configuration/Configuration.h"
|
||||
using namespace std;
|
||||
|
||||
void DebugManager::printDebugMessage(string sender, string message)
|
||||
void DebugManager::printDebugMessage(std::string sender, std::string message)
|
||||
{
|
||||
if (Configuration::getInstance().Debug) {
|
||||
if (Configuration::getInstance().debug) {
|
||||
if (writeToConsole)
|
||||
cout << " at " << sc_time_stamp() << "\t in " << sender << "\t: " << message <<
|
||||
endl;
|
||||
std::cout << " at " << sc_time_stamp() << "\t in " << sender << "\t: " << message <<
|
||||
std::endl;
|
||||
|
||||
if (writeToFile && debugFile)
|
||||
debugFile << " at " << sc_time_stamp() << " in " << sender << "\t: " << message
|
||||
@@ -54,13 +53,13 @@ void DebugManager::printDebugMessage(string sender, string message)
|
||||
}
|
||||
}
|
||||
|
||||
void DebugManager::printMessage(string sender, string message)
|
||||
void DebugManager::printMessage(std::string sender, std::string message)
|
||||
{
|
||||
cout << " at " << sc_time_stamp() << "\t in " << sender << "\t: " << message <<
|
||||
endl;
|
||||
std::cout << " at " << sc_time_stamp() << "\t in " << sender << "\t: " << message <<
|
||||
std::endl;
|
||||
}
|
||||
|
||||
void DebugManager::openDebugFile(string filename)
|
||||
void DebugManager::openDebugFile(std::string filename)
|
||||
{
|
||||
if (debugFile)
|
||||
debugFile.close();
|
||||
|
||||
@@ -37,9 +37,7 @@
|
||||
#ifndef DEBUGMANAGER_H
|
||||
#define DEBUGMANAGER_H
|
||||
|
||||
//#define DEBUGGING
|
||||
|
||||
#ifndef DEBUGGING
|
||||
#ifdef NDEBUG
|
||||
#define PRINTDEBUGMESSAGE(sender, message) {}
|
||||
#else
|
||||
#define PRINTDEBUGMESSAGE(sender, message) DebugManager::getInstance().printDebugMessage(sender, message)
|
||||
|
||||
@@ -40,10 +40,10 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "TlmRecorder.h"
|
||||
#include "protocol.h"
|
||||
#include "dramExtensions.h"
|
||||
#include "XmlAddressDecoder.h"
|
||||
#include "../configuration/Configuration.h"
|
||||
#include "../controller/Command.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
@@ -100,7 +100,7 @@ void TlmRecorder::recordPhase(tlm_generic_payload &trans,
|
||||
std::string phaseBeginPrefix = "BEGIN_";
|
||||
std::string phaseEndPrefix = "END_";
|
||||
|
||||
if (phaseName.find(phaseBeginPrefix) != string::npos) {
|
||||
if (phaseName.find(phaseBeginPrefix) != std::string::npos) {
|
||||
phaseName.erase(0, phaseBeginPrefix.length());
|
||||
assert(currentTransactionsInSystem.count(&trans) != 0);
|
||||
currentTransactionsInSystem[&trans].insertPhase(phaseName, time);
|
||||
@@ -153,12 +153,12 @@ void TlmRecorder::introduceTransactionSystem(tlm_generic_payload &trans)
|
||||
currentTransactionsInSystem[&trans].timeOfGeneration =
|
||||
GenerationExtension::getExtension(&trans).TimeOfGeneration();
|
||||
|
||||
PRINTDEBUGMESSAGE(name, "New transaction #" + to_string(id) + " generation time " +
|
||||
PRINTDEBUGMESSAGE(name, "New transaction #" + std::to_string(id) + " generation time " +
|
||||
currentTransactionsInSystem[&trans].timeOfGeneration.to_string());
|
||||
|
||||
if (id % transactionCommitRate == 0) {
|
||||
PRINTDEBUGMESSAGE(name, "Committing transactions " +
|
||||
to_string(id - transactionCommitRate + 1) + " - " + to_string(id));
|
||||
std::to_string(id - transactionCommitRate + 1) + " - " + std::to_string(id));
|
||||
commitRecordedDataToDB();
|
||||
}
|
||||
}
|
||||
@@ -168,7 +168,7 @@ void TlmRecorder::removeTransactionFromSystem(tlm_generic_payload &trans)
|
||||
assert(currentTransactionsInSystem.count(&trans) != 0);
|
||||
|
||||
PRINTDEBUGMESSAGE(name, "Removing transaction #" +
|
||||
to_string(currentTransactionsInSystem[&trans].id));
|
||||
std::to_string(currentTransactionsInSystem[&trans].id));
|
||||
|
||||
Transaction &recordingData = currentTransactionsInSystem[&trans];
|
||||
recordedData.push_back(recordingData);
|
||||
@@ -259,14 +259,6 @@ void TlmRecorder::setUpTransactionTerminatingPhases()
|
||||
(END_PDNP));
|
||||
transactionTerminatingPhases.push_back(static_cast<const tlm_phase>
|
||||
(END_SREF));
|
||||
|
||||
// Phases for Power Down Bankwise
|
||||
transactionTerminatingPhases.push_back(static_cast<const tlm_phase>
|
||||
(END_PDNAB));
|
||||
transactionTerminatingPhases.push_back(static_cast<const tlm_phase>
|
||||
(END_PDNPB));
|
||||
transactionTerminatingPhases.push_back(static_cast<const tlm_phase>
|
||||
(END_SREFB));
|
||||
}
|
||||
|
||||
void TlmRecorder::prepareSqlStatements()
|
||||
@@ -325,11 +317,11 @@ void TlmRecorder::insertGeneralInfo()
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 2,
|
||||
simulationTimeCoveredByRecording.value());
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 3,
|
||||
Configuration::getInstance().memSpec->NumberOfRanks);
|
||||
Configuration::getInstance().memSpec->numberOfRanks);
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 4,
|
||||
Configuration::getInstance().memSpec->NumberOfBanks);
|
||||
Configuration::getInstance().memSpec->numberOfBanks);
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 5,
|
||||
Configuration::getInstance().memSpec->clk.value());
|
||||
Configuration::getInstance().memSpec->tCK.value());
|
||||
sqlite3_bind_text(insertGeneralInfoStatement, 6, "PS", 2, NULL);
|
||||
sqlite3_bind_text(insertGeneralInfoStatement, 7, mcconfig.c_str(),
|
||||
mcconfig.length(), NULL);
|
||||
@@ -337,18 +329,18 @@ void TlmRecorder::insertGeneralInfo()
|
||||
memspec.length(), NULL);
|
||||
sqlite3_bind_text(insertGeneralInfoStatement, 9, traces.c_str(),
|
||||
traces.length(), NULL);
|
||||
if (!Configuration::getInstance().EnableWindowing)
|
||||
if (!Configuration::getInstance().enableWindowing)
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 10, 0);
|
||||
else
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 10,
|
||||
(Configuration::getInstance().memSpec->clk *
|
||||
Configuration::getInstance().WindowSize).value());
|
||||
if (Configuration::getInstance().ControllerCoreRefEnablePostpone
|
||||
|| Configuration::getInstance().ControllerCoreRefEnablePullIn) {
|
||||
(Configuration::getInstance().memSpec->tCK *
|
||||
Configuration::getInstance().windowSize).value());
|
||||
if ((Configuration::getInstance().refreshMaxPostponed > 0)
|
||||
|| (Configuration::getInstance().refreshMaxPulledin > 0)) {
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 11, 1);
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 12,
|
||||
std::max(Configuration::getInstance().ControllerCoreRefMaxPulledIn,
|
||||
Configuration::getInstance().ControllerCoreRefMaxPostponed));
|
||||
std::max(Configuration::getInstance().refreshMaxPostponed,
|
||||
Configuration::getInstance().refreshMaxPulledin));
|
||||
} else {
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 11, 0);
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 12, 0);
|
||||
@@ -361,21 +353,21 @@ void TlmRecorder::insertCommandLengths()
|
||||
{
|
||||
MemSpec *memSpec = Configuration::getInstance().memSpec;
|
||||
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 1, memSpec->commandLength[Command::ACT]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 2, memSpec->commandLength[Command::PRE]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 3, memSpec->commandLength[Command::PREA]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 4, memSpec->commandLength[Command::RD]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 5, memSpec->commandLength[Command::RDA]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 6, memSpec->commandLength[Command::WR]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 7, memSpec->commandLength[Command::WRA]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 8, memSpec->commandLength[Command::REFA]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 9, memSpec->commandLength[Command::REFB]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 10, memSpec->commandLength[Command::PDEA]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 11, memSpec->commandLength[Command::PDXA]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 12, memSpec->commandLength[Command::PDEP]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 13, memSpec->commandLength[Command::PDXP]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 14, memSpec->commandLength[Command::SREFEN]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 15, memSpec->commandLength[Command::SREFEX]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 1, memSpec->commandLengthInCycles[Command::ACT]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 2, memSpec->commandLengthInCycles[Command::PRE]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 3, memSpec->commandLengthInCycles[Command::PREA]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 4, memSpec->commandLengthInCycles[Command::RD]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 5, memSpec->commandLengthInCycles[Command::RDA]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 6, memSpec->commandLengthInCycles[Command::WR]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 7, memSpec->commandLengthInCycles[Command::WRA]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 8, memSpec->commandLengthInCycles[Command::REFA]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 9, memSpec->commandLengthInCycles[Command::REFB]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 10, memSpec->commandLengthInCycles[Command::PDEA]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 11, memSpec->commandLengthInCycles[Command::PDXA]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 12, memSpec->commandLengthInCycles[Command::PDEP]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 13, memSpec->commandLengthInCycles[Command::PDXP]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 14, memSpec->commandLengthInCycles[Command::SREFEN]);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 15, memSpec->commandLengthInCycles[Command::SREFEX]);
|
||||
|
||||
executeSqlStatement(insertCommandLengthsStatement);
|
||||
}
|
||||
@@ -439,7 +431,7 @@ void TlmRecorder::executeSqlStatement(sqlite3_stmt *statement)
|
||||
int errorCode = sqlite3_step(statement);
|
||||
if (errorCode != SQLITE_DONE) {
|
||||
reportFatal("Error in TraceRecorder",
|
||||
string("Could not execute statement. Error code: ") + to_string(errorCode));
|
||||
std::string("Could not execute statement. Error code: ") + std::to_string(errorCode));
|
||||
}
|
||||
sqlite3_reset(statement);
|
||||
}
|
||||
|
||||
@@ -53,8 +53,6 @@
|
||||
#include "DebugManager.h"
|
||||
#include "utils.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
class TlmRecorder
|
||||
{
|
||||
public:
|
||||
@@ -77,12 +75,12 @@ public:
|
||||
this->traces = traces;
|
||||
}
|
||||
|
||||
void recordPhase(tlm_generic_payload &trans, tlm_phase phase,
|
||||
void recordPhase(tlm::tlm_generic_payload &trans, tlm::tlm_phase phase,
|
||||
sc_time time);
|
||||
void recordPower(double timeInSeconds, double averagePower);
|
||||
void recordDebugMessage(std::string message, sc_time time);
|
||||
void updateDataStrobe(const sc_time &begin, const sc_time &end,
|
||||
tlm_generic_payload &trans);
|
||||
tlm::tlm_generic_payload &trans);
|
||||
void closeConnection();
|
||||
|
||||
private:
|
||||
@@ -121,8 +119,8 @@ private:
|
||||
void createTables(std::string pathToURI);
|
||||
void setUpTransactionTerminatingPhases();
|
||||
|
||||
void introduceTransactionSystem(tlm_generic_payload &trans);
|
||||
void removeTransactionFromSystem(tlm_generic_payload &trans);
|
||||
void introduceTransactionSystem(tlm::tlm_generic_payload &trans);
|
||||
void removeTransactionFromSystem(tlm::tlm_generic_payload &trans);
|
||||
|
||||
void commitRecordedDataToDB();
|
||||
void insertGeneralInfo();
|
||||
@@ -140,7 +138,7 @@ private:
|
||||
unsigned int totalNumTransactions;
|
||||
sc_time simulationTimeCoveredByRecording;
|
||||
|
||||
std::vector<tlm_phase> transactionTerminatingPhases;
|
||||
std::vector<tlm::tlm_phase> transactionTerminatingPhases;
|
||||
sqlite3 *db = NULL;
|
||||
sqlite3_stmt *insertTransactionStatement, *insertRangeStatement,
|
||||
*updateRangeStatement, *insertPhaseStatement, *updatePhaseStatement,
|
||||
|
||||
@@ -53,7 +53,7 @@ void XmlAddressDecoder::setConfiguration(std::string addressConfigURI)
|
||||
tinyxml2::XMLDocument doc;
|
||||
loadXML(addressConfigURI, doc);
|
||||
tinyxml2::XMLElement *addressMap = doc.RootElement();
|
||||
string xmlNodeName(addressMap->Name());
|
||||
std::string xmlNodeName(addressMap->Name());
|
||||
|
||||
if (xmlNodeName != "addressmapping")
|
||||
reportFatal("AddressDecorder", "addressmap node expected");
|
||||
@@ -124,10 +124,10 @@ void XmlAddressDecoder::setConfiguration(std::string addressConfigURI)
|
||||
Configuration &config = Configuration::getInstance();
|
||||
MemSpec *memSpec = config.memSpec;
|
||||
|
||||
if (config.NumberOfMemChannels != amount.channel || memSpec->NumberOfRanks != amount.rank
|
||||
|| memSpec->NumberOfBankGroups != amount.bankgroup || memSpec->NumberOfBanks != amount.bank
|
||||
|| memSpec->NumberOfRows != amount.row || memSpec->NumberOfColumns != amount.column
|
||||
|| config.NumberOfDevicesOnDIMM * memSpec->bitWidth != amount.bytes * 8)
|
||||
if (config.numberOfMemChannels != amount.channel || memSpec->numberOfRanks != amount.rank
|
||||
|| memSpec->numberOfBankGroups != amount.bankgroup || memSpec->numberOfBanks != amount.bank
|
||||
|| memSpec->numberOfRows != amount.row || memSpec->numberOfColumns != amount.column
|
||||
|| config.numberOfDevicesOnDIMM * memSpec->bitWidth != amount.bytes * 8)
|
||||
SC_REPORT_FATAL("XmlAddressDecoder", "Memspec and addressmapping do not match");
|
||||
}
|
||||
|
||||
|
||||
@@ -332,7 +332,7 @@ bool operator !=(const Row &lhs, const Row &rhs)
|
||||
|
||||
const Row Row::operator ++()
|
||||
{
|
||||
id = (id + 1) % Configuration::getInstance().memSpec->NumberOfRows;
|
||||
id = (id + 1) % Configuration::getInstance().memSpec->numberOfRows;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,8 +41,6 @@
|
||||
#include <iostream>
|
||||
#include <systemc.h>
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
class Thread
|
||||
{
|
||||
public:
|
||||
@@ -161,7 +159,7 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class DramExtension : public tlm_extension<DramExtension>
|
||||
class DramExtension : public tlm::tlm_extension<DramExtension>
|
||||
{
|
||||
public:
|
||||
DramExtension();
|
||||
@@ -172,29 +170,29 @@ public:
|
||||
const BankGroup &bankgroup, const Bank &bank, const Row &row,
|
||||
const Column &column, unsigned int burstlength, uint64_t payloadID);
|
||||
|
||||
virtual tlm_extension_base *clone() const;
|
||||
virtual void copy_from(const tlm_extension_base &ext);
|
||||
virtual tlm::tlm_extension_base *clone() const;
|
||||
virtual void copy_from(const tlm::tlm_extension_base &ext);
|
||||
|
||||
static DramExtension &getExtension(const tlm_generic_payload *payload);
|
||||
static DramExtension &getExtension(const tlm_generic_payload &payload);
|
||||
static DramExtension &getExtension(const tlm::tlm_generic_payload *payload);
|
||||
static DramExtension &getExtension(const tlm::tlm_generic_payload &payload);
|
||||
|
||||
// Used for convience, caller could also use getExtension(..) to access these field
|
||||
static Thread getThread(const tlm_generic_payload *payload);
|
||||
static Thread getThread(const tlm_generic_payload &payload);
|
||||
static Channel getChannel(const tlm_generic_payload *payload);
|
||||
static Channel getChannel(const tlm_generic_payload &payload);
|
||||
static Rank getRank(const tlm_generic_payload *payload);
|
||||
static Rank getRank(const tlm_generic_payload &payload);
|
||||
static BankGroup getBankGroup(const tlm_generic_payload *payload);
|
||||
static BankGroup getBankGroup(const tlm_generic_payload &payload);
|
||||
static Bank getBank(const tlm_generic_payload *payload);
|
||||
static Bank getBank(const tlm_generic_payload &payload);
|
||||
static Row getRow(const tlm_generic_payload *payload);
|
||||
static Row getRow(const tlm_generic_payload &payload);
|
||||
static Column getColumn(const tlm_generic_payload *payload);
|
||||
static Column getColumn(const tlm_generic_payload &payload);
|
||||
static uint64_t getPayloadID(const tlm_generic_payload *payload);
|
||||
static uint64_t getPayloadID(const tlm_generic_payload &payload);
|
||||
static Thread getThread(const tlm::tlm_generic_payload *payload);
|
||||
static Thread getThread(const tlm::tlm_generic_payload &payload);
|
||||
static Channel getChannel(const tlm::tlm_generic_payload *payload);
|
||||
static Channel getChannel(const tlm::tlm_generic_payload &payload);
|
||||
static Rank getRank(const tlm::tlm_generic_payload *payload);
|
||||
static Rank getRank(const tlm::tlm_generic_payload &payload);
|
||||
static BankGroup getBankGroup(const tlm::tlm_generic_payload *payload);
|
||||
static BankGroup getBankGroup(const tlm::tlm_generic_payload &payload);
|
||||
static Bank getBank(const tlm::tlm_generic_payload *payload);
|
||||
static Bank getBank(const tlm::tlm_generic_payload &payload);
|
||||
static Row getRow(const tlm::tlm_generic_payload *payload);
|
||||
static Row getRow(const tlm::tlm_generic_payload &payload);
|
||||
static Column getColumn(const tlm::tlm_generic_payload *payload);
|
||||
static Column getColumn(const tlm::tlm_generic_payload &payload);
|
||||
static uint64_t getPayloadID(const tlm::tlm_generic_payload *payload);
|
||||
static uint64_t getPayloadID(const tlm::tlm_generic_payload &payload);
|
||||
|
||||
Thread getThread() const;
|
||||
Channel getChannel() const;
|
||||
@@ -224,21 +222,21 @@ private:
|
||||
// Used to indicate the time when a payload is created (in a traceplayer or in a core)
|
||||
// Note that this time can be different from the time the payload enters the DRAM system
|
||||
//(at that time the phase BEGIN_REQ is recorded), so timeOfGeneration =< time(BEGIN_REQ)
|
||||
class GenerationExtension : public tlm_extension<GenerationExtension>
|
||||
class GenerationExtension : public tlm::tlm_extension<GenerationExtension>
|
||||
{
|
||||
public:
|
||||
GenerationExtension(sc_time timeOfGeneration)
|
||||
: timeOfGeneration(timeOfGeneration) {}
|
||||
virtual tlm_extension_base *clone() const;
|
||||
virtual void copy_from(const tlm_extension_base &ext);
|
||||
virtual tlm::tlm_extension_base *clone() const;
|
||||
virtual void copy_from(const tlm::tlm_extension_base &ext);
|
||||
static GenerationExtension
|
||||
&getExtension(const tlm_generic_payload *payload);
|
||||
&getExtension(const tlm::tlm_generic_payload *payload);
|
||||
sc_time TimeOfGeneration() const
|
||||
{
|
||||
return timeOfGeneration;
|
||||
}
|
||||
static sc_time getTimeOfGeneration(const tlm_generic_payload *payload);
|
||||
static sc_time getTimeOfGeneration(const tlm_generic_payload &payload);
|
||||
static sc_time getTimeOfGeneration(const tlm::tlm_generic_payload *payload);
|
||||
static sc_time getTimeOfGeneration(const tlm::tlm_generic_payload &payload);
|
||||
|
||||
private:
|
||||
sc_time timeOfGeneration;
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
#include "dramExtensions.h"
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
using namespace tinyxml2;
|
||||
using namespace tlm;
|
||||
|
||||
@@ -78,7 +77,7 @@ std::string phaseNameToString(tlm_phase phase)
|
||||
return str;
|
||||
}
|
||||
|
||||
unsigned int queryUIntParameter(XMLElement *node, string name)
|
||||
unsigned int queryUIntParameter(XMLElement *node, std::string name)
|
||||
{
|
||||
int result = 0;
|
||||
XMLElement *element;
|
||||
@@ -109,7 +108,7 @@ bool parameterExists(tinyxml2::XMLElement *node, std::string name)
|
||||
return false;
|
||||
}
|
||||
|
||||
double queryDoubleParameter(XMLElement *node, string name)
|
||||
double queryDoubleParameter(XMLElement *node, std::string name)
|
||||
{
|
||||
double result = 0;
|
||||
XMLElement *element;
|
||||
@@ -128,7 +127,7 @@ double queryDoubleParameter(XMLElement *node, string name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool queryBoolParameter(XMLElement *node, string name)
|
||||
bool queryBoolParameter(XMLElement *node, std::string name)
|
||||
{
|
||||
bool result = false;
|
||||
XMLElement *element;// = node->FirstChildElement("parameter");
|
||||
@@ -147,7 +146,7 @@ bool queryBoolParameter(XMLElement *node, string name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
string queryStringParameter(XMLElement *node, string name)
|
||||
std::string queryStringParameter(XMLElement *node, std::string name)
|
||||
{
|
||||
XMLElement *element;
|
||||
for (element = node->FirstChildElement("parameter"); element != NULL;
|
||||
@@ -161,7 +160,7 @@ string queryStringParameter(XMLElement *node, string name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
string errorToString(XMLError error)
|
||||
std::string errorToString(XMLError error)
|
||||
{
|
||||
switch (error) {
|
||||
case XML_NO_ERROR:
|
||||
@@ -209,7 +208,7 @@ string errorToString(XMLError error)
|
||||
}
|
||||
}
|
||||
|
||||
void loadXML(string uri, XMLDocument &doc)
|
||||
void loadXML(std::string uri, XMLDocument &doc)
|
||||
{
|
||||
XMLError error = doc.LoadFile(uri.c_str());
|
||||
|
||||
@@ -219,12 +218,12 @@ void loadXML(string uri, XMLDocument &doc)
|
||||
}
|
||||
}
|
||||
|
||||
string loadTextFileContents(string filename)
|
||||
std::string loadTextFileContents(std::string filename)
|
||||
{
|
||||
|
||||
ifstream in(filename.c_str(), ios::in | ios::binary);
|
||||
if (in) {
|
||||
string contents;
|
||||
std::string contents;
|
||||
in.seekg(0, ios::end);
|
||||
contents.resize(in.tellg());
|
||||
in.seekg(0, ios::beg);
|
||||
|
||||
@@ -42,76 +42,10 @@
|
||||
#include "ConfigurationLoader.h"
|
||||
#include "../common/XmlAddressDecoder.h"
|
||||
|
||||
using namespace std;
|
||||
std::string Configuration::memspecUri = "";
|
||||
std::string Configuration::mcconfigUri = "";
|
||||
|
||||
string Configuration::memspecUri = "";
|
||||
string Configuration::mcconfigUri = "";
|
||||
|
||||
bool string2bool(string s)
|
||||
{
|
||||
if (s.compare("0") == 0) {
|
||||
return false;
|
||||
} else if (s.compare("1") == 0) {
|
||||
return true;
|
||||
} else {
|
||||
SC_REPORT_FATAL("Configuration", ("Could not convert to bool: " + s).c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int string2int(string s)
|
||||
{
|
||||
return std::stoi(s);
|
||||
}
|
||||
|
||||
unsigned long long string2ull(string s)
|
||||
{
|
||||
return std::stoull(s);
|
||||
}
|
||||
|
||||
StorageMode string2StoreMode(string s)
|
||||
{
|
||||
if (s == "NoStorage")
|
||||
return StorageMode::NoStorage;
|
||||
else if (s == "Store")
|
||||
return StorageMode::Store;
|
||||
else if (s == "ErrorModel")
|
||||
return StorageMode::ErrorModel;
|
||||
else {
|
||||
SC_REPORT_FATAL("Configuration", ("Unknown StorageMode: " + s).c_str());
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
EPowerDownMode string2PDNMode(string s)
|
||||
{
|
||||
if (s == "NoPowerDown")
|
||||
return EPowerDownMode::NoPowerDown;
|
||||
else if (s == "Staggered")
|
||||
return EPowerDownMode::Staggered;
|
||||
else if (s == "TimeoutPDN")
|
||||
return EPowerDownMode::TimeoutPDN;
|
||||
else if (s == "TimeoutSREF")
|
||||
return EPowerDownMode::TimeoutSREF;
|
||||
else {
|
||||
SC_REPORT_FATAL("Configuration", ("Unknown PowerDownMode: " + s).c_str());
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
ECCControllerMode string2ECCControllerMode(string s)
|
||||
{
|
||||
if (s == "Disabled")
|
||||
return ECCControllerMode::Disabled;
|
||||
else if (s == "Hamming")
|
||||
return ECCControllerMode::Hamming;
|
||||
else {
|
||||
SC_REPORT_FATAL("Configuration", ("Unknown ECCControllerMode: " + s).c_str());
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
enum sc_time_unit string2TimeUnit(string s)
|
||||
enum sc_time_unit string2TimeUnit(std::string s)
|
||||
{
|
||||
if (s == "s")
|
||||
return SC_SEC;
|
||||
@@ -134,150 +68,83 @@ enum sc_time_unit string2TimeUnit(string s)
|
||||
|
||||
void Configuration::setParameter(std::string name, std::string value)
|
||||
{
|
||||
if (name == "BankwiseLogic")
|
||||
BankwiseLogic = string2bool(value);
|
||||
else if (name == "OpenPagePolicy")
|
||||
OpenPagePolicy = string2bool(value);
|
||||
else if (name == "AdaptivePagePolicy")
|
||||
AdaptivePagePolicy = string2bool(value);
|
||||
else if (name == "MaxNrOfTransactions")
|
||||
MaxNrOfTransactions = string2int(value);
|
||||
// MCConfig
|
||||
if (name == "PagePolicy")
|
||||
pagePolicy = value;
|
||||
else if (name == "Scheduler")
|
||||
Scheduler = value;
|
||||
else if (name == "SJFProbability")
|
||||
{
|
||||
if (string2int(value) > 100 || string2int(value) < 0)
|
||||
SC_REPORT_FATAL("Configuration",
|
||||
("Invalid value for parameter " + name +
|
||||
". This parameter must be between 0 and 100.").c_str());
|
||||
else
|
||||
SJFProbability = string2int(value);
|
||||
}
|
||||
scheduler = value;
|
||||
else if (name == "RequestBufferSize")
|
||||
RequestBufferSize = string2int(value);
|
||||
else if (name == "Capsize")
|
||||
Capsize = string2int(value);
|
||||
requestBufferSize = std::stoul(value);
|
||||
else if (name == "CmdMux")
|
||||
cmdMux = value;
|
||||
else if (name == "RespQueue")
|
||||
respQueue = value;
|
||||
else if (name == "RefreshPolicy")
|
||||
refreshPolicy = value;
|
||||
else if (name == "RefreshMode")
|
||||
refreshMode = std::stoul(value);
|
||||
else if (name == "RefreshMaxPostponed")
|
||||
refreshMaxPostponed = std::stoul(value);
|
||||
else if (name == "RefreshMaxPulledin")
|
||||
refreshMaxPulledin = std::stoul(value);
|
||||
else if (name == "PowerDownPolicy")
|
||||
powerDownPolicy = value;
|
||||
else if (name == "PowerDownTimeout")
|
||||
powerDownTimeoutInClk = string2int(value);
|
||||
else if (name == "PowerDownMode")
|
||||
PowerDownMode = string2PDNMode(value);
|
||||
else if (name == "ReadWriteGrouping")
|
||||
ReadWriteGrouping = string2bool(value);
|
||||
else if (name == "ReorderBuffer")
|
||||
ReorderBuffer = string2bool(value);
|
||||
|
||||
powerDownTimeout = std::stoul(value);
|
||||
//SimConfig------------------------------------------------
|
||||
else if (name == "SimulationName")
|
||||
SimulationName = value;
|
||||
simulationName = value;
|
||||
else if (name == "DatabaseRecording")
|
||||
DatabaseRecording = string2bool(value);
|
||||
databaseRecording = std::stoul(value);
|
||||
else if (name == "PowerAnalysis")
|
||||
PowerAnalysis = string2bool(value);
|
||||
powerAnalysis = std::stoul(value);
|
||||
else if (name == "EnableWindowing")
|
||||
EnableWindowing = string2bool(value);
|
||||
enableWindowing = std::stoul(value);
|
||||
else if (name == "WindowSize")
|
||||
{
|
||||
if (string2int(value) < 1)
|
||||
windowSize = std::stoul(value);
|
||||
if (windowSize == 0)
|
||||
SC_REPORT_FATAL("Configuration",
|
||||
("Invalid value for parameter " + name +
|
||||
". This parameter must be at least one.").c_str());
|
||||
else
|
||||
WindowSize = string2int(value);
|
||||
}
|
||||
else if (name == "Debug")
|
||||
Debug = string2bool(value);
|
||||
debug = std::stoul(value);
|
||||
else if (name == "NumberOfMemChannels")
|
||||
NumberOfMemChannels = string2int(value);
|
||||
else if (name == "ControllerCoreRefDisable")
|
||||
ControllerCoreRefDisable = string2bool(value);
|
||||
else if (name == "ControllerCoreRGR")
|
||||
RowGranularRef = string2bool(value);
|
||||
else if (name == "ControllerCoreRGRRowInc")
|
||||
RowInc = string2int(value);
|
||||
else if (name == "ControllerCoreRefMode")
|
||||
{
|
||||
RefMode = string2int(value);
|
||||
if (RefMode != 1 && RefMode != 2 && RefMode != 4)
|
||||
SC_REPORT_FATAL("Configuration", (name + " invalid value.").c_str());
|
||||
}
|
||||
else if (name == "ControllerCoreRefNumARCmdsIntREFI")
|
||||
NumAR = string2int(value);
|
||||
else if (name == "ControllerCoreRGRB0")
|
||||
RGRB0 = string2bool(value);
|
||||
else if (name == "ControllerCoreRGRB1")
|
||||
RGRB1 = string2bool(value);
|
||||
else if (name == "ControllerCoreRGRB2")
|
||||
RGRB2 = string2bool(value);
|
||||
else if (name == "ControllerCoreRGRB3")
|
||||
RGRB3 = string2bool(value);
|
||||
else if (name == "ControllerCoreRGRB4")
|
||||
RGRB4 = string2bool(value);
|
||||
else if (name == "ControllerCoreRGRB5")
|
||||
RGRB5 = string2bool(value);
|
||||
else if (name == "ControllerCoreRGRB6")
|
||||
RGRB6 = string2bool(value);
|
||||
else if (name == "ControllerCoreRGRB7")
|
||||
RGRB7 = string2bool(value);
|
||||
else if (name == "ControllerCoreRGRB8")
|
||||
RGRB8 = string2bool(value);
|
||||
else if (name == "ControllerCoreRGRB9")
|
||||
RGRB9 = string2bool(value);
|
||||
else if (name == "ControllerCoreRGRB10")
|
||||
RGRB10 = string2bool(value);
|
||||
else if (name == "ControllerCoreRGRB11")
|
||||
RGRB11 = string2bool(value);
|
||||
else if (name == "ControllerCoreRGRB12")
|
||||
RGRB12 = string2bool(value);
|
||||
else if (name == "ControllerCoreRGRB13")
|
||||
RGRB13 = string2bool(value);
|
||||
else if (name == "ControllerCoreRGRB14")
|
||||
RGRB14 = string2bool(value);
|
||||
else if (name == "ControllerCoreRGRB15")
|
||||
RGRB15 = string2bool(value);
|
||||
else if (name == "ControllerCoreRefForceMaxPostponeBurst")
|
||||
ControllerCoreRefForceMaxPostponeBurst = string2bool(value);
|
||||
else if (name == "ControllerCoreRefEnablePostpone")
|
||||
ControllerCoreRefEnablePostpone = string2bool(value);
|
||||
else if (name == "ControllerCoreRefEnablePullIn")
|
||||
ControllerCoreRefEnablePullIn = string2bool(value);
|
||||
else if (name == "ControllerCoreRefMaxPostponed")
|
||||
ControllerCoreRefMaxPostponed = string2int(value);
|
||||
else if (name == "ControllerCoreRefMaxPulledIn")
|
||||
ControllerCoreRefMaxPulledIn = string2int(value);
|
||||
numberOfMemChannels = std::stoul(value);
|
||||
else if (name == "ThermalSimulation")
|
||||
ThermalSimulation = string2bool(value);
|
||||
thermalSimulation = std::stoul(value);
|
||||
else if (name == "SimulationProgressBar")
|
||||
SimulationProgressBar = string2bool(value);
|
||||
simulationProgressBar = std::stoul(value);
|
||||
else if (name == "NumberOfDevicesOnDIMM")
|
||||
{
|
||||
if (string2int(value) < 1)
|
||||
numberOfDevicesOnDIMM = std::stoul(value);
|
||||
if (numberOfDevicesOnDIMM == 0)
|
||||
SC_REPORT_FATAL("Configuration",
|
||||
("Invalid value for parameter " + name +
|
||||
". This parameter must be at least one.").c_str());
|
||||
else
|
||||
NumberOfDevicesOnDIMM = string2int(value);
|
||||
}
|
||||
else if (name == "AddressOffset")
|
||||
{
|
||||
#ifdef DRAMSYS_GEM5
|
||||
AddressOffset = string2ull(value);
|
||||
addressOffset = std::stoull(value);
|
||||
#else
|
||||
AddressOffset = 0;
|
||||
addressOffset = 0;
|
||||
#endif
|
||||
}
|
||||
else if (name == "UseMalloc")
|
||||
UseMalloc = string2bool(value);
|
||||
useMalloc = std::stoul(value);
|
||||
else if (name == "CheckTLM2Protocol")
|
||||
CheckTLM2Protocol = string2bool(value);
|
||||
checkTLM2Protocol = std::stoul(value);
|
||||
else if (name == "ECCControllerMode")
|
||||
ECCMode = string2ECCControllerMode(value);
|
||||
ECCMode = value;
|
||||
// Specification for ErrorChipSeed, ErrorCSVFile path and StoreMode
|
||||
else if (name == "ErrorChipSeed")
|
||||
ErrorChipSeed = string2int(value);
|
||||
errorChipSeed = std::stoul(value);
|
||||
else if (name == "ErrorCSVFile")
|
||||
ErrorCSVFile = value;
|
||||
errorCSVFile = value;
|
||||
else if (name == "StoreMode")
|
||||
StoreMode = string2StoreMode(value);
|
||||
storeMode = value;
|
||||
// Temperature Simulation related
|
||||
else if (name == "TemperatureScale")
|
||||
{
|
||||
@@ -287,7 +154,7 @@ void Configuration::setParameter(std::string name, std::string value)
|
||||
temperatureSim.TemperatureScale = value;
|
||||
}
|
||||
else if (name == "StaticTemperatureDefaultValue")
|
||||
temperatureSim.StaticTemperatureDefaultValue = string2int(value);
|
||||
temperatureSim.StaticTemperatureDefaultValue = std::stoi(value);
|
||||
else if (name == "ThermalSimPeriod")
|
||||
temperatureSim.ThermalSimPeriod = std::stod(value.c_str());
|
||||
else if (name == "ThermalSimUnit")
|
||||
@@ -300,15 +167,15 @@ void Configuration::setParameter(std::string name, std::string value)
|
||||
else if (name == "IceServerIp")
|
||||
temperatureSim.IceServerIp = value;
|
||||
else if (name == "IceServerPort")
|
||||
temperatureSim.IceServerPort = string2int(value);
|
||||
temperatureSim.IceServerPort = std::stoul(value);
|
||||
else if (name == "SimPeriodAdjustFactor")
|
||||
temperatureSim.SimPeriodAdjustFactor = std::stoi(value.c_str());
|
||||
else if (name == "NPowStableCyclesToIncreasePeriod")
|
||||
temperatureSim.NPowStableCyclesToIncreasePeriod = std::stoi(value.c_str());
|
||||
else if (name == "GenerateTemperatureMap")
|
||||
temperatureSim.GenerateTemperatureMap = string2bool(value);
|
||||
temperatureSim.GenerateTemperatureMap = std::stoul(value);
|
||||
else if (name == "GeneratePowerMap")
|
||||
temperatureSim.GeneratePowerMap = string2bool(value);
|
||||
temperatureSim.GeneratePowerMap = std::stoul(value);
|
||||
else
|
||||
SC_REPORT_FATAL("Configuration",
|
||||
("Parameter " + name + " not defined in Configuration").c_str());
|
||||
@@ -320,36 +187,23 @@ void Configuration::setPathToResources(std::string path)
|
||||
temperatureSim.setPathToResources(path);
|
||||
}
|
||||
|
||||
std::string Configuration::getPathToResources()
|
||||
{
|
||||
return pathToResources;
|
||||
}
|
||||
// TODO: Never used
|
||||
void Configuration::setParameters(std::map<std::string, std::string>
|
||||
parameterMap)
|
||||
{
|
||||
for (auto item : parameterMap) {
|
||||
setParameter(item.first, item.second);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the total memory size in bytes
|
||||
std::uint64_t Configuration::getSimMemSizeInBytes()
|
||||
{
|
||||
// 1. Get number of banks, rows, columns and data width in bits for one die (or chip)
|
||||
std::string type = memSpec->MemoryType;
|
||||
std::uint64_t ranks = memSpec->NumberOfRanks;
|
||||
std::uint64_t bankgroups = memSpec->NumberOfBankGroups;
|
||||
std::uint64_t banks = memSpec->NumberOfBanks;
|
||||
std::uint64_t rows = memSpec->NumberOfRows;
|
||||
std::uint64_t columns = memSpec->NumberOfColumns;
|
||||
std::string type = memSpec->memoryType;
|
||||
std::uint64_t ranks = memSpec->numberOfRanks;
|
||||
std::uint64_t bankgroups = memSpec->numberOfBankGroups;
|
||||
std::uint64_t banks = memSpec->numberOfBanks;
|
||||
std::uint64_t rows = memSpec->numberOfRows;
|
||||
std::uint64_t columns = memSpec->numberOfColumns;
|
||||
std::uint64_t bitWidth = memSpec->bitWidth;
|
||||
// 2. Calculate size of one DRAM chip in bits
|
||||
std::uint64_t chipBitSize = banks * rows * columns * bitWidth;
|
||||
// 3. Calculate size of one DRAM chip in bytes
|
||||
std::uint64_t chipSize = chipBitSize / 8;
|
||||
// 4. Total memory size in Bytes of one DIMM (with only support of 1 rank on a DIMM)
|
||||
std::uint64_t memorySize = chipSize * NumberOfDevicesOnDIMM;
|
||||
std::uint64_t memorySize = chipSize * numberOfDevicesOnDIMM;
|
||||
|
||||
std::cout << headline << std::endl;
|
||||
std::cout << "Per Channel Configuration:" << std::endl << std::endl;
|
||||
@@ -363,7 +217,7 @@ std::uint64_t Configuration::getSimMemSizeInBytes()
|
||||
std::cout << " Chip data bus width: " << bitWidth << std::endl;
|
||||
std::cout << " Chip size in bits: " << chipBitSize << std::endl;
|
||||
std::cout << " Chip Size in bytes: " << chipSize << std::endl;
|
||||
std::cout << " Devices/Chips on DIMM: " << NumberOfDevicesOnDIMM << std::endl;
|
||||
std::cout << " Devices/Chips on DIMM: " << numberOfDevicesOnDIMM << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
assert(memorySize > 0);
|
||||
@@ -376,7 +230,7 @@ std::uint64_t Configuration::getSimMemSizeInBytes()
|
||||
// The bus width is given in bits, e.g., 64-bit data bus, 128-bit data bus, etc.
|
||||
unsigned int Configuration::getDataBusWidth()
|
||||
{
|
||||
unsigned int dataBusWidth = memSpec->bitWidth * NumberOfDevicesOnDIMM;
|
||||
unsigned int dataBusWidth = memSpec->bitWidth * numberOfDevicesOnDIMM;
|
||||
assert(dataBusWidth > 0);
|
||||
return dataBusWidth;
|
||||
}
|
||||
@@ -385,51 +239,35 @@ unsigned int Configuration::getDataBusWidth()
|
||||
unsigned int Configuration::getBytesPerBurst()
|
||||
{
|
||||
// First multiply to get the number of bits in a burst, then divide by 8 to get the value in bytes. The order is important. Think on a single x4 device.
|
||||
unsigned int bytesPerBurst = (memSpec->BurstLength * getDataBusWidth()) / 8;
|
||||
unsigned int bytesPerBurst = (memSpec->burstLength * getDataBusWidth()) / 8;
|
||||
assert(bytesPerBurst > 0);
|
||||
|
||||
if (NumberOfDevicesOnDIMM > 1) {
|
||||
if (numberOfDevicesOnDIMM > 1) {
|
||||
// The least significant bits of the physical address are the byte
|
||||
// offset of the N-byte-wide memory module (DIMM) (a single data word
|
||||
// or burst element has N bytes. N = 2^(# bits for byte offset)).
|
||||
unsigned int burstElementSizeInBytes =
|
||||
AddressDecoder::getInstance().amount.bytes;
|
||||
assert(bytesPerBurst == (burstElementSizeInBytes * memSpec->BurstLength));
|
||||
assert(bytesPerBurst == (burstElementSizeInBytes * memSpec->burstLength));
|
||||
}
|
||||
|
||||
return bytesPerBurst;
|
||||
}
|
||||
|
||||
bool Configuration::getRGRBank(unsigned int w)
|
||||
{
|
||||
bool flg = w == 0 ? RGRB0 : w == 1 ? RGRB1 : w == 2 ? RGRB2 : w == 3 ? RGRB3 : w
|
||||
== 4 ? RGRB4 : w == 5 ? RGRB5 : w == 6 ? RGRB6 : w == 7 ? RGRB7 : w == 8 ? RGRB8
|
||||
: w == 9 ? RGRB9 : w == 10 ? RGRB10 : w == 11 ? RGRB11 : w == 12 ? RGRB12 : w ==
|
||||
13 ? RGRB13 : w == 14 ? RGRB14 : w == 15 ? RGRB15 : true;
|
||||
return flg;
|
||||
}
|
||||
unsigned int Configuration::getNumAR(void)
|
||||
{
|
||||
return NumAR;
|
||||
}
|
||||
unsigned int Configuration::getRowInc(void)
|
||||
{
|
||||
return RowInc;
|
||||
}
|
||||
|
||||
unsigned int Configuration::getRefMode(void)
|
||||
{
|
||||
return RefMode;
|
||||
}
|
||||
|
||||
// Changes the number of bytes depeding on the ECC Controller. This function is needed for modules which get data directly or indirectly from the ECC Controller
|
||||
unsigned int Configuration::adjustNumBytesAfterECC(unsigned nBytes)
|
||||
{
|
||||
// Manipulate the number of bytes only if there is an ECC Controller selected
|
||||
if (ECCMode == ECCControllerMode::Disabled)
|
||||
if (ECCMode == "Disabled")
|
||||
return nBytes;
|
||||
else {
|
||||
else if (ECCMode == "Hamming")
|
||||
{
|
||||
assert(pECC != nullptr);
|
||||
return pECC->AllocationSize(nBytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("Configuration", ("ECC mode " + ECCMode + " unsupported").c_str());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,10 +50,6 @@
|
||||
|
||||
enum class StorageMode {NoStorage, Store, ErrorModel};
|
||||
|
||||
enum class EPowerDownMode {NoPowerDown, Staggered, TimeoutPDN, TimeoutSREF};
|
||||
|
||||
enum class ECCControllerMode {Disabled, Hamming};
|
||||
|
||||
struct Configuration
|
||||
{
|
||||
static std::string memspecUri;
|
||||
@@ -63,80 +59,44 @@ struct Configuration
|
||||
DEF_SINGLETON(Configuration);
|
||||
|
||||
// MCConfig:
|
||||
bool BankwiseLogic = false;
|
||||
bool OpenPagePolicy = true;
|
||||
bool AdaptivePagePolicy = false;
|
||||
unsigned int MaxNrOfTransactions = 8;
|
||||
std::string Scheduler;
|
||||
unsigned int SJFProbability;
|
||||
unsigned int RequestBufferSize;
|
||||
unsigned int Capsize = 5;
|
||||
sc_time getPowerDownTimeout()
|
||||
{
|
||||
return powerDownTimeoutInClk * memSpec->clk;
|
||||
}
|
||||
EPowerDownMode PowerDownMode = EPowerDownMode::Staggered;
|
||||
bool ReadWriteGrouping = false;
|
||||
bool ReorderBuffer = false;
|
||||
|
||||
std::string pagePolicy = "Open";
|
||||
std::string scheduler = "Fifo";
|
||||
std::string cmdMux = "Oldest";
|
||||
std::string respQueue = "Fifo";
|
||||
unsigned int requestBufferSize = 8;
|
||||
std::string refreshPolicy = "Rankwise";
|
||||
unsigned int refreshMode = 1;
|
||||
unsigned int refreshMaxPostponed = 0;
|
||||
unsigned int refreshMaxPulledin = 0;
|
||||
std::string powerDownPolicy = "NoPowerDown";
|
||||
unsigned int powerDownTimeout = 3;
|
||||
// SimConfig
|
||||
std::string SimulationName = "default";
|
||||
bool DatabaseRecording = true;
|
||||
bool PowerAnalysis = false;
|
||||
bool EnableWindowing = false;
|
||||
unsigned int WindowSize = 1000;
|
||||
bool Debug = false;
|
||||
unsigned int NumberOfMemChannels = 1;
|
||||
bool ControllerCoreRefDisable = false;
|
||||
bool RowGranularRef = false;
|
||||
bool RGRB0 = true;
|
||||
bool RGRB1 = true;
|
||||
bool RGRB2 = true;
|
||||
bool RGRB3 = true;
|
||||
bool RGRB4 = true;
|
||||
bool RGRB5 = true;
|
||||
bool RGRB6 = true;
|
||||
bool RGRB7 = true;
|
||||
bool RGRB8 = true;
|
||||
bool RGRB9 = true;
|
||||
bool RGRB10 = true;
|
||||
bool RGRB11 = true;
|
||||
bool RGRB12 = true;
|
||||
bool RGRB13 = true;
|
||||
bool RGRB14 = true;
|
||||
bool RGRB15 = true;
|
||||
unsigned int NumAR = 8192;
|
||||
unsigned int RefMode = 1;
|
||||
unsigned int RowInc = 1;
|
||||
bool getRGRBank(unsigned int);
|
||||
unsigned int getNumAR(void);
|
||||
unsigned int getRowInc(void);
|
||||
unsigned int getRefMode(void);
|
||||
bool ControllerCoreRefForceMaxPostponeBurst = false;
|
||||
bool ControllerCoreRefEnablePostpone = false;
|
||||
bool ControllerCoreRefEnablePullIn = false;
|
||||
unsigned int ControllerCoreRefMaxPostponed = 8;
|
||||
unsigned int ControllerCoreRefMaxPulledIn = 8;
|
||||
bool ThermalSimulation = false;
|
||||
bool SimulationProgressBar = false;
|
||||
unsigned int NumberOfDevicesOnDIMM = 1;
|
||||
bool CheckTLM2Protocol = false;
|
||||
ECCControllerMode ECCMode = ECCControllerMode::Disabled;
|
||||
std::string simulationName = "default";
|
||||
bool databaseRecording = false;
|
||||
bool powerAnalysis = false;
|
||||
bool enableWindowing = false;
|
||||
unsigned int windowSize = 1000;
|
||||
bool debug = false;
|
||||
unsigned int numberOfMemChannels = 1;
|
||||
bool thermalSimulation = false;
|
||||
bool simulationProgressBar = false;
|
||||
unsigned int numberOfDevicesOnDIMM = 8;
|
||||
bool checkTLM2Protocol = false;
|
||||
std::string ECCMode = "Disabled";
|
||||
ECCBaseClass *pECC = nullptr;
|
||||
bool gem5 = false;
|
||||
bool UseMalloc = false;
|
||||
unsigned long long int AddressOffset = 0;
|
||||
bool useMalloc = false;
|
||||
unsigned long long int addressOffset = 0;
|
||||
|
||||
// MemSpec (from DRAM-Power XML)
|
||||
MemSpec *memSpec;
|
||||
|
||||
void setParameter(std::string name, std::string value);
|
||||
void setParameters(std::map<std::string, std::string> parameterMap);
|
||||
|
||||
//Configs for Seed, csv file and StorageMode
|
||||
unsigned int ErrorChipSeed;
|
||||
std::string ErrorCSVFile = "not defined.";
|
||||
StorageMode StoreMode;
|
||||
unsigned int errorChipSeed;
|
||||
std::string errorCSVFile = "not defined.";
|
||||
std::string storeMode;
|
||||
|
||||
// Temperature Simulation related
|
||||
TemperatureSimConfig temperatureSim;
|
||||
@@ -146,11 +106,6 @@ struct Configuration
|
||||
unsigned int getBytesPerBurst();
|
||||
unsigned int adjustNumBytesAfterECC(unsigned bytes);
|
||||
void setPathToResources(std::string path);
|
||||
std::string getPathToResources();
|
||||
|
||||
private:
|
||||
Configuration() {}
|
||||
unsigned int powerDownTimeoutInClk = 3;
|
||||
};
|
||||
|
||||
#endif // CONFIGURATION_H
|
||||
|
||||
@@ -46,13 +46,11 @@
|
||||
#include "memspec/MemSpecGDDR5.h"
|
||||
#include "memspec/MemSpecGDDR5X.h"
|
||||
#include "memspec/MemSpecGDDR6.h"
|
||||
#include "../common/timingCalculations.h"
|
||||
|
||||
using namespace tinyxml2;
|
||||
using namespace std;
|
||||
|
||||
void ConfigurationLoader::loadSimConfig(Configuration &config,
|
||||
string simconfigUri)
|
||||
std::string simconfigUri)
|
||||
{
|
||||
tinyxml2::XMLDocument doc;
|
||||
|
||||
@@ -66,7 +64,7 @@ void ConfigurationLoader::loadSimConfig(Configuration &config,
|
||||
{
|
||||
if (simconfig->Attribute("src")) {
|
||||
XMLDocument doc;
|
||||
string src(simconfig->Attribute("src"));
|
||||
std::string src(simconfig->Attribute("src"));
|
||||
loadXML(src, doc);
|
||||
loadSimConfig(config, doc.FirstChildElement("simconfig"));
|
||||
}
|
||||
@@ -112,7 +110,7 @@ void ConfigurationLoader::loadConfigFromUri(Configuration &config,
|
||||
}
|
||||
|
||||
void ConfigurationLoader::loadMCConfig(Configuration &config,
|
||||
string mcconfigUri)
|
||||
std::string mcconfigUri)
|
||||
{
|
||||
tinyxml2::XMLDocument doc;
|
||||
config.mcconfigUri = mcconfigUri;
|
||||
@@ -127,7 +125,7 @@ void ConfigurationLoader::loadMCConfig(Configuration &config,
|
||||
if (mcconfig->Attribute("src"))
|
||||
{
|
||||
XMLDocument doc;
|
||||
string src(mcconfig->Attribute("src"));
|
||||
std::string src(mcconfig->Attribute("src"));
|
||||
config.mcconfigUri = src;
|
||||
loadXML(src, doc);
|
||||
loadMCConfig(config, doc.FirstChildElement("mcconfig"));
|
||||
@@ -136,7 +134,7 @@ void ConfigurationLoader::loadMCConfig(Configuration &config,
|
||||
loadConfig(config, mcconfig);
|
||||
}
|
||||
|
||||
void ConfigurationLoader::loadMemSpec(Configuration &config, string memspecUri)
|
||||
void ConfigurationLoader::loadMemSpec(Configuration &config, std::string memspecUri)
|
||||
{
|
||||
tinyxml2::XMLDocument doc;
|
||||
config.memspecUri = memspecUri;
|
||||
@@ -148,7 +146,7 @@ void ConfigurationLoader::loadMemSpec(Configuration &config, string memspecUri)
|
||||
void ConfigurationLoader::loadMemSpec(Configuration &config,
|
||||
XMLElement *memspec)
|
||||
{
|
||||
string memoryType = queryStringParameter(memspec, "memoryType");
|
||||
std::string memoryType = queryStringParameter(memspec, "memoryType");
|
||||
if (memoryType == "DDR4")
|
||||
{
|
||||
Configuration::getInstance().memSpec = new MemSpecDDR4();
|
||||
@@ -211,21 +209,23 @@ void ConfigurationLoader::loadCommons(Configuration &config, XMLElement *xmlSpec
|
||||
{
|
||||
MemSpec *memSpec = config.memSpec;
|
||||
|
||||
memSpec->MemoryId = queryStringParameter(xmlSpec, "memoryId");
|
||||
memSpec->MemoryType = queryStringParameter(xmlSpec, "memoryType");
|
||||
memSpec->memoryId = queryStringParameter(xmlSpec, "memoryId");
|
||||
memSpec->memoryType = queryStringParameter(xmlSpec, "memoryType");
|
||||
|
||||
// MemArchitecture
|
||||
XMLElement *architecture = xmlSpec->FirstChildElement("memarchitecturespec");
|
||||
memSpec->BurstLength = queryUIntParameter(architecture, "burstLength");
|
||||
memSpec->DataRate = queryUIntParameter(architecture, "dataRate");
|
||||
memSpec->NumberOfRows = queryUIntParameter(architecture, "nbrOfRows");
|
||||
memSpec->NumberOfColumns = queryUIntParameter(architecture, "nbrOfColumns");
|
||||
memSpec->burstLength = queryUIntParameter(architecture, "burstLength");
|
||||
memSpec->dataRate = queryUIntParameter(architecture, "dataRate");
|
||||
memSpec->numberOfRows = queryUIntParameter(architecture, "nbrOfRows");
|
||||
memSpec->numberOfColumns = queryUIntParameter(architecture, "nbrOfColumns");
|
||||
memSpec->bitWidth = queryUIntParameter(architecture, "width");
|
||||
|
||||
// Clock
|
||||
XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec");
|
||||
memSpec->clkMHz = queryDoubleParameter(timings, "clkMhz");
|
||||
memSpec->clk = FrequencyToClk(memSpec->clkMHz);
|
||||
memSpec->fCKMHz = queryDoubleParameter(timings, "clkMhz");
|
||||
memSpec->tCK = sc_time(1.0 / memSpec->fCKMHz, SC_US);
|
||||
|
||||
memSpec->burstDuration = memSpec->tCK * (memSpec->burstLength / memSpec->dataRate);
|
||||
}
|
||||
|
||||
void ConfigurationLoader::loadDDR3(Configuration &config, XMLElement *xmlSpec)
|
||||
@@ -236,38 +236,37 @@ void ConfigurationLoader::loadDDR3(Configuration &config, XMLElement *xmlSpec)
|
||||
|
||||
// MemArchitecture
|
||||
XMLElement *architecture = xmlSpec->FirstChildElement("memarchitecturespec");
|
||||
memSpec->NumberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
memSpec->BanksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
memSpec->GroupsPerRank = 1;
|
||||
memSpec->BanksPerGroup = memSpec->BanksPerRank / memSpec->GroupsPerRank;
|
||||
memSpec->NumberOfBanks = memSpec->BanksPerRank * memSpec->NumberOfRanks;
|
||||
memSpec->NumberOfBankGroups = memSpec->GroupsPerRank * memSpec->NumberOfRanks;
|
||||
memSpec->numberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
memSpec->banksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
memSpec->groupsPerRank = 1;
|
||||
memSpec->banksPerGroup = memSpec->banksPerRank / memSpec->groupsPerRank;
|
||||
memSpec->numberOfBanks = memSpec->banksPerRank * memSpec->numberOfRanks;
|
||||
memSpec->numberOfBankGroups = memSpec->groupsPerRank * memSpec->numberOfRanks;
|
||||
|
||||
// MemTimings specific for DDR3
|
||||
XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec");
|
||||
sc_time clk = memSpec->clk;
|
||||
memSpec->tCKE = clk * queryUIntParameter(timings, "CKE");
|
||||
memSpec->tCKESR = clk * queryUIntParameter(timings, "CKESR");
|
||||
//memSpec->tDQSCK = clk * queryUIntParameter(timings, "DQSCK");
|
||||
memSpec->tRAS = clk * queryUIntParameter(timings, "RAS");
|
||||
memSpec->tRC = clk * queryUIntParameter(timings, "RC");
|
||||
memSpec->tRCD = clk * queryUIntParameter(timings, "RCD");
|
||||
memSpec->tRL = clk * queryUIntParameter(timings, "RL");
|
||||
memSpec->tRTP = clk * queryUIntParameter(timings, "RTP");
|
||||
memSpec->tWL = clk * queryUIntParameter(timings, "WL");
|
||||
memSpec->tWR = clk * queryUIntParameter(timings, "WR");
|
||||
memSpec->tXP = clk * queryUIntParameter(timings, "XP");
|
||||
memSpec->tXS = clk * queryUIntParameter(timings, "XS");
|
||||
memSpec->tCCD = clk * queryUIntParameter(timings, "CCD");
|
||||
memSpec->tFAW = clk * queryUIntParameter(timings, "FAW");
|
||||
memSpec->tREFI = clk * queryUIntParameter(timings, "REFI");
|
||||
memSpec->tRFC = clk * queryUIntParameter(timings, "RFC");
|
||||
memSpec->tRP = clk * queryUIntParameter(timings, "RP");
|
||||
memSpec->tRRD = clk * queryUIntParameter(timings, "RRD");
|
||||
memSpec->tWTR = clk * queryUIntParameter(timings, "WTR");
|
||||
memSpec->tAL = clk * queryUIntParameter(timings, "AL");
|
||||
memSpec->tXPDLL = clk * queryUIntParameter(timings, "XPDLL");
|
||||
memSpec->tXSDLL = clk * queryUIntParameter(timings, "XSDLL");
|
||||
memSpec->tCKE = memSpec->tCK * queryUIntParameter(timings, "CKE");
|
||||
memSpec->tCKESR = memSpec->tCK * queryUIntParameter(timings, "CKESR");
|
||||
//memSpec->tDQSCK = memSpec->tCK * queryUIntParameter(timings, "DQSCK");
|
||||
memSpec->tRAS = memSpec->tCK * queryUIntParameter(timings, "RAS");
|
||||
memSpec->tRC = memSpec->tCK * queryUIntParameter(timings, "RC");
|
||||
memSpec->tRCD = memSpec->tCK * queryUIntParameter(timings, "RCD");
|
||||
memSpec->tRL = memSpec->tCK * queryUIntParameter(timings, "RL");
|
||||
memSpec->tRTP = memSpec->tCK * queryUIntParameter(timings, "RTP");
|
||||
memSpec->tWL = memSpec->tCK * queryUIntParameter(timings, "WL");
|
||||
memSpec->tWR = memSpec->tCK * queryUIntParameter(timings, "WR");
|
||||
memSpec->tXP = memSpec->tCK * queryUIntParameter(timings, "XP");
|
||||
memSpec->tXS = memSpec->tCK * queryUIntParameter(timings, "XS");
|
||||
memSpec->tCCD = memSpec->tCK * queryUIntParameter(timings, "CCD");
|
||||
memSpec->tFAW = memSpec->tCK * queryUIntParameter(timings, "FAW");
|
||||
memSpec->tREFI = memSpec->tCK * queryUIntParameter(timings, "REFI");
|
||||
memSpec->tRFC = memSpec->tCK * queryUIntParameter(timings, "RFC");
|
||||
memSpec->tRP = memSpec->tCK * queryUIntParameter(timings, "RP");
|
||||
memSpec->tRRD = memSpec->tCK * queryUIntParameter(timings, "RRD");
|
||||
memSpec->tWTR = memSpec->tCK * queryUIntParameter(timings, "WTR");
|
||||
memSpec->tAL = memSpec->tCK * queryUIntParameter(timings, "AL");
|
||||
memSpec->tXPDLL = memSpec->tCK * queryUIntParameter(timings, "XPDLL");
|
||||
memSpec->tXSDLL = memSpec->tCK * queryUIntParameter(timings, "XSDLL");
|
||||
|
||||
// Currents and voltages
|
||||
XMLElement *powers = xmlSpec->FirstChildElement("mempowerspec");
|
||||
@@ -293,57 +292,56 @@ void ConfigurationLoader::loadDDR4(Configuration &config, XMLElement *xmlSpec)
|
||||
|
||||
// MemArchitecture
|
||||
XMLElement *architecture = xmlSpec->FirstChildElement("memarchitecturespec");
|
||||
memSpec->NumberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
memSpec->BanksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
memSpec->GroupsPerRank = queryUIntParameter(architecture, "nbrOfBankGroups");
|
||||
memSpec->BanksPerGroup = memSpec->BanksPerRank / memSpec->GroupsPerRank;
|
||||
memSpec->NumberOfBanks = memSpec->BanksPerRank * memSpec->NumberOfRanks;
|
||||
memSpec->NumberOfBankGroups = memSpec->GroupsPerRank * memSpec->NumberOfRanks;
|
||||
memSpec->numberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
memSpec->banksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
memSpec->groupsPerRank = queryUIntParameter(architecture, "nbrOfBankGroups");
|
||||
memSpec->banksPerGroup = memSpec->banksPerRank / memSpec->groupsPerRank;
|
||||
memSpec->numberOfBanks = memSpec->banksPerRank * memSpec->numberOfRanks;
|
||||
memSpec->numberOfBankGroups = memSpec->groupsPerRank * memSpec->numberOfRanks;
|
||||
|
||||
// MemTimings specific for DDR4
|
||||
XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec");
|
||||
sc_time clk = memSpec->clk;
|
||||
memSpec->tCKE = clk * queryUIntParameter(timings, "CKE");
|
||||
memSpec->tCKESR = clk * queryUIntParameter(timings, "CKESR");
|
||||
//memSpec->tDQSCK = clk * queryUIntParameter(timings, "DQSCK");
|
||||
memSpec->tRAS = clk * queryUIntParameter(timings, "RAS");
|
||||
memSpec->tRC = clk * queryUIntParameter(timings, "RC");
|
||||
memSpec->tRCD = clk * queryUIntParameter(timings, "RCD");
|
||||
memSpec->tRL = clk * queryUIntParameter(timings, "RL");
|
||||
memSpec->tRTP = clk * queryUIntParameter(timings, "RTP");
|
||||
memSpec->tWL = clk * queryUIntParameter(timings, "WL");
|
||||
memSpec->tWR = clk * queryUIntParameter(timings, "WR");
|
||||
memSpec->tXP = clk * queryUIntParameter(timings, "XP");
|
||||
memSpec->tXS = clk * queryUIntParameter(timings, "XS");
|
||||
memSpec->tCCD_S = clk * queryUIntParameter(timings, "CCD_S");
|
||||
memSpec->tCCD_L = clk * queryUIntParameter(timings, "CCD_L");
|
||||
memSpec->tFAW = clk * queryUIntParameter(timings, "FAW");
|
||||
unsigned refMode = Configuration::getInstance().getRefMode();
|
||||
if (refMode == 1)
|
||||
memSpec->tCKE = memSpec->tCK * queryUIntParameter(timings, "CKE");
|
||||
memSpec->tCKESR = memSpec->tCK * queryUIntParameter(timings, "CKESR");
|
||||
//memSpec->tDQSCK = memSpec->tCK * queryUIntParameter(timings, "DQSCK");
|
||||
memSpec->tRAS = memSpec->tCK * queryUIntParameter(timings, "RAS");
|
||||
memSpec->tRC = memSpec->tCK * queryUIntParameter(timings, "RC");
|
||||
memSpec->tRCD = memSpec->tCK * queryUIntParameter(timings, "RCD");
|
||||
memSpec->tRL = memSpec->tCK * queryUIntParameter(timings, "RL");
|
||||
memSpec->tRTP = memSpec->tCK * queryUIntParameter(timings, "RTP");
|
||||
memSpec->tWL = memSpec->tCK * queryUIntParameter(timings, "WL");
|
||||
memSpec->tWR = memSpec->tCK * queryUIntParameter(timings, "WR");
|
||||
memSpec->tXP = memSpec->tCK * queryUIntParameter(timings, "XP");
|
||||
memSpec->tXS = memSpec->tCK * queryUIntParameter(timings, "XS");
|
||||
memSpec->tCCD_S = memSpec->tCK * queryUIntParameter(timings, "CCD_S");
|
||||
memSpec->tCCD_L = memSpec->tCK * queryUIntParameter(timings, "CCD_L");
|
||||
memSpec->tFAW = memSpec->tCK * queryUIntParameter(timings, "FAW");
|
||||
unsigned refreshMode = Configuration::getInstance().refreshMode;
|
||||
if (refreshMode == 1)
|
||||
{
|
||||
memSpec->tREFI = clk * queryUIntParameter(timings, "REFI");
|
||||
memSpec->tRFC = clk * queryUIntParameter(timings, "RFC");
|
||||
memSpec->tREFI = memSpec->tCK * queryUIntParameter(timings, "REFI");
|
||||
memSpec->tRFC = memSpec->tCK * queryUIntParameter(timings, "RFC");
|
||||
}
|
||||
else if (refMode == 2)
|
||||
else if (refreshMode == 2)
|
||||
{
|
||||
memSpec->tREFI = clk * (queryUIntParameter(timings, "REFI") / 2);
|
||||
memSpec->tRFC = clk * queryUIntParameter(timings, "RFC2");
|
||||
memSpec->tREFI = memSpec->tCK * (queryUIntParameter(timings, "REFI") / 2);
|
||||
memSpec->tRFC = memSpec->tCK * queryUIntParameter(timings, "RFC2");
|
||||
}
|
||||
else if (refMode == 4)
|
||||
else if (refreshMode == 4)
|
||||
{
|
||||
memSpec->tREFI = clk * (queryUIntParameter(timings, "REFI") / 2);
|
||||
memSpec->tRFC = clk * queryUIntParameter(timings, "RFC4");
|
||||
memSpec->tREFI = memSpec->tCK * (queryUIntParameter(timings, "REFI") / 2);
|
||||
memSpec->tRFC = memSpec->tCK * queryUIntParameter(timings, "RFC4");
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("ConfigurationLoader", "Refresh Mode not supported");
|
||||
memSpec->tRP = clk * queryUIntParameter(timings, "RP");
|
||||
memSpec->tRRD_S = clk * queryUIntParameter(timings, "RRD_S");
|
||||
memSpec->tRRD_L = clk * queryUIntParameter(timings, "RRD_L");
|
||||
memSpec->tWTR_S = clk * queryUIntParameter(timings, "WTR_S");
|
||||
memSpec->tWTR_L = clk * queryUIntParameter(timings, "WTR_L");
|
||||
memSpec->tAL = clk * queryUIntParameter(timings, "AL");
|
||||
memSpec->tXPDLL = clk * queryUIntParameter(timings, "XPDLL");
|
||||
memSpec->tXSDLL = clk * queryUIntParameter(timings, "XSDLL");
|
||||
memSpec->tRP = memSpec->tCK * queryUIntParameter(timings, "RP");
|
||||
memSpec->tRRD_S = memSpec->tCK * queryUIntParameter(timings, "RRD_S");
|
||||
memSpec->tRRD_L = memSpec->tCK * queryUIntParameter(timings, "RRD_L");
|
||||
memSpec->tWTR_S = memSpec->tCK * queryUIntParameter(timings, "WTR_S");
|
||||
memSpec->tWTR_L = memSpec->tCK * queryUIntParameter(timings, "WTR_L");
|
||||
memSpec->tAL = memSpec->tCK * queryUIntParameter(timings, "AL");
|
||||
memSpec->tXPDLL = memSpec->tCK * queryUIntParameter(timings, "XPDLL");
|
||||
memSpec->tXSDLL = memSpec->tCK * queryUIntParameter(timings, "XSDLL");
|
||||
|
||||
// Currents and voltages
|
||||
XMLElement *powers = xmlSpec->FirstChildElement("mempowerspec");
|
||||
@@ -372,44 +370,43 @@ void ConfigurationLoader::loadLPDDR4(Configuration &config, XMLElement *xmlSpec)
|
||||
|
||||
// MemArchitecture:
|
||||
XMLElement *architecture = xmlSpec->FirstChildElement("memarchitecturespec");
|
||||
memSpec->NumberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
memSpec->BanksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
memSpec->GroupsPerRank = 1;
|
||||
memSpec->BanksPerGroup = memSpec->BanksPerRank / memSpec->GroupsPerRank;
|
||||
memSpec->NumberOfBanks = memSpec->BanksPerRank * memSpec->NumberOfRanks;
|
||||
memSpec->NumberOfBankGroups = memSpec->GroupsPerRank * memSpec->NumberOfRanks;
|
||||
memSpec->numberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
memSpec->banksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
memSpec->groupsPerRank = 1;
|
||||
memSpec->banksPerGroup = memSpec->banksPerRank / memSpec->groupsPerRank;
|
||||
memSpec->numberOfBanks = memSpec->banksPerRank * memSpec->numberOfRanks;
|
||||
memSpec->numberOfBankGroups = memSpec->groupsPerRank * memSpec->numberOfRanks;
|
||||
|
||||
// MemTimings specific for LPDDR4
|
||||
XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec");
|
||||
sc_time clk = memSpec->clk;
|
||||
memSpec->tREFI = clk * queryUIntParameter(timings, "REFI");
|
||||
memSpec->tREFIpb = clk * queryUIntParameter(timings, "REFIPB");
|
||||
memSpec->tRFCab = clk * queryUIntParameter(timings, "RFCAB");
|
||||
memSpec->tRFCpb = clk * queryUIntParameter(timings, "RFCPB");
|
||||
memSpec->tRPab = clk * queryUIntParameter(timings, "RPAB");
|
||||
memSpec->tRPpb = clk * queryUIntParameter(timings, "RPPB");
|
||||
memSpec->tPPD = clk * queryUIntParameter(timings, "PPD");
|
||||
memSpec->tRAS = clk * queryUIntParameter(timings, "RAS");
|
||||
memSpec->tRCD = clk * queryUIntParameter(timings, "RCD");
|
||||
memSpec->tFAW = clk * queryUIntParameter(timings, "FAW");
|
||||
memSpec->tRRD = clk * queryUIntParameter(timings, "RRD");
|
||||
memSpec->tCCD = clk * queryUIntParameter(timings, "CCD");
|
||||
memSpec->tRL = clk * queryUIntParameter(timings, "RL");
|
||||
memSpec->tRPST = clk * queryUIntParameter(timings, "RPST");
|
||||
memSpec->tDQSCK = clk * queryUIntParameter(timings, "DQSCK");
|
||||
memSpec->tRTP = clk * queryUIntParameter(timings, "RTP");
|
||||
memSpec->tWL = clk * queryUIntParameter(timings, "WL");
|
||||
memSpec->tDQSS = clk * queryUIntParameter(timings, "DQSS");
|
||||
memSpec->tDQS2DQ = clk * queryUIntParameter(timings, "DQS2DQ");
|
||||
memSpec->tWR = clk * queryUIntParameter(timings, "WR");
|
||||
memSpec->tWPRE = clk * queryUIntParameter(timings, "WPRE");
|
||||
memSpec->tWTR = clk * queryUIntParameter(timings, "WTR");
|
||||
memSpec->tXP = clk * queryUIntParameter(timings, "XP");
|
||||
memSpec->tSR = clk * queryUIntParameter(timings, "SR");
|
||||
memSpec->tXSR = clk * queryUIntParameter(timings, "XSR");
|
||||
memSpec->tESCKE = clk * queryUIntParameter(timings, "ESCKE");
|
||||
memSpec->tCKE = clk * queryUIntParameter(timings, "CKE");
|
||||
memSpec->tCMDCKE = clk * queryUIntParameter(timings, "CMDCKE");
|
||||
memSpec->tREFI = memSpec->tCK * queryUIntParameter(timings, "REFI");
|
||||
memSpec->tREFIpb = memSpec->tCK * queryUIntParameter(timings, "REFIPB");
|
||||
memSpec->tRFCab = memSpec->tCK * queryUIntParameter(timings, "RFCAB");
|
||||
memSpec->tRFCpb = memSpec->tCK * queryUIntParameter(timings, "RFCPB");
|
||||
memSpec->tRPab = memSpec->tCK * queryUIntParameter(timings, "RPAB");
|
||||
memSpec->tRPpb = memSpec->tCK * queryUIntParameter(timings, "RPPB");
|
||||
memSpec->tPPD = memSpec->tCK * queryUIntParameter(timings, "PPD");
|
||||
memSpec->tRAS = memSpec->tCK * queryUIntParameter(timings, "RAS");
|
||||
memSpec->tRCD = memSpec->tCK * queryUIntParameter(timings, "RCD");
|
||||
memSpec->tFAW = memSpec->tCK * queryUIntParameter(timings, "FAW");
|
||||
memSpec->tRRD = memSpec->tCK * queryUIntParameter(timings, "RRD");
|
||||
memSpec->tCCD = memSpec->tCK * queryUIntParameter(timings, "CCD");
|
||||
memSpec->tRL = memSpec->tCK * queryUIntParameter(timings, "RL");
|
||||
memSpec->tRPST = memSpec->tCK * queryUIntParameter(timings, "RPST");
|
||||
memSpec->tDQSCK = memSpec->tCK * queryUIntParameter(timings, "DQSCK");
|
||||
memSpec->tRTP = memSpec->tCK * queryUIntParameter(timings, "RTP");
|
||||
memSpec->tWL = memSpec->tCK * queryUIntParameter(timings, "WL");
|
||||
memSpec->tDQSS = memSpec->tCK * queryUIntParameter(timings, "DQSS");
|
||||
memSpec->tDQS2DQ = memSpec->tCK * queryUIntParameter(timings, "DQS2DQ");
|
||||
memSpec->tWR = memSpec->tCK * queryUIntParameter(timings, "WR");
|
||||
memSpec->tWPRE = memSpec->tCK * queryUIntParameter(timings, "WPRE");
|
||||
memSpec->tWTR = memSpec->tCK * queryUIntParameter(timings, "WTR");
|
||||
memSpec->tXP = memSpec->tCK * queryUIntParameter(timings, "XP");
|
||||
memSpec->tSR = memSpec->tCK * queryUIntParameter(timings, "SR");
|
||||
memSpec->tXSR = memSpec->tCK * queryUIntParameter(timings, "XSR");
|
||||
memSpec->tESCKE = memSpec->tCK * queryUIntParameter(timings, "ESCKE");
|
||||
memSpec->tCKE = memSpec->tCK * queryUIntParameter(timings, "CKE");
|
||||
memSpec->tCMDCKE = memSpec->tCK * queryUIntParameter(timings, "CMDCKE");
|
||||
|
||||
// Currents and voltages
|
||||
// TODO: to be completed
|
||||
@@ -423,36 +420,35 @@ void ConfigurationLoader::loadWideIO(Configuration &config, XMLElement *xmlSpec)
|
||||
|
||||
// MemArchitecture
|
||||
XMLElement *architecture = xmlSpec->FirstChildElement("memarchitecturespec");
|
||||
memSpec->NumberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
memSpec->BanksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
memSpec->GroupsPerRank = 1;
|
||||
memSpec->BanksPerGroup = memSpec->BanksPerRank / memSpec->GroupsPerRank;
|
||||
memSpec->NumberOfBanks = memSpec->BanksPerRank * memSpec->NumberOfRanks;
|
||||
memSpec->NumberOfBankGroups = memSpec->GroupsPerRank * memSpec->NumberOfRanks;
|
||||
memSpec->numberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
memSpec->banksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
memSpec->groupsPerRank = 1;
|
||||
memSpec->banksPerGroup = memSpec->banksPerRank / memSpec->groupsPerRank;
|
||||
memSpec->numberOfBanks = memSpec->banksPerRank * memSpec->numberOfRanks;
|
||||
memSpec->numberOfBankGroups = memSpec->groupsPerRank * memSpec->numberOfRanks;
|
||||
|
||||
// MemTimings specific for WideIO
|
||||
XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec");
|
||||
sc_time clk = memSpec->clk;
|
||||
memSpec->tCKE = clk * queryUIntParameter(timings, "CKE");
|
||||
memSpec->tCKESR = clk * queryUIntParameter(timings, "CKESR");
|
||||
memSpec->tDQSCK = clk * queryUIntParameter(timings, "DQSCK");
|
||||
memSpec->tAC = clk * queryUIntParameter(timings, "AC");
|
||||
memSpec->tRAS = clk * queryUIntParameter(timings, "RAS");
|
||||
memSpec->tRC = clk * queryUIntParameter(timings, "RC");
|
||||
memSpec->tRCD = clk * queryUIntParameter(timings, "RCD");
|
||||
memSpec->tRL = clk * queryUIntParameter(timings, "RL");
|
||||
memSpec->tWL = clk * queryUIntParameter(timings, "WL");
|
||||
memSpec->tWR = clk * queryUIntParameter(timings, "WR");
|
||||
memSpec->tXP = clk * queryUIntParameter(timings, "XP");
|
||||
memSpec->tXS = clk * queryUIntParameter(timings, "XS");
|
||||
memSpec->tCCD_R = clk * queryUIntParameter(timings, "CCD_R");
|
||||
memSpec->tCCD_W = clk * queryUIntParameter(timings, "CCD_W");
|
||||
memSpec->tREFI = clk * queryUIntParameter(timings, "REFI");
|
||||
memSpec->tRFC = clk * queryUIntParameter(timings, "RFC");
|
||||
memSpec->tRP = clk * queryUIntParameter(timings, "RP");
|
||||
memSpec->tRRD = clk * queryUIntParameter(timings, "RRD");
|
||||
memSpec->tTAW = clk * queryUIntParameter(timings, "TAW");
|
||||
memSpec->tWTR = clk * queryUIntParameter(timings, "WTR");
|
||||
memSpec->tCKE = memSpec->tCK * queryUIntParameter(timings, "CKE");
|
||||
memSpec->tCKESR = memSpec->tCK * queryUIntParameter(timings, "CKESR");
|
||||
memSpec->tDQSCK = memSpec->tCK * queryUIntParameter(timings, "DQSCK");
|
||||
memSpec->tAC = memSpec->tCK * queryUIntParameter(timings, "AC");
|
||||
memSpec->tRAS = memSpec->tCK * queryUIntParameter(timings, "RAS");
|
||||
memSpec->tRC = memSpec->tCK * queryUIntParameter(timings, "RC");
|
||||
memSpec->tRCD = memSpec->tCK * queryUIntParameter(timings, "RCD");
|
||||
memSpec->tRL = memSpec->tCK * queryUIntParameter(timings, "RL");
|
||||
memSpec->tWL = memSpec->tCK * queryUIntParameter(timings, "WL");
|
||||
memSpec->tWR = memSpec->tCK * queryUIntParameter(timings, "WR");
|
||||
memSpec->tXP = memSpec->tCK * queryUIntParameter(timings, "XP");
|
||||
memSpec->tXS = memSpec->tCK * queryUIntParameter(timings, "XS");
|
||||
memSpec->tCCD_R = memSpec->tCK * queryUIntParameter(timings, "CCD_R");
|
||||
memSpec->tCCD_W = memSpec->tCK * queryUIntParameter(timings, "CCD_W");
|
||||
memSpec->tREFI = memSpec->tCK * queryUIntParameter(timings, "REFI");
|
||||
memSpec->tRFC = memSpec->tCK * queryUIntParameter(timings, "RFC");
|
||||
memSpec->tRP = memSpec->tCK * queryUIntParameter(timings, "RP");
|
||||
memSpec->tRRD = memSpec->tCK * queryUIntParameter(timings, "RRD");
|
||||
memSpec->tTAW = memSpec->tCK * queryUIntParameter(timings, "TAW");
|
||||
memSpec->tWTR = memSpec->tCK * queryUIntParameter(timings, "WTR");
|
||||
|
||||
// Currents and voltages
|
||||
XMLElement *powers = xmlSpec->FirstChildElement("mempowerspec");
|
||||
@@ -490,40 +486,39 @@ void ConfigurationLoader::loadWideIO2(Configuration &config, XMLElement *xmlSpec
|
||||
|
||||
// MemArchitecture
|
||||
XMLElement *architecture = xmlSpec->FirstChildElement("memarchitecturespec");
|
||||
memSpec->NumberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
memSpec->BanksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
memSpec->GroupsPerRank = 1;
|
||||
memSpec->BanksPerGroup = memSpec->BanksPerRank / memSpec->GroupsPerRank;
|
||||
memSpec->NumberOfBanks = memSpec->BanksPerRank * memSpec->NumberOfRanks;
|
||||
memSpec->NumberOfBankGroups = memSpec->GroupsPerRank * memSpec->NumberOfRanks;
|
||||
memSpec->numberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
memSpec->banksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
memSpec->groupsPerRank = 1;
|
||||
memSpec->banksPerGroup = memSpec->banksPerRank / memSpec->groupsPerRank;
|
||||
memSpec->numberOfBanks = memSpec->banksPerRank * memSpec->numberOfRanks;
|
||||
memSpec->numberOfBankGroups = memSpec->groupsPerRank * memSpec->numberOfRanks;
|
||||
|
||||
// MemTimings specific for WideIO
|
||||
XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec");
|
||||
sc_time clk = memSpec->clk;
|
||||
memSpec->tDQSCK = clk * queryUIntParameter(timings, "DQSCK");
|
||||
memSpec->tDQSS = clk * queryUIntParameter(timings, "DQSS");
|
||||
memSpec->tCKE = clk * queryUIntParameter(timings, "CKE");
|
||||
memSpec->tRL = clk * queryUIntParameter(timings, "RL");
|
||||
memSpec->tWL = clk * queryUIntParameter(timings, "WL");
|
||||
memSpec->tRCpb = clk * queryUIntParameter(timings, "RCPB");
|
||||
memSpec->tRCab = clk * queryUIntParameter(timings, "RCAB");
|
||||
memSpec->tCKESR = clk * queryUIntParameter(timings, "CKESR");
|
||||
memSpec->tXSR = clk * queryUIntParameter(timings, "XSR");
|
||||
memSpec->tXP = clk * queryUIntParameter(timings, "XP");
|
||||
memSpec->tCCD = clk * queryUIntParameter(timings, "CCD");
|
||||
memSpec->tRTP = clk * queryUIntParameter(timings, "RTP");
|
||||
memSpec->tRCD = clk * queryUIntParameter(timings, "RCD");
|
||||
memSpec->tRPpb = clk * queryUIntParameter(timings, "RPPB");
|
||||
memSpec->tRPab = clk * queryUIntParameter(timings, "RPAB");
|
||||
memSpec->tRAS = clk * queryUIntParameter(timings, "RAS");
|
||||
memSpec->tWR = clk * queryUIntParameter(timings, "WR");
|
||||
memSpec->tWTR = clk * queryUIntParameter(timings, "WTR");
|
||||
memSpec->tRRD = clk * queryUIntParameter(timings, "RRD");
|
||||
memSpec->tFAW = clk * queryUIntParameter(timings, "FAW");
|
||||
memSpec->tREFI = clk * queryUIntParameter(timings, "REFI");
|
||||
memSpec->tREFIpb = clk * queryUIntParameter(timings, "REFIPB");
|
||||
memSpec->tRFCab = clk * queryUIntParameter(timings, "RFCAB");
|
||||
memSpec->tRFCpb = clk * queryUIntParameter(timings, "RFCPB");
|
||||
memSpec->tDQSCK = memSpec->tCK * queryUIntParameter(timings, "DQSCK");
|
||||
memSpec->tDQSS = memSpec->tCK * queryUIntParameter(timings, "DQSS");
|
||||
memSpec->tCKE = memSpec->tCK * queryUIntParameter(timings, "CKE");
|
||||
memSpec->tRL = memSpec->tCK * queryUIntParameter(timings, "RL");
|
||||
memSpec->tWL = memSpec->tCK * queryUIntParameter(timings, "WL");
|
||||
memSpec->tRCpb = memSpec->tCK * queryUIntParameter(timings, "RCPB");
|
||||
memSpec->tRCab = memSpec->tCK * queryUIntParameter(timings, "RCAB");
|
||||
memSpec->tCKESR = memSpec->tCK * queryUIntParameter(timings, "CKESR");
|
||||
memSpec->tXSR = memSpec->tCK * queryUIntParameter(timings, "XSR");
|
||||
memSpec->tXP = memSpec->tCK * queryUIntParameter(timings, "XP");
|
||||
memSpec->tCCD = memSpec->tCK * queryUIntParameter(timings, "CCD");
|
||||
memSpec->tRTP = memSpec->tCK * queryUIntParameter(timings, "RTP");
|
||||
memSpec->tRCD = memSpec->tCK * queryUIntParameter(timings, "RCD");
|
||||
memSpec->tRPpb = memSpec->tCK * queryUIntParameter(timings, "RPPB");
|
||||
memSpec->tRPab = memSpec->tCK * queryUIntParameter(timings, "RPAB");
|
||||
memSpec->tRAS = memSpec->tCK * queryUIntParameter(timings, "RAS");
|
||||
memSpec->tWR = memSpec->tCK * queryUIntParameter(timings, "WR");
|
||||
memSpec->tWTR = memSpec->tCK * queryUIntParameter(timings, "WTR");
|
||||
memSpec->tRRD = memSpec->tCK * queryUIntParameter(timings, "RRD");
|
||||
memSpec->tFAW = memSpec->tCK * queryUIntParameter(timings, "FAW");
|
||||
memSpec->tREFI = memSpec->tCK * queryUIntParameter(timings, "REFI");
|
||||
memSpec->tREFIpb = memSpec->tCK * queryUIntParameter(timings, "REFIPB");
|
||||
memSpec->tRFCab = memSpec->tCK * queryUIntParameter(timings, "RFCAB");
|
||||
memSpec->tRFCpb = memSpec->tCK * queryUIntParameter(timings, "RFCPB");
|
||||
|
||||
// Currents and voltages
|
||||
// TODO: to be completed
|
||||
@@ -537,55 +532,54 @@ void ConfigurationLoader::loadHBM2(Configuration &config, XMLElement *xmlSpec)
|
||||
|
||||
// MemArchitecture
|
||||
XMLElement *architecture = xmlSpec->FirstChildElement("memarchitecturespec");
|
||||
memSpec->NumberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
memSpec->BanksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
memSpec->GroupsPerRank = queryUIntParameter(architecture, "nbrOfBankGroups");
|
||||
memSpec->BanksPerGroup = memSpec->BanksPerRank / memSpec->GroupsPerRank;
|
||||
memSpec->NumberOfBanks = memSpec->BanksPerRank * memSpec->NumberOfRanks;
|
||||
memSpec->NumberOfBankGroups = memSpec->GroupsPerRank * memSpec->NumberOfRanks;
|
||||
memSpec->numberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
memSpec->banksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
memSpec->groupsPerRank = queryUIntParameter(architecture, "nbrOfBankGroups");
|
||||
memSpec->banksPerGroup = memSpec->banksPerRank / memSpec->groupsPerRank;
|
||||
memSpec->numberOfBanks = memSpec->banksPerRank * memSpec->numberOfRanks;
|
||||
memSpec->numberOfBankGroups = memSpec->groupsPerRank * memSpec->numberOfRanks;
|
||||
|
||||
// MemTimings specific for HBM2
|
||||
XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec");
|
||||
sc_time clk = memSpec->clk;
|
||||
memSpec->tDQSCK = clk * queryUIntParameter(timings, "DQSCK");
|
||||
// memSpec->tDQSQ = clk * queryUIntParameter(timings, "DQSQ");
|
||||
memSpec->tRC = clk * queryUIntParameter(timings, "RC");
|
||||
memSpec->tRAS = clk * queryUIntParameter(timings, "RAS");
|
||||
memSpec->tRCDRD = clk * queryUIntParameter(timings, "RCDRD");
|
||||
memSpec->tRCDWR = clk * queryUIntParameter(timings, "RCDWR");
|
||||
memSpec->tRRDL = clk * queryUIntParameter(timings, "RRDL");
|
||||
memSpec->tRRDS = clk * queryUIntParameter(timings, "RRDS");
|
||||
memSpec->tFAW = clk * queryUIntParameter(timings, "FAW");
|
||||
memSpec->tRTP = clk * queryUIntParameter(timings, "RTP");
|
||||
memSpec->tRP = clk * queryUIntParameter(timings, "RP");
|
||||
memSpec->tRL = clk * queryUIntParameter(timings, "RL");
|
||||
memSpec->tWL = clk * queryUIntParameter(timings, "WL");
|
||||
memSpec->tPL = clk * queryUIntParameter(timings, "PL");
|
||||
memSpec->tWR = clk * queryUIntParameter(timings, "WR");
|
||||
memSpec->tCCDL = clk * queryUIntParameter(timings, "CCDL");
|
||||
memSpec->tCCDS = clk * queryUIntParameter(timings, "CCDS");
|
||||
// memSpec->tCCDR = clk * queryUIntParameter(timings, "CCDR");
|
||||
memSpec->tWTRL = clk * queryUIntParameter(timings, "WTRL");
|
||||
memSpec->tWTRS = clk * queryUIntParameter(timings, "WTRS");
|
||||
memSpec->tRTW = clk * queryUIntParameter(timings, "RTW");
|
||||
memSpec->tXP = clk * queryUIntParameter(timings, "XP");
|
||||
memSpec->tCKE = clk * queryUIntParameter(timings, "CKE");
|
||||
memSpec->tDQSCK = memSpec->tCK * queryUIntParameter(timings, "DQSCK");
|
||||
// memSpec->tDQSQ = memSpec->tCK * queryUIntParameter(timings, "DQSQ");
|
||||
memSpec->tRC = memSpec->tCK * queryUIntParameter(timings, "RC");
|
||||
memSpec->tRAS = memSpec->tCK * queryUIntParameter(timings, "RAS");
|
||||
memSpec->tRCDRD = memSpec->tCK * queryUIntParameter(timings, "RCDRD");
|
||||
memSpec->tRCDWR = memSpec->tCK * queryUIntParameter(timings, "RCDWR");
|
||||
memSpec->tRRDL = memSpec->tCK * queryUIntParameter(timings, "RRDL");
|
||||
memSpec->tRRDS = memSpec->tCK * queryUIntParameter(timings, "RRDS");
|
||||
memSpec->tFAW = memSpec->tCK * queryUIntParameter(timings, "FAW");
|
||||
memSpec->tRTP = memSpec->tCK * queryUIntParameter(timings, "RTP");
|
||||
memSpec->tRP = memSpec->tCK * queryUIntParameter(timings, "RP");
|
||||
memSpec->tRL = memSpec->tCK * queryUIntParameter(timings, "RL");
|
||||
memSpec->tWL = memSpec->tCK * queryUIntParameter(timings, "WL");
|
||||
memSpec->tPL = memSpec->tCK * queryUIntParameter(timings, "PL");
|
||||
memSpec->tWR = memSpec->tCK * queryUIntParameter(timings, "WR");
|
||||
memSpec->tCCDL = memSpec->tCK * queryUIntParameter(timings, "CCDL");
|
||||
memSpec->tCCDS = memSpec->tCK * queryUIntParameter(timings, "CCDS");
|
||||
// memSpec->tCCDR = memSpec->tCK * queryUIntParameter(timings, "CCDR");
|
||||
memSpec->tWTRL = memSpec->tCK * queryUIntParameter(timings, "WTRL");
|
||||
memSpec->tWTRS = memSpec->tCK * queryUIntParameter(timings, "WTRS");
|
||||
memSpec->tRTW = memSpec->tCK * queryUIntParameter(timings, "RTW");
|
||||
memSpec->tXP = memSpec->tCK * queryUIntParameter(timings, "XP");
|
||||
memSpec->tCKE = memSpec->tCK * queryUIntParameter(timings, "CKE");
|
||||
memSpec->tPD = memSpec->tCKE;
|
||||
memSpec->tRDPDE = memSpec->tRL + memSpec->tPL
|
||||
+ (memSpec->BurstLength / memSpec->DataRate + 1) * memSpec->clk;
|
||||
+ (memSpec->burstLength / memSpec->dataRate + 1) * memSpec->tCK;
|
||||
memSpec->tWRPDE = memSpec->tWL + memSpec->tPL
|
||||
+ (memSpec->BurstLength / memSpec->DataRate + 1) * memSpec->clk + memSpec->tWR;
|
||||
+ (memSpec->burstLength / memSpec->dataRate + 1) * memSpec->tCK + memSpec->tWR;
|
||||
memSpec->tWRAPDE = memSpec->tWL + memSpec->tPL
|
||||
+ (memSpec->BurstLength / memSpec->DataRate + 1) * memSpec->clk + memSpec->tWR;
|
||||
memSpec->tCKESR = memSpec->tCKE + memSpec->clk;
|
||||
+ (memSpec->burstLength / memSpec->dataRate + 1) * memSpec->tCK + memSpec->tWR;
|
||||
memSpec->tCKESR = memSpec->tCKE + memSpec->tCK;
|
||||
memSpec->tRDSRE = memSpec->tRL + memSpec->tPL
|
||||
+ (memSpec->BurstLength / memSpec->DataRate + 1) * memSpec->clk;
|
||||
memSpec->tXS = clk * queryUIntParameter(timings, "XS");
|
||||
memSpec->tRFC = clk * queryUIntParameter(timings, "RFC");
|
||||
memSpec->tRFCSB = clk * queryUIntParameter(timings, "RFCSB");
|
||||
memSpec->tRREFD = clk * queryUIntParameter(timings, "RREFD");
|
||||
memSpec->tREFI = clk * queryUIntParameter(timings, "REFI");
|
||||
memSpec->tREFISB = clk * queryUIntParameter(timings, "REFISB");
|
||||
+ (memSpec->burstLength / memSpec->dataRate + 1) * memSpec->tCK;
|
||||
memSpec->tXS = memSpec->tCK * queryUIntParameter(timings, "XS");
|
||||
memSpec->tRFC = memSpec->tCK * queryUIntParameter(timings, "RFC");
|
||||
memSpec->tRFCSB = memSpec->tCK * queryUIntParameter(timings, "RFCSB");
|
||||
memSpec->tRREFD = memSpec->tCK * queryUIntParameter(timings, "RREFD");
|
||||
memSpec->tREFI = memSpec->tCK * queryUIntParameter(timings, "REFI");
|
||||
memSpec->tREFISB = memSpec->tCK * queryUIntParameter(timings, "REFISB");
|
||||
|
||||
// Currents and voltages
|
||||
// TODO: to be completed
|
||||
@@ -599,53 +593,52 @@ void ConfigurationLoader::loadGDDR5(Configuration &config, XMLElement *xmlSpec)
|
||||
|
||||
// MemArchitecture
|
||||
XMLElement *architecture = xmlSpec->FirstChildElement("memarchitecturespec");
|
||||
memSpec->NumberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
memSpec->BanksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
memSpec->GroupsPerRank = queryUIntParameter(architecture, "nbrOfBankGroups");
|
||||
memSpec->BanksPerGroup = memSpec->BanksPerRank / memSpec->GroupsPerRank;
|
||||
memSpec->NumberOfBanks = memSpec->BanksPerRank * memSpec->NumberOfRanks;
|
||||
memSpec->NumberOfBankGroups = memSpec->GroupsPerRank * memSpec->NumberOfRanks;
|
||||
memSpec->numberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
memSpec->banksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
memSpec->groupsPerRank = queryUIntParameter(architecture, "nbrOfBankGroups");
|
||||
memSpec->banksPerGroup = memSpec->banksPerRank / memSpec->groupsPerRank;
|
||||
memSpec->numberOfBanks = memSpec->banksPerRank * memSpec->numberOfRanks;
|
||||
memSpec->numberOfBankGroups = memSpec->groupsPerRank * memSpec->numberOfRanks;
|
||||
|
||||
// MemTimings specific for GDDR5
|
||||
XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec");
|
||||
sc_time clk = memSpec->clk;
|
||||
memSpec->tRP = clk * queryUIntParameter(timings, "RP");
|
||||
memSpec->tRAS = clk * queryUIntParameter(timings, "RAS");
|
||||
memSpec->tRC = clk * queryUIntParameter(timings, "RC");
|
||||
memSpec->tRCDRD = clk * queryUIntParameter(timings, "RCDRD");
|
||||
memSpec->tRCDWR = clk * queryUIntParameter(timings, "RCDWR");
|
||||
memSpec->tRTP = clk * queryUIntParameter(timings, "RTP");
|
||||
memSpec->tRRDS = clk * queryUIntParameter(timings, "RRDS");
|
||||
memSpec->tRRDL = clk * queryUIntParameter(timings, "RRDL");
|
||||
memSpec->tCCDS = clk * queryUIntParameter(timings, "CCDS");
|
||||
memSpec->tCCDL = clk * queryUIntParameter(timings, "CCDL");
|
||||
memSpec->tCL = clk * queryUIntParameter(timings, "CL");
|
||||
memSpec->tWCK2CKPIN = clk * queryUIntParameter(timings, "WCK2CKPIN");
|
||||
memSpec->tWCK2CK = clk * queryUIntParameter(timings, "WCK2CK");
|
||||
memSpec->tWCK2DQO = clk * queryUIntParameter(timings, "WCK2DQO");
|
||||
memSpec->tRTW = clk * queryUIntParameter(timings, "RTW");
|
||||
memSpec->tWL = clk * queryUIntParameter(timings, "WL");
|
||||
memSpec->tWCK2DQI = clk * queryUIntParameter(timings, "WCK2DQI");
|
||||
memSpec->tWR = clk * queryUIntParameter(timings, "WR");
|
||||
memSpec->tWTRS = clk * queryUIntParameter(timings, "WTRS");
|
||||
memSpec->tWTRL = clk * queryUIntParameter(timings, "WTRL");
|
||||
memSpec->tCKE = clk * queryUIntParameter(timings, "CKE");
|
||||
memSpec->tRP = memSpec->tCK * queryUIntParameter(timings, "RP");
|
||||
memSpec->tRAS = memSpec->tCK * queryUIntParameter(timings, "RAS");
|
||||
memSpec->tRC = memSpec->tCK * queryUIntParameter(timings, "RC");
|
||||
memSpec->tRCDRD = memSpec->tCK * queryUIntParameter(timings, "RCDRD");
|
||||
memSpec->tRCDWR = memSpec->tCK * queryUIntParameter(timings, "RCDWR");
|
||||
memSpec->tRTP = memSpec->tCK * queryUIntParameter(timings, "RTP");
|
||||
memSpec->tRRDS = memSpec->tCK * queryUIntParameter(timings, "RRDS");
|
||||
memSpec->tRRDL = memSpec->tCK * queryUIntParameter(timings, "RRDL");
|
||||
memSpec->tCCDS = memSpec->tCK * queryUIntParameter(timings, "CCDS");
|
||||
memSpec->tCCDL = memSpec->tCK * queryUIntParameter(timings, "CCDL");
|
||||
memSpec->tCL = memSpec->tCK * queryUIntParameter(timings, "CL");
|
||||
memSpec->tWCK2CKPIN = memSpec->tCK * queryUIntParameter(timings, "WCK2CKPIN");
|
||||
memSpec->tWCK2CK = memSpec->tCK * queryUIntParameter(timings, "WCK2CK");
|
||||
memSpec->tWCK2DQO = memSpec->tCK * queryUIntParameter(timings, "WCK2DQO");
|
||||
memSpec->tRTW = memSpec->tCK * queryUIntParameter(timings, "RTW");
|
||||
memSpec->tWL = memSpec->tCK * queryUIntParameter(timings, "WL");
|
||||
memSpec->tWCK2DQI = memSpec->tCK * queryUIntParameter(timings, "WCK2DQI");
|
||||
memSpec->tWR = memSpec->tCK * queryUIntParameter(timings, "WR");
|
||||
memSpec->tWTRS = memSpec->tCK * queryUIntParameter(timings, "WTRS");
|
||||
memSpec->tWTRL = memSpec->tCK * queryUIntParameter(timings, "WTRL");
|
||||
memSpec->tCKE = memSpec->tCK * queryUIntParameter(timings, "CKE");
|
||||
memSpec->tPD = memSpec->tCKE;
|
||||
memSpec->tXPN = clk * queryUIntParameter(timings, "XPN");
|
||||
memSpec->tREFI = clk * queryUIntParameter(timings, "REFI");
|
||||
memSpec->tREFIPB = clk * queryUIntParameter(timings, "REFIPB");
|
||||
memSpec->tRFC = clk * queryUIntParameter(timings, "RFC");
|
||||
memSpec->tRFCPB = clk * queryUIntParameter(timings, "RFCPB");
|
||||
memSpec->tRREFD = clk * queryUIntParameter(timings, "RREFD");
|
||||
memSpec->tXS = clk * queryUIntParameter(timings, "XS");
|
||||
memSpec->tFAW = clk * queryUIntParameter(timings, "FAW");
|
||||
memSpec->t32AW = clk * queryUIntParameter(timings, "32AW");
|
||||
memSpec->tXPN = memSpec->tCK * queryUIntParameter(timings, "XPN");
|
||||
memSpec->tREFI = memSpec->tCK * queryUIntParameter(timings, "REFI");
|
||||
memSpec->tREFIPB = memSpec->tCK * queryUIntParameter(timings, "REFIPB");
|
||||
memSpec->tRFC = memSpec->tCK * queryUIntParameter(timings, "RFC");
|
||||
memSpec->tRFCPB = memSpec->tCK * queryUIntParameter(timings, "RFCPB");
|
||||
memSpec->tRREFD = memSpec->tCK * queryUIntParameter(timings, "RREFD");
|
||||
memSpec->tXS = memSpec->tCK * queryUIntParameter(timings, "XS");
|
||||
memSpec->tFAW = memSpec->tCK * queryUIntParameter(timings, "FAW");
|
||||
memSpec->t32AW = memSpec->tCK * queryUIntParameter(timings, "32AW");
|
||||
memSpec->tRDSRE = memSpec->tCL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK
|
||||
+ memSpec->tWCK2DQO + memSpec->BurstLength / memSpec->DataRate * clk;
|
||||
+ memSpec->tWCK2DQO + memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
|
||||
memSpec->tWRSRE = memSpec->tWL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK
|
||||
+ memSpec->tWCK2DQI + memSpec->BurstLength / memSpec->DataRate * clk;
|
||||
memSpec->tPPD = clk * queryUIntParameter(timings, "PPD");
|
||||
memSpec->tLK = clk * queryUIntParameter(timings, "LK");
|
||||
+ memSpec->tWCK2DQI + memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
|
||||
memSpec->tPPD = memSpec->tCK * queryUIntParameter(timings, "PPD");
|
||||
memSpec->tLK = memSpec->tCK * queryUIntParameter(timings, "LK");
|
||||
|
||||
// Currents and voltages
|
||||
// TODO: to be completed
|
||||
@@ -659,53 +652,52 @@ void ConfigurationLoader::loadGDDR5X(Configuration &config, XMLElement *xmlSpec)
|
||||
|
||||
// MemArchitecture
|
||||
XMLElement *architecture = xmlSpec->FirstChildElement("memarchitecturespec");
|
||||
memSpec->NumberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
memSpec->BanksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
memSpec->GroupsPerRank = queryUIntParameter(architecture, "nbrOfBankGroups");
|
||||
memSpec->BanksPerGroup = memSpec->BanksPerRank / memSpec->GroupsPerRank;
|
||||
memSpec->NumberOfBanks = memSpec->BanksPerRank * memSpec->NumberOfRanks;
|
||||
memSpec->NumberOfBankGroups = memSpec->GroupsPerRank * memSpec->NumberOfRanks;
|
||||
memSpec->numberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
memSpec->banksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
memSpec->groupsPerRank = queryUIntParameter(architecture, "nbrOfBankGroups");
|
||||
memSpec->banksPerGroup = memSpec->banksPerRank / memSpec->groupsPerRank;
|
||||
memSpec->numberOfBanks = memSpec->banksPerRank * memSpec->numberOfRanks;
|
||||
memSpec->numberOfBankGroups = memSpec->groupsPerRank * memSpec->numberOfRanks;
|
||||
|
||||
// MemTimings specific for GDDR5X
|
||||
XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec");
|
||||
sc_time clk = memSpec->clk;
|
||||
memSpec->tRP = clk * queryUIntParameter(timings, "RP");
|
||||
memSpec->tRAS = clk * queryUIntParameter(timings, "RAS");
|
||||
memSpec->tRC = clk * queryUIntParameter(timings, "RC");
|
||||
memSpec->tRCDRD = clk * queryUIntParameter(timings, "RCDRD");
|
||||
memSpec->tRCDWR = clk * queryUIntParameter(timings, "RCDWR");
|
||||
memSpec->tRTP = clk * queryUIntParameter(timings, "RTP");
|
||||
memSpec->tRRDS = clk * queryUIntParameter(timings, "RRDS");
|
||||
memSpec->tRRDL = clk * queryUIntParameter(timings, "RRDL");
|
||||
memSpec->tCCDS = clk * queryUIntParameter(timings, "CCDS");
|
||||
memSpec->tCCDL = clk * queryUIntParameter(timings, "CCDL");
|
||||
memSpec->tRL = clk * queryUIntParameter(timings, "RL");
|
||||
memSpec->tWCK2CKPIN = clk * queryUIntParameter(timings, "WCK2CKPIN");
|
||||
memSpec->tWCK2CK = clk * queryUIntParameter(timings, "WCK2CK");
|
||||
memSpec->tWCK2DQO = clk * queryUIntParameter(timings, "WCK2DQO");
|
||||
memSpec->tRTW = clk * queryUIntParameter(timings, "RTW");
|
||||
memSpec->tWL = clk * queryUIntParameter(timings, "WL");
|
||||
memSpec->tWCK2DQI = clk * queryUIntParameter(timings, "WCK2DQI");
|
||||
memSpec->tWR = clk * queryUIntParameter(timings, "WR");
|
||||
memSpec->tWTRS = clk * queryUIntParameter(timings, "WTRS");
|
||||
memSpec->tWTRL = clk * queryUIntParameter(timings, "WTRL");
|
||||
memSpec->tCKE = clk * queryUIntParameter(timings, "CKE");
|
||||
memSpec->tRP = memSpec->tCK * queryUIntParameter(timings, "RP");
|
||||
memSpec->tRAS = memSpec->tCK * queryUIntParameter(timings, "RAS");
|
||||
memSpec->tRC = memSpec->tCK * queryUIntParameter(timings, "RC");
|
||||
memSpec->tRCDRD = memSpec->tCK * queryUIntParameter(timings, "RCDRD");
|
||||
memSpec->tRCDWR = memSpec->tCK * queryUIntParameter(timings, "RCDWR");
|
||||
memSpec->tRTP = memSpec->tCK * queryUIntParameter(timings, "RTP");
|
||||
memSpec->tRRDS = memSpec->tCK * queryUIntParameter(timings, "RRDS");
|
||||
memSpec->tRRDL = memSpec->tCK * queryUIntParameter(timings, "RRDL");
|
||||
memSpec->tCCDS = memSpec->tCK * queryUIntParameter(timings, "CCDS");
|
||||
memSpec->tCCDL = memSpec->tCK * queryUIntParameter(timings, "CCDL");
|
||||
memSpec->tRL = memSpec->tCK * queryUIntParameter(timings, "RL");
|
||||
memSpec->tWCK2CKPIN = memSpec->tCK * queryUIntParameter(timings, "WCK2CKPIN");
|
||||
memSpec->tWCK2CK = memSpec->tCK * queryUIntParameter(timings, "WCK2CK");
|
||||
memSpec->tWCK2DQO = memSpec->tCK * queryUIntParameter(timings, "WCK2DQO");
|
||||
memSpec->tRTW = memSpec->tCK * queryUIntParameter(timings, "RTW");
|
||||
memSpec->tWL = memSpec->tCK * queryUIntParameter(timings, "WL");
|
||||
memSpec->tWCK2DQI = memSpec->tCK * queryUIntParameter(timings, "WCK2DQI");
|
||||
memSpec->tWR = memSpec->tCK * queryUIntParameter(timings, "WR");
|
||||
memSpec->tWTRS = memSpec->tCK * queryUIntParameter(timings, "WTRS");
|
||||
memSpec->tWTRL = memSpec->tCK * queryUIntParameter(timings, "WTRL");
|
||||
memSpec->tCKE = memSpec->tCK * queryUIntParameter(timings, "CKE");
|
||||
memSpec->tPD = memSpec->tCKE;
|
||||
memSpec->tXP = clk * queryUIntParameter(timings, "XP");
|
||||
memSpec->tREFI = clk * queryUIntParameter(timings, "REFI");
|
||||
memSpec->tREFIPB = clk * queryUIntParameter(timings, "REFIPB");
|
||||
memSpec->tRFC = clk * queryUIntParameter(timings, "RFC");
|
||||
memSpec->tRFCPB = clk * queryUIntParameter(timings, "RFCPB");
|
||||
memSpec->tRREFD = clk * queryUIntParameter(timings, "RREFD");
|
||||
memSpec->tXS = clk * queryUIntParameter(timings, "XS");
|
||||
memSpec->tFAW = clk * queryUIntParameter(timings, "FAW");
|
||||
memSpec->t32AW = clk * queryUIntParameter(timings, "32AW");
|
||||
memSpec->tXP = memSpec->tCK * queryUIntParameter(timings, "XP");
|
||||
memSpec->tREFI = memSpec->tCK * queryUIntParameter(timings, "REFI");
|
||||
memSpec->tREFIPB = memSpec->tCK * queryUIntParameter(timings, "REFIPB");
|
||||
memSpec->tRFC = memSpec->tCK * queryUIntParameter(timings, "RFC");
|
||||
memSpec->tRFCPB = memSpec->tCK * queryUIntParameter(timings, "RFCPB");
|
||||
memSpec->tRREFD = memSpec->tCK * queryUIntParameter(timings, "RREFD");
|
||||
memSpec->tXS = memSpec->tCK * queryUIntParameter(timings, "XS");
|
||||
memSpec->tFAW = memSpec->tCK * queryUIntParameter(timings, "FAW");
|
||||
memSpec->t32AW = memSpec->tCK * queryUIntParameter(timings, "32AW");
|
||||
memSpec->tRDSRE = memSpec->tRL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK
|
||||
+ memSpec->tWCK2DQO + memSpec->BurstLength / memSpec->DataRate * clk;
|
||||
+ memSpec->tWCK2DQO + memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
|
||||
memSpec->tWRSRE = memSpec->tWL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK
|
||||
+ memSpec->tWCK2DQI + memSpec->BurstLength / memSpec->DataRate * clk;
|
||||
memSpec->tPPD = clk * queryUIntParameter(timings, "PPD");
|
||||
memSpec->tLK = clk * queryUIntParameter(timings, "LK");
|
||||
+ memSpec->tWCK2DQI + memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
|
||||
memSpec->tPPD = memSpec->tCK * queryUIntParameter(timings, "PPD");
|
||||
memSpec->tLK = memSpec->tCK * queryUIntParameter(timings, "LK");
|
||||
|
||||
// Currents and voltages
|
||||
// TODO: to be completed
|
||||
@@ -719,56 +711,55 @@ void ConfigurationLoader::loadGDDR6(Configuration &config, XMLElement *xmlSpec)
|
||||
|
||||
// MemArchitecture
|
||||
XMLElement *architecture = xmlSpec->FirstChildElement("memarchitecturespec");
|
||||
memSpec->NumberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
memSpec->BanksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
memSpec->GroupsPerRank = queryUIntParameter(architecture, "nbrOfBankGroups");
|
||||
memSpec->BanksPerGroup = memSpec->BanksPerRank / memSpec->GroupsPerRank;
|
||||
memSpec->NumberOfBanks = memSpec->BanksPerRank * memSpec->NumberOfRanks;
|
||||
memSpec->NumberOfBankGroups = memSpec->GroupsPerRank * memSpec->NumberOfRanks;
|
||||
memSpec->numberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
memSpec->banksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
memSpec->groupsPerRank = queryUIntParameter(architecture, "nbrOfBankGroups");
|
||||
memSpec->banksPerGroup = memSpec->banksPerRank / memSpec->groupsPerRank;
|
||||
memSpec->numberOfBanks = memSpec->banksPerRank * memSpec->numberOfRanks;
|
||||
memSpec->numberOfBankGroups = memSpec->groupsPerRank * memSpec->numberOfRanks;
|
||||
|
||||
// MemTimings specific for GDDR6
|
||||
XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec");
|
||||
sc_time clk = memSpec->clk;
|
||||
memSpec->tRP = clk * queryUIntParameter(timings, "RP");
|
||||
memSpec->tRAS = clk * queryUIntParameter(timings, "RAS");
|
||||
memSpec->tRC = clk * queryUIntParameter(timings, "RC");
|
||||
memSpec->tRCDRD = clk * queryUIntParameter(timings, "RCDRD");
|
||||
memSpec->tRCDWR = clk * queryUIntParameter(timings, "RCDWR");
|
||||
memSpec->tRTP = clk * queryUIntParameter(timings, "RTP");
|
||||
memSpec->tRRDS = clk * queryUIntParameter(timings, "RRDS");
|
||||
memSpec->tRRDL = clk * queryUIntParameter(timings, "RRDL");
|
||||
memSpec->tCCDS = clk * queryUIntParameter(timings, "CCDS");
|
||||
memSpec->tCCDL = clk * queryUIntParameter(timings, "CCDL");
|
||||
memSpec->tRL = clk * queryUIntParameter(timings, "RL");
|
||||
memSpec->tWCK2CKPIN = clk * queryUIntParameter(timings, "WCK2CKPIN");
|
||||
memSpec->tWCK2CK = clk * queryUIntParameter(timings, "WCK2CK");
|
||||
memSpec->tWCK2DQO = clk * queryUIntParameter(timings, "WCK2DQO");
|
||||
memSpec->tRTW = clk * queryUIntParameter(timings, "RTW");
|
||||
memSpec->tWL = clk * queryUIntParameter(timings, "WL");
|
||||
memSpec->tWCK2DQI = clk * queryUIntParameter(timings, "WCK2DQI");
|
||||
memSpec->tWR = clk * queryUIntParameter(timings, "WR");
|
||||
memSpec->tWTRS = clk * queryUIntParameter(timings, "WTRS");
|
||||
memSpec->tWTRL = clk * queryUIntParameter(timings, "WTRL");
|
||||
memSpec->tCKE = clk * queryUIntParameter(timings, "CKE");
|
||||
memSpec->tRP = memSpec->tCK * queryUIntParameter(timings, "RP");
|
||||
memSpec->tRAS = memSpec->tCK * queryUIntParameter(timings, "RAS");
|
||||
memSpec->tRC = memSpec->tCK * queryUIntParameter(timings, "RC");
|
||||
memSpec->tRCDRD = memSpec->tCK * queryUIntParameter(timings, "RCDRD");
|
||||
memSpec->tRCDWR = memSpec->tCK * queryUIntParameter(timings, "RCDWR");
|
||||
memSpec->tRTP = memSpec->tCK * queryUIntParameter(timings, "RTP");
|
||||
memSpec->tRRDS = memSpec->tCK * queryUIntParameter(timings, "RRDS");
|
||||
memSpec->tRRDL = memSpec->tCK * queryUIntParameter(timings, "RRDL");
|
||||
memSpec->tCCDS = memSpec->tCK * queryUIntParameter(timings, "CCDS");
|
||||
memSpec->tCCDL = memSpec->tCK * queryUIntParameter(timings, "CCDL");
|
||||
memSpec->tRL = memSpec->tCK * queryUIntParameter(timings, "RL");
|
||||
memSpec->tWCK2CKPIN = memSpec->tCK * queryUIntParameter(timings, "WCK2CKPIN");
|
||||
memSpec->tWCK2CK = memSpec->tCK * queryUIntParameter(timings, "WCK2CK");
|
||||
memSpec->tWCK2DQO = memSpec->tCK * queryUIntParameter(timings, "WCK2DQO");
|
||||
memSpec->tRTW = memSpec->tCK * queryUIntParameter(timings, "RTW");
|
||||
memSpec->tWL = memSpec->tCK * queryUIntParameter(timings, "WL");
|
||||
memSpec->tWCK2DQI = memSpec->tCK * queryUIntParameter(timings, "WCK2DQI");
|
||||
memSpec->tWR = memSpec->tCK * queryUIntParameter(timings, "WR");
|
||||
memSpec->tWTRS = memSpec->tCK * queryUIntParameter(timings, "WTRS");
|
||||
memSpec->tWTRL = memSpec->tCK * queryUIntParameter(timings, "WTRL");
|
||||
memSpec->tCKE = memSpec->tCK * queryUIntParameter(timings, "CKE");
|
||||
memSpec->tPD = memSpec->tCKE;
|
||||
memSpec->tCKESR = clk * queryUIntParameter(timings, "CKESR");
|
||||
memSpec->tXP = clk * queryUIntParameter(timings, "XP");
|
||||
memSpec->tREFI = clk * queryUIntParameter(timings, "REFI");
|
||||
memSpec->tREFIPB = clk * queryUIntParameter(timings, "REFIPB");
|
||||
memSpec->tRFC = clk * queryUIntParameter(timings, "RFC");
|
||||
memSpec->tRFCPB = clk * queryUIntParameter(timings, "RFCPB");
|
||||
memSpec->tRREFD = clk * queryUIntParameter(timings, "RREFD");
|
||||
memSpec->tXS = clk * queryUIntParameter(timings, "XS");
|
||||
memSpec->tFAW = clk * queryUIntParameter(timings, "FAW");
|
||||
memSpec->tCKESR = memSpec->tCK * queryUIntParameter(timings, "CKESR");
|
||||
memSpec->tXP = memSpec->tCK * queryUIntParameter(timings, "XP");
|
||||
memSpec->tREFI = memSpec->tCK * queryUIntParameter(timings, "REFI");
|
||||
memSpec->tREFIPB = memSpec->tCK * queryUIntParameter(timings, "REFIPB");
|
||||
memSpec->tRFC = memSpec->tCK * queryUIntParameter(timings, "RFC");
|
||||
memSpec->tRFCPB = memSpec->tCK * queryUIntParameter(timings, "RFCPB");
|
||||
memSpec->tRREFD = memSpec->tCK * queryUIntParameter(timings, "RREFD");
|
||||
memSpec->tXS = memSpec->tCK * queryUIntParameter(timings, "XS");
|
||||
memSpec->tFAW = memSpec->tCK * queryUIntParameter(timings, "FAW");
|
||||
memSpec->tRDSRE = memSpec->tRL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK
|
||||
+ memSpec->tWCK2DQO + memSpec->BurstLength / memSpec->DataRate * clk;
|
||||
+ memSpec->tWCK2DQO + memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
|
||||
memSpec->tWRSRE = memSpec->tWL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK
|
||||
+ memSpec->tWCK2DQI + memSpec->BurstLength / memSpec->DataRate * clk;
|
||||
memSpec->tPPD = clk * queryUIntParameter(timings, "PPD");
|
||||
memSpec->tLK = clk * queryUIntParameter(timings, "LK");
|
||||
memSpec->tACTPDE = clk * queryUIntParameter(timings, "ACTPDE");
|
||||
memSpec->tPREPDE = clk * queryUIntParameter(timings, "PREPDE");
|
||||
memSpec->tREFPDE = clk * queryUIntParameter(timings, "REFPDE");
|
||||
+ memSpec->tWCK2DQI + memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
|
||||
memSpec->tPPD = memSpec->tCK * queryUIntParameter(timings, "PPD");
|
||||
memSpec->tLK = memSpec->tCK * queryUIntParameter(timings, "LK");
|
||||
memSpec->tACTPDE = memSpec->tCK * queryUIntParameter(timings, "ACTPDE");
|
||||
memSpec->tPREPDE = memSpec->tCK * queryUIntParameter(timings, "PREPDE");
|
||||
memSpec->tREFPDE = memSpec->tCK * queryUIntParameter(timings, "REFPDE");
|
||||
|
||||
// Currents and voltages
|
||||
// TODO: to be completed
|
||||
|
||||
@@ -44,44 +44,10 @@ using namespace tlm;
|
||||
|
||||
MemSpec::MemSpec()
|
||||
{
|
||||
commandLength = std::vector<unsigned>(numberOfCommands(), 1);
|
||||
commandLengthInCycles = std::vector<unsigned>(numberOfCommands(), 1);
|
||||
}
|
||||
|
||||
const std::vector<Bank> &MemSpec::getBanks() const
|
||||
sc_time MemSpec::getCommandLength(Command command) const
|
||||
{
|
||||
static std::vector<Bank> banks;
|
||||
if (banks.size() == 0) {
|
||||
for (unsigned int i = 0; i < NumberOfBanks; i++)
|
||||
banks.push_back(Bank(i));
|
||||
}
|
||||
return banks;
|
||||
return tCK * commandLengthInCycles[command];
|
||||
}
|
||||
|
||||
sc_time MemSpec::getReadAccessTime() const
|
||||
{
|
||||
return clk * (BurstLength / DataRate);
|
||||
}
|
||||
|
||||
sc_time MemSpec::getWriteAccessTime() const
|
||||
{
|
||||
return clk * (BurstLength / DataRate);
|
||||
}
|
||||
|
||||
unsigned MemSpec::getCommandLength(Command command) const
|
||||
{
|
||||
return commandLength[command];
|
||||
}
|
||||
|
||||
//sc_time MemSpec::getMinExecutionTimeForPowerDownCmd(Command command) const
|
||||
//{
|
||||
// if (command == Command::PDEA || command == Command::PDEP)
|
||||
// return tCKE;
|
||||
// else if (command == Command::SREFEN)
|
||||
// return tCKESR;
|
||||
// else
|
||||
// {
|
||||
// SC_REPORT_FATAL("getMinimalExecutionTime",
|
||||
// "command is not know or command has a fixed execution time");
|
||||
// return SC_ZERO_TIME;
|
||||
// }
|
||||
//}
|
||||
|
||||
@@ -44,51 +44,43 @@
|
||||
#include "../../controller/Command.h"
|
||||
#include "../../common/utils.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
struct MemSpec
|
||||
{
|
||||
MemSpec();
|
||||
virtual ~MemSpec() {}
|
||||
|
||||
const std::vector<Bank> &getBanks() const;
|
||||
|
||||
sc_time getWriteAccessTime() const;
|
||||
sc_time getReadAccessTime() const;
|
||||
|
||||
virtual sc_time getRefreshIntervalAB() const = 0;
|
||||
virtual sc_time getRefreshIntervalPB() const = 0;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm_generic_payload &) const = 0;
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const = 0;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const = 0;
|
||||
|
||||
unsigned getCommandLength(Command) const;
|
||||
sc_time getCommandLength(Command) const;
|
||||
|
||||
// Returns the minimum execution time for commands that have a variable execution time
|
||||
//virtual sc_time getMinExecutionTimeForPowerDownCmd(Command command) const = 0;
|
||||
std::string memoryId = "not defined.";
|
||||
std::string memoryType = "not defined.";
|
||||
|
||||
std::string MemoryId = "not defined.";
|
||||
std::string MemoryType = "not defined.";
|
||||
|
||||
unsigned int NumberOfRanks;
|
||||
unsigned int NumberOfBankGroups;
|
||||
unsigned int NumberOfBanks;
|
||||
unsigned int NumberOfRows;
|
||||
unsigned int NumberOfColumns;
|
||||
unsigned int BurstLength;
|
||||
unsigned int DataRate;
|
||||
unsigned int numberOfRanks;
|
||||
unsigned int numberOfBankGroups;
|
||||
unsigned int numberOfBanks;
|
||||
unsigned int numberOfRows;
|
||||
unsigned int numberOfColumns;
|
||||
unsigned int burstLength;
|
||||
unsigned int dataRate;
|
||||
unsigned int bitWidth;
|
||||
|
||||
unsigned int BanksPerRank;
|
||||
unsigned int BanksPerGroup;
|
||||
unsigned int GroupsPerRank;
|
||||
unsigned int banksPerRank;
|
||||
unsigned int banksPerGroup;
|
||||
unsigned int groupsPerRank;
|
||||
|
||||
// Clock
|
||||
double clkMHz;
|
||||
sc_time clk;
|
||||
double fCKMHz;
|
||||
sc_time tCK;
|
||||
|
||||
// Command lengths on bus, standardly one clock cycle
|
||||
std::vector<unsigned> commandLength;
|
||||
sc_time burstDuration;
|
||||
|
||||
// Command lengths on bus, usually one clock cycle
|
||||
std::vector<unsigned> commandLengthInCycles;
|
||||
};
|
||||
|
||||
#endif // MEMSPEC_H
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
|
||||
#include "MemSpecDDR3.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
sc_time MemSpecDDR3::getRefreshIntervalAB() const
|
||||
{
|
||||
return tREFI;
|
||||
@@ -53,16 +55,16 @@ sc_time MemSpecDDR3::getExecutionTime(Command command, const tlm_generic_payload
|
||||
return tRP;
|
||||
else if (command == Command::ACT)
|
||||
return tRCD;
|
||||
else if (command == Command::RD || command == Command::RDA)
|
||||
return tRL + getReadAccessTime();
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
return tWL + getWriteAccessTime();
|
||||
else if (command == Command::RD)
|
||||
return tRL + burstDuration;
|
||||
else if (command == Command::RDA)
|
||||
return tRTP + tRP;
|
||||
else if (command == Command::WR)
|
||||
return tWL + burstDuration;
|
||||
else if (command == Command::WRA)
|
||||
return tWL + burstDuration + tWR + tRP;
|
||||
else if (command == Command::REFA)
|
||||
return tRFC;
|
||||
else if (command == Command::REFB)
|
||||
return tRFC;
|
||||
else if (command == Command::PDXA || command == Command::PDXP || command == Command::SREFEX)
|
||||
return clk;
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("getExecutionTime",
|
||||
@@ -74,9 +76,9 @@ sc_time MemSpecDDR3::getExecutionTime(Command command, const tlm_generic_payload
|
||||
TimeInterval MemSpecDDR3::getIntervalOnDataStrobe(Command command) const
|
||||
{
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
return TimeInterval(sc_time_stamp() + tRL, sc_time_stamp() + tRL + getReadAccessTime());
|
||||
return TimeInterval(sc_time_stamp() + tRL, sc_time_stamp() + tRL + burstDuration);
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
return TimeInterval(sc_time_stamp() + tWL, sc_time_stamp() + tWL + getWriteAccessTime());
|
||||
return TimeInterval(sc_time_stamp() + tWL, sc_time_stamp() + tWL + burstDuration);
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpec", "Method was called with invalid argument");
|
||||
|
||||
@@ -81,7 +81,7 @@ struct MemSpecDDR3 final : public MemSpec
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm_generic_payload &) const override;
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
|
||||
#include "MemSpecDDR4.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
sc_time MemSpecDDR4::getRefreshIntervalAB() const
|
||||
{
|
||||
return tREFI;
|
||||
@@ -53,14 +55,16 @@ sc_time MemSpecDDR4::getExecutionTime(Command command, const tlm_generic_payload
|
||||
return tRP;
|
||||
else if (command == Command::ACT)
|
||||
return tRCD;
|
||||
else if (command == Command::RD || command == Command::RDA)
|
||||
return tRL + getReadAccessTime();
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
return tWL + getWriteAccessTime();
|
||||
else if (command == Command::RD)
|
||||
return tRL + burstDuration;
|
||||
else if (command == Command::RDA)
|
||||
return tRTP + tRP;
|
||||
else if (command == Command::WR)
|
||||
return tWL + burstDuration;
|
||||
else if (command == Command::WRA)
|
||||
return tWL + burstDuration + tWR + tRP;
|
||||
else if (command == Command::REFA)
|
||||
return tRFC;
|
||||
else if (command == Command::REFB)
|
||||
return tRFC;
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("getExecutionTime",
|
||||
@@ -72,9 +76,9 @@ sc_time MemSpecDDR4::getExecutionTime(Command command, const tlm_generic_payload
|
||||
TimeInterval MemSpecDDR4::getIntervalOnDataStrobe(Command command) const
|
||||
{
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
return TimeInterval(sc_time_stamp() + tRL, sc_time_stamp() + tRL + getReadAccessTime());
|
||||
return TimeInterval(sc_time_stamp() + tRL, sc_time_stamp() + tRL + burstDuration);
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
return TimeInterval(sc_time_stamp() + tWL, sc_time_stamp() + tWL + getWriteAccessTime());
|
||||
return TimeInterval(sc_time_stamp() + tWL, sc_time_stamp() + tWL + burstDuration);
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpec", "Method was called with invalid argument");
|
||||
|
||||
@@ -87,7 +87,7 @@ struct MemSpecDDR4 final : public MemSpec
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm_generic_payload &) const override;
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
|
||||
#include "MemSpecGDDR5.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
sc_time MemSpecGDDR5::getRefreshIntervalAB() const
|
||||
{
|
||||
return tREFI;
|
||||
@@ -52,14 +54,18 @@ sc_time MemSpecGDDR5::getExecutionTime(Command command, const tlm_generic_payloa
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
if (payload.get_command() == TLM_READ_COMMAND)
|
||||
return tRCDRD + clk;
|
||||
return tRCDRD;
|
||||
else
|
||||
return tRCDWR + clk;
|
||||
return tRCDWR;
|
||||
}
|
||||
else if (command == Command::RD || command == Command::RDA)
|
||||
return tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + getReadAccessTime();
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
return tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + getWriteAccessTime();
|
||||
else if (command == Command::RD)
|
||||
return tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + burstDuration;
|
||||
else if (command == Command::RDA)
|
||||
return tRTP + tRP;
|
||||
else if (command == Command::WR)
|
||||
return tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + burstDuration;
|
||||
else if (command == Command::WRA)
|
||||
return tWL + burstDuration + tWR + tRP;
|
||||
else if (command == Command::REFA)
|
||||
return tRFC;
|
||||
else if (command == Command::REFB)
|
||||
@@ -76,10 +82,10 @@ TimeInterval MemSpecGDDR5::getIntervalOnDataStrobe(Command command) const
|
||||
{
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
return TimeInterval(sc_time_stamp() + tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO,
|
||||
sc_time_stamp() + tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + getReadAccessTime());
|
||||
sc_time_stamp() + tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + burstDuration);
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
return TimeInterval(sc_time_stamp() + tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI,
|
||||
sc_time_stamp() + tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + getWriteAccessTime());
|
||||
sc_time_stamp() + tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + burstDuration);
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpecGDDR5", "Method was called with invalid argument");
|
||||
|
||||
@@ -83,7 +83,7 @@ struct MemSpecGDDR5 final : public MemSpec
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm_generic_payload &) const override;
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
|
||||
#include "MemSpecGDDR5X.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
sc_time MemSpecGDDR5X::getRefreshIntervalAB() const
|
||||
{
|
||||
return tREFI;
|
||||
@@ -52,14 +54,18 @@ sc_time MemSpecGDDR5X::getExecutionTime(Command command, const tlm_generic_paylo
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
if (payload.get_command() == TLM_READ_COMMAND)
|
||||
return tRCDRD + clk;
|
||||
return tRCDRD;
|
||||
else
|
||||
return tRCDWR + clk;
|
||||
return tRCDWR;
|
||||
}
|
||||
else if (command == Command::RD || command == Command::RDA)
|
||||
return tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + getReadAccessTime();
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
return tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + getWriteAccessTime();
|
||||
else if (command == Command::RD)
|
||||
return tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + burstDuration;
|
||||
else if (command == Command::RDA)
|
||||
return tRTP + tRP;
|
||||
else if (command == Command::WR)
|
||||
return tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + burstDuration;
|
||||
else if (command == Command::WRA)
|
||||
return tWL + burstDuration + tWR + tRP;
|
||||
else if (command == Command::REFA)
|
||||
return tRFC;
|
||||
else if (command == Command::REFB)
|
||||
@@ -76,10 +82,10 @@ TimeInterval MemSpecGDDR5X::getIntervalOnDataStrobe(Command command) const
|
||||
{
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
return TimeInterval(sc_time_stamp() + tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO,
|
||||
sc_time_stamp() + tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + getReadAccessTime());
|
||||
sc_time_stamp() + tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + burstDuration);
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
return TimeInterval(sc_time_stamp() + tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI,
|
||||
sc_time_stamp() + tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + getWriteAccessTime());
|
||||
sc_time_stamp() + tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + burstDuration);
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpecGDDR5X", "Method was called with invalid argument");
|
||||
|
||||
@@ -83,7 +83,7 @@ struct MemSpecGDDR5X final : public MemSpec
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm_generic_payload &) const override;
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
|
||||
#include "MemSpecGDDR6.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
sc_time MemSpecGDDR6::getRefreshIntervalAB() const
|
||||
{
|
||||
return tREFI;
|
||||
@@ -52,14 +54,18 @@ sc_time MemSpecGDDR6::getExecutionTime(Command command, const tlm_generic_payloa
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
if (payload.get_command() == TLM_READ_COMMAND)
|
||||
return tRCDRD + clk;
|
||||
return tRCDRD + tCK;
|
||||
else
|
||||
return tRCDWR + clk;
|
||||
return tRCDWR + tCK;
|
||||
}
|
||||
else if (command == Command::RD || command == Command::RDA)
|
||||
return tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + getReadAccessTime();
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
return tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + getWriteAccessTime();
|
||||
else if (command == Command::RD)
|
||||
return tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + burstDuration;
|
||||
else if (command == Command::RDA)
|
||||
return tRTP + tRP;
|
||||
else if (command == Command::WR)
|
||||
return tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + burstDuration;
|
||||
else if (command == Command::WRA)
|
||||
return tWL + burstDuration + tWR + tRP;
|
||||
else if (command == Command::REFA)
|
||||
return tRFC;
|
||||
else if (command == Command::REFB)
|
||||
@@ -76,10 +82,10 @@ TimeInterval MemSpecGDDR6::getIntervalOnDataStrobe(Command command) const
|
||||
{
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
return TimeInterval(sc_time_stamp() + tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO,
|
||||
sc_time_stamp() + tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + getReadAccessTime());
|
||||
sc_time_stamp() + tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + burstDuration);
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
return TimeInterval(sc_time_stamp() + tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI,
|
||||
sc_time_stamp() + tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + getWriteAccessTime());
|
||||
sc_time_stamp() + tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + burstDuration);
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpecGDDR6", "Method was called with invalid argument");
|
||||
|
||||
@@ -86,7 +86,7 @@ struct MemSpecGDDR6 final : public MemSpec
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm_generic_payload &) const override;
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -35,9 +35,11 @@
|
||||
|
||||
#include "MemSpecHBM2.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
MemSpecHBM2::MemSpecHBM2()
|
||||
{
|
||||
commandLength[Command::ACT] = 2;
|
||||
commandLengthInCycles[Command::ACT] = 2;
|
||||
}
|
||||
|
||||
sc_time MemSpecHBM2::getRefreshIntervalAB() const
|
||||
@@ -57,14 +59,18 @@ sc_time MemSpecHBM2::getExecutionTime(Command command, const tlm_generic_payload
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
if (payload.get_command() == TLM_READ_COMMAND)
|
||||
return tRCDRD + clk;
|
||||
return tRCDRD + tCK;
|
||||
else
|
||||
return tRCDWR + clk;
|
||||
return tRCDWR + tCK;
|
||||
}
|
||||
else if (command == Command::RD || command == Command::RDA)
|
||||
return tRL + tDQSCK + getReadAccessTime();
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
return tWL + getWriteAccessTime();
|
||||
else if (command == Command::RD)
|
||||
return tRL + tDQSCK + burstDuration;
|
||||
else if (command == Command::RDA)
|
||||
return tRTP + tRP;
|
||||
else if (command == Command::WR)
|
||||
return tWL + burstDuration;
|
||||
else if (command == Command::WRA)
|
||||
return tWL + burstDuration + tWR + tRP;
|
||||
else if (command == Command::REFA)
|
||||
return tRFC;
|
||||
else if (command == Command::REFB)
|
||||
@@ -81,10 +87,10 @@ TimeInterval MemSpecHBM2::getIntervalOnDataStrobe(Command command) const
|
||||
{
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
return TimeInterval(sc_time_stamp() + tRL + tDQSCK,
|
||||
sc_time_stamp() + tRL + tDQSCK + getReadAccessTime());
|
||||
sc_time_stamp() + tRL + tDQSCK + burstDuration);
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
return TimeInterval(sc_time_stamp() + tWL,
|
||||
sc_time_stamp() + tWL + getWriteAccessTime());
|
||||
sc_time_stamp() + tWL + burstDuration);
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpecHBM2", "Method was called with invalid argument");
|
||||
|
||||
@@ -67,11 +67,11 @@ struct MemSpecHBM2 final : public MemSpec
|
||||
sc_time tXP;
|
||||
sc_time tCKE;
|
||||
sc_time tPD; // = tCKE;
|
||||
sc_time tRDPDE; // = tRL + tPL + (BurstLength / DataRate) * clk + clk;
|
||||
sc_time tWRPDE; // = tWL + tPL + (BurstLength / DataRate) * clk + clk + tWR;
|
||||
sc_time tWRAPDE; // = tWL + tPL + (BurstLength / DataRate) * clk + clk + tWR;
|
||||
sc_time tCKESR; // = tCKE + clk;
|
||||
sc_time tRDSRE; // = tRL + tPL + (BurstLength / DataRate) * clk + clk;
|
||||
sc_time tRDPDE; // = tRL + tPL + (BurstLength / DataRate) * tCK + tCK;
|
||||
sc_time tWRPDE; // = tWL + tPL + (BurstLength / DataRate) * tCK + tCK + tWR;
|
||||
sc_time tWRAPDE; // = tWL + tPL + (BurstLength / DataRate) * tCK + tCK + tWR;
|
||||
sc_time tCKESR; // = tCKE + tCK;
|
||||
sc_time tRDSRE; // = tRL + tPL + (BurstLength / DataRate) * tCK + tCK;
|
||||
sc_time tXS;
|
||||
sc_time tRFC;
|
||||
sc_time tRFCSB;
|
||||
@@ -85,7 +85,7 @@ struct MemSpecHBM2 final : public MemSpec
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm_generic_payload &) const override;
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -35,19 +35,21 @@
|
||||
|
||||
#include "MemSpecLPDDR4.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
MemSpecLPDDR4::MemSpecLPDDR4()
|
||||
{
|
||||
commandLength[Command::ACT] = 4;
|
||||
commandLength[Command::PRE] = 2;
|
||||
commandLength[Command::PREA] = 2;
|
||||
commandLength[Command::RD] = 4;
|
||||
commandLength[Command::RDA] = 4;
|
||||
commandLength[Command::WR] = 4;
|
||||
commandLength[Command::WRA] = 4;
|
||||
commandLength[Command::REFA] = 2;
|
||||
commandLength[Command::REFB] = 2;
|
||||
commandLength[Command::SREFEN] = 2;
|
||||
commandLength[Command::SREFEX] = 2;
|
||||
commandLengthInCycles[Command::ACT] = 4;
|
||||
commandLengthInCycles[Command::PRE] = 2;
|
||||
commandLengthInCycles[Command::PREA] = 2;
|
||||
commandLengthInCycles[Command::RD] = 4;
|
||||
commandLengthInCycles[Command::RDA] = 4;
|
||||
commandLengthInCycles[Command::WR] = 4;
|
||||
commandLengthInCycles[Command::WRA] = 4;
|
||||
commandLengthInCycles[Command::REFA] = 2;
|
||||
commandLengthInCycles[Command::REFB] = 2;
|
||||
commandLengthInCycles[Command::SREFEN] = 2;
|
||||
commandLengthInCycles[Command::SREFEX] = 2;
|
||||
}
|
||||
|
||||
sc_time MemSpecLPDDR4::getRefreshIntervalAB() const
|
||||
@@ -63,19 +65,23 @@ sc_time MemSpecLPDDR4::getRefreshIntervalPB() const
|
||||
sc_time MemSpecLPDDR4::getExecutionTime(Command command, const tlm_generic_payload &) const
|
||||
{
|
||||
if (command == Command::PRE)
|
||||
return tRPpb + clk;
|
||||
return tRPpb + tCK;
|
||||
else if (command == Command::PREA)
|
||||
return tRPab + clk;
|
||||
return tRPab + tCK;
|
||||
else if (command == Command::ACT)
|
||||
return tRCD + 3 * clk;
|
||||
else if (command == Command::RD || command == Command::RDA)
|
||||
return tRL + tDQSCK + getReadAccessTime() + 3 * clk;
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
return tWL + tDQSS + tDQS2DQ + getWriteAccessTime() + 3 * clk;
|
||||
return tRCD + 3 * tCK;
|
||||
else if (command == Command::RD)
|
||||
return tRL + tDQSCK + burstDuration + 3 * tCK;
|
||||
else if (command == Command::RDA)
|
||||
return burstDuration + tRTP - 5 * tCK + tRPpb;
|
||||
else if (command == Command::WR)
|
||||
return tWL + tDQSS + tDQS2DQ + burstDuration + 3 * tCK;
|
||||
else if (command == Command::WRA)
|
||||
return tWL + 4 * tCK + burstDuration + tWR + tRPpb;
|
||||
else if (command == Command::REFA)
|
||||
return tRFCab + clk;
|
||||
return tRFCab + tCK;
|
||||
else if (command == Command::REFB)
|
||||
return tRFCpb + clk;
|
||||
return tRFCpb + tCK;
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("getExecutionTime",
|
||||
@@ -87,11 +93,11 @@ sc_time MemSpecLPDDR4::getExecutionTime(Command command, const tlm_generic_paylo
|
||||
TimeInterval MemSpecLPDDR4::getIntervalOnDataStrobe(Command command) const
|
||||
{
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
return TimeInterval(sc_time_stamp() + tRL + tDQSCK + 3 * clk,
|
||||
sc_time_stamp() + tRL + tDQSCK + getReadAccessTime() + 3 * clk);
|
||||
return TimeInterval(sc_time_stamp() + tRL + tDQSCK + 3 * tCK,
|
||||
sc_time_stamp() + tRL + tDQSCK + burstDuration + 3 * tCK);
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
return TimeInterval(sc_time_stamp() + tWL + tDQSS + tDQS2DQ + 3 * clk,
|
||||
sc_time_stamp() + tWL + tDQSS + tDQS2DQ + getWriteAccessTime() + 3 * clk);
|
||||
return TimeInterval(sc_time_stamp() + tWL + tDQSS + tDQS2DQ + 3 * tCK,
|
||||
sc_time_stamp() + tWL + tDQSS + tDQS2DQ + burstDuration + 3 * tCK);
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpecLPDDR4", "Method was called with invalid argument");
|
||||
|
||||
@@ -78,7 +78,7 @@ struct MemSpecLPDDR4 final : public MemSpec
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm_generic_payload &) const override;
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
|
||||
#include "MemSpecWideIO.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
sc_time MemSpecWideIO::getRefreshIntervalAB() const
|
||||
{
|
||||
return tREFI;
|
||||
@@ -53,10 +55,14 @@ sc_time MemSpecWideIO::getExecutionTime(Command command, const tlm_generic_paylo
|
||||
return tRP;
|
||||
else if (command == Command::ACT)
|
||||
return tRCD;
|
||||
else if (command == Command::RD || command == Command::RDA)
|
||||
return tRL + tAC + getReadAccessTime();
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
return tWL + getWriteAccessTime();
|
||||
else if (command == Command::RD)
|
||||
return tRL + tAC + burstDuration;
|
||||
else if (command == Command::RDA)
|
||||
return burstDuration + tRP;
|
||||
else if (command == Command::WR)
|
||||
return tWL + burstDuration;
|
||||
else if (command == Command::WRA)
|
||||
return tWL + burstDuration - tCK + tWR + tRP;
|
||||
else if (command == Command::REFA)
|
||||
return tRFC;
|
||||
else
|
||||
@@ -71,10 +77,10 @@ TimeInterval MemSpecWideIO::getIntervalOnDataStrobe(Command command) const
|
||||
{
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
return TimeInterval(sc_time_stamp() + tRL + tAC,
|
||||
sc_time_stamp() + tRL + tAC + getReadAccessTime());
|
||||
sc_time_stamp() + tRL + tAC + burstDuration);
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
return TimeInterval(sc_time_stamp() + tWL,
|
||||
sc_time_stamp() + tWL + getWriteAccessTime());
|
||||
sc_time_stamp() + tWL + burstDuration);
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpec", "Method was called with invalid argument");
|
||||
|
||||
@@ -91,7 +91,7 @@ struct MemSpecWideIO final : public MemSpec
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm_generic_payload &) const override;
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
|
||||
#include "MemSpecWideIO2.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
sc_time MemSpecWideIO2::getRefreshIntervalAB() const
|
||||
{
|
||||
return tREFI;
|
||||
@@ -54,10 +56,14 @@ sc_time MemSpecWideIO2::getExecutionTime(Command command, const tlm_generic_payl
|
||||
return tRPab;
|
||||
else if (command == Command::ACT)
|
||||
return tRCD;
|
||||
else if (command == Command::RD || command == Command::RDA)
|
||||
return tRL + tDQSCK + getReadAccessTime();
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
return tWL + tDQSS + getWriteAccessTime();
|
||||
else if (command == Command::RD)
|
||||
return tRL + tDQSCK + burstDuration;
|
||||
else if (command == Command::RDA)
|
||||
return burstDuration - 2 * tCK + tRTP + tRPpb;
|
||||
else if (command == Command::WR)
|
||||
return tWL + tDQSS + burstDuration;
|
||||
else if (command == Command::WRA)
|
||||
return tWL + burstDuration + tCK + tWR + tRPpb;
|
||||
else if (command == Command::REFA)
|
||||
return tRFCab;
|
||||
else if (command == Command::REFB)
|
||||
@@ -74,10 +80,10 @@ TimeInterval MemSpecWideIO2::getIntervalOnDataStrobe(Command command) const
|
||||
{
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
return TimeInterval(sc_time_stamp() + tRL + tDQSCK,
|
||||
sc_time_stamp() + tRL + tDQSCK + getReadAccessTime());
|
||||
sc_time_stamp() + tRL + tDQSCK + burstDuration);
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
return TimeInterval(sc_time_stamp() + tWL + tDQSS,
|
||||
sc_time_stamp() + tWL + tDQSS + getWriteAccessTime());
|
||||
sc_time_stamp() + tWL + tDQSS + burstDuration);
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpec", "Method was called with invalid argument");
|
||||
|
||||
@@ -72,7 +72,7 @@ struct MemSpecWideIO2 final : public MemSpec
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm_generic_payload &) const override;
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -34,12 +34,14 @@
|
||||
|
||||
#include "BankMachine.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
BankMachine::BankMachine(SchedulerIF *scheduler, CheckerIF *checker, Bank bank)
|
||||
: scheduler(scheduler), checker(checker), bank(bank)
|
||||
{
|
||||
MemSpec *memSpec = Configuration::getInstance().memSpec;
|
||||
rank = Rank(bank.ID() / memSpec->BanksPerRank);
|
||||
bankgroup = BankGroup(bank.ID() / memSpec->BanksPerGroup);
|
||||
rank = Rank(bank.ID() / memSpec->banksPerRank);
|
||||
bankgroup = BankGroup(bank.ID() / memSpec->banksPerGroup);
|
||||
}
|
||||
|
||||
std::pair<Command, tlm_generic_payload *> BankMachine::getNextCommand()
|
||||
@@ -52,29 +54,33 @@ std::pair<Command, tlm_generic_payload *> BankMachine::getNextCommand()
|
||||
|
||||
void BankMachine::updateState(Command command)
|
||||
{
|
||||
if (command == Command::ACT)
|
||||
switch (command)
|
||||
{
|
||||
case Command::ACT:
|
||||
currentState = BmState::Activated;
|
||||
currentRow = DramExtension::getRow(currentPayload);
|
||||
}
|
||||
else if (command == Command::PRE || command == Command::PREA)
|
||||
break;
|
||||
case Command::PRE: case Command::PREA:
|
||||
currentState = BmState::Precharged;
|
||||
else if (command == Command::RD || command == Command::WR)
|
||||
break;
|
||||
case Command::RD: case Command::WR:
|
||||
currentPayload = nullptr;
|
||||
else if (command == Command::RDA || command == Command::WRA)
|
||||
{
|
||||
break;
|
||||
case Command::RDA: case Command::WRA:
|
||||
currentState = BmState::Precharged;
|
||||
currentPayload = nullptr;
|
||||
}
|
||||
else if (command == Command::PDEA || command == Command::PDEP || command == Command::SREFEN)
|
||||
break;
|
||||
case Command::PDEA: case Command::PDEP: case Command::SREFEN:
|
||||
sleeping = true;
|
||||
else if (command == Command::REFA || command == Command::REFB)
|
||||
{
|
||||
break;
|
||||
case Command::REFA: case Command::REFB:
|
||||
sleeping = false;
|
||||
blocked = false;
|
||||
}
|
||||
else if (command == Command::PDXA || command == Command::PDXP)
|
||||
break;
|
||||
case Command::PDXA: case Command::PDXP:
|
||||
sleeping = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void BankMachine::block()
|
||||
@@ -118,21 +124,17 @@ BankMachineOpen::BankMachineOpen(SchedulerIF *scheduler, CheckerIF *checker, Ban
|
||||
sc_time BankMachineOpen::start()
|
||||
{
|
||||
timeToSchedule = sc_max_time();
|
||||
sc_time delay = sc_max_time() - sc_time_stamp();
|
||||
|
||||
if (sleeping)
|
||||
return delay;
|
||||
return timeToSchedule;
|
||||
|
||||
currentPayload = scheduler->getNextRequest(this);
|
||||
if (currentPayload == nullptr)
|
||||
{
|
||||
currentPayload = scheduler->getNextRequest(this);
|
||||
if (currentPayload == nullptr)
|
||||
return delay;
|
||||
}
|
||||
return timeToSchedule;
|
||||
|
||||
if (currentState == BmState::Precharged && !blocked) // row miss
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::ACT, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::ACT, rank, bankgroup, bank);
|
||||
nextCommand = Command::ACT;
|
||||
}
|
||||
else if (currentState == BmState::Activated)
|
||||
@@ -141,12 +143,12 @@ sc_time BankMachineOpen::start()
|
||||
{
|
||||
if (currentPayload->get_command() == TLM_READ_COMMAND)
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::RD, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::RD, rank, bankgroup, bank);
|
||||
nextCommand = Command::RD;
|
||||
}
|
||||
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::WR, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::WR, rank, bankgroup, bank);
|
||||
nextCommand = Command::WR;
|
||||
}
|
||||
else
|
||||
@@ -154,13 +156,11 @@ sc_time BankMachineOpen::start()
|
||||
}
|
||||
else if (!blocked) // row miss
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::PRE, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::PRE, rank, bankgroup, bank);
|
||||
nextCommand = Command::PRE;
|
||||
}
|
||||
}
|
||||
|
||||
timeToSchedule = sc_time_stamp() + delay;
|
||||
return delay;
|
||||
return timeToSchedule;
|
||||
}
|
||||
|
||||
BankMachineClosed::BankMachineClosed(SchedulerIF *scheduler, CheckerIF *checker, Bank bank)
|
||||
@@ -169,40 +169,35 @@ BankMachineClosed::BankMachineClosed(SchedulerIF *scheduler, CheckerIF *checker,
|
||||
sc_time BankMachineClosed::start()
|
||||
{
|
||||
timeToSchedule = sc_max_time();
|
||||
sc_time delay = sc_max_time() - sc_time_stamp();
|
||||
|
||||
if (sleeping)
|
||||
return delay;
|
||||
return timeToSchedule;
|
||||
|
||||
currentPayload = scheduler->getNextRequest(this);
|
||||
if (currentPayload == nullptr)
|
||||
{
|
||||
currentPayload = scheduler->getNextRequest(this);
|
||||
if (currentPayload == nullptr)
|
||||
return delay;
|
||||
}
|
||||
return timeToSchedule;
|
||||
|
||||
if (currentState == BmState::Precharged && !blocked) // row miss
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::ACT, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::ACT, rank, bankgroup, bank);
|
||||
nextCommand = Command::ACT;
|
||||
}
|
||||
else if (currentState == BmState::Activated)
|
||||
{
|
||||
if (currentPayload->get_command() == TLM_READ_COMMAND)
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::RDA, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::RDA, rank, bankgroup, bank);
|
||||
nextCommand = Command::RDA;
|
||||
}
|
||||
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::WRA, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::WRA, rank, bankgroup, bank);
|
||||
nextCommand = Command::WRA;
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
|
||||
}
|
||||
timeToSchedule = sc_time_stamp() + delay;
|
||||
return delay;
|
||||
return timeToSchedule;
|
||||
}
|
||||
|
||||
BankMachineOpenAdaptive::BankMachineOpenAdaptive(SchedulerIF *scheduler, CheckerIF *checker, Bank bank)
|
||||
@@ -211,37 +206,33 @@ BankMachineOpenAdaptive::BankMachineOpenAdaptive(SchedulerIF *scheduler, Checker
|
||||
sc_time BankMachineOpenAdaptive::start()
|
||||
{
|
||||
timeToSchedule = sc_max_time();
|
||||
sc_time delay = sc_max_time() - sc_time_stamp();
|
||||
|
||||
if (sleeping)
|
||||
return delay;
|
||||
return timeToSchedule;
|
||||
|
||||
currentPayload = scheduler->getNextRequest(this);
|
||||
if (currentPayload == nullptr)
|
||||
{
|
||||
currentPayload = scheduler->getNextRequest(this);
|
||||
if (currentPayload == nullptr)
|
||||
return delay;
|
||||
}
|
||||
return timeToSchedule;
|
||||
|
||||
if (currentState == BmState::Precharged && !blocked) // row miss
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::ACT, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::ACT, rank, bankgroup, bank);
|
||||
nextCommand = Command::ACT;
|
||||
}
|
||||
else if (currentState == BmState::Activated)
|
||||
{
|
||||
if (DramExtension::getRow(currentPayload) == currentRow) // row hit
|
||||
{
|
||||
if (scheduler->hasRequest(bank) && !scheduler->hasRowHit(bank, currentRow))
|
||||
if (scheduler->hasFurtherRequest(bank) && !scheduler->hasFurtherRowHit(bank, currentRow))
|
||||
{
|
||||
if (currentPayload->get_command() == TLM_READ_COMMAND)
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::RDA, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::RDA, rank, bankgroup, bank);
|
||||
nextCommand = Command::RDA;
|
||||
}
|
||||
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::WRA, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::WRA, rank, bankgroup, bank);
|
||||
nextCommand = Command::WRA;
|
||||
}
|
||||
else
|
||||
@@ -251,12 +242,12 @@ sc_time BankMachineOpenAdaptive::start()
|
||||
{
|
||||
if (currentPayload->get_command() == TLM_READ_COMMAND)
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::RD, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::RD, rank, bankgroup, bank);
|
||||
nextCommand = Command::RD;
|
||||
}
|
||||
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::WR, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::WR, rank, bankgroup, bank);
|
||||
nextCommand = Command::WR;
|
||||
}
|
||||
else
|
||||
@@ -265,12 +256,11 @@ sc_time BankMachineOpenAdaptive::start()
|
||||
}
|
||||
else if (!blocked) // row miss
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::PRE, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::PRE, rank, bankgroup, bank);
|
||||
nextCommand = Command::PRE;
|
||||
}
|
||||
}
|
||||
timeToSchedule = sc_time_stamp() + delay;
|
||||
return delay;
|
||||
return timeToSchedule;
|
||||
}
|
||||
|
||||
BankMachineClosedAdaptive::BankMachineClosedAdaptive(SchedulerIF *scheduler, CheckerIF *checker, Bank bank)
|
||||
@@ -279,37 +269,33 @@ BankMachineClosedAdaptive::BankMachineClosedAdaptive(SchedulerIF *scheduler, Che
|
||||
sc_time BankMachineClosedAdaptive::start()
|
||||
{
|
||||
timeToSchedule = sc_max_time();
|
||||
sc_time delay = sc_max_time() - sc_time_stamp();
|
||||
|
||||
if (sleeping)
|
||||
return delay;
|
||||
return timeToSchedule;
|
||||
|
||||
currentPayload = scheduler->getNextRequest(this);
|
||||
if (currentPayload == nullptr)
|
||||
{
|
||||
currentPayload = scheduler->getNextRequest(this);
|
||||
if (currentPayload == nullptr)
|
||||
return delay;
|
||||
}
|
||||
return timeToSchedule;
|
||||
|
||||
if (currentState == BmState::Precharged && !blocked) // row miss
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::ACT, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::ACT, rank, bankgroup, bank);
|
||||
nextCommand = Command::ACT;
|
||||
}
|
||||
else if (currentState == BmState::Activated)
|
||||
{
|
||||
if (DramExtension::getRow(currentPayload) == currentRow) // row hit
|
||||
{
|
||||
if (scheduler->hasRowHit(bank, currentRow))
|
||||
if (scheduler->hasFurtherRowHit(bank, currentRow))
|
||||
{
|
||||
if (currentPayload->get_command() == TLM_READ_COMMAND)
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::RD, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::RD, rank, bankgroup, bank);
|
||||
nextCommand = Command::RD;
|
||||
}
|
||||
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::WR, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::WR, rank, bankgroup, bank);
|
||||
nextCommand = Command::WR;
|
||||
}
|
||||
else
|
||||
@@ -319,12 +305,12 @@ sc_time BankMachineClosedAdaptive::start()
|
||||
{
|
||||
if (currentPayload->get_command() == TLM_READ_COMMAND)
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::RDA, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::RDA, rank, bankgroup, bank);
|
||||
nextCommand = Command::RDA;
|
||||
}
|
||||
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::WRA, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::WRA, rank, bankgroup, bank);
|
||||
nextCommand = Command::WRA;
|
||||
}
|
||||
else
|
||||
@@ -333,11 +319,10 @@ sc_time BankMachineClosedAdaptive::start()
|
||||
}
|
||||
else if (!blocked) // row miss TODO: remove this, can never happen
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::PRE, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(Command::PRE, rank, bankgroup, bank);
|
||||
nextCommand = Command::PRE;
|
||||
SC_REPORT_FATAL("BankMachine", "Should never be reached for this policy");
|
||||
}
|
||||
}
|
||||
timeToSchedule = sc_time_stamp() + delay;
|
||||
return delay;
|
||||
return timeToSchedule;
|
||||
}
|
||||
|
||||
@@ -44,8 +44,6 @@
|
||||
#include "scheduler/SchedulerIF.h"
|
||||
#include "checker/CheckerIF.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
class SchedulerIF;
|
||||
class CheckerIF;
|
||||
|
||||
@@ -60,7 +58,7 @@ class BankMachine
|
||||
public:
|
||||
virtual ~BankMachine() {}
|
||||
virtual sc_time start() = 0;
|
||||
std::pair<Command, tlm_generic_payload *> getNextCommand();
|
||||
std::pair<Command, tlm::tlm_generic_payload *> getNextCommand();
|
||||
void updateState(Command);
|
||||
void block();
|
||||
|
||||
@@ -73,7 +71,7 @@ public:
|
||||
|
||||
protected:
|
||||
BankMachine(SchedulerIF *, CheckerIF *, Bank);
|
||||
tlm_generic_payload *currentPayload = nullptr;
|
||||
tlm::tlm_generic_payload *currentPayload = nullptr;
|
||||
SchedulerIF *scheduler;
|
||||
CheckerIF *checker;
|
||||
Command nextCommand;
|
||||
|
||||
@@ -38,88 +38,30 @@
|
||||
#include "Command.h"
|
||||
#include <systemc.h>
|
||||
|
||||
using namespace tlm;
|
||||
using namespace DRAMPower;
|
||||
|
||||
std::string commandToString(Command command)
|
||||
{
|
||||
switch (command) {
|
||||
case Command::RD:
|
||||
return "RD";
|
||||
break;
|
||||
case Command::RDA:
|
||||
return "RDA";
|
||||
break;
|
||||
case Command::WR:
|
||||
return "WR";
|
||||
break;
|
||||
case Command::WRA:
|
||||
return "WRA";
|
||||
break;
|
||||
case Command::PRE:
|
||||
return "PRE";
|
||||
break;
|
||||
case Command::ACT:
|
||||
return "ACT";
|
||||
break;
|
||||
case Command::PREA:
|
||||
return "PREA";
|
||||
break;
|
||||
case Command::REFA:
|
||||
return "REFA";
|
||||
break;
|
||||
case Command::REFB:
|
||||
return "REFB";
|
||||
break;
|
||||
case Command::PDEA:
|
||||
return "PDEA";
|
||||
break;
|
||||
case Command::PDXA:
|
||||
return "PDXA";
|
||||
break;
|
||||
case Command::PDEP:
|
||||
return "PDEP";
|
||||
break;
|
||||
case Command::PDXP:
|
||||
return "PDXP";
|
||||
break;
|
||||
case Command::SREFEN:
|
||||
return "SREFEN";
|
||||
break;
|
||||
case Command::SREFEX:
|
||||
return "SREFEX";
|
||||
break;
|
||||
|
||||
case Command::NOP:
|
||||
return "NOP";
|
||||
break;
|
||||
|
||||
default:
|
||||
SC_REPORT_FATAL("command", "commandToString was called with unknown command");
|
||||
break;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
const std::vector<Command> &getAllCommands()
|
||||
{
|
||||
static std::vector<Command> allCommands( { Command::NOP,
|
||||
Command::RD,
|
||||
Command::WR,
|
||||
Command::RDA,
|
||||
Command::WRA,
|
||||
Command::PRE,
|
||||
Command::ACT,
|
||||
Command::REFB,
|
||||
Command::PREA,
|
||||
Command::REFA,
|
||||
Command::PDEA,
|
||||
Command::PDXA,
|
||||
Command::PDEP,
|
||||
Command::PDXP,
|
||||
Command::SREFEN,
|
||||
Command::SREFEX
|
||||
});
|
||||
return allCommands;
|
||||
{
|
||||
assert(command >= 0 && command <= 15);
|
||||
static std::array<std::string, 16> stringOfCommand =
|
||||
{"NOP",
|
||||
"RD",
|
||||
"WR",
|
||||
"RDA",
|
||||
"WRA",
|
||||
"PRE",
|
||||
"ACT",
|
||||
"REFB",
|
||||
"PREA",
|
||||
"REFA",
|
||||
"PDEA",
|
||||
"PDXA",
|
||||
"PDEP",
|
||||
"PDXP",
|
||||
"SREFEN",
|
||||
"SREFEX"};
|
||||
return stringOfCommand[command];
|
||||
}
|
||||
|
||||
unsigned numberOfCommands()
|
||||
@@ -127,48 +69,104 @@ unsigned numberOfCommands()
|
||||
return 16;
|
||||
}
|
||||
|
||||
bool commandIsIn(Command command, std::vector<Command> commands)
|
||||
tlm_phase commandToPhase(Command command)
|
||||
{
|
||||
for (Command c : commands) {
|
||||
if (c == command)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
assert(command >= 0 && command <= 15);
|
||||
static std::array<tlm_phase, 16> phaseOfCommand =
|
||||
{UNINITIALIZED_PHASE,
|
||||
BEGIN_RD,
|
||||
BEGIN_WR,
|
||||
BEGIN_RDA,
|
||||
BEGIN_WRA,
|
||||
BEGIN_PRE,
|
||||
BEGIN_ACT,
|
||||
BEGIN_REFB,
|
||||
BEGIN_PREA,
|
||||
BEGIN_REFA,
|
||||
BEGIN_PDNA,
|
||||
END_PDNA,
|
||||
BEGIN_PDNP,
|
||||
END_PDNP,
|
||||
BEGIN_SREF,
|
||||
END_SREF};
|
||||
return phaseOfCommand[command];
|
||||
}
|
||||
|
||||
std::array<tlm_phase, 16> phaseOfCommand = {UNINITIALIZED_PHASE,
|
||||
BEGIN_RD,
|
||||
BEGIN_WR,
|
||||
BEGIN_RDA,
|
||||
BEGIN_WRA,
|
||||
BEGIN_PRE,
|
||||
BEGIN_ACT,
|
||||
BEGIN_REFB,
|
||||
BEGIN_PREA,
|
||||
BEGIN_REFA,
|
||||
BEGIN_PDNA,
|
||||
END_PDNA,
|
||||
BEGIN_PDNP,
|
||||
END_PDNP,
|
||||
BEGIN_SREF,
|
||||
END_SREF};
|
||||
Command phaseToCommand(tlm_phase phase)
|
||||
{
|
||||
assert(phase >= 5 && phase <= 19);
|
||||
static std::array<Command, 16> commandOfPhase =
|
||||
{Command::RD,
|
||||
Command::WR,
|
||||
Command::RDA,
|
||||
Command::WRA,
|
||||
Command::PRE,
|
||||
Command::ACT,
|
||||
Command::REFB,
|
||||
Command::PREA,
|
||||
Command::REFA,
|
||||
Command::PDEA,
|
||||
Command::PDXA,
|
||||
Command::PDEP,
|
||||
Command::PDXP,
|
||||
Command::SREFEN,
|
||||
Command::SREFEX};
|
||||
return commandOfPhase[phase - 5];
|
||||
}
|
||||
|
||||
MemCommand::cmds phaseToDRAMPowerCommand(tlm_phase phase)
|
||||
{
|
||||
assert(phase >= 5 && phase <= 19);
|
||||
static std::array<MemCommand::cmds, 16> phaseOfCommand =
|
||||
{MemCommand::RD,
|
||||
MemCommand::WR,
|
||||
MemCommand::RDA,
|
||||
MemCommand::WRA,
|
||||
MemCommand::PRE,
|
||||
MemCommand::ACT,
|
||||
MemCommand::REFB,
|
||||
MemCommand::PREA,
|
||||
MemCommand::REF,
|
||||
MemCommand::PDN_S_ACT,
|
||||
MemCommand::PUP_ACT,
|
||||
MemCommand::PDN_S_PRE,
|
||||
MemCommand::PUP_PRE,
|
||||
MemCommand::SREN,
|
||||
MemCommand::SREX};
|
||||
return phaseOfCommand[phase - 5];
|
||||
}
|
||||
|
||||
bool phaseNeedsEnd(tlm_phase phase)
|
||||
{
|
||||
return (phase >= 5 && phase <= 13);
|
||||
}
|
||||
|
||||
tlm_phase getEndPhase(tlm_phase phase)
|
||||
{
|
||||
assert(phase >= 5 && phase <= 13);
|
||||
return (phase + 15);
|
||||
}
|
||||
|
||||
bool isBankCommand(Command command)
|
||||
{
|
||||
assert(command >= 0 && command <= 15);
|
||||
return (command <= 7);
|
||||
}
|
||||
|
||||
bool isRankCommand(Command command)
|
||||
{
|
||||
assert(command >= 0 && command <= 15);
|
||||
return (command >= 8);
|
||||
}
|
||||
|
||||
bool isCasCommand(Command command)
|
||||
{
|
||||
assert(command >= 0 && command <= 15);
|
||||
return (command <= 4);
|
||||
}
|
||||
|
||||
bool isRasCommand(Command command)
|
||||
{
|
||||
assert(command >= 0 && command <= 15);
|
||||
return (command >= 5);
|
||||
}
|
||||
|
||||
@@ -40,9 +40,34 @@
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <tlm.h>
|
||||
#include "../common/protocol.h"
|
||||
#include "../common/third_party/DRAMPower/src/MemCommand.h"
|
||||
|
||||
using namespace tlm;
|
||||
// DO NOT CHANGE THE ORDER!
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_RD); // 5
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_WR); // 6
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_RDA); // 7
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_WRA); // 8
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_PRE); // 9
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_ACT); // 10
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_REFB); // 11
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_PREA); // 12
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_REFA); // 13
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_PDNA); // 14
|
||||
DECLARE_EXTENDED_PHASE(END_PDNA); // 15
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_PDNP); // 16
|
||||
DECLARE_EXTENDED_PHASE(END_PDNP); // 17
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_SREF); // 18
|
||||
DECLARE_EXTENDED_PHASE(END_SREF); // 19
|
||||
|
||||
DECLARE_EXTENDED_PHASE(END_RD); // 20
|
||||
DECLARE_EXTENDED_PHASE(END_WR); // 21
|
||||
DECLARE_EXTENDED_PHASE(END_RDA); // 22
|
||||
DECLARE_EXTENDED_PHASE(END_WRA); // 23
|
||||
DECLARE_EXTENDED_PHASE(END_PRE); // 24
|
||||
DECLARE_EXTENDED_PHASE(END_ACT); // 25
|
||||
DECLARE_EXTENDED_PHASE(END_REFB); // 26
|
||||
DECLARE_EXTENDED_PHASE(END_PREA); // 27
|
||||
DECLARE_EXTENDED_PHASE(END_REFA); // 28
|
||||
|
||||
enum Command
|
||||
{
|
||||
@@ -64,15 +89,16 @@ enum Command
|
||||
SREFEX
|
||||
};
|
||||
|
||||
std::string commandToString(Command command);
|
||||
const std::vector<Command> &getAllCommands();
|
||||
std::string commandToString(Command);
|
||||
tlm::tlm_phase commandToPhase(Command);
|
||||
Command phaseToCommand(tlm::tlm_phase);
|
||||
DRAMPower::MemCommand::cmds phaseToDRAMPowerCommand(tlm::tlm_phase);
|
||||
bool phaseNeedsEnd(tlm::tlm_phase);
|
||||
tlm::tlm_phase getEndPhase(tlm::tlm_phase);
|
||||
unsigned numberOfCommands();
|
||||
bool commandIsIn(Command command, std::vector<Command> commands);
|
||||
bool isBankCommand(Command command);
|
||||
bool isRankCommand(Command command);
|
||||
bool isCasCommand(Command command);
|
||||
bool isRasCommand(Command command);
|
||||
|
||||
extern std::array<tlm_phase, 16> phaseOfCommand;
|
||||
bool isBankCommand(Command);
|
||||
bool isRankCommand(Command);
|
||||
bool isCasCommand(Command);
|
||||
bool isRasCommand(Command);
|
||||
|
||||
#endif // COMMAND_H
|
||||
|
||||
@@ -35,12 +35,8 @@
|
||||
#include "Controller.h"
|
||||
|
||||
#include "../configuration/Configuration.h"
|
||||
#include "scheduler/SchedulerFifo.h"
|
||||
#include "scheduler/SchedulerFrFcfs.h"
|
||||
#include "cmdmux/CmdMuxStrict.h"
|
||||
#include "cmdmux/CmdMuxOldest.h"
|
||||
#include "../common/dramExtensions.h"
|
||||
#include "../common/protocol.h"
|
||||
#include "Command.h"
|
||||
#include "checker/CheckerDDR3.h"
|
||||
#include "checker/CheckerDDR4.h"
|
||||
#include "checker/CheckerWideIO.h"
|
||||
@@ -50,149 +46,161 @@
|
||||
#include "checker/CheckerGDDR5.h"
|
||||
#include "checker/CheckerGDDR5X.h"
|
||||
#include "checker/CheckerGDDR6.h"
|
||||
#include "refresh/RefreshManager.h"
|
||||
#include "scheduler/SchedulerFifo.h"
|
||||
#include "scheduler/SchedulerFrFcfs.h"
|
||||
#include "scheduler/SchedulerFrFcfsGrp.h"
|
||||
#include "cmdmux/CmdMuxStrict.h"
|
||||
#include "cmdmux/CmdMuxOldest.h"
|
||||
#include "respqueue/RespQueueFifo.h"
|
||||
#include "respqueue/RespQueueReorder.h"
|
||||
#include "refresh/RefreshManagerRankwise.h"
|
||||
#include "refresh/RefreshManagerDummy.h"
|
||||
#include "refresh/RefreshManagerBankwise.h"
|
||||
#include "powerdown/PowerDownManagerStaggered.h"
|
||||
#include "powerdown/PowerDownManagerDummy.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
Controller::Controller(sc_module_name name) :
|
||||
GenericController(name)
|
||||
ControllerIF(name)
|
||||
{
|
||||
SC_METHOD(controllerMethod);
|
||||
sensitive << beginReqEvent << endRespEvent << controllerEvent << dataResponseEventQueue;
|
||||
dont_initialize();
|
||||
sensitive << beginReqEvent << endRespEvent << controllerEvent << dataResponseEvent;
|
||||
|
||||
Configuration &config = Configuration::getInstance();
|
||||
MemSpec *memSpec = config.memSpec;
|
||||
ranksNumberOfPayloads = std::vector<unsigned>(memSpec->NumberOfRanks);
|
||||
memSpec = config.memSpec;
|
||||
ranksNumberOfPayloads = std::vector<unsigned>(memSpec->numberOfRanks);
|
||||
|
||||
// instantiate timing checker
|
||||
if (memSpec->MemoryType == "DDR3")
|
||||
if (memSpec->memoryType == "DDR3")
|
||||
checker = new CheckerDDR3();
|
||||
else if (memSpec->MemoryType == "DDR4")
|
||||
else if (memSpec->memoryType == "DDR4")
|
||||
checker = new CheckerDDR4();
|
||||
else if (memSpec->MemoryType == "WIDEIO_SDR")
|
||||
else if (memSpec->memoryType == "WIDEIO_SDR")
|
||||
checker = new CheckerWideIO();
|
||||
else if (memSpec->MemoryType == "LPDDR4")
|
||||
else if (memSpec->memoryType == "LPDDR4")
|
||||
checker = new CheckerLPDDR4();
|
||||
else if (memSpec->MemoryType == "WIDEIO2")
|
||||
else if (memSpec->memoryType == "WIDEIO2")
|
||||
checker = new CheckerWideIO2();
|
||||
else if (memSpec->MemoryType == "HBM2")
|
||||
else if (memSpec->memoryType == "HBM2")
|
||||
checker = new CheckerHBM2();
|
||||
else if (memSpec->MemoryType == "GDDR5")
|
||||
else if (memSpec->memoryType == "GDDR5")
|
||||
checker = new CheckerGDDR5();
|
||||
else if (memSpec->MemoryType == "GDDR5X")
|
||||
else if (memSpec->memoryType == "GDDR5X")
|
||||
checker = new CheckerGDDR5X();
|
||||
else if (memSpec->MemoryType == "GDDR6")
|
||||
else if (memSpec->memoryType == "GDDR6")
|
||||
checker = new CheckerGDDR6();
|
||||
else
|
||||
SC_REPORT_FATAL("Controller", "Unsupported DRAM type!");
|
||||
|
||||
// instantiate scheduler and command mux
|
||||
if (config.Scheduler == "FifoStrict")
|
||||
{
|
||||
if (config.scheduler == "Fifo")
|
||||
scheduler = new SchedulerFifo();
|
||||
commandMux = new CmdMuxStrict();
|
||||
}
|
||||
else if (config.Scheduler == "FrFcfs")
|
||||
{
|
||||
else if (config.scheduler == "FrFcfs")
|
||||
scheduler = new SchedulerFrFcfs();
|
||||
commandMux = new CmdMuxOldest();
|
||||
}
|
||||
else if (config.scheduler == "FrFcfsGrp")
|
||||
scheduler = new SchedulerFrFcfsGrp();
|
||||
else
|
||||
SC_REPORT_FATAL("Controller", "Selected scheduler not supported!");
|
||||
|
||||
if (config.cmdMux == "Oldest")
|
||||
cmdMux = new CmdMuxOldest();
|
||||
else if (config.cmdMux == "Strict")
|
||||
cmdMux = new CmdMuxStrict();
|
||||
else
|
||||
SC_REPORT_FATAL("Controller", "Selected cmdmux not supported!");
|
||||
|
||||
if (config.respQueue == "Fifo")
|
||||
respQueue = new RespQueueFifo();
|
||||
else if (config.respQueue == "Reorder")
|
||||
respQueue = new RespQueueReorder();
|
||||
else
|
||||
SC_REPORT_FATAL("Controller", "Selected respqueue not supported!");
|
||||
|
||||
// instantiate bank machines (one per bank)
|
||||
if (config.OpenPagePolicy)
|
||||
if (config.pagePolicy == "Open")
|
||||
{
|
||||
if (config.AdaptivePagePolicy)
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < memSpec->NumberOfBanks; bankID++)
|
||||
bankMachines.push_back(new BankMachineOpenAdaptive(scheduler, checker, Bank(bankID)));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < memSpec->NumberOfBanks; bankID++)
|
||||
bankMachines.push_back(new BankMachineOpen(scheduler, checker, Bank(bankID)));
|
||||
}
|
||||
for (unsigned bankID = 0; bankID < memSpec->numberOfBanks; bankID++)
|
||||
bankMachines.push_back(new BankMachineOpen(scheduler, checker, Bank(bankID)));
|
||||
}
|
||||
else if (config.pagePolicy == "OpenAdaptive")
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < memSpec->numberOfBanks; bankID++)
|
||||
bankMachines.push_back(new BankMachineOpenAdaptive(scheduler, checker, Bank(bankID)));
|
||||
}
|
||||
else if (config.pagePolicy == "Closed")
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < memSpec->numberOfBanks; bankID++)
|
||||
bankMachines.push_back(new BankMachineClosed(scheduler, checker, Bank(bankID)));
|
||||
}
|
||||
else if (config.pagePolicy == "ClosedAdaptive")
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < memSpec->numberOfBanks; bankID++)
|
||||
bankMachines.push_back(new BankMachineClosedAdaptive(scheduler, checker, Bank(bankID)));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (config.AdaptivePagePolicy)
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < memSpec->NumberOfBanks; bankID++)
|
||||
bankMachines.push_back(new BankMachineClosedAdaptive(scheduler, checker, Bank(bankID)));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < memSpec->NumberOfBanks; bankID++)
|
||||
bankMachines.push_back(new BankMachineClosed(scheduler, checker, Bank(bankID)));
|
||||
}
|
||||
}
|
||||
SC_REPORT_FATAL("Controller", "Selected page policy not supported!");
|
||||
|
||||
for (unsigned rankID = 0; rankID < memSpec->NumberOfRanks; rankID++)
|
||||
for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++)
|
||||
{
|
||||
bankMachinesOnRank.push_back(std::vector<BankMachine *>(bankMachines.begin() + rankID * memSpec->BanksPerRank,
|
||||
bankMachines.begin() + (rankID + 1) * memSpec->BanksPerRank));
|
||||
bankMachinesOnRank.push_back(std::vector<BankMachine *>(bankMachines.begin() + rankID * memSpec->banksPerRank,
|
||||
bankMachines.begin() + (rankID + 1) * memSpec->banksPerRank));
|
||||
}
|
||||
|
||||
// instantiate power-down managers (one per rank)
|
||||
if (config.PowerDownMode == EPowerDownMode::NoPowerDown)
|
||||
if (config.powerDownPolicy == "NoPowerDown")
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec->NumberOfRanks; rankID++)
|
||||
for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++)
|
||||
{
|
||||
PowerDownManagerIF *manager = new PowerDownManagerDummy();
|
||||
powerDownManagers.push_back(manager);
|
||||
}
|
||||
}
|
||||
else if (config.PowerDownMode == EPowerDownMode::Staggered)
|
||||
else if (config.powerDownPolicy == "Staggered")
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec->NumberOfRanks; rankID++)
|
||||
for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++)
|
||||
{
|
||||
PowerDownManagerIF *manager = new PowerDownManagerStaggered(Rank(rankID), checker);
|
||||
powerDownManagers.push_back(manager);
|
||||
manager->triggerEntry(TriggerSource::Controller);
|
||||
controllerEvent.notify(manager->start());
|
||||
}
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("Controller", "Selected power-down mode not supported!");
|
||||
|
||||
// instantiate refresh managers (one per rank)
|
||||
if (config.ControllerCoreRefDisable)
|
||||
if (config.refreshPolicy == "NoRefresh")
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec->NumberOfRanks; rankID++)
|
||||
for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++)
|
||||
refreshManagers.push_back(new RefreshManagerDummy());
|
||||
}
|
||||
else if (config.BankwiseLogic)
|
||||
else if (config.refreshPolicy == "Rankwise")
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec->NumberOfRanks; rankID++)
|
||||
for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++)
|
||||
{
|
||||
RefreshManagerIF *manager = new RefreshManagerRankwise
|
||||
(bankMachinesOnRank[rankID], powerDownManagers[rankID], Rank(rankID), checker);
|
||||
refreshManagers.push_back(manager);
|
||||
}
|
||||
}
|
||||
else if (config.refreshPolicy == "Bankwise")
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++)
|
||||
{
|
||||
// TODO: remove bankMachines in constructor
|
||||
RefreshManagerIF *manager = new RefreshManagerBankwise
|
||||
(bankMachinesOnRank[rankID], powerDownManagers[rankID], Rank(rankID), checker);
|
||||
refreshManagers.push_back(manager);
|
||||
controllerEvent.notify(manager->start());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec->NumberOfRanks; rankID++)
|
||||
{
|
||||
RefreshManagerIF *manager = new RefreshManager
|
||||
(bankMachinesOnRank[rankID], powerDownManagers[rankID], Rank(rankID), checker);
|
||||
refreshManagers.push_back(manager);
|
||||
controllerEvent.notify(manager->start());
|
||||
}
|
||||
}
|
||||
SC_REPORT_FATAL("Controller", "Selected refresh mode not supported!");
|
||||
|
||||
startBandwidthIdleCollector();
|
||||
idleTimeCollector.start();
|
||||
}
|
||||
|
||||
Controller::~Controller()
|
||||
{
|
||||
endBandwithIdleCollector();
|
||||
idleTimeCollector.end();
|
||||
|
||||
for (auto it : refreshManagers)
|
||||
delete it;
|
||||
@@ -200,46 +208,31 @@ Controller::~Controller()
|
||||
delete it;
|
||||
for (auto it : bankMachines)
|
||||
delete it;
|
||||
delete commandMux;
|
||||
delete respQueue;
|
||||
delete cmdMux;
|
||||
delete scheduler;
|
||||
delete checker;
|
||||
}
|
||||
|
||||
void Controller::controllerMethod()
|
||||
{
|
||||
// (1) Release payload if arbiter has accepted the result
|
||||
if (sc_time_stamp() == timeToRelease && payloadToRelease != nullptr)
|
||||
releasePayload();
|
||||
// (1) Release payload if arbiter has accepted the result (finish END_RESP)
|
||||
if (payloadToRelease != nullptr && timeToRelease <= sc_time_stamp())
|
||||
finishEndResp();
|
||||
|
||||
// (2) Send next result to arbiter
|
||||
if (payloadToRelease == nullptr && !responseQueue.empty())
|
||||
// (2) Send next result to arbiter (start BEGIN_RESP)
|
||||
if (payloadToRelease == nullptr)
|
||||
startBeginResp();
|
||||
|
||||
// (3) Insert new request from arbiter into scheduler and restart appropriate BM (finish BEGIN_REQ)
|
||||
if (payloadToAcquire != nullptr && timeToAcquire <= sc_time_stamp())
|
||||
{
|
||||
std::pair<sc_time, tlm_generic_payload *> element = responseQueue.front();
|
||||
if (sc_time_stamp() >= element.first)
|
||||
{
|
||||
payloadToRelease = element.second;
|
||||
responseQueue.pop();
|
||||
sendToFrontend(payloadToRelease, BEGIN_RESP);
|
||||
}
|
||||
}
|
||||
|
||||
// (3) Accept new request from arbiter and start appropriate BM if necessary
|
||||
if (sc_time_stamp() >= timeToAcquire && payloadToAcquire != nullptr)
|
||||
{
|
||||
if (scheduler->hasBufferSpace(payloadToAcquire))
|
||||
{
|
||||
Bank bank = DramExtension::getBank(payloadToAcquire);
|
||||
acquirePayload();
|
||||
|
||||
if (bankMachines[bank.ID()]->isIdle())
|
||||
bankMachines[bank.ID()]->start();
|
||||
}
|
||||
else
|
||||
PRINTDEBUGMESSAGE(name(), "Total number of payloads exceeded, backpressure!");
|
||||
unsigned bankID = DramExtension::getBank(payloadToAcquire).ID();
|
||||
finishBeginReq();
|
||||
bankMachines[bankID]->start();
|
||||
}
|
||||
|
||||
// (4) Start refresh and power-down managers to issue requests for the current time
|
||||
// TODO: check if the order of start() matters, do I always need to start them at this point? No, only if something happened in steps 1-3!!!
|
||||
for (auto it : refreshManagers)
|
||||
it->start();
|
||||
for (auto it : powerDownManagers)
|
||||
@@ -249,7 +242,7 @@ void Controller::controllerMethod()
|
||||
std::pair<Command, tlm_generic_payload *> commandPair;
|
||||
std::vector<std::pair<Command, tlm_generic_payload *>> readyCommands;
|
||||
// (5.1) Check for power-down commands (PDEA/PDEP/SREFEN or PDXA/PDXP/SREFEX)
|
||||
for (unsigned rankID = 0; rankID < Configuration::getInstance().memSpec->NumberOfRanks; rankID++)
|
||||
for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++)
|
||||
{
|
||||
commandPair = powerDownManagers[rankID]->getNextCommand();
|
||||
if (commandPair.second != nullptr)
|
||||
@@ -276,7 +269,7 @@ void Controller::controllerMethod()
|
||||
bool readyCmdBlocked = false;
|
||||
if (!readyCommands.empty())
|
||||
{
|
||||
commandPair = commandMux->selectCommand(readyCommands);
|
||||
commandPair = cmdMux->selectCommand(readyCommands);
|
||||
if (commandPair.second != nullptr) // can happen with FIFO strict
|
||||
{
|
||||
Rank rank = DramExtension::getRank(commandPair.second);
|
||||
@@ -295,30 +288,46 @@ void Controller::controllerMethod()
|
||||
powerDownManagers[rank.ID()]->updateState(commandPair.first);
|
||||
checker->insert(commandPair.first, rank, bankgroup, bank);
|
||||
|
||||
if (isCasCommand(commandPair.first))
|
||||
{
|
||||
scheduler->removeRequest(commandPair.second);
|
||||
respQueue->insertPayload(commandPair.second, memSpec->getIntervalOnDataStrobe(commandPair.first).end);
|
||||
|
||||
sc_time triggerTime = respQueue->getTriggerTime();
|
||||
if (triggerTime != sc_max_time())
|
||||
dataResponseEvent.notify(triggerTime - sc_time_stamp());
|
||||
|
||||
ranksNumberOfPayloads[rank.ID()]--;
|
||||
}
|
||||
if (ranksNumberOfPayloads[rank.ID()] == 0)
|
||||
powerDownManagers[rank.ID()]->triggerEntry();
|
||||
|
||||
sendToDram(commandPair.first, commandPair.second);
|
||||
}
|
||||
else
|
||||
readyCmdBlocked = true;
|
||||
}
|
||||
|
||||
// (6) Restart bank machines and refresh managers to issue new requests for the future
|
||||
// (6) Accept request from arbiter if scheduler is not full, otherwise backpressure (start END_REQ)
|
||||
if (payloadToAcquire != nullptr && timeToAcquire == sc_max_time())
|
||||
startEndReq();
|
||||
|
||||
// (7) Restart bank machines, refresh managers and power-down managers to issue new requests for the future
|
||||
// TODO: check if all calls are necessary
|
||||
sc_time delayForNextTrigger = sc_max_time();
|
||||
sc_time timeForNextTrigger = sc_max_time();
|
||||
for (auto it : bankMachines)
|
||||
{
|
||||
sc_time localDelay = it->start();
|
||||
if (!(localDelay == SC_ZERO_TIME && readyCmdBlocked))
|
||||
delayForNextTrigger = std::min(delayForNextTrigger, localDelay);
|
||||
sc_time localTime = it->start();
|
||||
if (!(localTime == sc_time_stamp() && readyCmdBlocked))
|
||||
timeForNextTrigger = std::min(timeForNextTrigger, localTime);
|
||||
}
|
||||
if (payloadToAcquire != nullptr && sc_time_stamp() >= timeToAcquire && scheduler->hasBufferSpace(payloadToAcquire))
|
||||
acquirePayload();
|
||||
for (auto it : refreshManagers)
|
||||
delayForNextTrigger = std::min(delayForNextTrigger, it->start());
|
||||
timeForNextTrigger = std::min(timeForNextTrigger, it->start());
|
||||
for (auto it : powerDownManagers)
|
||||
delayForNextTrigger = std::min(delayForNextTrigger, it->start());
|
||||
timeForNextTrigger = std::min(timeForNextTrigger, it->start());
|
||||
|
||||
if (!(delayForNextTrigger == (sc_max_time() - sc_time_stamp())))
|
||||
controllerEvent.notify(delayForNextTrigger);
|
||||
if (timeForNextTrigger != sc_max_time())
|
||||
controllerEvent.notify(timeForNextTrigger - sc_time_stamp());
|
||||
}
|
||||
|
||||
tlm_sync_enum Controller::nb_transport_fw(tlm_generic_payload &trans,
|
||||
@@ -328,19 +337,19 @@ tlm_sync_enum Controller::nb_transport_fw(tlm_generic_payload &trans,
|
||||
|
||||
if (phase == BEGIN_REQ)
|
||||
{
|
||||
notificationDelay += Configuration::getInstance().memSpec->clk;
|
||||
notificationDelay += Configuration::getInstance().memSpec->tCK;
|
||||
payloadToAcquire = &trans;
|
||||
timeToAcquire = sc_time_stamp() + notificationDelay;
|
||||
beginReqEvent.notify(notificationDelay);
|
||||
}
|
||||
else if (phase = END_RESP)
|
||||
{
|
||||
notificationDelay += Configuration::getInstance().memSpec->clk;
|
||||
notificationDelay += Configuration::getInstance().memSpec->tCK;
|
||||
timeToRelease = sc_time_stamp() + notificationDelay;
|
||||
endRespEvent.notify(notificationDelay);
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL(0, "nb_transport_fw in controller was triggered with unknown phase");
|
||||
SC_REPORT_FATAL("Controller", "nb_transport_fw in controller was triggered with unknown phase");
|
||||
|
||||
PRINTDEBUGMESSAGE(name(), "[fw] " + phaseNameToString(phase) + " notification in " +
|
||||
notificationDelay.to_string());
|
||||
@@ -348,26 +357,10 @@ tlm_sync_enum Controller::nb_transport_fw(tlm_generic_payload &trans,
|
||||
return TLM_ACCEPTED;
|
||||
}
|
||||
|
||||
tlm_sync_enum Controller::nb_transport_bw(tlm_generic_payload &trans,
|
||||
tlm_phase &phase, sc_time &delay)
|
||||
tlm_sync_enum Controller::nb_transport_bw(tlm_generic_payload &,
|
||||
tlm_phase &, sc_time &)
|
||||
{
|
||||
PRINTDEBUGMESSAGE(name(), "[bw] " + phaseNameToString(phase) + " notification in " +
|
||||
delay.to_string());
|
||||
|
||||
if (phase == END_RD || phase == END_RDA || phase == END_WR || phase == END_WRA)
|
||||
{
|
||||
// TODO: check this part (order of responses)
|
||||
responseQueue.push({(sc_time_stamp() + delay), &trans});
|
||||
dataResponseEventQueue.notify(delay);
|
||||
|
||||
Rank rank = DramExtension::getRank(trans);
|
||||
ranksNumberOfPayloads[rank.ID()]--;
|
||||
if (ranksNumberOfPayloads[rank.ID()] == 0)
|
||||
{
|
||||
refreshManagers[rank.ID()]->notifyIdle();
|
||||
powerDownManagers[rank.ID()]->triggerEntry(TriggerSource::Controller);
|
||||
}
|
||||
}
|
||||
SC_REPORT_FATAL("Controller", "nb_transport_bw of controller must not be called");
|
||||
return TLM_ACCEPTED;
|
||||
}
|
||||
|
||||
@@ -377,7 +370,53 @@ unsigned int Controller::transport_dbg(tlm_generic_payload &)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Controller::releasePayload()
|
||||
void Controller::finishBeginReq()
|
||||
{
|
||||
uint64_t id __attribute__((unused)) = DramExtension::getPayloadID(payloadToAcquire);
|
||||
PRINTDEBUGMESSAGE(name(), "Payload " + std::to_string(id) + " entered system.");
|
||||
|
||||
if (totalNumberOfPayloads == 0)
|
||||
idleTimeCollector.end();
|
||||
totalNumberOfPayloads++;
|
||||
|
||||
Rank rank = DramExtension::getRank(payloadToAcquire);
|
||||
if (ranksNumberOfPayloads[rank.ID()] == 0)
|
||||
powerDownManagers[rank.ID()]->triggerExit();
|
||||
|
||||
ranksNumberOfPayloads[rank.ID()]++;
|
||||
|
||||
scheduler->storeRequest(payloadToAcquire);
|
||||
payloadToAcquire->acquire();
|
||||
timeToAcquire = sc_max_time();
|
||||
}
|
||||
|
||||
void Controller::startEndReq()
|
||||
{
|
||||
if (scheduler->hasBufferSpace())
|
||||
{
|
||||
payloadToAcquire->set_response_status(TLM_OK_RESPONSE);
|
||||
sendToFrontend(payloadToAcquire, END_REQ);
|
||||
payloadToAcquire = nullptr;
|
||||
}
|
||||
else
|
||||
PRINTDEBUGMESSAGE(name(), "Total number of payloads exceeded, backpressure!");
|
||||
}
|
||||
|
||||
void Controller::startBeginResp()
|
||||
{
|
||||
payloadToRelease = respQueue->nextPayload();
|
||||
|
||||
if (payloadToRelease != nullptr)
|
||||
sendToFrontend(payloadToRelease, BEGIN_RESP);
|
||||
else
|
||||
{
|
||||
sc_time triggerTime = respQueue->getTriggerTime();
|
||||
if (triggerTime != sc_max_time())
|
||||
dataResponseEvent.notify(triggerTime - sc_time_stamp());
|
||||
}
|
||||
}
|
||||
|
||||
void Controller::finishEndResp()
|
||||
{
|
||||
uint64_t id __attribute__((unused)) = DramExtension::getPayloadID(payloadToRelease);
|
||||
PRINTDEBUGMESSAGE(name(), "Payload " + std::to_string(id) + " left system.");
|
||||
@@ -389,33 +428,7 @@ void Controller::releasePayload()
|
||||
|
||||
totalNumberOfPayloads--;
|
||||
if (totalNumberOfPayloads == 0)
|
||||
startBandwidthIdleCollector();
|
||||
}
|
||||
|
||||
void Controller::acquirePayload()
|
||||
{
|
||||
uint64_t id __attribute__((unused)) = DramExtension::getPayloadID(payloadToAcquire);
|
||||
PRINTDEBUGMESSAGE(name(), "Payload " + std::to_string(id) + " entered system.");
|
||||
|
||||
Rank rank = DramExtension::getRank(payloadToAcquire);
|
||||
|
||||
if (totalNumberOfPayloads == 0)
|
||||
endBandwithIdleCollector();
|
||||
totalNumberOfPayloads++;
|
||||
|
||||
if(ranksNumberOfPayloads[rank.ID()] == 0)
|
||||
{
|
||||
refreshManagers[rank.ID()]->notifyActive();
|
||||
powerDownManagers[rank.ID()]->triggerExit(TriggerSource::Controller);
|
||||
}
|
||||
ranksNumberOfPayloads[rank.ID()]++;
|
||||
|
||||
scheduler->storeRequest(payloadToAcquire);
|
||||
payloadToAcquire->acquire();
|
||||
payloadToAcquire->set_response_status(TLM_OK_RESPONSE);
|
||||
sendToFrontend(payloadToAcquire, END_REQ);
|
||||
payloadToAcquire = nullptr;
|
||||
timeToAcquire = sc_max_time();
|
||||
idleTimeCollector.start();
|
||||
}
|
||||
|
||||
void Controller::sendToFrontend(tlm_generic_payload *payload, tlm_phase phase)
|
||||
@@ -427,27 +440,7 @@ void Controller::sendToFrontend(tlm_generic_payload *payload, tlm_phase phase)
|
||||
void Controller::sendToDram(Command command, tlm_generic_payload *payload)
|
||||
{
|
||||
sc_time delay = SC_ZERO_TIME;
|
||||
tlm_phase phase = phaseOfCommand[command];
|
||||
tlm_phase phase = commandToPhase(command);
|
||||
|
||||
iSocket->nb_transport_fw(*payload, phase, delay);
|
||||
}
|
||||
|
||||
void Controller::startBandwidthIdleCollector()
|
||||
{
|
||||
if (!isIdle)
|
||||
{
|
||||
PRINTDEBUGMESSAGE(name(), "IDLE start");
|
||||
idleStart = sc_time_stamp();
|
||||
isIdle = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Controller::endBandwithIdleCollector()
|
||||
{
|
||||
if (isIdle)
|
||||
{
|
||||
PRINTDEBUGMESSAGE(name(), "IDLE end");
|
||||
idleTime += sc_time_stamp() - idleStart;
|
||||
isIdle = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
#include <tlm.h>
|
||||
#include <tlm_utils/simple_initiator_socket.h>
|
||||
#include <tlm_utils/simple_target_socket.h>
|
||||
#include "GenericController.h"
|
||||
#include "ControllerIF.h"
|
||||
#include "../common/dramExtensions.h"
|
||||
#include "BankMachine.h"
|
||||
#include "cmdmux/CmdMuxIF.h"
|
||||
@@ -51,14 +51,13 @@
|
||||
#include "checker/CheckerIF.h"
|
||||
#include "refresh/RefreshManagerIF.h"
|
||||
#include "powerdown/PowerDownManagerIF.h"
|
||||
|
||||
using namespace tlm;
|
||||
#include "respqueue/RespQueueIF.h"
|
||||
|
||||
class BankMachine;
|
||||
class SchedulerIF;
|
||||
class PowerDownManagerStaggered;
|
||||
|
||||
class Controller : public GenericController
|
||||
class Controller : public ControllerIF
|
||||
{
|
||||
public:
|
||||
Controller(sc_module_name);
|
||||
@@ -66,42 +65,40 @@ public:
|
||||
virtual ~Controller();
|
||||
|
||||
protected:
|
||||
virtual tlm_sync_enum nb_transport_fw(tlm_generic_payload &, tlm_phase &, sc_time &);
|
||||
virtual tlm_sync_enum nb_transport_bw(tlm_generic_payload &, tlm_phase &, sc_time &);
|
||||
virtual unsigned int transport_dbg(tlm_generic_payload &);
|
||||
virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &, tlm::tlm_phase &, sc_time &);
|
||||
virtual tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &, tlm::tlm_phase &, sc_time &);
|
||||
virtual unsigned int transport_dbg(tlm::tlm_generic_payload &);
|
||||
|
||||
virtual void sendToFrontend(tlm_generic_payload *, tlm_phase);
|
||||
virtual void sendToDram(Command, tlm_generic_payload *);
|
||||
virtual void sendToFrontend(tlm::tlm_generic_payload *, tlm::tlm_phase);
|
||||
virtual void sendToDram(Command, tlm::tlm_generic_payload *);
|
||||
|
||||
private:
|
||||
unsigned totalNumberOfPayloads = 0;
|
||||
std::vector<unsigned> ranksNumberOfPayloads;
|
||||
tlm_generic_payload *payloadToAcquire = nullptr;
|
||||
sc_time timeToAcquire = sc_max_time();
|
||||
tlm_generic_payload *payloadToRelease = nullptr;
|
||||
sc_time timeToRelease = sc_max_time();
|
||||
std::queue<std::pair<sc_time, tlm_generic_payload *>> responseQueue;
|
||||
|
||||
MemSpec *memSpec;
|
||||
|
||||
std::vector<BankMachine *> bankMachines;
|
||||
std::vector<std::vector<BankMachine *>> bankMachinesOnRank;
|
||||
CmdMuxIF *commandMux;
|
||||
CmdMuxIF *cmdMux;
|
||||
SchedulerIF *scheduler;
|
||||
CheckerIF *checker;
|
||||
RespQueueIF *respQueue;
|
||||
std::vector<RefreshManagerIF *> refreshManagers;
|
||||
std::vector<PowerDownManagerIF *> powerDownManagers;
|
||||
|
||||
void releasePayload();
|
||||
void acquirePayload();
|
||||
tlm::tlm_generic_payload *payloadToAcquire = nullptr;
|
||||
sc_time timeToAcquire = sc_max_time();
|
||||
tlm::tlm_generic_payload *payloadToRelease = nullptr;
|
||||
sc_time timeToRelease = sc_max_time();
|
||||
|
||||
void finishBeginReq();
|
||||
void startEndReq();
|
||||
void startBeginResp();
|
||||
void finishEndResp();
|
||||
|
||||
void controllerMethod();
|
||||
sc_event beginReqEvent, endRespEvent, controllerEvent;
|
||||
sc_event_queue dataResponseEventQueue;
|
||||
|
||||
// Bandwidth related
|
||||
sc_time idleStart;
|
||||
bool isIdle = false;
|
||||
void startBandwidthIdleCollector();
|
||||
void endBandwithIdleCollector();
|
||||
sc_event beginReqEvent, endRespEvent, controllerEvent, dataResponseEvent;
|
||||
};
|
||||
|
||||
#endif // CONTROLLER_H
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef GENERICCONTROLLER_H
|
||||
#define GENERICCONTROLLER_H
|
||||
#ifndef CONTROLLERIF_H
|
||||
#define CONTROLLERIF_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include <tlm.h>
|
||||
@@ -7,37 +7,35 @@
|
||||
#include <tlm_utils/simple_target_socket.h>
|
||||
#include "../configuration/Configuration.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
// Utiliy class to pass around the DRAMSys, without having to propagate the template defintions
|
||||
// throughout all classes
|
||||
class GenericController : public sc_module
|
||||
class ControllerIF : public sc_module
|
||||
{
|
||||
public:
|
||||
// Already create and bind sockets to the virtual functions
|
||||
tlm_utils::simple_target_socket<GenericController> tSocket; // Arbiter side
|
||||
tlm_utils::simple_initiator_socket<GenericController> iSocket; // DRAM side
|
||||
tlm_utils::simple_target_socket<ControllerIF> tSocket; // Arbiter side
|
||||
tlm_utils::simple_initiator_socket<ControllerIF> iSocket; // DRAM side
|
||||
|
||||
// Destructor
|
||||
virtual ~GenericController()
|
||||
virtual ~ControllerIF()
|
||||
{
|
||||
sc_time activeTime = numberOfTransactionsServed
|
||||
* Configuration::getInstance().memSpec->BurstLength
|
||||
/ Configuration::getInstance().memSpec->DataRate
|
||||
* Configuration::getInstance().memSpec->clk;
|
||||
* Configuration::getInstance().memSpec->burstLength
|
||||
/ Configuration::getInstance().memSpec->dataRate
|
||||
* Configuration::getInstance().memSpec->tCK;
|
||||
|
||||
double bandwidth = (activeTime / sc_time_stamp() * 100);
|
||||
double bandwidth_IDLE = ((activeTime) / (sc_time_stamp() - idleTime) * 100);
|
||||
double bandwidthWoIdle = ((activeTime) / (sc_time_stamp() - idleTimeCollector.getIdleTime()) * 100);
|
||||
|
||||
double maxBandwidth = (
|
||||
// clk in Mhz e.g. 800 [MHz]:
|
||||
(1000000 / Configuration::getInstance().memSpec->clk.to_double())
|
||||
// fCK in Mhz e.g. 800 [MHz]:
|
||||
(1000000 / Configuration::getInstance().memSpec->tCK.to_double())
|
||||
// DataRate e.g. 2
|
||||
* Configuration::getInstance().memSpec->DataRate
|
||||
* Configuration::getInstance().memSpec->dataRate
|
||||
// BusWidth e.g. 8 or 64
|
||||
* Configuration::getInstance().memSpec->bitWidth
|
||||
// Number of devices on a DIMM e.g. 8
|
||||
* Configuration::getInstance().NumberOfDevicesOnDIMM ) / ( 1024 );
|
||||
* Configuration::getInstance().numberOfDevicesOnDIMM ) / ( 1024 );
|
||||
|
||||
std::cout << name() << std::string(" Total Time: ")
|
||||
<< sc_time_stamp().to_string()
|
||||
@@ -49,8 +47,8 @@ public:
|
||||
<< std::endl;
|
||||
std::cout << name() << std::string(" AVG BW\\IDLE: ")
|
||||
<< std::fixed << std::setprecision(2)
|
||||
<< ((bandwidth_IDLE / 100) * maxBandwidth)
|
||||
<< " Gibit/s (" << bandwidth_IDLE << " %)"
|
||||
<< ((bandwidthWoIdle / 100) * maxBandwidth)
|
||||
<< " Gibit/s (" << bandwidthWoIdle << " %)"
|
||||
<< endl;
|
||||
std::cout << name() << std::string(" MAX BW: ")
|
||||
<< std::fixed << std::setprecision(2)
|
||||
@@ -60,24 +58,57 @@ public:
|
||||
|
||||
protected:
|
||||
// Bind sockets with virtual functions
|
||||
GenericController(sc_module_name name) :
|
||||
ControllerIF(sc_module_name name) :
|
||||
sc_module(name), tSocket("tSocket"), iSocket("iSocket")
|
||||
{
|
||||
tSocket.register_nb_transport_fw(this, &GenericController::nb_transport_fw);
|
||||
tSocket.register_transport_dbg(this, &GenericController::transport_dbg);
|
||||
iSocket.register_nb_transport_bw(this, &GenericController::nb_transport_bw);
|
||||
tSocket.register_nb_transport_fw(this, &ControllerIF::nb_transport_fw);
|
||||
tSocket.register_transport_dbg(this, &ControllerIF::transport_dbg);
|
||||
iSocket.register_nb_transport_bw(this, &ControllerIF::nb_transport_bw);
|
||||
}
|
||||
SC_HAS_PROCESS(GenericController);
|
||||
SC_HAS_PROCESS(ControllerIF);
|
||||
|
||||
// Virtual transport functions
|
||||
virtual tlm_sync_enum nb_transport_fw(tlm_generic_payload &, tlm_phase &, sc_time &) = 0;
|
||||
virtual unsigned int transport_dbg(tlm_generic_payload &) = 0;
|
||||
virtual tlm_sync_enum nb_transport_bw(tlm_generic_payload &, tlm_phase &, sc_time &) = 0;
|
||||
virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &, tlm::tlm_phase &, sc_time &) = 0;
|
||||
virtual unsigned int transport_dbg(tlm::tlm_generic_payload &) = 0;
|
||||
virtual tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &, tlm::tlm_phase &, sc_time &) = 0;
|
||||
|
||||
// Bandwidth related
|
||||
sc_time idleTime = SC_ZERO_TIME;
|
||||
class IdleTimeCollector
|
||||
{
|
||||
public:
|
||||
void start()
|
||||
{
|
||||
if (!isIdle)
|
||||
{
|
||||
PRINTDEBUGMESSAGE("IdleTimeCollector", "IDLE start");
|
||||
idleStart = sc_time_stamp();
|
||||
isIdle = true;
|
||||
}
|
||||
}
|
||||
|
||||
void end()
|
||||
{
|
||||
if (isIdle)
|
||||
{
|
||||
PRINTDEBUGMESSAGE("IdleTimeCollector", "IDLE end");
|
||||
idleTime += sc_time_stamp() - idleStart;
|
||||
isIdle = false;
|
||||
}
|
||||
}
|
||||
|
||||
sc_time getIdleTime()
|
||||
{
|
||||
return idleTime;
|
||||
}
|
||||
|
||||
private:
|
||||
bool isIdle = false;
|
||||
sc_time idleTime = SC_ZERO_TIME;
|
||||
sc_time idleStart;
|
||||
} idleTimeCollector;
|
||||
|
||||
uint64_t numberOfTransactionsServed = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif // GENERICCONTROLLER_H
|
||||
#endif // CONTROLLERIF_H
|
||||
@@ -33,10 +33,10 @@
|
||||
*/
|
||||
|
||||
#include "ControllerRecordable.h"
|
||||
|
||||
#include "../common/protocol.h"
|
||||
#include "../configuration/Configuration.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
tlm_sync_enum ControllerRecordable::nb_transport_fw(tlm_generic_payload &trans,
|
||||
tlm_phase &phase, sc_time &delay)
|
||||
{
|
||||
@@ -60,7 +60,7 @@ void ControllerRecordable::sendToFrontend(tlm_generic_payload *payload, tlm_phas
|
||||
|
||||
void ControllerRecordable::sendToDram(Command command, tlm_generic_payload *payload)
|
||||
{
|
||||
if (commandIsIn(command, {Command::RD, Command::RDA, Command::WR, Command::WRA}))
|
||||
if (isCasCommand(command))
|
||||
{
|
||||
TimeInterval dataStrobe = Configuration::getInstance().memSpec->getIntervalOnDataStrobe(command);
|
||||
tlmRecorder->updateDataStrobe(dataStrobe.start, dataStrobe.end, *payload);
|
||||
@@ -81,9 +81,9 @@ void ControllerRecordable::recordPhase(tlm_generic_payload &trans, tlm_phase pha
|
||||
uint64_t id __attribute__((unused)) = DramExtension::getExtension(trans).getPayloadID();
|
||||
|
||||
PRINTDEBUGMESSAGE(name(), "Recording " + phaseNameToString(phase) + " thread " +
|
||||
to_string(thr) + " channel " + to_string(ch) + " bank group " + to_string(
|
||||
bg) + " bank " + to_string(bank) + " row " + to_string(row) + " column " +
|
||||
to_string(col) + " id " + to_string(id) + " at " + recTime.to_string());
|
||||
std::to_string(thr) + " channel " + std::to_string(ch) + " bank group " + std::to_string(
|
||||
bg) + " bank " + std::to_string(bank) + " row " + std::to_string(row) + " column " +
|
||||
std::to_string(col) + " id " + std::to_string(id) + " at " + recTime.to_string());
|
||||
|
||||
tlmRecorder->recordPhase(trans, phase, recTime);
|
||||
}
|
||||
|
||||
@@ -45,15 +45,15 @@ public:
|
||||
Controller(name), tlmRecorder(tlmRecorder) {}
|
||||
|
||||
private:
|
||||
tlm_sync_enum nb_transport_fw(tlm_generic_payload &trans,
|
||||
tlm_phase &phase, sc_time &delay) override;
|
||||
tlm_sync_enum nb_transport_bw(tlm_generic_payload &trans,
|
||||
tlm_phase &phase, sc_time &delay) override;
|
||||
tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &trans,
|
||||
tlm::tlm_phase &phase, sc_time &delay) override;
|
||||
tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &trans,
|
||||
tlm::tlm_phase &phase, sc_time &delay) override;
|
||||
|
||||
void sendToFrontend(tlm_generic_payload *, tlm_phase) override;
|
||||
void sendToDram(Command, tlm_generic_payload *) override;
|
||||
void sendToFrontend(tlm::tlm_generic_payload *, tlm::tlm_phase) override;
|
||||
void sendToDram(Command, tlm::tlm_generic_payload *) override;
|
||||
|
||||
void recordPhase(tlm_generic_payload &trans, tlm_phase phase, sc_time delay);
|
||||
void recordPhase(tlm::tlm_generic_payload &trans, tlm::tlm_phase phase, sc_time delay);
|
||||
|
||||
TlmRecorder *tlmRecorder;
|
||||
};
|
||||
|
||||
@@ -42,17 +42,15 @@ CheckerDDR3::CheckerDDR3()
|
||||
SC_REPORT_FATAL("CheckerDDR3", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->NumberOfBanks));
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfBanks));
|
||||
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->NumberOfRanks));
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfRanks));
|
||||
lastScheduledByCommand = std::vector<sc_time>(numberOfCommands());
|
||||
|
||||
lastActivates = std::vector<std::queue<sc_time>>(memSpec->NumberOfRanks);
|
||||
|
||||
burstClocks = (memSpec->BurstLength / memSpec->DataRate) * memSpec->clk;
|
||||
lastActivates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
|
||||
}
|
||||
|
||||
sc_time CheckerDDR3::delayToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const
|
||||
sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
@@ -66,7 +64,7 @@ sc_time CheckerDDR3::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR + memSpec->tRP);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -123,20 +121,20 @@ sc_time CheckerDDR3::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTR);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWTR);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR - memSpec->tRTP);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR - memSpec->tRTP);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTR);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWTR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -154,12 +152,12 @@ sc_time CheckerDDR3::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tRL + burstClocks + 2 * memSpec->clk - memSpec->tWL);
|
||||
+ memSpec->tRL + memSpec->burstDuration + 2 * memSpec->tCK - memSpec->tWL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tRL + burstClocks + 2 * memSpec->clk - memSpec->tWL);
|
||||
+ memSpec->tRL + memSpec->burstDuration + 2 * memSpec->tCK - memSpec->tWL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -189,7 +187,7 @@ sc_time CheckerDDR3::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -211,12 +209,12 @@ sc_time CheckerDDR3::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -235,7 +233,7 @@ sc_time CheckerDDR3::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR + memSpec->tRP);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -262,22 +260,22 @@ sc_time CheckerDDR3::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tRL + 5 * memSpec->clk);
|
||||
+ memSpec->tRL + 5 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tRL + 5 * memSpec->clk);
|
||||
+ memSpec->tRL + 5 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + 4 * memSpec->clk + memSpec->tWR);
|
||||
+ memSpec->tWL + 4 * memSpec->tCK + memSpec->tWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + 5 * memSpec->clk + memSpec->tWR);
|
||||
+ memSpec->tWL + 5 * memSpec->tCK + memSpec->tWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -294,17 +292,17 @@ sc_time CheckerDDR3::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tRL + 5 * memSpec->clk);
|
||||
+ memSpec->tRL + 5 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tRL + 5 * memSpec->clk);
|
||||
+ memSpec->tRL + 5 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + 5 * memSpec->clk + memSpec->tWR);
|
||||
+ memSpec->tWL + 5 * memSpec->tCK + memSpec->tWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -325,12 +323,12 @@ sc_time CheckerDDR3::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ std::max(memSpec->tRL + 5 * memSpec->clk, memSpec->tAL + memSpec->tRTP + memSpec->tRP));
|
||||
+ std::max(memSpec->tRL + 5 * memSpec->tCK, memSpec->tAL + memSpec->tRTP + memSpec->tRP));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ std::max(memSpec->tWL + 5 * memSpec->clk + memSpec->tWR, memSpec->tWL + burstClocks + memSpec->tWR + memSpec->tRP));
|
||||
+ std::max(memSpec->tWL + 5 * memSpec->tCK + memSpec->tWR, memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tRP));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -362,9 +360,9 @@ sc_time CheckerDDR3::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
reportFatal("CheckerDDR3", "Unknown command!");
|
||||
|
||||
// Check if command bus is free
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK);
|
||||
|
||||
return (earliestTimeToStart - sc_time_stamp());
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerDDR3::insert(Command command, Rank rank, BankGroup, Bank bank)
|
||||
|
||||
@@ -45,7 +45,7 @@ class CheckerDDR3 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerDDR3();
|
||||
virtual sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
|
||||
private:
|
||||
@@ -58,8 +58,6 @@ private:
|
||||
|
||||
// Four activate window
|
||||
std::vector<std::queue<sc_time>> lastActivates;
|
||||
|
||||
sc_time burstClocks;
|
||||
};
|
||||
|
||||
#endif // CHECKERDDR3_H
|
||||
|
||||
@@ -42,19 +42,17 @@ CheckerDDR4::CheckerDDR4()
|
||||
SC_REPORT_FATAL("CheckerDDR4", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->NumberOfBanks));
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfBanks));
|
||||
lastScheduledByCommandAndBankGroup = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->NumberOfBankGroups));
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfBankGroups));
|
||||
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->NumberOfRanks));
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfRanks));
|
||||
lastScheduledByCommand = std::vector<sc_time>(numberOfCommands());
|
||||
|
||||
lastActivates = std::vector<std::queue<sc_time>>(memSpec->NumberOfRanks);
|
||||
|
||||
burstClocks = (memSpec->BurstLength / memSpec->DataRate) * memSpec->clk;
|
||||
lastActivates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
|
||||
}
|
||||
|
||||
sc_time CheckerDDR4::delayToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
@@ -68,7 +66,7 @@ sc_time CheckerDDR4::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL
|
||||
+ burstClocks + memSpec->tWR + memSpec->tRP);
|
||||
+ memSpec->burstDuration + memSpec->tWR + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -121,30 +119,30 @@ sc_time CheckerDDR4::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL
|
||||
+ burstClocks + memSpec->tWTR_L);
|
||||
+ memSpec->burstDuration + memSpec->tWTR_L);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR - memSpec->tRTP);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR - memSpec->tRTP);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL
|
||||
+ burstClocks + memSpec->tWTR_S);
|
||||
+ memSpec->burstDuration + memSpec->tWTR_S);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL
|
||||
+ burstClocks + memSpec->tWTR_L);
|
||||
+ memSpec->burstDuration + memSpec->tWTR_L);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL
|
||||
+ burstClocks + memSpec->tWTR_S);
|
||||
+ memSpec->burstDuration + memSpec->tWTR_S);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
{
|
||||
@@ -154,12 +152,12 @@ sc_time CheckerDDR4::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRL
|
||||
+ burstClocks + 2 * memSpec->clk - memSpec->tWL);
|
||||
+ memSpec->burstDuration + 2 * memSpec->tCK - memSpec->tWL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRL
|
||||
+ burstClocks + 2 * memSpec->clk - memSpec->tWL);
|
||||
+ memSpec->burstDuration + 2 * memSpec->tCK - memSpec->tWL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -189,7 +187,7 @@ sc_time CheckerDDR4::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL
|
||||
+ burstClocks + memSpec->tWR);
|
||||
+ memSpec->burstDuration + memSpec->tWR);
|
||||
}
|
||||
else if (command == Command::PREA)
|
||||
{
|
||||
@@ -207,12 +205,12 @@ sc_time CheckerDDR4::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL
|
||||
+ burstClocks + memSpec->tWR);
|
||||
+ memSpec->burstDuration + memSpec->tWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL
|
||||
+ burstClocks + memSpec->tWR);
|
||||
+ memSpec->burstDuration + memSpec->tWR);
|
||||
}
|
||||
else if (command == Command::REFA)
|
||||
{
|
||||
@@ -227,7 +225,7 @@ sc_time CheckerDDR4::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL
|
||||
+ burstClocks + memSpec->tWR + memSpec->tRP);
|
||||
+ memSpec->burstDuration + memSpec->tWR + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -245,9 +243,9 @@ sc_time CheckerDDR4::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
reportFatal("CheckerDDR4", "Unknown command!");
|
||||
|
||||
// Check if command bus is free
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK);
|
||||
|
||||
return (earliestTimeToStart - sc_time_stamp());
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerDDR4::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank)
|
||||
|
||||
@@ -45,7 +45,7 @@ class CheckerDDR4 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerDDR4();
|
||||
virtual sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
|
||||
private:
|
||||
@@ -59,8 +59,6 @@ private:
|
||||
|
||||
// Four activate window
|
||||
std::vector<std::queue<sc_time>> lastActivates;
|
||||
|
||||
sc_time burstClocks;
|
||||
};
|
||||
|
||||
#endif // CHECKERDDR4_H
|
||||
|
||||
@@ -42,20 +42,18 @@ CheckerGDDR5::CheckerGDDR5()
|
||||
SC_REPORT_FATAL("CheckerGDDR5", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->NumberOfBanks));
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfBanks));
|
||||
lastScheduledByCommandAndBankGroup = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->NumberOfBankGroups));
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfBankGroups));
|
||||
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->NumberOfRanks));
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfRanks));
|
||||
lastScheduledByCommand = std::vector<sc_time>(numberOfCommands());
|
||||
|
||||
last4Activates = std::vector<std::queue<sc_time>>(memSpec->NumberOfRanks);
|
||||
last32Activates = std::vector<std::queue<sc_time>>(memSpec->NumberOfRanks);
|
||||
|
||||
burstClocks = (memSpec->BurstLength / memSpec->DataRate) * memSpec->clk;
|
||||
last4Activates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
|
||||
last32Activates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
|
||||
}
|
||||
|
||||
sc_time CheckerGDDR5::delayToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
@@ -81,7 +79,7 @@ sc_time CheckerGDDR5::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR + memSpec->tRP);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -108,8 +106,6 @@ sc_time CheckerGDDR5::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
|
||||
if (last32Activates[rank.ID()].size() == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last32Activates[rank.ID()].front() + memSpec->t32AW);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::RD || command == Command::RDA)
|
||||
{
|
||||
@@ -135,32 +131,30 @@ sc_time CheckerGDDR5::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRL);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWTRL);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR - memSpec->tRTP);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR - memSpec->tRTP);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRS);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRL);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWTRL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWTRS);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
{
|
||||
@@ -190,8 +184,6 @@ sc_time CheckerGDDR5::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::PRE)
|
||||
{
|
||||
@@ -205,13 +197,11 @@ sc_time CheckerGDDR5::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::PREA)
|
||||
{
|
||||
@@ -229,18 +219,16 @@ sc_time CheckerGDDR5::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::REFA)
|
||||
{
|
||||
@@ -255,7 +243,7 @@ sc_time CheckerGDDR5::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR + memSpec->tRP);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -268,8 +256,6 @@ sc_time CheckerGDDR5::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::REFB)
|
||||
{
|
||||
@@ -292,7 +278,7 @@ sc_time CheckerGDDR5::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR + memSpec->tRP);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -316,15 +302,15 @@ sc_time CheckerGDDR5::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
|
||||
if (last32Activates[rank.ID()].size() == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last32Activates[rank.ID()].front() + memSpec->t32AW);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else
|
||||
{
|
||||
reportFatal("CheckerGDDR5", "Unknown command!");
|
||||
}
|
||||
// Check if command bus is free
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK);
|
||||
|
||||
return (earliestTimeToStart - sc_time_stamp());
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerGDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank)
|
||||
@@ -350,5 +336,5 @@ void CheckerGDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank
|
||||
}
|
||||
|
||||
if (command == Command::REFB)
|
||||
bankwiseRefreshCounter = (bankwiseRefreshCounter + 1) % memSpec->BanksPerRank;
|
||||
bankwiseRefreshCounter = (bankwiseRefreshCounter + 1) % memSpec->banksPerRank;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ class CheckerGDDR5 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerGDDR5();
|
||||
virtual sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
|
||||
private:
|
||||
@@ -61,8 +61,6 @@ private:
|
||||
std::vector<std::queue<sc_time>> last4Activates;
|
||||
std::vector<std::queue<sc_time>> last32Activates;
|
||||
|
||||
sc_time burstClocks;
|
||||
|
||||
unsigned bankwiseRefreshCounter = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -42,20 +42,18 @@ CheckerGDDR5X::CheckerGDDR5X()
|
||||
SC_REPORT_FATAL("CheckerGDDR5X", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->NumberOfBanks));
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfBanks));
|
||||
lastScheduledByCommandAndBankGroup = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->NumberOfBankGroups));
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfBankGroups));
|
||||
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->NumberOfRanks));
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfRanks));
|
||||
lastScheduledByCommand = std::vector<sc_time>(numberOfCommands());
|
||||
|
||||
last4Activates = std::vector<std::queue<sc_time>>(memSpec->NumberOfRanks);
|
||||
last32Activates = std::vector<std::queue<sc_time>>(memSpec->NumberOfRanks);
|
||||
|
||||
burstClocks = (memSpec->BurstLength / memSpec->DataRate) * memSpec->clk;
|
||||
last4Activates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
|
||||
last32Activates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
|
||||
}
|
||||
|
||||
sc_time CheckerGDDR5X::delayToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
@@ -81,7 +79,7 @@ sc_time CheckerGDDR5X::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR + memSpec->tRP);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -108,8 +106,6 @@ sc_time CheckerGDDR5X::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
|
||||
if (last32Activates[rank.ID()].size() == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last32Activates[rank.ID()].front() + memSpec->t32AW);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::RD || command == Command::RDA)
|
||||
{
|
||||
@@ -135,32 +131,30 @@ sc_time CheckerGDDR5X::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRL);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWTRL);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR - memSpec->tRTP);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR - memSpec->tRTP);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRS);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRL);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWTRL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWTRS);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
{
|
||||
@@ -190,8 +184,6 @@ sc_time CheckerGDDR5X::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::PRE)
|
||||
{
|
||||
@@ -205,13 +197,11 @@ sc_time CheckerGDDR5X::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::PREA)
|
||||
{
|
||||
@@ -229,18 +219,16 @@ sc_time CheckerGDDR5X::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::REFA)
|
||||
{
|
||||
@@ -255,7 +243,7 @@ sc_time CheckerGDDR5X::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR + memSpec->tRP);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -268,8 +256,6 @@ sc_time CheckerGDDR5X::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::REFB)
|
||||
{
|
||||
@@ -292,7 +278,7 @@ sc_time CheckerGDDR5X::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR + memSpec->tRP);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -316,15 +302,15 @@ sc_time CheckerGDDR5X::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
|
||||
if (last32Activates[rank.ID()].size() == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last32Activates[rank.ID()].front() + memSpec->t32AW);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else
|
||||
{
|
||||
reportFatal("CheckerGDDR5X", "Unknown command!");
|
||||
}
|
||||
// Check if command bus is free
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK);
|
||||
|
||||
return (earliestTimeToStart - sc_time_stamp());
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerGDDR5X::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank)
|
||||
@@ -350,5 +336,5 @@ void CheckerGDDR5X::insert(Command command, Rank rank, BankGroup bankgroup, Bank
|
||||
}
|
||||
|
||||
if (command == Command::REFB)
|
||||
bankwiseRefreshCounter = (bankwiseRefreshCounter + 1) % memSpec->BanksPerRank;
|
||||
bankwiseRefreshCounter = (bankwiseRefreshCounter + 1) % memSpec->banksPerRank;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ class CheckerGDDR5X final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerGDDR5X();
|
||||
virtual sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
|
||||
private:
|
||||
@@ -61,8 +61,6 @@ private:
|
||||
std::vector<std::queue<sc_time>> last4Activates;
|
||||
std::vector<std::queue<sc_time>> last32Activates;
|
||||
|
||||
sc_time burstClocks;
|
||||
|
||||
unsigned bankwiseRefreshCounter = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -42,19 +42,17 @@ CheckerGDDR6::CheckerGDDR6()
|
||||
SC_REPORT_FATAL("CheckerGDDR6", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->NumberOfBanks));
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfBanks));
|
||||
lastScheduledByCommandAndBankGroup = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->NumberOfBankGroups));
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfBankGroups));
|
||||
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->NumberOfRanks));
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfRanks));
|
||||
lastScheduledByCommand = std::vector<sc_time>(numberOfCommands());
|
||||
|
||||
lastActivates = std::vector<std::queue<sc_time>>(memSpec->NumberOfRanks);
|
||||
|
||||
burstClocks = (memSpec->BurstLength / memSpec->DataRate) * memSpec->clk;
|
||||
lastActivates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
|
||||
}
|
||||
|
||||
sc_time CheckerGDDR6::delayToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
@@ -80,7 +78,7 @@ sc_time CheckerGDDR6::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR + memSpec->tRP);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -104,8 +102,6 @@ sc_time CheckerGDDR6::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
|
||||
if (lastActivates[rank.ID()].size() == 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastActivates[rank.ID()].front() + memSpec->tFAW);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::RD || command == Command::RDA)
|
||||
{
|
||||
@@ -131,32 +127,30 @@ sc_time CheckerGDDR6::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRL);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWTRL);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR - memSpec->tRTP);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR - memSpec->tRTP);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRS);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRL);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWTRL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWTRS);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
{
|
||||
@@ -186,8 +180,6 @@ sc_time CheckerGDDR6::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::PRE)
|
||||
{
|
||||
@@ -201,13 +193,11 @@ sc_time CheckerGDDR6::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::PREA)
|
||||
{
|
||||
@@ -225,18 +215,16 @@ sc_time CheckerGDDR6::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::REFA)
|
||||
{
|
||||
@@ -251,7 +239,7 @@ sc_time CheckerGDDR6::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR + memSpec->tRP);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -264,8 +252,6 @@ sc_time CheckerGDDR6::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::REFB)
|
||||
{
|
||||
@@ -288,7 +274,7 @@ sc_time CheckerGDDR6::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR + memSpec->tRP);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -309,15 +295,15 @@ sc_time CheckerGDDR6::delayToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
|
||||
if (lastActivates[rank.ID()].size() == 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastActivates[rank.ID()].front() + memSpec->tFAW);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else
|
||||
{
|
||||
reportFatal("CheckerGDDR6", "Unknown command!");
|
||||
}
|
||||
// Check if command bus is free
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK);
|
||||
|
||||
return (earliestTimeToStart - sc_time_stamp());
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerGDDR6::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank)
|
||||
@@ -339,5 +325,5 @@ void CheckerGDDR6::insert(Command command, Rank rank, BankGroup bankgroup, Bank
|
||||
}
|
||||
|
||||
if (command == Command::REFB)
|
||||
bankwiseRefreshCounter = (bankwiseRefreshCounter + 1) % memSpec->BanksPerRank;
|
||||
bankwiseRefreshCounter = (bankwiseRefreshCounter + 1) % memSpec->banksPerRank;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ class CheckerGDDR6 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerGDDR6();
|
||||
virtual sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
|
||||
private:
|
||||
@@ -60,8 +60,6 @@ private:
|
||||
// four activate window
|
||||
std::vector<std::queue<sc_time>> lastActivates;
|
||||
|
||||
sc_time burstClocks;
|
||||
|
||||
unsigned bankwiseRefreshCounter = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -42,20 +42,18 @@ CheckerHBM2::CheckerHBM2()
|
||||
SC_REPORT_FATAL("CheckerHBM2", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->NumberOfBanks));
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfBanks));
|
||||
lastScheduledByCommandAndBankGroup = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->NumberOfBankGroups));
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfBankGroups));
|
||||
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->NumberOfRanks));
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfRanks));
|
||||
lastScheduledByCommand = std::vector<sc_time>(numberOfCommands());
|
||||
|
||||
lastActivates = std::vector<std::queue<sc_time>>(memSpec->NumberOfRanks);
|
||||
bankwiseRefreshCounter = std::vector<unsigned>(memSpec->NumberOfRanks);
|
||||
|
||||
burstClocks = (memSpec->BurstLength / 2) * memSpec->clk;
|
||||
lastActivates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
|
||||
bankwiseRefreshCounter = std::vector<unsigned>(memSpec->numberOfRanks);
|
||||
}
|
||||
|
||||
sc_time CheckerHBM2::delayToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
@@ -77,43 +75,43 @@ sc_time CheckerHBM2::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tRTP + memSpec->tRP - memSpec->clk);
|
||||
+ memSpec->tRTP + memSpec->tRP - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR + memSpec->tRP - memSpec->clk);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tRP - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC - memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFB][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCSB - memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCSB - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFB][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD - memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD - memSpec->tCK);
|
||||
|
||||
if (lastActivates[rank.ID()].size() == 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart,
|
||||
lastActivates[rank.ID()].front() + memSpec->tFAW - memSpec->clk);
|
||||
lastActivates[rank.ID()].front() + memSpec->tFAW - memSpec->tCK);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRASBus + memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::RD || command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDRD + memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDRD + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -134,37 +132,37 @@ sc_time CheckerHBM2::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRL);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWTRL);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR - memSpec->tRTP);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR - memSpec->tRTP);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRS);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRL);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWTRL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRS);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWTRS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnCASBus + memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnCasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDWR + memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDWR + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -190,12 +188,12 @@ sc_time CheckerHBM2::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnCASBus + memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnCasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::PRE)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -204,14 +202,14 @@ sc_time CheckerHBM2::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRASBus + memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::PREA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -224,20 +222,20 @@ sc_time CheckerHBM2::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRASBus + memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::REFA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -246,7 +244,7 @@ sc_time CheckerHBM2::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR + memSpec->tRP);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -260,21 +258,21 @@ sc_time CheckerHBM2::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRASBus + memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::REFB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDL + memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDL + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS + memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -283,7 +281,7 @@ sc_time CheckerHBM2::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR + memSpec->tRP);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -305,14 +303,14 @@ sc_time CheckerHBM2::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
if (lastActivates[rank.ID()].size() == 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastActivates[rank.ID()].front() + memSpec->tFAW);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRASBus + memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else
|
||||
{
|
||||
reportFatal("CheckerHBM2", "Unknown command!");
|
||||
}
|
||||
|
||||
return (earliestTimeToStart - sc_time_stamp());
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerHBM2::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank)
|
||||
@@ -325,20 +323,20 @@ void CheckerHBM2::insert(Command command, Rank rank, BankGroup bankgroup, Bank b
|
||||
lastScheduledByCommandAndRank[command][rank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommand[command] = sc_time_stamp();
|
||||
|
||||
if (command == Command::RD || command == Command::RDA || command == Command::WR || command == Command::WRA)
|
||||
lastCommandOnCASBus = sc_time_stamp();
|
||||
if (isCasCommand(command))
|
||||
lastCommandOnCasBus = sc_time_stamp();
|
||||
else if (command == Command::ACT)
|
||||
lastCommandOnRASBus = sc_time_stamp() + memSpec->clk;
|
||||
lastCommandOnRasBus = sc_time_stamp() + memSpec->tCK;
|
||||
else
|
||||
lastCommandOnRASBus = sc_time_stamp();
|
||||
lastCommandOnRasBus = sc_time_stamp();
|
||||
|
||||
if (command == Command::ACT || command == Command::REFB)
|
||||
{
|
||||
if (lastActivates[rank.ID()].size() == 4)
|
||||
lastActivates[rank.ID()].pop();
|
||||
lastActivates[rank.ID()].push(lastCommandOnRASBus);
|
||||
lastActivates[rank.ID()].push(lastCommandOnRasBus);
|
||||
}
|
||||
|
||||
if (command == Command::REFB)
|
||||
bankwiseRefreshCounter[rank.ID()] = (bankwiseRefreshCounter[rank.ID()] + 1) % memSpec->BanksPerRank;
|
||||
bankwiseRefreshCounter[rank.ID()] = (bankwiseRefreshCounter[rank.ID()] + 1) % memSpec->banksPerRank;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ class CheckerHBM2 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerHBM2();
|
||||
virtual sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
|
||||
private:
|
||||
@@ -55,14 +55,12 @@ private:
|
||||
std::vector<std::vector<sc_time>> lastScheduledByCommandAndBankGroup;
|
||||
std::vector<std::vector<sc_time>> lastScheduledByCommandAndRank;
|
||||
std::vector<sc_time> lastScheduledByCommand;
|
||||
sc_time lastCommandOnRASBus;
|
||||
sc_time lastCommandOnCASBus;
|
||||
sc_time lastCommandOnRasBus;
|
||||
sc_time lastCommandOnCasBus;
|
||||
|
||||
// Four activate window
|
||||
std::vector<std::queue<sc_time>> lastActivates;
|
||||
std::vector<unsigned> bankwiseRefreshCounter;
|
||||
|
||||
sc_time burstClocks;
|
||||
};
|
||||
|
||||
#endif // CHECKERHBM2_H
|
||||
|
||||
@@ -46,7 +46,7 @@ class CheckerIF
|
||||
public:
|
||||
virtual ~CheckerIF() {}
|
||||
|
||||
virtual sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const = 0;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const = 0;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -42,15 +42,15 @@ CheckerLPDDR4::CheckerLPDDR4()
|
||||
SC_REPORT_FATAL("CheckerLPDDR4", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->NumberOfBanks));
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfBanks));
|
||||
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->NumberOfRanks));
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfRanks));
|
||||
lastScheduledByCommand = std::vector<sc_time>(numberOfCommands());
|
||||
|
||||
lastActivates = std::vector<std::queue<sc_time>>(memSpec->NumberOfRanks);
|
||||
lastActivates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
|
||||
}
|
||||
|
||||
sc_time CheckerLPDDR4::delayToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const
|
||||
sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
@@ -63,16 +63,16 @@ sc_time CheckerLPDDR4::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + memSpec->tCCD
|
||||
+ memSpec->tWR + memSpec->clk + memSpec->tRPpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + memSpec->burstDuration
|
||||
+ memSpec->tWR + memSpec->tCK + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPpb - 2 * memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPpb - 2 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab - 2 * memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab - 2 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -84,18 +84,18 @@ sc_time CheckerLPDDR4::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab - 2 * memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab - 2 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFB][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb - 2 * memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb - 2 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFB][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD - 2 * memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD - 2 * memSpec->tCK);
|
||||
|
||||
if (lastActivates[rank.ID()].size() == 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastActivates[rank.ID()].front() + memSpec->tFAW - 3 * memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastActivates[rank.ID()].front() + memSpec->tFAW - 3 * memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::RD || command == Command::RDA)
|
||||
{
|
||||
@@ -112,19 +112,19 @@ sc_time CheckerLPDDR4::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + memSpec->clk + memSpec->tCCD + memSpec->tWTR);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + memSpec->tCK + memSpec->burstDuration + memSpec->tWTR);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + memSpec->clk + memSpec->tCCD + memSpec->tWR - memSpec->tRTP);
|
||||
+ memSpec->tWL + memSpec->tCK + memSpec->burstDuration + memSpec->tWR - memSpec->tRTP);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + memSpec->clk + memSpec->tCCD + memSpec->tWTR);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + memSpec->tCK + memSpec->burstDuration + memSpec->tWTR);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
{
|
||||
@@ -133,11 +133,11 @@ sc_time CheckerLPDDR4::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRL + memSpec->tDQSCK + memSpec->tCCD - memSpec->tWL + memSpec->tWPRE + memSpec->tRPST);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRL + memSpec->tDQSCK + memSpec->burstDuration - memSpec->tWL + memSpec->tWPRE + memSpec->tRPST);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRL + memSpec->tDQSCK + memSpec->tCCD - memSpec->tWL + memSpec->tWPRE + memSpec->tRPST);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRL + memSpec->tDQSCK + memSpec->burstDuration - memSpec->tWL + memSpec->tWPRE + memSpec->tRPST);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -150,15 +150,15 @@ sc_time CheckerLPDDR4::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
else if (command == Command::PRE)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + 2 * memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + 2 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD + memSpec->tRTP - 6 * memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->burstDuration + memSpec->tRTP - 6 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + memSpec->tCCD + memSpec->tWR + 3 * memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + memSpec->burstDuration + memSpec->tWR + 3 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -167,23 +167,23 @@ sc_time CheckerLPDDR4::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
else if (command == Command::PREA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + 2 * memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + 2 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD + memSpec->tRTP - 6 * memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->burstDuration + memSpec->tRTP - 6 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD + memSpec->tRTP - 6 * memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->burstDuration + memSpec->tRTP - 6 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + memSpec->tCCD + memSpec->tWR + 3 * memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + memSpec->burstDuration + memSpec->tWR + 3 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + memSpec->tCCD + memSpec->tWR + 3 * memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + memSpec->burstDuration + memSpec->tWR + 3 * memSpec->tCK);
|
||||
|
||||
// lastCommandStart = lastScheduledByCommandAndRank[Command::REFB][rank.ID()];
|
||||
// if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -197,16 +197,16 @@ sc_time CheckerLPDDR4::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tRPpb + 2 * memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tRPpb + 2 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRPpb + 2 * memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRPpb + 2 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + memSpec->tCCD
|
||||
+ memSpec->tWR + 3 * memSpec->clk + memSpec->tRPpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + memSpec->burstDuration
|
||||
+ memSpec->tWR + 3 * memSpec->tCK + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -228,20 +228,20 @@ sc_time CheckerLPDDR4::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tRPpb + 2 * memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tRPpb + 2 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD + 2 * memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD + 2 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRPpb + 2 * memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRPpb + 2 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + memSpec->tCCD
|
||||
+ memSpec->tWR + 3 * memSpec->clk + memSpec->tRPpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + memSpec->burstDuration
|
||||
+ memSpec->tWR + 3 * memSpec->tCK + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -260,16 +260,16 @@ sc_time CheckerLPDDR4::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
|
||||
if (lastActivates[rank.ID()].size() == 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastActivates[rank.ID()].front() + memSpec->tFAW - memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastActivates[rank.ID()].front() + memSpec->tFAW - memSpec->tCK);
|
||||
}
|
||||
else
|
||||
{
|
||||
reportFatal("CheckerLPDDR4", "Unknown command!");
|
||||
}
|
||||
// Check if command bus is free
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK);
|
||||
|
||||
return (earliestTimeToStart - sc_time_stamp());
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerLPDDR4::insert(Command command, Rank rank, BankGroup, Bank bank)
|
||||
@@ -280,7 +280,7 @@ void CheckerLPDDR4::insert(Command command, Rank rank, BankGroup, Bank bank)
|
||||
lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndRank[command][rank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommand[command] = sc_time_stamp();
|
||||
lastCommandOnBus = sc_time_stamp() + (memSpec->getCommandLength(command) - 1) * memSpec->clk;
|
||||
lastCommandOnBus = sc_time_stamp() + memSpec->getCommandLength(command) - memSpec->tCK;
|
||||
|
||||
if (command == Command::ACT || command == Command::REFB)
|
||||
{
|
||||
|
||||
@@ -45,7 +45,7 @@ class CheckerLPDDR4 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerLPDDR4();
|
||||
virtual sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -42,17 +42,15 @@ CheckerWideIO::CheckerWideIO()
|
||||
SC_REPORT_FATAL("CheckerWideIO", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->NumberOfBanks));
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfBanks));
|
||||
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->NumberOfRanks));
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfRanks));
|
||||
lastScheduledByCommand = std::vector<sc_time>(numberOfCommands());
|
||||
|
||||
lastActivates = std::vector<std::queue<sc_time>>(memSpec->NumberOfRanks);
|
||||
|
||||
burstClocks = memSpec->BurstLength * memSpec->clk;
|
||||
lastActivates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
|
||||
}
|
||||
|
||||
sc_time CheckerWideIO::delayToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const
|
||||
sc_time CheckerWideIO::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
@@ -61,12 +59,12 @@ sc_time CheckerWideIO::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + burstClocks + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->burstDuration + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL
|
||||
+ burstClocks - memSpec->clk + memSpec->tWR + memSpec->tRP);
|
||||
+ memSpec->burstDuration - memSpec->tCK + memSpec->tWR + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -98,29 +96,29 @@ sc_time CheckerWideIO::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + burstClocks);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->burstDuration);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + burstClocks);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->burstDuration);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks - memSpec->clk + memSpec->tWTR);
|
||||
+ memSpec->tWL + memSpec->burstDuration - memSpec->tCK + memSpec->tWTR);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + memSpec->clk + memSpec->tWR);
|
||||
+ memSpec->tWL + memSpec->tCK + memSpec->tWR);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks - memSpec->clk + memSpec->tWTR);
|
||||
+ memSpec->tWL + memSpec->burstDuration - memSpec->tCK + memSpec->tWTR);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
{
|
||||
@@ -130,20 +128,20 @@ sc_time CheckerWideIO::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tRL + burstClocks + memSpec->clk);
|
||||
+ memSpec->tRL + memSpec->burstDuration + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tRL + burstClocks + memSpec->clk);
|
||||
+ memSpec->tRL + memSpec->burstDuration + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + burstClocks);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->burstDuration);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + burstClocks);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->burstDuration);
|
||||
}
|
||||
else if (command == Command::PRE)
|
||||
{
|
||||
@@ -152,12 +150,12 @@ sc_time CheckerWideIO::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + burstClocks);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->burstDuration);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks - memSpec->clk + memSpec->tWR);
|
||||
+ memSpec->tWL + memSpec->burstDuration - memSpec->tCK + memSpec->tWR);
|
||||
}
|
||||
else if (command == Command::PREA)
|
||||
{
|
||||
@@ -166,21 +164,21 @@ sc_time CheckerWideIO::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + burstClocks);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->burstDuration);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + burstClocks);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->burstDuration);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks - memSpec->clk + memSpec->tWR);
|
||||
+ memSpec->tWL + memSpec->burstDuration - memSpec->tCK + memSpec->tWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks - memSpec->clk + memSpec->tWR);
|
||||
+ memSpec->tWL + memSpec->burstDuration - memSpec->tCK + memSpec->tWR);
|
||||
}
|
||||
else if (command == Command::REFA)
|
||||
{
|
||||
@@ -190,12 +188,12 @@ sc_time CheckerWideIO::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + burstClocks + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->burstDuration + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks - memSpec->clk + memSpec->tWR + memSpec->tRP);
|
||||
+ memSpec->tWL + memSpec->burstDuration - memSpec->tCK + memSpec->tWR + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -214,9 +212,9 @@ sc_time CheckerWideIO::delayToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
reportFatal("CheckerWideIO", "Unknown command!");
|
||||
}
|
||||
// Check if command bus is free
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastScheduled + memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastScheduled + memSpec->tCK);
|
||||
|
||||
return (earliestTimeToStart - sc_time_stamp());
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerWideIO::insert(Command command, Rank rank, BankGroup, Bank bank)
|
||||
|
||||
@@ -45,7 +45,7 @@ class CheckerWideIO final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerWideIO();
|
||||
virtual sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
|
||||
private:
|
||||
@@ -58,8 +58,6 @@ private:
|
||||
|
||||
// Four activate window
|
||||
std::vector<std::queue<sc_time>> lastActivates;
|
||||
|
||||
sc_time burstClocks;
|
||||
};
|
||||
|
||||
#endif // CHECKERWIDEIO_H
|
||||
|
||||
@@ -42,15 +42,15 @@ CheckerWideIO2::CheckerWideIO2()
|
||||
SC_REPORT_FATAL("CheckerWideIO2", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->NumberOfBanks));
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfBanks));
|
||||
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->NumberOfRanks));
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfRanks));
|
||||
lastScheduledByCommand = std::vector<sc_time>(numberOfCommands());
|
||||
|
||||
lastActivates = std::vector<std::queue<sc_time>>(memSpec->NumberOfRanks);
|
||||
lastActivates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
|
||||
}
|
||||
|
||||
sc_time CheckerWideIO2::delayToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const
|
||||
sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
@@ -68,12 +68,12 @@ sc_time CheckerWideIO2::delayToSatisfyConstraints(Command command, Rank rank, Ba
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tCCD + memSpec->tRTP - 2 * memSpec->clk + memSpec->tRPpb);
|
||||
+ memSpec->burstDuration + memSpec->tRTP - 2 * memSpec->tCK + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + memSpec->tCCD + memSpec->tWR + memSpec->clk + memSpec->tRPpb);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tCK + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -114,20 +114,20 @@ sc_time CheckerWideIO2::delayToSatisfyConstraints(Command command, Rank rank, Ba
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + memSpec->clk + memSpec->tCCD + memSpec->tWTR);
|
||||
+ memSpec->tWL + memSpec->tCK + memSpec->burstDuration + memSpec->tWTR);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + memSpec->clk + memSpec->tCCD + memSpec->tWR - memSpec->tRTP);
|
||||
+ memSpec->tWL + memSpec->tCK + memSpec->burstDuration + memSpec->tWR - memSpec->tRTP);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + memSpec->clk + memSpec->tCCD + memSpec->tWTR);
|
||||
+ memSpec->tWL + memSpec->tCK + memSpec->burstDuration + memSpec->tWTR);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
{
|
||||
@@ -137,12 +137,12 @@ sc_time CheckerWideIO2::delayToSatisfyConstraints(Command command, Rank rank, Ba
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tRL + memSpec->tDQSCK + memSpec->tCCD + memSpec->clk - memSpec->tWL);
|
||||
+ memSpec->tRL + memSpec->tDQSCK + memSpec->burstDuration + memSpec->tCK - memSpec->tWL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tRL + memSpec->tDQSCK + memSpec->tCCD + memSpec->clk - memSpec->tWL);
|
||||
+ memSpec->tRL + memSpec->tDQSCK + memSpec->burstDuration + memSpec->tCK - memSpec->tWL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -160,12 +160,12 @@ sc_time CheckerWideIO2::delayToSatisfyConstraints(Command command, Rank rank, Ba
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tCCD + memSpec->tRTP - 2 * memSpec->clk);
|
||||
+ memSpec->burstDuration + memSpec->tRTP - 2 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + memSpec->tCCD + memSpec->tWR + memSpec->clk);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::PREA)
|
||||
{
|
||||
@@ -175,26 +175,26 @@ sc_time CheckerWideIO2::delayToSatisfyConstraints(Command command, Rank rank, Ba
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tCCD + memSpec->tRTP - 2 * memSpec->clk);
|
||||
+ memSpec->burstDuration + memSpec->tRTP - 2 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tCCD + memSpec->tRTP - 2 * memSpec->clk);
|
||||
+ memSpec->burstDuration + memSpec->tRTP - 2 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + memSpec->tCCD + memSpec->tWR + memSpec->clk);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + memSpec->tCCD + memSpec->tWR + memSpec->clk);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 2 * memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 2 * memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::REFA)
|
||||
{
|
||||
@@ -205,12 +205,12 @@ sc_time CheckerWideIO2::delayToSatisfyConstraints(Command command, Rank rank, Ba
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tCCD + memSpec->tRTP - 2 * memSpec->clk + memSpec->tRPpb);
|
||||
+ memSpec->burstDuration + memSpec->tRTP - 2 * memSpec->tCK + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + memSpec->tCCD + memSpec->tWR + memSpec->clk + memSpec->tRPpb);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tCK + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -237,12 +237,12 @@ sc_time CheckerWideIO2::delayToSatisfyConstraints(Command command, Rank rank, Ba
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tCCD + memSpec->tRTP - 2 * memSpec->clk + memSpec->tRPpb);
|
||||
+ memSpec->burstDuration + memSpec->tRTP - 2 * memSpec->tCK + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + memSpec->tCCD + memSpec->tWR + memSpec->clk + memSpec->tRPpb);
|
||||
+ memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tCK + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -260,9 +260,9 @@ sc_time CheckerWideIO2::delayToSatisfyConstraints(Command command, Rank rank, Ba
|
||||
reportFatal("CheckerWideIO2", "Unknown command!");
|
||||
}
|
||||
// Check if command bus is free
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK);
|
||||
|
||||
return (earliestTimeToStart - sc_time_stamp());
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerWideIO2::insert(Command command, Rank rank, BankGroup, Bank bank)
|
||||
|
||||
@@ -45,7 +45,7 @@ class CheckerWideIO2 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerWideIO2();
|
||||
virtual sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -40,14 +40,12 @@
|
||||
#include <vector>
|
||||
#include "../Command.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
class CmdMuxIF
|
||||
{
|
||||
public:
|
||||
virtual ~CmdMuxIF() {}
|
||||
virtual std::pair<Command, tlm_generic_payload *>
|
||||
selectCommand(std::vector<std::pair<Command, tlm_generic_payload *>> &) = 0;
|
||||
virtual std::pair<Command, tlm::tlm_generic_payload *>
|
||||
selectCommand(std::vector<std::pair<Command, tlm::tlm_generic_payload *>> &) = 0;
|
||||
};
|
||||
|
||||
#endif // CMDMUXIF_H
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
|
||||
#include "../../common/dramExtensions.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
std::pair<Command, tlm_generic_payload *>
|
||||
CmdMuxOldest::selectCommand(std::vector<std::pair<Command, tlm_generic_payload *>> &readyCommands)
|
||||
{
|
||||
|
||||
@@ -40,8 +40,8 @@
|
||||
class CmdMuxOldest : public CmdMuxIF
|
||||
{
|
||||
public:
|
||||
std::pair<Command, tlm_generic_payload *>
|
||||
selectCommand(std::vector<std::pair<Command, tlm_generic_payload *>> &);
|
||||
std::pair<Command, tlm::tlm_generic_payload *>
|
||||
selectCommand(std::vector<std::pair<Command, tlm::tlm_generic_payload *>> &);
|
||||
};
|
||||
|
||||
#endif // CMDMUXOLDEST_H
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
|
||||
#include "../../common/dramExtensions.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
std::pair<Command, tlm_generic_payload *>
|
||||
CmdMuxStrict::selectCommand(std::vector<std::pair<Command, tlm_generic_payload *>> &readyCommands)
|
||||
{
|
||||
|
||||
@@ -40,8 +40,8 @@
|
||||
class CmdMuxStrict : public CmdMuxIF
|
||||
{
|
||||
public:
|
||||
std::pair<Command, tlm_generic_payload *>
|
||||
selectCommand(std::vector<std::pair<Command, tlm_generic_payload *>> &);
|
||||
std::pair<Command, tlm::tlm_generic_payload *>
|
||||
selectCommand(std::vector<std::pair<Command, tlm::tlm_generic_payload *>> &);
|
||||
|
||||
private:
|
||||
uint64_t nextPayloadID = 0;
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
|
||||
#include "PowerDownManagerDummy.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
std::pair<Command, tlm_generic_payload *> PowerDownManagerDummy::getNextCommand()
|
||||
{
|
||||
return std::pair<Command, tlm_generic_payload *>(Command::NOP, nullptr);
|
||||
@@ -41,5 +43,5 @@ std::pair<Command, tlm_generic_payload *> PowerDownManagerDummy::getNextCommand(
|
||||
|
||||
sc_time PowerDownManagerDummy::start()
|
||||
{
|
||||
return sc_max_time() - sc_time_stamp();
|
||||
return sc_max_time();
|
||||
}
|
||||
|
||||
@@ -37,17 +37,16 @@
|
||||
|
||||
#include "PowerDownManagerIF.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
class PowerDownManagerDummy final : public PowerDownManagerIF
|
||||
{
|
||||
public:
|
||||
PowerDownManagerDummy() {}
|
||||
|
||||
virtual void triggerEntry(TriggerSource) override {}
|
||||
virtual void triggerExit(TriggerSource) override {}
|
||||
virtual void triggerEntry() override {}
|
||||
virtual void triggerExit() override {}
|
||||
virtual void triggerInterruption() override {}
|
||||
|
||||
virtual std::pair<Command, tlm_generic_payload *> getNextCommand() override;
|
||||
virtual std::pair<Command, tlm::tlm_generic_payload *> getNextCommand() override;
|
||||
virtual void updateState(Command) override {}
|
||||
virtual sc_time start() override;
|
||||
};
|
||||
|
||||
@@ -40,19 +40,16 @@
|
||||
#include <tlm.h>
|
||||
#include "../Command.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
enum class TriggerSource {Controller, RefreshManager};
|
||||
|
||||
class PowerDownManagerIF
|
||||
{
|
||||
public:
|
||||
virtual ~PowerDownManagerIF() {}
|
||||
|
||||
virtual void triggerEntry(TriggerSource) = 0;
|
||||
virtual void triggerExit(TriggerSource) = 0;
|
||||
virtual void triggerEntry() = 0;
|
||||
virtual void triggerExit() = 0;
|
||||
virtual void triggerInterruption() = 0;
|
||||
|
||||
virtual std::pair<Command, tlm_generic_payload *> getNextCommand() = 0;
|
||||
virtual std::pair<Command, tlm::tlm_generic_payload *> getNextCommand() = 0;
|
||||
virtual void updateState(Command) = 0;
|
||||
virtual sc_time start() = 0;
|
||||
};
|
||||
|
||||
@@ -35,46 +35,38 @@
|
||||
#include "PowerDownManagerStaggered.h"
|
||||
#include "../../common/utils.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
PowerDownManagerStaggered::PowerDownManagerStaggered(Rank rank, CheckerIF *checker)
|
||||
: rank(rank), checker(checker)
|
||||
{
|
||||
setUpDummy(powerDownPayload, rank);
|
||||
}
|
||||
|
||||
void PowerDownManagerStaggered::triggerEntry(TriggerSource source)
|
||||
void PowerDownManagerStaggered::triggerEntry()
|
||||
{
|
||||
if (source == TriggerSource::Controller)
|
||||
controllerIdle = true;
|
||||
controllerIdle = true;
|
||||
|
||||
// TODO: check if state is always idle here
|
||||
if (state == PdmState::Idle && controllerIdle)
|
||||
triggered = true;
|
||||
if (state == PdmState::Idle)
|
||||
entryTriggered = true;
|
||||
}
|
||||
|
||||
void PowerDownManagerStaggered::triggerExit(TriggerSource source)
|
||||
void PowerDownManagerStaggered::triggerExit()
|
||||
{
|
||||
if (source == TriggerSource::Controller)
|
||||
{
|
||||
controllerIdle = false;
|
||||
enterSelfRefresh = false;
|
||||
controllerIdle = false;
|
||||
enterSelfRefresh = false;
|
||||
entryTriggered = false;
|
||||
|
||||
if (state == PdmState::Idle)
|
||||
triggered = false;
|
||||
else
|
||||
triggered = true;
|
||||
}
|
||||
else // if (source == TriggerSource::RefreshManager)
|
||||
{
|
||||
if (state == PdmState::Idle && !enterSelfRefresh)
|
||||
triggered = false;
|
||||
else if (state == PdmState::PrechargePd && !triggered)
|
||||
{
|
||||
triggered = true;
|
||||
enterSelfRefresh = true;
|
||||
}
|
||||
else if (state == PdmState::ActivePd) // TODO: check if normal else is also ok here
|
||||
triggered = true;
|
||||
}
|
||||
if (state != PdmState::Idle)
|
||||
exitTriggered = true;
|
||||
}
|
||||
|
||||
void PowerDownManagerStaggered::triggerInterruption()
|
||||
{
|
||||
entryTriggered = false;
|
||||
|
||||
if (state != PdmState::Idle)
|
||||
exitTriggered = true;
|
||||
}
|
||||
|
||||
std::pair<Command, tlm_generic_payload *> PowerDownManagerStaggered::getNextCommand()
|
||||
@@ -88,75 +80,89 @@ std::pair<Command, tlm_generic_payload *> PowerDownManagerStaggered::getNextComm
|
||||
sc_time PowerDownManagerStaggered::start()
|
||||
{
|
||||
timeToSchedule = sc_max_time();
|
||||
sc_time delay = sc_max_time() - sc_time_stamp();
|
||||
|
||||
if (triggered)
|
||||
if (exitTriggered)
|
||||
{
|
||||
if (state == PdmState::Idle)
|
||||
{
|
||||
if (enterSelfRefresh)
|
||||
nextCommand = Command::SREFEN;
|
||||
else if (activatedBanks == 0)
|
||||
nextCommand = Command::PDEP;
|
||||
else
|
||||
nextCommand = Command::PDEA;
|
||||
}
|
||||
else if (state == PdmState::ActivePd)
|
||||
if (state == PdmState::ActivePdn)
|
||||
nextCommand = Command::PDXA;
|
||||
else if (state == PdmState::PrechargePd)
|
||||
else if (state == PdmState::PrechargePdn)
|
||||
nextCommand = Command::PDXP;
|
||||
else if (state == PdmState::SelfRefresh)
|
||||
nextCommand = Command::SREFEX;
|
||||
else // if (state == PdmState::Refresh)
|
||||
else if (state == PdmState::ExtraRefresh)
|
||||
nextCommand = Command::REFA;
|
||||
|
||||
delay = checker->delayToSatisfyConstraints(nextCommand, rank, BankGroup(0), Bank(0));
|
||||
timeToSchedule = sc_time_stamp() + delay;
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, BankGroup(0), Bank(0));
|
||||
}
|
||||
else if (entryTriggered)
|
||||
{
|
||||
if (activatedBanks != 0)
|
||||
nextCommand = Command::PDEA;
|
||||
else
|
||||
nextCommand = Command::PDEP;
|
||||
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, BankGroup(0), Bank(0));
|
||||
}
|
||||
else if (enterSelfRefresh)
|
||||
{
|
||||
nextCommand = Command::SREFEN;
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, BankGroup(0), Bank(0));
|
||||
}
|
||||
|
||||
return delay;
|
||||
return timeToSchedule;
|
||||
}
|
||||
|
||||
void PowerDownManagerStaggered::updateState(Command command)
|
||||
{
|
||||
if (command == Command::ACT)
|
||||
switch (command)
|
||||
{
|
||||
case Command::ACT:
|
||||
activatedBanks++;
|
||||
else if (command == Command::PRE)
|
||||
break;
|
||||
case Command::PRE:
|
||||
activatedBanks--;
|
||||
else if (command == Command::PREA)
|
||||
break;
|
||||
case Command::PREA:
|
||||
activatedBanks = 0;
|
||||
else if (command == Command::PDEA)
|
||||
{
|
||||
state = PdmState::ActivePd;
|
||||
triggered = false;
|
||||
}
|
||||
else if (command == Command::PDEP)
|
||||
{
|
||||
state = PdmState::PrechargePd;
|
||||
triggered = false;
|
||||
}
|
||||
else if (command == Command::SREFEN)
|
||||
{
|
||||
break;
|
||||
case Command::PDEA:
|
||||
state = PdmState::ActivePdn;
|
||||
entryTriggered = false;
|
||||
break;
|
||||
case Command::PDEP:
|
||||
state = PdmState::PrechargePdn;
|
||||
entryTriggered = false;
|
||||
break;
|
||||
case Command::SREFEN:
|
||||
state = PdmState::SelfRefresh;
|
||||
triggered = false;
|
||||
entryTriggered = false;
|
||||
enterSelfRefresh = false;
|
||||
}
|
||||
else if (command == Command::PDXA)
|
||||
{
|
||||
break;
|
||||
case Command::PDXA:
|
||||
state = PdmState::Idle;
|
||||
triggered = false;
|
||||
}
|
||||
else if (command == Command::PDXP)
|
||||
{
|
||||
exitTriggered = false;
|
||||
break;
|
||||
case Command::PDXP:
|
||||
state = PdmState::Idle;
|
||||
if (!enterSelfRefresh)
|
||||
triggered = false;
|
||||
}
|
||||
else if (command == Command::SREFEX)
|
||||
state = PdmState::Refresh;
|
||||
else if (command == Command::REFA && state == PdmState::Refresh)
|
||||
{
|
||||
state = PdmState::Idle;
|
||||
triggered = false;
|
||||
exitTriggered = false;
|
||||
if (controllerIdle)
|
||||
enterSelfRefresh = true;
|
||||
break;
|
||||
case Command::SREFEX:
|
||||
state = PdmState::ExtraRefresh;
|
||||
break;
|
||||
case Command::REFA:
|
||||
if (state == PdmState::ExtraRefresh)
|
||||
{
|
||||
state = PdmState::Idle;
|
||||
exitTriggered = false;
|
||||
}
|
||||
else if (controllerIdle)
|
||||
entryTriggered = true;
|
||||
break;
|
||||
case Command::REFB:
|
||||
if (controllerIdle)
|
||||
entryTriggered = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,32 +39,32 @@
|
||||
#include "../BankMachine.h"
|
||||
#include "../checker/CheckerIF.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
class PowerDownManagerStaggered final : public PowerDownManagerIF
|
||||
{
|
||||
public:
|
||||
PowerDownManagerStaggered(Rank, CheckerIF *);
|
||||
|
||||
virtual void triggerEntry(TriggerSource) override;
|
||||
virtual void triggerExit(TriggerSource) override;
|
||||
virtual void triggerEntry() override;
|
||||
virtual void triggerExit() override;
|
||||
virtual void triggerInterruption() override;
|
||||
|
||||
virtual std::pair<Command, tlm_generic_payload *> getNextCommand() override;
|
||||
virtual std::pair<Command, tlm::tlm_generic_payload *> getNextCommand() override;
|
||||
virtual void updateState(Command) override;
|
||||
virtual sc_time start() override;
|
||||
|
||||
private:
|
||||
enum class PdmState {Idle, ActivePd, PrechargePd, SelfRefresh, Refresh} state = PdmState::Idle;
|
||||
tlm_generic_payload powerDownPayload;
|
||||
enum class PdmState {Idle, ActivePdn, PrechargePdn, SelfRefresh, ExtraRefresh} state = PdmState::Idle;
|
||||
tlm::tlm_generic_payload powerDownPayload;
|
||||
Rank rank;
|
||||
CheckerIF *checker;
|
||||
|
||||
sc_time timeToSchedule;
|
||||
sc_time timeToSchedule = sc_max_time();
|
||||
Command nextCommand;
|
||||
|
||||
bool triggered = false;
|
||||
bool enterSelfRefresh = false;
|
||||
bool controllerIdle = true;
|
||||
bool entryTriggered = true;
|
||||
bool exitTriggered = false;
|
||||
bool enterSelfRefresh = false;
|
||||
unsigned activatedBanks = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -37,33 +37,33 @@
|
||||
#include "../../common/utils.h"
|
||||
#include "../../common/dramExtensions.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
RefreshManagerBankwise::RefreshManagerBankwise(std::vector<BankMachine *> &bankMachines,
|
||||
PowerDownManagerIF *powerDownManager, Rank rank, CheckerIF *checker)
|
||||
: bankMachines(bankMachines), powerDownManager(powerDownManager), rank(rank), checker(checker)
|
||||
: bankMachinesOnRank(bankMachines), powerDownManager(powerDownManager), rank(rank), checker(checker)
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
memSpec = config.memSpec;
|
||||
timeForNextTrigger = memSpec->getRefreshIntervalPB();
|
||||
|
||||
refreshPayloads = std::vector<tlm_generic_payload>(memSpec->BanksPerRank);
|
||||
for (unsigned bankID = 0; bankID < memSpec->BanksPerRank; bankID++)
|
||||
refreshPayloads = std::vector<tlm_generic_payload>(memSpec->banksPerRank);
|
||||
for (unsigned bankID = 0; bankID < memSpec->banksPerRank; bankID++)
|
||||
{
|
||||
setUpDummy(refreshPayloads[bankID], rank, bankMachines[bankID]->getBank());
|
||||
allBankMachines.push_back(bankMachines[bankID]);
|
||||
}
|
||||
remainingBankMachines = allBankMachines;
|
||||
|
||||
if (config.ControllerCoreRefEnablePostpone)
|
||||
maxPostponed = config.ControllerCoreRefMaxPostponed * memSpec->BanksPerRank;
|
||||
if (config.ControllerCoreRefEnablePullIn)
|
||||
maxPulledin = -(config.ControllerCoreRefMaxPulledIn * memSpec->BanksPerRank);
|
||||
maxPostponed = config.refreshMaxPostponed * memSpec->banksPerRank;
|
||||
maxPulledin = -(config.refreshMaxPulledin * memSpec->banksPerRank);
|
||||
}
|
||||
|
||||
std::pair<Command, tlm_generic_payload *> RefreshManagerBankwise::getNextCommand()
|
||||
{
|
||||
if (sc_time_stamp() == timeToSchedule)
|
||||
return std::pair<Command, tlm_generic_payload *>
|
||||
(nextCommand, &refreshPayloads[currentBankMachine->getBank().ID() % memSpec->BanksPerRank]);
|
||||
(nextCommand, &refreshPayloads[currentBankMachine->getBank().ID() % memSpec->banksPerRank]);
|
||||
else
|
||||
return std::pair<Command, tlm_generic_payload *>(Command::NOP, nullptr);
|
||||
}
|
||||
@@ -74,9 +74,9 @@ sc_time RefreshManagerBankwise::start()
|
||||
|
||||
if (sc_time_stamp() >= timeForNextTrigger)
|
||||
{
|
||||
powerDownManager->triggerExit(TriggerSource::RefreshManager);
|
||||
powerDownManager->triggerInterruption();
|
||||
if (sleeping)
|
||||
return sc_max_time() - sc_time_stamp();
|
||||
return timeToSchedule;
|
||||
|
||||
if (sc_time_stamp() >= timeForNextTrigger + memSpec->getRefreshIntervalPB())
|
||||
{
|
||||
@@ -84,7 +84,6 @@ sc_time RefreshManagerBankwise::start()
|
||||
state = RmState::Regular;
|
||||
}
|
||||
|
||||
sc_time delay;
|
||||
if (state == RmState::Regular)
|
||||
{
|
||||
currentIterator = remainingBankMachines.begin();
|
||||
@@ -107,7 +106,7 @@ sc_time RefreshManagerBankwise::start()
|
||||
{
|
||||
flexibilityCounter++;
|
||||
timeForNextTrigger += memSpec->getRefreshIntervalPB();
|
||||
return timeForNextTrigger - sc_time_stamp();
|
||||
return timeForNextTrigger;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -115,10 +114,9 @@ sc_time RefreshManagerBankwise::start()
|
||||
nextCommand = Command::PRE;
|
||||
else
|
||||
nextCommand = Command::REFB;
|
||||
delay = checker->delayToSatisfyConstraints(nextCommand, rank,
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank,
|
||||
currentBankMachine->getBankGroup(), currentBankMachine->getBank());
|
||||
timeToSchedule = sc_time_stamp() + delay;
|
||||
return delay;
|
||||
return timeToSchedule;
|
||||
}
|
||||
}
|
||||
else // if (state == RmState::Pulledin)
|
||||
@@ -140,7 +138,7 @@ sc_time RefreshManagerBankwise::start()
|
||||
{
|
||||
state = RmState::Regular;
|
||||
timeForNextTrigger += memSpec->getRefreshIntervalPB();
|
||||
return timeForNextTrigger - sc_time_stamp();
|
||||
return timeForNextTrigger;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -148,21 +146,21 @@ sc_time RefreshManagerBankwise::start()
|
||||
nextCommand = Command::PRE;
|
||||
else
|
||||
nextCommand = Command::REFB;
|
||||
delay = checker->delayToSatisfyConstraints(nextCommand, rank,
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank,
|
||||
currentBankMachine->getBankGroup(), currentBankMachine->getBank());
|
||||
timeToSchedule = sc_time_stamp() + delay;
|
||||
return delay;
|
||||
return timeToSchedule;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return timeForNextTrigger - sc_time_stamp();
|
||||
return timeForNextTrigger;
|
||||
}
|
||||
|
||||
void RefreshManagerBankwise::updateState(Command command, tlm_generic_payload *payload)
|
||||
{
|
||||
if (command == Command::REFB)
|
||||
switch (command)
|
||||
{
|
||||
case Command::REFB:
|
||||
remainingBankMachines.erase(currentIterator);
|
||||
if (remainingBankMachines.empty())
|
||||
remainingBankMachines = allBankMachines;
|
||||
@@ -176,23 +174,23 @@ void RefreshManagerBankwise::updateState(Command command, tlm_generic_payload *p
|
||||
{
|
||||
state = RmState::Regular;
|
||||
timeForNextTrigger += memSpec->getRefreshIntervalPB();
|
||||
powerDownManager->triggerEntry(TriggerSource::RefreshManager);
|
||||
}
|
||||
}
|
||||
else if (command == Command::REFA)
|
||||
{
|
||||
break;
|
||||
case Command::REFA:
|
||||
// Refresh command after SREFEX
|
||||
state = RmState::Regular; // TODO: check if this assignment is necessary
|
||||
timeForNextTrigger = sc_time_stamp() + memSpec->getRefreshIntervalPB();
|
||||
sleeping = false;
|
||||
}
|
||||
else if (command == Command::PDEA || command == Command::PDEP)
|
||||
break;
|
||||
case Command::PDEA: case Command::PDEP:
|
||||
sleeping = true;
|
||||
else if (command == Command::SREFEN)
|
||||
{
|
||||
break;
|
||||
case Command::SREFEN:
|
||||
sleeping = true;
|
||||
timeForNextTrigger = sc_max_time();
|
||||
}
|
||||
else if (command == Command::PDXA || command == Command::PDXP)
|
||||
break;
|
||||
case Command::PDXA: case Command::PDXP:
|
||||
sleeping = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,26 +43,21 @@
|
||||
#include <utility>
|
||||
#include <list>
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
class RefreshManagerBankwise final : public RefreshManagerIF
|
||||
{
|
||||
public:
|
||||
RefreshManagerBankwise(std::vector<BankMachine *> &, PowerDownManagerIF *, Rank, CheckerIF *);
|
||||
|
||||
virtual std::pair<Command, tlm_generic_payload *> getNextCommand() override;
|
||||
virtual std::pair<Command, tlm::tlm_generic_payload *> getNextCommand() override;
|
||||
virtual sc_time start() override;
|
||||
virtual void updateState(Command, tlm_generic_payload *) override;
|
||||
|
||||
virtual void notifyActive() override {}
|
||||
virtual void notifyIdle() override {}
|
||||
virtual void updateState(Command, tlm::tlm_generic_payload *) override;
|
||||
|
||||
private:
|
||||
enum class RmState {Regular, Pulledin} state = RmState::Regular;
|
||||
const MemSpec *memSpec;
|
||||
std::vector<BankMachine *> &bankMachines;
|
||||
std::vector<BankMachine *> &bankMachinesOnRank;
|
||||
PowerDownManagerIF *powerDownManager;
|
||||
std::vector<tlm_generic_payload> refreshPayloads;
|
||||
std::vector<tlm::tlm_generic_payload> refreshPayloads;
|
||||
sc_time timeForNextTrigger = sc_max_time();
|
||||
sc_time timeToSchedule = sc_max_time();
|
||||
Rank rank;
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
|
||||
#include "RefreshManagerDummy.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
std::pair<Command, tlm_generic_payload *> RefreshManagerDummy::getNextCommand()
|
||||
{
|
||||
return std::pair<Command, tlm_generic_payload *>(Command::NOP, nullptr);
|
||||
@@ -41,5 +43,5 @@ std::pair<Command, tlm_generic_payload *> RefreshManagerDummy::getNextCommand()
|
||||
|
||||
sc_time RefreshManagerDummy::start()
|
||||
{
|
||||
return sc_max_time() - sc_time_stamp();
|
||||
return sc_max_time();
|
||||
}
|
||||
|
||||
@@ -41,17 +41,12 @@
|
||||
#include "RefreshManagerIF.h"
|
||||
#include "../Command.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
class RefreshManagerDummy final : public RefreshManagerIF
|
||||
{
|
||||
public:
|
||||
virtual std::pair<Command, tlm_generic_payload *> getNextCommand() override;
|
||||
virtual std::pair<Command, tlm::tlm_generic_payload *> getNextCommand() override;
|
||||
virtual sc_time start() override;
|
||||
virtual void updateState(Command, tlm_generic_payload *) override {}
|
||||
|
||||
virtual void notifyActive() override {}
|
||||
virtual void notifyIdle() override {}
|
||||
virtual void updateState(Command, tlm::tlm_generic_payload *) override {}
|
||||
};
|
||||
|
||||
#endif // REFRESHMANAGERDUMMY_H
|
||||
|
||||
@@ -40,19 +40,14 @@
|
||||
#include <utility>
|
||||
#include "../Command.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
class RefreshManagerIF
|
||||
{
|
||||
public:
|
||||
virtual ~RefreshManagerIF() {}
|
||||
|
||||
virtual std::pair<Command, tlm_generic_payload *> getNextCommand() = 0;
|
||||
virtual std::pair<Command, tlm::tlm_generic_payload *> getNextCommand() = 0;
|
||||
virtual sc_time start() = 0;
|
||||
virtual void updateState(Command, tlm_generic_payload *) = 0;
|
||||
|
||||
virtual void notifyIdle() = 0;
|
||||
virtual void notifyActive() = 0;
|
||||
virtual void updateState(Command, tlm::tlm_generic_payload *) = 0;
|
||||
};
|
||||
|
||||
#endif // REFRESHMANAGERIF_H
|
||||
|
||||
@@ -32,37 +32,27 @@
|
||||
* Author: Lukas Steiner
|
||||
*/
|
||||
|
||||
#include "RefreshManager.h"
|
||||
#include "RefreshManagerRankwise.h"
|
||||
#include "../../common/dramExtensions.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
#include "../../common/utils.h"
|
||||
|
||||
RefreshManager::RefreshManager(std::vector<BankMachine *> &bankMachines,
|
||||
using namespace tlm;
|
||||
|
||||
RefreshManagerRankwise::RefreshManagerRankwise(std::vector<BankMachine *> &bankMachines,
|
||||
PowerDownManagerIF *powerDownManager, Rank rank, CheckerIF *checker)
|
||||
: bankMachines(bankMachines), powerDownManager(powerDownManager), rank(rank), checker(checker)
|
||||
: bankMachinesOnRank(bankMachines), powerDownManager(powerDownManager), rank(rank), checker(checker)
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
memSpec = config.memSpec;
|
||||
timeForNextTrigger = memSpec->getRefreshIntervalAB();
|
||||
setUpDummy(refreshPayload, rank);
|
||||
|
||||
if (config.ControllerCoreRefEnablePostpone)
|
||||
maxPostponed = config.ControllerCoreRefMaxPostponed;
|
||||
if (config.ControllerCoreRefEnablePullIn)
|
||||
maxPulledin = -config.ControllerCoreRefMaxPulledIn;
|
||||
maxPostponed = config.refreshMaxPostponed;
|
||||
maxPulledin = -config.refreshMaxPulledin;
|
||||
}
|
||||
|
||||
void RefreshManager::notifyActive()
|
||||
{
|
||||
controllerIdle = false;
|
||||
}
|
||||
|
||||
void RefreshManager::notifyIdle()
|
||||
{
|
||||
controllerIdle = true;
|
||||
}
|
||||
|
||||
std::pair<Command, tlm_generic_payload *> RefreshManager::getNextCommand()
|
||||
std::pair<Command, tlm_generic_payload *> RefreshManagerRankwise::getNextCommand()
|
||||
{
|
||||
if (sc_time_stamp() == timeToSchedule)
|
||||
return std::pair<Command, tlm_generic_payload *>(nextCommand, &refreshPayload);
|
||||
@@ -70,15 +60,15 @@ std::pair<Command, tlm_generic_payload *> RefreshManager::getNextCommand()
|
||||
return std::pair<Command, tlm_generic_payload *>(Command::NOP, nullptr);
|
||||
}
|
||||
|
||||
sc_time RefreshManager::start()
|
||||
sc_time RefreshManagerRankwise::start()
|
||||
{
|
||||
timeToSchedule = sc_max_time();
|
||||
|
||||
if (sc_time_stamp() >= timeForNextTrigger)
|
||||
{
|
||||
powerDownManager->triggerExit(TriggerSource::RefreshManager);
|
||||
powerDownManager->triggerInterruption();
|
||||
if (sleeping)
|
||||
return sc_max_time() - sc_time_stamp();
|
||||
return timeToSchedule;
|
||||
|
||||
if (sc_time_stamp() >= timeForNextTrigger + memSpec->getRefreshIntervalAB())
|
||||
{
|
||||
@@ -86,64 +76,84 @@ sc_time RefreshManager::start()
|
||||
state = RmState::Regular;
|
||||
}
|
||||
|
||||
sc_time delay;
|
||||
if (state == RmState::Regular)
|
||||
{
|
||||
bool forcedRefresh = (flexibilityCounter == maxPostponed);
|
||||
if (!forcedRefresh && !controllerIdle) // no forced refresh & controller is busy -> postpone
|
||||
if (flexibilityCounter == maxPostponed) // forced refresh
|
||||
{
|
||||
flexibilityCounter++;
|
||||
timeForNextTrigger += memSpec->getRefreshIntervalAB();
|
||||
return timeForNextTrigger - sc_time_stamp();
|
||||
for (auto it : bankMachinesOnRank)
|
||||
it->block();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (forcedRefresh)
|
||||
bool controllerBusy = false;
|
||||
for (auto it : bankMachinesOnRank)
|
||||
{
|
||||
for (auto it : bankMachines)
|
||||
it->block();
|
||||
if (!it->isIdle())
|
||||
{
|
||||
controllerBusy = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (activatedBanks > 0)
|
||||
nextCommand = Command::PREA;
|
||||
else
|
||||
nextCommand = Command::REFA;
|
||||
delay = checker->delayToSatisfyConstraints(nextCommand, rank, BankGroup(0), Bank(0));
|
||||
timeToSchedule = sc_time_stamp() + delay;
|
||||
return delay;
|
||||
if (controllerBusy)
|
||||
{
|
||||
flexibilityCounter++;
|
||||
timeForNextTrigger += memSpec->getRefreshIntervalAB();
|
||||
return timeForNextTrigger;
|
||||
}
|
||||
}
|
||||
|
||||
if (activatedBanks > 0)
|
||||
nextCommand = Command::PREA;
|
||||
else
|
||||
nextCommand = Command::REFA;
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, BankGroup(0), Bank(0));
|
||||
return timeToSchedule;
|
||||
}
|
||||
else // if (state == RmState::Pulledin)
|
||||
{
|
||||
if (!controllerIdle)
|
||||
bool controllerBusy = false;
|
||||
for (auto it : bankMachinesOnRank)
|
||||
{
|
||||
if (!it->isIdle())
|
||||
{
|
||||
controllerBusy = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (controllerBusy)
|
||||
{
|
||||
state = RmState::Regular;
|
||||
timeForNextTrigger += memSpec->getRefreshIntervalAB();
|
||||
return timeForNextTrigger - sc_time_stamp();
|
||||
return timeForNextTrigger;
|
||||
}
|
||||
else
|
||||
{
|
||||
// nextCommand stays Command::REFA
|
||||
delay = checker->delayToSatisfyConstraints(nextCommand, rank, BankGroup(0), Bank(0));
|
||||
timeToSchedule = sc_time_stamp() + delay;
|
||||
return delay;
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, BankGroup(0), Bank(0));
|
||||
return timeToSchedule;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return timeForNextTrigger - sc_time_stamp();
|
||||
return timeForNextTrigger;
|
||||
}
|
||||
|
||||
void RefreshManager::updateState(Command command, tlm_generic_payload *)
|
||||
void RefreshManagerRankwise::updateState(Command command, tlm_generic_payload *)
|
||||
{
|
||||
if (command == Command::ACT)
|
||||
activatedBanks++;
|
||||
else if (command == Command::PRE)
|
||||
activatedBanks--;
|
||||
else if (command == Command::PREA)
|
||||
activatedBanks = 0;
|
||||
else if (command == Command::REFA)
|
||||
switch (command)
|
||||
{
|
||||
case Command::ACT:
|
||||
activatedBanks++;
|
||||
break;
|
||||
case Command::PRE:
|
||||
activatedBanks--;
|
||||
break;
|
||||
case Command::PREA:
|
||||
activatedBanks = 0;
|
||||
break;
|
||||
case Command::REFA:
|
||||
if (sleeping)
|
||||
{
|
||||
// Refresh command after SREFEX
|
||||
@@ -162,17 +172,18 @@ void RefreshManager::updateState(Command command, tlm_generic_payload *)
|
||||
{
|
||||
state = RmState::Regular;
|
||||
timeForNextTrigger += memSpec->getRefreshIntervalAB();
|
||||
powerDownManager->triggerEntry(TriggerSource::RefreshManager);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (command == Command::PDEA || command == Command::PDEP)
|
||||
break;
|
||||
case Command::PDEA: case Command::PDEP:
|
||||
sleeping = true;
|
||||
else if (command == Command::SREFEN)
|
||||
{
|
||||
break;
|
||||
case Command::SREFEN:
|
||||
sleeping = true;
|
||||
timeForNextTrigger = sc_max_time();
|
||||
}
|
||||
else if (command == Command::PDXA || command == Command::PDXP)
|
||||
break;
|
||||
case Command::PDXA: case Command::PDXP:
|
||||
sleeping = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -32,8 +32,8 @@
|
||||
* Author: Lukas Steiner
|
||||
*/
|
||||
|
||||
#ifndef REFRESHMANAGER_H
|
||||
#define REFRESHMANAGER_H
|
||||
#ifndef REFRESHMANAGERRANKWISE_H
|
||||
#define REFRESHMANAGERRANKWISE_H
|
||||
|
||||
#include "RefreshManagerIF.h"
|
||||
#include "../../configuration/memspec/MemSpec.h"
|
||||
@@ -41,33 +41,27 @@
|
||||
#include "../powerdown/PowerDownManagerIF.h"
|
||||
#include "../checker/CheckerIF.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
class RefreshManager final : public RefreshManagerIF
|
||||
class RefreshManagerRankwise final : public RefreshManagerIF
|
||||
{
|
||||
public:
|
||||
RefreshManager(std::vector<BankMachine *> &, PowerDownManagerIF *, Rank, CheckerIF *);
|
||||
RefreshManagerRankwise(std::vector<BankMachine *> &, PowerDownManagerIF *, Rank, CheckerIF *);
|
||||
|
||||
virtual std::pair<Command, tlm_generic_payload *> getNextCommand() override;
|
||||
virtual std::pair<Command, tlm::tlm_generic_payload *> getNextCommand() override;
|
||||
virtual sc_time start() override;
|
||||
virtual void updateState(Command, tlm_generic_payload *) override;
|
||||
|
||||
virtual void notifyActive() override;
|
||||
virtual void notifyIdle() override;
|
||||
virtual void updateState(Command, tlm::tlm_generic_payload *) override;
|
||||
|
||||
private:
|
||||
enum class RmState {Regular, Pulledin} state = RmState::Regular;
|
||||
const MemSpec *memSpec;
|
||||
std::vector<BankMachine *> &bankMachines;
|
||||
std::vector<BankMachine *> &bankMachinesOnRank;
|
||||
PowerDownManagerIF *powerDownManager;
|
||||
tlm_generic_payload refreshPayload;
|
||||
tlm::tlm_generic_payload refreshPayload;
|
||||
sc_time timeForNextTrigger = sc_max_time();
|
||||
sc_time timeToSchedule = sc_max_time();
|
||||
Rank rank;
|
||||
CheckerIF *checker;
|
||||
Command nextCommand;
|
||||
|
||||
bool controllerIdle = true;
|
||||
unsigned activatedBanks = 0;
|
||||
|
||||
int flexibilityCounter = 0;
|
||||
@@ -77,4 +71,4 @@ private:
|
||||
bool sleeping = false;
|
||||
};
|
||||
|
||||
#endif // REFRESHMANAGER_H
|
||||
#endif // REFRESHMANAGERRANKWISE_H
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, University of Kaiserslautern
|
||||
* Copyright (c) 2019, University of Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -29,43 +29,39 @@
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors:
|
||||
* Janik Schlemminger
|
||||
* Matthias Jung
|
||||
* Author: Lukas Steiner
|
||||
*/
|
||||
|
||||
#include "timingCalculations.h"
|
||||
#include "../configuration/memspec/MemSpec.h"
|
||||
#include "DebugManager.h"
|
||||
#include "../configuration/Configuration.h"
|
||||
#include "utils.h"
|
||||
#include "RespQueueFifo.h"
|
||||
|
||||
sc_time getDelayToMeetConstraint(sc_time previous, sc_time start,
|
||||
sc_time constraint)
|
||||
using namespace tlm;
|
||||
|
||||
void RespQueueFifo::insertPayload(tlm_generic_payload *payload, sc_time strobeEnd)
|
||||
{
|
||||
if (previous + constraint > start)
|
||||
return previous + constraint - start;
|
||||
else
|
||||
return SC_ZERO_TIME;
|
||||
buffer.push({payload, strobeEnd});
|
||||
}
|
||||
|
||||
const sc_time FrequencyToClk(double frequencyMhz)
|
||||
tlm_generic_payload *RespQueueFifo::nextPayload()
|
||||
{
|
||||
return sc_time(1 / frequencyMhz, SC_US);
|
||||
if (!buffer.empty())
|
||||
{
|
||||
std::pair<tlm_generic_payload *, sc_time> element = buffer.front();
|
||||
if (element.second <= sc_time_stamp())
|
||||
{
|
||||
buffer.pop();
|
||||
return element.first;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const sc_time clkAlign(sc_time time, Alignment alignment)
|
||||
sc_time RespQueueFifo::getTriggerTime() const
|
||||
{
|
||||
sc_time clk = Configuration::getInstance().memSpec->clk;
|
||||
if (alignment == UP)
|
||||
return ceil(time / clk) * clk;
|
||||
else
|
||||
return floor(time / clk) * clk;
|
||||
if (!buffer.empty())
|
||||
{
|
||||
sc_time triggerTime = buffer.front().second;
|
||||
if (triggerTime > sc_time_stamp())
|
||||
return triggerTime;
|
||||
}
|
||||
return sc_max_time();
|
||||
}
|
||||
|
||||
bool isClkAligned(sc_time time, sc_time clk)
|
||||
{
|
||||
return !((time / clk) - ceil(time / clk));
|
||||
}
|
||||
|
||||
|
||||
55
DRAMSys/library/src/controller/respqueue/RespQueueFifo.h
Normal file
55
DRAMSys/library/src/controller/respqueue/RespQueueFifo.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2019, University of Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Author: Lukas Steiner
|
||||
*/
|
||||
|
||||
#ifndef RESPQUEUEFIFO_H
|
||||
#define RESPQUEUEFIFO_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include <tlm.h>
|
||||
#include "RespQueueIF.h"
|
||||
#include <utility>
|
||||
#include <queue>
|
||||
|
||||
class RespQueueFifo final : public RespQueueIF
|
||||
{
|
||||
public:
|
||||
virtual void insertPayload(tlm::tlm_generic_payload *, sc_time) override;
|
||||
virtual tlm::tlm_generic_payload *nextPayload() override;
|
||||
virtual sc_time getTriggerTime() const override;
|
||||
|
||||
private:
|
||||
std::queue<std::pair<tlm::tlm_generic_payload *, sc_time>> buffer;
|
||||
};
|
||||
|
||||
#endif // RESPQUEUEFIFO_H
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, University of Kaiserslautern
|
||||
* Copyright (c) 2019, University of Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -29,24 +29,21 @@
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors:
|
||||
* Janik Schlemminger
|
||||
* Matthias Jung
|
||||
* Author: Lukas Steiner
|
||||
*/
|
||||
|
||||
#ifndef TIMINGCALCULATIONS_H
|
||||
#define TIMINGCALCULATIONS_H
|
||||
#ifndef RESPQUEUEIF_H
|
||||
#define RESPQUEUEIF_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include <tlm.h>
|
||||
#include "dramExtensions.h"
|
||||
|
||||
sc_time getDelayToMeetConstraint(sc_time previous, sc_time start,
|
||||
sc_time constraint);
|
||||
class RespQueueIF
|
||||
{
|
||||
public:
|
||||
virtual void insertPayload(tlm::tlm_generic_payload *, sc_time) = 0;
|
||||
virtual tlm::tlm_generic_payload *nextPayload() = 0;
|
||||
virtual sc_time getTriggerTime() const = 0;
|
||||
};
|
||||
|
||||
enum Alignment {UP, DOWN};
|
||||
const sc_time clkAlign(sc_time time, Alignment alignment = UP);
|
||||
bool isClkAligned(sc_time time, sc_time clk);
|
||||
const sc_time FrequencyToClk(double frequencyMhz);
|
||||
|
||||
#endif // TIMINGCALCULATIONS_H
|
||||
#endif // RESPQUEUEIF_H
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, University of Kaiserslautern
|
||||
* Copyright (c) 2019, University of Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -29,63 +29,46 @@
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors:
|
||||
* Janik Schlemminger
|
||||
* Robert Gernhardt
|
||||
* Matthias Jung
|
||||
* Author: Lukas Steiner
|
||||
*/
|
||||
|
||||
#ifndef PROTOCOL_H
|
||||
#define PROTOCOL_H
|
||||
#include "RespQueueReorder.h"
|
||||
#include "../../common/dramExtensions.h"
|
||||
|
||||
// DRAM Control Phases
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_PRE);
|
||||
DECLARE_EXTENDED_PHASE(END_PRE);
|
||||
using namespace tlm;
|
||||
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_PREA);
|
||||
DECLARE_EXTENDED_PHASE(END_PREA);
|
||||
void RespQueueReorder::insertPayload(tlm_generic_payload *payload, sc_time strobeEnd)
|
||||
{
|
||||
buffer[DramExtension::getPayloadID(payload)] = {payload, strobeEnd};
|
||||
}
|
||||
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_ACT);
|
||||
DECLARE_EXTENDED_PHASE(END_ACT);
|
||||
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_REFA);
|
||||
DECLARE_EXTENDED_PHASE(END_REFA);
|
||||
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_REFB);
|
||||
DECLARE_EXTENDED_PHASE(END_REFB);
|
||||
|
||||
// Phases for Read and Write
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_WR);
|
||||
DECLARE_EXTENDED_PHASE(END_WR);
|
||||
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_RD);
|
||||
DECLARE_EXTENDED_PHASE(END_RD);
|
||||
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_WRA);
|
||||
DECLARE_EXTENDED_PHASE(END_WRA);
|
||||
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_RDA);
|
||||
DECLARE_EXTENDED_PHASE(END_RDA);
|
||||
|
||||
// Phases for Power Down
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_PDNP);
|
||||
DECLARE_EXTENDED_PHASE(END_PDNP);
|
||||
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_PDNA);
|
||||
DECLARE_EXTENDED_PHASE(END_PDNA);
|
||||
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_SREF);
|
||||
DECLARE_EXTENDED_PHASE(END_SREF);
|
||||
|
||||
// Phases for Power Down Bankwise
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_PDNPB);
|
||||
DECLARE_EXTENDED_PHASE(END_PDNPB);
|
||||
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_PDNAB);
|
||||
DECLARE_EXTENDED_PHASE(END_PDNAB);
|
||||
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_SREFB);
|
||||
DECLARE_EXTENDED_PHASE(END_SREFB);
|
||||
|
||||
#endif // PROTOCOL_H
|
||||
tlm_generic_payload *RespQueueReorder::nextPayload()
|
||||
{
|
||||
if (!buffer.empty())
|
||||
{
|
||||
if (buffer.begin()->first == currentPayloadID)
|
||||
{
|
||||
std::pair<tlm_generic_payload *, sc_time> element = buffer.begin()->second;
|
||||
if (element.second <= sc_time_stamp())
|
||||
{
|
||||
buffer.erase(currentPayloadID++);
|
||||
return element.first;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sc_time RespQueueReorder::getTriggerTime() const
|
||||
{
|
||||
if (!buffer.empty())
|
||||
{
|
||||
if (buffer.begin()->first == currentPayloadID)
|
||||
{
|
||||
sc_time triggerTime = buffer.begin()->second.second;
|
||||
if (triggerTime > sc_time_stamp())
|
||||
return triggerTime;
|
||||
}
|
||||
}
|
||||
return sc_max_time();
|
||||
}
|
||||
56
DRAMSys/library/src/controller/respqueue/RespQueueReorder.h
Normal file
56
DRAMSys/library/src/controller/respqueue/RespQueueReorder.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2019, University of Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Author: Lukas Steiner
|
||||
*/
|
||||
|
||||
#ifndef RESPQUEUEREORDER_H
|
||||
#define RESPQUEUEREORDER_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include <tlm.h>
|
||||
#include "RespQueueIF.h"
|
||||
#include <map>
|
||||
|
||||
class RespQueueReorder final : public RespQueueIF
|
||||
{
|
||||
public:
|
||||
virtual void insertPayload(tlm::tlm_generic_payload *, sc_time) override;
|
||||
virtual tlm::tlm_generic_payload *nextPayload() override;
|
||||
virtual sc_time getTriggerTime() const override;
|
||||
|
||||
private:
|
||||
uint64_t currentPayloadID = 0;
|
||||
// Muss die Zeit aller Payloads gespeichert werden?
|
||||
std::map<uint64_t, std::pair<tlm::tlm_generic_payload *, sc_time>> buffer;
|
||||
};
|
||||
|
||||
#endif // RESPQUEUEREORDER_H
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user