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:
Matthias Jung
2020-04-07 14:51:53 +02:00
144 changed files with 2799 additions and 3551 deletions

View File

@@ -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:

View File

@@ -1 +0,0 @@
memconfig.xml

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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)

View File

@@ -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

View File

@@ -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();

View File

@@ -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)

View File

@@ -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);
}

View File

@@ -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,

View File

@@ -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");
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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;
// }
//}

View File

@@ -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

View File

@@ -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");

View File

@@ -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;
};

View File

@@ -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");

View File

@@ -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;
};

View File

@@ -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");

View File

@@ -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;
};

View File

@@ -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");

View File

@@ -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;
};

View File

@@ -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");

View File

@@ -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;
};

View File

@@ -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");

View File

@@ -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;
};

View File

@@ -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");

View File

@@ -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;
};

View File

@@ -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");

View File

@@ -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;
};

View File

@@ -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");

View File

@@ -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;
};

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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;
};

View File

@@ -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)

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;
};

View File

@@ -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;
}

View File

@@ -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;
};

View File

@@ -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;
}

View File

@@ -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;
};

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
};

View File

@@ -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)
{

View File

@@ -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:

View File

@@ -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)

View File

@@ -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

View File

@@ -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)

View File

@@ -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:

View File

@@ -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

View File

@@ -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)
{

View File

@@ -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

View File

@@ -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)
{

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -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;
};

View File

@@ -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;
};

View File

@@ -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;
}
}

View File

@@ -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;
};

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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));
}

View 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

View File

@@ -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

View File

@@ -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();
}

View 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