diff --git a/DRAMSys/docs/flexible-refresh.pdf b/DRAMSys/docs/flexible-refresh.pdf
deleted file mode 100644
index 4ebfe2dd..00000000
Binary files a/DRAMSys/docs/flexible-refresh.pdf and /dev/null differ
diff --git a/DRAMSys/library/library.pro b/DRAMSys/library/library.pro
index 7a455f7f..c4cef29a 100644
--- a/DRAMSys/library/library.pro
+++ b/DRAMSys/library/library.pro
@@ -85,6 +85,7 @@ SOURCES += \
src/controller/scheduler/SMS.cpp \
src/controller/core/refresh/RefreshManagerBankwise.cpp \
src/controller/core/refresh/RefreshManager.cpp \
+ src/controller/core/refresh/RGR.cpp \
src/controller/core/scheduling/checker/WriteChecker.cpp \
src/controller/core/scheduling/checker/RefreshChecker.cpp \
src/controller/core/scheduling/checker/ReadChecker.cpp \
@@ -92,6 +93,8 @@ SOURCES += \
src/controller/core/scheduling/checker/PrechargeAllChecker.cpp \
src/controller/core/scheduling/checker/PowerDownChecker.cpp \
src/controller/core/scheduling/checker/ActivateChecker.cpp \
+ src/controller/core/scheduling/checker/PreBChecker.cpp \
+ src/controller/core/scheduling/checker/ActBChecker.cpp \
src/controller/core/scheduling/ScheduledCommand.cpp \
src/controller/core/TimingCalculation.cpp \
src/controller/core/Slots.cpp \
@@ -146,6 +149,7 @@ HEADERS += \
src/controller/core/refresh/RefreshManagerBankwise.h \
src/controller/core/refresh/RefreshManager.h \
src/controller/core/refresh/IRefreshManager.h \
+ src/controller/core/refresh/RGR.h \
src/controller/core/scheduling/checker/WriteChecker.h \
src/controller/core/scheduling/checker/RefreshChecker.h \
src/controller/core/scheduling/checker/ReadChecker.h \
@@ -154,6 +158,8 @@ HEADERS += \
src/controller/core/scheduling/checker/PowerDownChecker.h \
src/controller/core/scheduling/checker/ICommandChecker.h \
src/controller/core/scheduling/checker/ActivateChecker.h \
+ src/controller/core/scheduling/checker/PreBChecker.h \
+ src/controller/core/scheduling/checker/ActBChecker.h \
src/controller/core/scheduling/Trigger.h \
src/controller/core/scheduling/ScheduledCommand.h \
src/controller/core/TimingCalculation.h \
diff --git a/DRAMSys/library/resources/configs/amconfigs/orgr_ddr4_4x16Gbx16_dimm_p2KB_brc.xml b/DRAMSys/library/resources/configs/amconfigs/orgr_ddr4_4x16Gbx16_dimm_p2KB_brc.xml
new file mode 100644
index 00000000..b387e522
--- /dev/null
+++ b/DRAMSys/library/resources/configs/amconfigs/orgr_ddr4_4x16Gbx16_dimm_p2KB_brc.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/DRAMSys/library/resources/configs/amconfigs/rgram.xml b/DRAMSys/library/resources/configs/amconfigs/rgram.xml
new file mode 100644
index 00000000..b5e85906
--- /dev/null
+++ b/DRAMSys/library/resources/configs/amconfigs/rgram.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs_bw_buffer16.xml b/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs_bw_buffer16.xml
new file mode 100644
index 00000000..66a560b4
--- /dev/null
+++ b/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs_bw_buffer16.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs_bw_buffer16_close_page.xml b/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs_bw_buffer16_close_page.xml
new file mode 100644
index 00000000..936a8503
--- /dev/null
+++ b/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs_bw_buffer16_close_page.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs_nbw_buffer16.xml b/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs_nbw_buffer16.xml
new file mode 100644
index 00000000..ba32827b
--- /dev/null
+++ b/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs_nbw_buffer16.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs_nbw_buffer16_close_page.xml b/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs_nbw_buffer16_close_page.xml
new file mode 100644
index 00000000..3e3d5aac
--- /dev/null
+++ b/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs_nbw_buffer16_close_page.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DRAMSys/library/resources/configs/mcconfigs/rgrmccfg.xml b/DRAMSys/library/resources/configs/mcconfigs/rgrmccfg.xml
new file mode 100644
index 00000000..f6b02b27
--- /dev/null
+++ b/DRAMSys/library/resources/configs/mcconfigs/rgrmccfg.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DRAMSys/library/resources/configs/memspecs/SAMSUNG_K4B4G1646Q_4Gb_DDR3-1066_16bit.xml b/DRAMSys/library/resources/configs/memspecs/SAMSUNG_K4B4G1646Q_4Gb_DDR3-1066_16bit.xml
index c8c12b52..e4c571e3 100644
--- a/DRAMSys/library/resources/configs/memspecs/SAMSUNG_K4B4G1646Q_4Gb_DDR3-1066_16bit.xml
+++ b/DRAMSys/library/resources/configs/memspecs/SAMSUNG_K4B4G1646Q_4Gb_DDR3-1066_16bit.xml
@@ -11,7 +11,7 @@
Device mounted: K4B4G1646Q-HYK0
Original fck is 800 MHz (DDR3-1600). Adapted to fck 533 MHz (DDR-1066).
- Deepak provided most of the timing and current values.
+ Deepak provided most of the timing and current values. For the ones not provided datasheet values were used.
-->
@@ -43,25 +43,25 @@
-
-
+
+
-
-
+
+
-
+
-
-
-
-
-
+
+
+
+
+
diff --git a/DRAMSys/library/resources/configs/memspecs/orgr_16Gb_ddr4.xml b/DRAMSys/library/resources/configs/memspecs/orgr_16Gb_ddr4.xml
new file mode 100644
index 00000000..42105d48
--- /dev/null
+++ b/DRAMSys/library/resources/configs/memspecs/orgr_16Gb_ddr4.xml
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DRAMSys/library/resources/configs/memspecs/orgr_16Gb_ddr4_2x.xml b/DRAMSys/library/resources/configs/memspecs/orgr_16Gb_ddr4_2x.xml
new file mode 100644
index 00000000..a41e1e57
--- /dev/null
+++ b/DRAMSys/library/resources/configs/memspecs/orgr_16Gb_ddr4_2x.xml
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DRAMSys/library/resources/configs/memspecs/orgr_16Gb_ddr4_4x.xml b/DRAMSys/library/resources/configs/memspecs/orgr_16Gb_ddr4_4x.xml
new file mode 100644
index 00000000..2b56ba2d
--- /dev/null
+++ b/DRAMSys/library/resources/configs/memspecs/orgr_16Gb_ddr4_4x.xml
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DRAMSys/library/resources/configs/memspecs/rgrspec.xml b/DRAMSys/library/resources/configs/memspecs/rgrspec.xml
new file mode 100644
index 00000000..d3bc6990
--- /dev/null
+++ b/DRAMSys/library/resources/configs/memspecs/rgrspec.xml
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DRAMSys/library/resources/configs/simulator/orgr.xml b/DRAMSys/library/resources/configs/simulator/orgr.xml
new file mode 100644
index 00000000..5ea7d678
--- /dev/null
+++ b/DRAMSys/library/resources/configs/simulator/orgr.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DRAMSys/library/resources/configs/simulator/orgr_4b_opt_timings_ddr3.xml b/DRAMSys/library/resources/configs/simulator/orgr_4b_opt_timings_ddr3.xml
new file mode 100644
index 00000000..c1ee0c9b
--- /dev/null
+++ b/DRAMSys/library/resources/configs/simulator/orgr_4b_opt_timings_ddr3.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DRAMSys/library/resources/configs/simulator/orgr_4b_std_timings_ddr3.xml b/DRAMSys/library/resources/configs/simulator/orgr_4b_std_timings_ddr3.xml
new file mode 100644
index 00000000..66460ef1
--- /dev/null
+++ b/DRAMSys/library/resources/configs/simulator/orgr_4b_std_timings_ddr3.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DRAMSys/library/resources/configs/simulator/orgr_8b_opt_timings_ddr3.xml b/DRAMSys/library/resources/configs/simulator/orgr_8b_opt_timings_ddr3.xml
new file mode 100644
index 00000000..10673780
--- /dev/null
+++ b/DRAMSys/library/resources/configs/simulator/orgr_8b_opt_timings_ddr3.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DRAMSys/library/resources/configs/simulator/orgr_8b_std_timings_ddr3.xml b/DRAMSys/library/resources/configs/simulator/orgr_8b_std_timings_ddr3.xml
new file mode 100644
index 00000000..d8846262
--- /dev/null
+++ b/DRAMSys/library/resources/configs/simulator/orgr_8b_std_timings_ddr3.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DRAMSys/library/resources/configs/simulator/orgr_ddr4.xml b/DRAMSys/library/resources/configs/simulator/orgr_ddr4.xml
new file mode 100644
index 00000000..4aeea8c9
--- /dev/null
+++ b/DRAMSys/library/resources/configs/simulator/orgr_ddr4.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DRAMSys/library/resources/configs/simulator/rgrsimcfg.xml b/DRAMSys/library/resources/configs/simulator/rgrsimcfg.xml
new file mode 100644
index 00000000..633da858
--- /dev/null
+++ b/DRAMSys/library/resources/configs/simulator/rgrsimcfg.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DRAMSys/library/resources/resources.pri b/DRAMSys/library/resources/resources.pri
index bfd194b2..81a9c654 100644
--- a/DRAMSys/library/resources/resources.pri
+++ b/DRAMSys/library/resources/resources.pri
@@ -4,11 +4,58 @@
# Simulation Files
OTHER_FILES += resources/simulations/ddr3-example.xml
OTHER_FILES += resources/simulations/ddr3-single-device.xml
+OTHER_FILES += resources/simulations/ddr3-rgr.xml
+OTHER_FILES += resources/simulations/ddr3-rgr00.xml
+OTHER_FILES += resources/simulations/ddr3-rgr01.xml
+OTHER_FILES += resources/simulations/ddr3-rgr02.xml
+OTHER_FILES += resources/simulations/ddr3-rgr03.xml
+OTHER_FILES += resources/simulations/ddr3-rgr04.xml
+OTHER_FILES += resources/simulations/ddr3-rgr05.xml
+OTHER_FILES += resources/simulations/ddr3-rgr06.xml
+OTHER_FILES += resources/simulations/ddr3-rgr07.xml
+OTHER_FILES += resources/simulations/ddr3-rgr08.xml
+OTHER_FILES += resources/simulations/ddr3-rgr09.xml
+OTHER_FILES += resources/simulations/ddr3-rgr10.xml
+OTHER_FILES += resources/simulations/ddr3-rgr11.xml
+OTHER_FILES += resources/simulations/ddr3-rgr12.xml
+OTHER_FILES += resources/simulations/ddr3-rgr13.xml
+OTHER_FILES += resources/simulations/ddr3-rgr14.xml
+OTHER_FILES += resources/simulations/ddr3-rgr15.xml
+OTHER_FILES += resources/simulations/ddr3-rgr16.xml
+OTHER_FILES += resources/simulations/ddr3-rgr17.xml
+OTHER_FILES += resources/simulations/ddr3-rgr18.xml
+OTHER_FILES += resources/simulations/ddr3-rgr19.xml
+OTHER_FILES += resources/simulations/ddr3-rgr20.xml
+OTHER_FILES += resources/simulations/ddr3-rgr21.xml
+OTHER_FILES += resources/simulations/ddr3-rgr22.xml
+OTHER_FILES += resources/simulations/ddr3-rgr23.xml
+OTHER_FILES += resources/simulations/ddr3-rgr24.xml
+OTHER_FILES += resources/simulations/ddr3-rgr25.xml
+OTHER_FILES += resources/simulations/ddr3-rgr26.xml
+OTHER_FILES += resources/simulations/ddr3-rgr27.xml
+OTHER_FILES += resources/simulations/ddr3-rgr28.xml
+OTHER_FILES += resources/simulations/ddr3-rgr29.xml
+OTHER_FILES += resources/simulations/ddr3-rgr30.xml
+OTHER_FILES += resources/simulations/ddr3-rgr31.xml
+OTHER_FILES += resources/simulations/ddr3-rgr32.xml
+OTHER_FILES += resources/simulations/ddr3-rgr33.xml
+OTHER_FILES += resources/simulations/ddr3-rgr34.xml
+OTHER_FILES += resources/simulations/ddr3-rgr35.xml
+OTHER_FILES += resources/simulations/ddr3-rgr36.xml
+OTHER_FILES += resources/simulations/ddr3-rgr37.xml
+OTHER_FILES += resources/simulations/ddr3-rgr38.xml
+OTHER_FILES += resources/simulations/ddr3-rgr39.xml
+OTHER_FILES += resources/simulations/ddr3-rgr40.xml
+OTHER_FILES += resources/simulations/ddr3-rgr41.xml
+OTHER_FILES += resources/simulations/ddr3-rgr42.xml
+OTHER_FILES += resources/simulations/ddr3-rgr43.xml
+OTHER_FILES += resources/simulations/ddr3-rgr44.xml
OTHER_FILES += resources/simulations/wideio-example.xml
OTHER_FILES += resources/simulations/wideio-ecc.xml
OTHER_FILES += resources/simulations/ddr3-ecc.xml
OTHER_FILES += resources/simulations/sms-example.xml
OTHER_FILES += resources/simulations/ddr3_postpone_ref_test.xml
+OTHER_FILES += resources/simulations/rgrsim.xml
# Simulator Files
OTHER_FILES += resources/configs/simulator/wideio.xml
@@ -18,6 +65,7 @@ OTHER_FILES += resources/configs/simulator/wideio_thermal.xml
OTHER_FILES += resources/configs/simulator/wideio_ecc.xml
OTHER_FILES += resources/configs/simulator/ddr3_ecc.xml
OTHER_FILES += resources/configs/simulator/sms.xml
+OTHER_FILES += resources/configs/simulator/rgrsimcfg.xml
# Scripts
OTHER_FILES += resources/scripts/address_scrambler.pl
@@ -69,6 +117,8 @@ OTHER_FILES += resources/traces/small.stl
OTHER_FILES += resources/traces/chstone-motion_32.stl
OTHER_FILES += resources/traces/mediabench-adpcmdecode_32.stl
OTHER_FILES += resources/traces/ddr3_example.stl
+OTHER_FILES += resources/traces/ddr3_exampleb.stl
+OTHER_FILES += resources/traces/ddr3_rgr.stl
OTHER_FILES += resources/traces/ddr3_single_dev_example.stl
OTHER_FILES += resources/traces/ddr3_SAMSUNG_M471B5674QH0_DIMM_example.stl
OTHER_FILES += resources/traces/test_ecc.stl
@@ -88,6 +138,7 @@ OTHER_FILES += resources/configs/mcconfigs/fr_fcfs.xml
OTHER_FILES += resources/configs/mcconfigs/par_bs.xml
OTHER_FILES += resources/configs/mcconfigs/fifo_ecc.xml
OTHER_FILES += resources/configs/mcconfigs/sms.xml
+OTHER_FILES += resources/configs/mcconfigs/rgrmccfg.xml
# Memspecs
OTHER_FILES += resources/configs/memspecs/memspec.dtd
@@ -129,9 +180,11 @@ OTHER_FILES += resources/configs/memspecs/MICRON_4Gb_LPDDR3-1333_32bit_A.xml
OTHER_FILES += resources/configs/memspecs/MICRON_4Gb_LPDDR3-1600_32bit_A.xml
OTHER_FILES += resources/configs/memspecs/SAMSUNG_K4B1G1646E_1Gb_DDR3-1600_16bit.xml
OTHER_FILES += resources/configs/memspecs/SAMSUNG_K4B4G1646Q_4Gb_DDR3-1066_16bit.xml
+OTHER_FILES += resources/configs/memspecs/orgr_16Gb_ddr4.xml
OTHER_FILES += resources/configs/memspecs/wideio.xml
OTHER_FILES += resources/configs/memspecs/wideio_less_refresh.xml
OTHER_FILES += resources/configs/memspecs/MICRON_1Gb_DDR3-1600_8bit_G_less_refresh.xml
+OTHER_FILES += resources/configs/memspecs/rgrspec.xml
# Address Mapping Configs
OTHER_FILES += resources/configs/amconfigs/am_ddr3.xml
@@ -151,6 +204,7 @@ OTHER_FILES += resources/configs/amconfigs/am_wideioFourBanks.xml
OTHER_FILES += resources/configs/amconfigs/am_ddr3_1Gbx8_p1KB_brc.xml
OTHER_FILES += resources/configs/amconfigs/am_ddr3_4x4Gbx16_dimm_p2KB_brc.xml
OTHER_FILES += resources/configs/amconfigs/am_ddr3_4x4Gbx16_dimm_p2KB_rbc.xml
+OTHER_FILES += resources/configs/amconfigs/rgram.xml
# Thermal Simulation configs
OTHER_FILES += resources/configs/thermalsim/core.flp
diff --git a/DRAMSys/library/resources/simulations/rgrsim.xml b/DRAMSys/library/resources/simulations/rgrsim.xml
new file mode 100644
index 00000000..fa6201b4
--- /dev/null
+++ b/DRAMSys/library/resources/simulations/rgrsim.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ rgr_postpone_test.stl
+
+
diff --git a/DRAMSys/library/src/common/TlmRecorder.cpp b/DRAMSys/library/src/common/TlmRecorder.cpp
index b75141a6..9cc03443 100644
--- a/DRAMSys/library/src/common/TlmRecorder.cpp
+++ b/DRAMSys/library/src/common/TlmRecorder.cpp
@@ -252,6 +252,10 @@ void TlmRecorder::setUpTransactionTerminatingPhases()
// Refresh Bank
transactionTerminatingPhases.push_back(static_cast
(END_REFB));
+ transactionTerminatingPhases.push_back(static_cast
+ (END_ACTB));
+ transactionTerminatingPhases.push_back(static_cast
+ (END_PREB));
// Phases for Power Down
transactionTerminatingPhases.push_back(static_cast
diff --git a/DRAMSys/library/src/common/protocol.h b/DRAMSys/library/src/common/protocol.h
index eb9d005b..00b03c36 100644
--- a/DRAMSys/library/src/common/protocol.h
+++ b/DRAMSys/library/src/common/protocol.h
@@ -39,12 +39,18 @@
#define EXTENDED_PHASE_DRAM
// DRAM Control Phases
+DECLARE_EXTENDED_PHASE(BEGIN_PREB);
+DECLARE_EXTENDED_PHASE(END_PREB);
+
DECLARE_EXTENDED_PHASE(BEGIN_PRE);
DECLARE_EXTENDED_PHASE(END_PRE);
DECLARE_EXTENDED_PHASE(BEGIN_PRE_ALL);
DECLARE_EXTENDED_PHASE(END_PRE_ALL);
+DECLARE_EXTENDED_PHASE(BEGIN_ACTB);
+DECLARE_EXTENDED_PHASE(END_ACTB);
+
DECLARE_EXTENDED_PHASE(BEGIN_ACT);
DECLARE_EXTENDED_PHASE(END_ACT);
diff --git a/DRAMSys/library/src/common/third_party/DRAMPower b/DRAMSys/library/src/common/third_party/DRAMPower
index 90d6290f..fa0627c4 160000
--- a/DRAMSys/library/src/common/third_party/DRAMPower
+++ b/DRAMSys/library/src/common/third_party/DRAMPower
@@ -1 +1 @@
-Subproject commit 90d6290f802c29b3de9e10233ceee22290907ce6
+Subproject commit fa0627c4e6c5b35a040e416592061fb7e672daaf
diff --git a/DRAMSys/library/src/controller/Command.cpp b/DRAMSys/library/src/controller/Command.cpp
index 448941b9..7b1b9d9f 100644
--- a/DRAMSys/library/src/controller/Command.cpp
+++ b/DRAMSys/library/src/controller/Command.cpp
@@ -54,9 +54,15 @@ std::string commandToString(Command command)
case Command::WriteA:
return "WRA";
break;
+ case Command::PreB:
+ return "PREB";
+ break;
case Command::Precharge:
return "PRE";
break;
+ case Command::ActB:
+ return "ACTB";
+ break;
case Command::Activate:
return "ACT";
break;
@@ -100,10 +106,22 @@ std::string commandToString(Command command)
const std::vector &getAllCommands()
{
- static std::vector allCommands( { Command::Precharge, Command::PrechargeAll,
- Command::Activate, Command::Read, Command::Write, Command::ReadA, Command::WriteA,
- Command::AutoRefresh, Command::PDNA, Command::PDNAX, Command::PDNP, Command::PDNPX,
- Command::SREF, Command::SREFX
+ static std::vector allCommands( { Command::PreB,
+ Command::Precharge,
+ Command::PrechargeAll,
+ Command::ActB,
+ Command::Activate,
+ Command::Read,
+ Command::Write,
+ Command::ReadA,
+ Command::WriteA,
+ Command::AutoRefresh,
+ Command::PDNA,
+ Command::PDNAX,
+ Command::PDNP,
+ Command::PDNPX,
+ Command::SREF,
+ Command::SREFX
});
return allCommands;
}
diff --git a/DRAMSys/library/src/controller/Command.h b/DRAMSys/library/src/controller/Command.h
index e8b5ee3f..da66fef4 100644
--- a/DRAMSys/library/src/controller/Command.h
+++ b/DRAMSys/library/src/controller/Command.h
@@ -40,7 +40,26 @@
#include
-enum class Command {NOP, Precharge, PrechargeAll, Activate, Read, Write, ReadA, WriteA, AutoRefresh, PDNA, PDNAX, PDNP, PDNPX, SREF, SREFX};
+enum class Command {
+ NOP,
+ PreB,
+ Precharge,
+ PrechargeAll,
+ ActB,
+ Activate,
+ Read,
+ Write,
+ ReadA,
+ WriteA,
+ AutoRefresh,
+ PDNA,
+ PDNAX,
+ PDNP,
+ PDNPX,
+ SREF,
+ SREFX
+};
+
std::string commandToString(Command command);
const std::vector &getAllCommands();
bool commandIsIn(Command command, std::vector commands);
diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp
index 3d0e6c58..e7bb8af2 100644
--- a/DRAMSys/library/src/controller/Controller.cpp
+++ b/DRAMSys/library/src/controller/Controller.cpp
@@ -35,13 +35,13 @@
* Felipe S. Prado
*/
+#include "core/configuration/Configuration.h"
#include "Controller.h"
#include
void Controller::buildScheduler()
{
string selectedScheduler = Configuration::getInstance().Scheduler;
- std::cout << "Selected Scheduler: " << selectedScheduler << std::endl;
if (selectedScheduler == "FIFO") {
scheduler = new Fifo(*controllerCore);
@@ -111,10 +111,18 @@ void Controller::send(const ScheduledCommand &command,
controllerCorePEQ.notify(payload, BEGIN_REFB,
command.getStart() - sc_time_stamp());
break;
+ case Command::ActB:
+ controllerCorePEQ.notify(payload, BEGIN_ACTB,
+ command.getStart() - sc_time_stamp());
+ break;
case Command::Activate:
controllerCorePEQ.notify(payload, BEGIN_ACT,
command.getStart() - sc_time_stamp());
break;
+ case Command::PreB:
+ controllerCorePEQ.notify(payload, BEGIN_PREB,
+ command.getStart() - sc_time_stamp());
+ break;
case Command::Precharge:
controllerCorePEQ.notify(payload, BEGIN_PRE,
command.getStart() - sc_time_stamp());
@@ -223,7 +231,9 @@ void Controller::controllerCorePEQCallback(tlm_generic_payload &payload,
else if (containsPhase(phase, { END_PDNA, END_PDNP, END_SREF }))
printDebugMessage("Leaving PowerDown " + phaseNameToString(
phase) + " on all banks" );
- else if (containsPhase(phase, { BEGIN_RD, BEGIN_WR, BEGIN_ACT, BEGIN_PRE, BEGIN_PRE_ALL, BEGIN_RDA, BEGIN_WRA })) {
+ else if (containsPhase(phase, { BEGIN_RD, BEGIN_WR, BEGIN_ACTB, BEGIN_ACT, BEGIN_PREB, BEGIN_PRE, BEGIN_PRE_ALL, BEGIN_RDA, BEGIN_WRA })) {
+ printDebugMessage("Controller has sent to DRAM this: " + phaseNameToString(
+ phase) + " bank " + to_string(bank.ID()));
}
else
SC_REPORT_FATAL(0,
@@ -492,7 +502,7 @@ void Controller::dramPEQCallback(tlm_generic_payload &payload,
scheduleNextFromScheduler(bank);
}
scheduleNextFromScheduler(bank);
- } else if (containsPhase(phase, { END_PRE, END_ACT })) {
+ } else if (containsPhase(phase, {END_PREB, END_PRE, END_ACTB, END_ACT})) {
scheduleNextFromScheduler(bank);
}
else if (phase == END_PRE_ALL) {
diff --git a/DRAMSys/library/src/controller/ControllerState.cpp b/DRAMSys/library/src/controller/ControllerState.cpp
index 14e19b23..efff0548 100644
--- a/DRAMSys/library/src/controller/ControllerState.cpp
+++ b/DRAMSys/library/src/controller/ControllerState.cpp
@@ -121,11 +121,19 @@ void ControllerState::change(const ScheduledCommand &scheduledCommand)
break;
case Command::AutoRefresh:
break;
+ case Command::ActB:
+ rowBufferStates->openRowInRowBuffer(scheduledCommand.getBank(),
+ scheduledCommand.getRow());
+ lastActivatesB.emplace(scheduledCommand.getStart(), scheduledCommand);
+ break;
case Command::Activate:
rowBufferStates->openRowInRowBuffer(scheduledCommand.getBank(),
scheduledCommand.getRow());
lastActivates.emplace(scheduledCommand.getStart(), scheduledCommand);
break;
+ case Command::PreB:
+ rowBufferStates->closeRowBuffer(scheduledCommand.getBank());
+ break;
case Command::Precharge:
rowBufferStates->closeRowBuffer(scheduledCommand.getBank());
break;
@@ -153,6 +161,10 @@ void ControllerState::cleanUp(sc_time time)
if (time >= config->memSpec.tActHistory())
lastActivates.erase(lastActivates.begin(),
lastActivates.lower_bound(time - config->memSpec.tActHistory()));
+
+ if (time >= config->memSpec.tActBHistory())
+ lastActivatesB.erase(lastActivatesB.begin(),
+ lastActivatesB.lower_bound(time - config->memSpec.tActBHistory()));
}
void ControllerState::printDebugMessage(std::string message)
diff --git a/DRAMSys/library/src/controller/ControllerState.h b/DRAMSys/library/src/controller/ControllerState.h
index f4eeb36c..fff61882 100644
--- a/DRAMSys/library/src/controller/ControllerState.h
+++ b/DRAMSys/library/src/controller/ControllerState.h
@@ -76,6 +76,7 @@ public:
Slots bus;
std::vector lastDataStrobeCommands;
std::map lastActivates;
+ std::map lastActivatesB;
private:
std::string ownerName;
diff --git a/DRAMSys/library/src/controller/core/ControllerCore.cpp b/DRAMSys/library/src/controller/core/ControllerCore.cpp
index eb9c5914..0a9f434a 100644
--- a/DRAMSys/library/src/controller/core/ControllerCore.cpp
+++ b/DRAMSys/library/src/controller/core/ControllerCore.cpp
@@ -37,7 +37,9 @@
#include
#include "ControllerCore.h"
+#include "scheduling/checker/ActBChecker.h"
#include "scheduling/checker/ActivateChecker.h"
+#include "scheduling/checker/PreBChecker.h"
#include "scheduling/checker/PrechargeChecker.h"
#include "scheduling/checker/PrechargeAllChecker.h"
#include "scheduling/checker/ReadChecker.h"
@@ -46,6 +48,7 @@
#include "scheduling/checker/PowerDownChecker.h"
#include "refresh/RefreshManagerBankwise.h"
#include "refresh/RefreshManager.h"
+#include "refresh/RGR.h"
#include "../../common/dramExtension.h"
#include "../../common/Utils.h"
#include "TimingCalculation.h"
@@ -64,7 +67,9 @@ ControllerCore::ControllerCore(sc_module_name /*name*/,
{
state = new ControllerState(name(), &config);
+ commandChecker[Command::ActB] = new ActBChecker(config, *state);
commandChecker[Command::Activate] = new ActivateChecker(config, *state);
+ commandChecker[Command::PreB] = new PreBChecker(config, *state);
commandChecker[Command::Precharge] = new PrechargeChecker(config, *state);
commandChecker[Command::PrechargeAll] = new PrechargeAllChecker(config, *state);
commandChecker[Command::Read] = new ReadChecker(config, *state);
@@ -80,10 +85,24 @@ ControllerCore::ControllerCore(sc_module_name /*name*/,
commandChecker[Command::PDNPX] = commandChecker[Command::PDNA];
commandChecker[Command::SREFX] = commandChecker[Command::PDNA];
- if (config.BankwiseLogic) {
- refreshManager = new RefreshManagerBankwise("refManagerBw", *this);
+ if (config.RowGranularRef) {
+ refreshManager = new RGR("RGR", *this);
+ assert(config.getTrasb() <= config.memSpec.tRAS);
+ assert(config.getTrasb() >= config.memSpec.tRCD);
+ if (config.memSpec.tRRD_L != config.memSpec.tRRD_S) {
+ cout << "double check assertions" << endl;
+ }
+ assert(config.getTrrdb_L() <= config.memSpec.tRRD_L);
+ assert(config.getTrrdb_S() <= config.memSpec.tRRD_S);
+ assert(config.getTrpb() <= config.memSpec.tRP);
+ assert(config.getTrcb() <= config.memSpec.tRC);
+ assert(config.getTfawb() <= config.memSpec.tNAW);
} else {
- refreshManager = new RefreshManager("refManager", *this);
+ if (config.BankwiseLogic) {
+ refreshManager = new RefreshManagerBankwise("refManagerBw", *this);
+ } else {
+ refreshManager = new RefreshManager("refManager", *this);
+ }
}
if (config.PowerDownMode == EPowerDownMode::Staggered) {
@@ -187,6 +206,10 @@ bool ControllerCore::hasPendingRequests()
return false;
}
+bool ControllerCore::hasPendingRequests(Bank bank)
+{
+ return (numberOfPayloads[bank] != 0) ? true : false;
+}
bool ControllerCore::bankIsBusy(Bank bank)
{
@@ -199,7 +222,7 @@ bool ControllerCore::bankIsBusy(Bank bank)
// Read and writes can overlap, so the bank should not be busy during a rd/wr
return (time < lastScheduledCommand.getStart());
}
- else if (lastScheduledCommand.commandIsIn( { Command::WriteA, Command::ReadA, Command::Precharge, Command::PrechargeAll, Command::Activate })) {
+ else if (lastScheduledCommand.commandIsIn( { Command::WriteA, Command::ReadA, Command::PreB, Command::Precharge, Command::PrechargeAll, Command::ActB, Command::Activate })) {
return (time < lastScheduledCommand.getEnd());
}
else if (lastScheduledCommand.getCommand() == Command::AutoRefresh) {
diff --git a/DRAMSys/library/src/controller/core/ControllerCore.h b/DRAMSys/library/src/controller/core/ControllerCore.h
index 405b25f6..7a3818ef 100644
--- a/DRAMSys/library/src/controller/core/ControllerCore.h
+++ b/DRAMSys/library/src/controller/core/ControllerCore.h
@@ -68,6 +68,7 @@ public:
return *(state->rowBufferStates);
}
bool hasPendingRequests();
+ bool hasPendingRequests(Bank bank);
bool bankIsBusy(Bank bank);
ICommandChecker &getCommandChecker(Command command);
diff --git a/DRAMSys/library/src/controller/core/TimingCalculation.cpp b/DRAMSys/library/src/controller/core/TimingCalculation.cpp
index da1db258..2c1f17cb 100644
--- a/DRAMSys/library/src/controller/core/TimingCalculation.cpp
+++ b/DRAMSys/library/src/controller/core/TimingCalculation.cpp
@@ -71,8 +71,12 @@ sc_time getExecutionTime(Command command, tlm::tlm_generic_payload &payload)
{
MemSpec &config = Configuration::getInstance().memSpec;
- if (command == Command::Precharge || command == Command::PrechargeAll) {
+ if (command == Command::PreB) {
+ return Configuration::getInstance().getTrpb();
+ } else if (command == Command::Precharge || command == Command::PrechargeAll) {
return config.tRP;
+ } else if (command == Command::ActB) {
+ return config.tRCD;
} else if (command == Command::Activate) {
return config.tRCD;
} else if (command == Command::Read) {
diff --git a/DRAMSys/library/src/controller/core/configuration/Configuration.cpp b/DRAMSys/library/src/controller/core/configuration/Configuration.cpp
index d2653b39..42f17b21 100644
--- a/DRAMSys/library/src/controller/core/configuration/Configuration.cpp
+++ b/DRAMSys/library/src/controller/core/configuration/Configuration.cpp
@@ -198,6 +198,39 @@ void Configuration::setParameter(std::string name, std::string value)
}
} else if (name == "ControllerCoreDisableRefresh")
ControllerCoreDisableRefresh = string2bool(value);
+ else if (name == "ControllerCoreRowGranularRef")
+ RowGranularRef = string2bool(value);
+ else if (name == "ControllerCoreRowGranularRefRowInc")RowInc = string2int(
+ value);
+ else if (name == "ControllerCoreRowGranularRefNumAR")NumAR = string2int(value);
+ else if (name == "ControllerCoreRowGranularRefB0")RGRB0 = string2bool(value);
+ else if (name == "ControllerCoreRowGranularRefB1")RGRB1 = string2bool(value);
+ else if (name == "ControllerCoreRowGranularRefB2")RGRB2 = string2bool(value);
+ else if (name == "ControllerCoreRowGranularRefB3")RGRB3 = string2bool(value);
+ else if (name == "ControllerCoreRowGranularRefB4")RGRB4 = string2bool(value);
+ else if (name == "ControllerCoreRowGranularRefB5")RGRB5 = string2bool(value);
+ else if (name == "ControllerCoreRowGranularRefB6")RGRB6 = string2bool(value);
+ else if (name == "ControllerCoreRowGranularRefB7")RGRB7 = string2bool(value);
+ else if (name == "ControllerCoreRowGranularRefB8")RGRB8 = string2bool(value);
+ else if (name == "ControllerCoreRowGranularRefB9")RGRB9 = string2bool(value);
+ else if (name == "ControllerCoreRowGranularRefB10")RGRB10 = string2bool(value);
+ else if (name == "ControllerCoreRowGranularRefB11")RGRB11 = string2bool(value);
+ else if (name == "ControllerCoreRowGranularRefB12")RGRB12 = string2bool(value);
+ else if (name == "ControllerCoreRowGranularRefB13")RGRB13 = string2bool(value);
+ else if (name == "ControllerCoreRowGranularRefB14")RGRB14 = string2bool(value);
+ else if (name == "ControllerCoreRowGranularRefB15")RGRB15 = string2bool(value);
+ else if (name == "ControllerCoreRowGranularRefRASBInClkCycles")
+ trasbclk = string2int(value);
+ else if (name == "ControllerCoreRowGranularRefRRDB_LInClkCycles")
+ trrdblclk = string2int(value);
+ else if (name == "ControllerCoreRowGranularRefRRDB_SInClkCycles")
+ trrdbsclk = string2int(value);
+ else if (name == "ControllerCoreRowGranularRefRPBInClkCycles")
+ trpbclk = string2int(value);
+ else if (name == "ControllerCoreRowGranularRefRCBInClkCycles")
+ trcbclk = string2int(value);
+ else if (name == "ControllerCoreRowGranularRefFAWBInClkCycles")
+ tfawbclk = string2int(value);
else if (name == "ControllerCoreForceMaxRefBurst")
ControllerCoreForceMaxRefBurst = string2bool(value);
else if (name == "ControllerCoreEnableRefPostpone") {
@@ -237,7 +270,6 @@ void Configuration::setParameter(std::string name, std::string value)
#else
AddressOffset = 0;
#endif
- cout << "Address Offset: " << AddressOffset << endl;
} else if (name == "CheckTLM2Protocol")
CheckTLM2Protocol = string2bool(value);
else if (name == "ECCControllerMode")
@@ -350,6 +382,47 @@ unsigned int Configuration::getBytesPerBurst()
return bytesPerBurst;
}
+sc_time Configuration::getTrasb()
+{
+ return trasbclk * memSpec.clk;
+}
+sc_time Configuration::getTrrdb_L()
+{
+ return trrdblclk * memSpec.clk;
+}
+sc_time Configuration::getTrrdb_S()
+{
+ return trrdbsclk * memSpec.clk;
+}
+sc_time Configuration::getTrpb()
+{
+ return trpbclk * memSpec.clk;
+}
+sc_time Configuration::getTrcb()
+{
+ return trcbclk * memSpec.clk;
+}
+sc_time Configuration::getTfawb()
+{
+ return tfawbclk * memSpec.clk;
+}
+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;
+}
+
// 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)
{
diff --git a/DRAMSys/library/src/controller/core/configuration/Configuration.h b/DRAMSys/library/src/controller/core/configuration/Configuration.h
index ea179604..99c9cb9e 100644
--- a/DRAMSys/library/src/controller/core/configuration/Configuration.h
+++ b/DRAMSys/library/src/controller/core/configuration/Configuration.h
@@ -41,6 +41,7 @@
#include
#include
+#include
#include "MemSpec.h"
#include "thermalSimConfig.h"
#include "../../../common/Utils.h"
@@ -85,6 +86,40 @@ struct Configuration {
bool Debug = false;
unsigned int NumberOfMemChannels = 1;
bool ControllerCoreDisableRefresh = false;
+ bool RowGranularRef = false;
+ unsigned int trasbclk = 0;
+ sc_time getTrasb();
+ unsigned int trrdblclk = 0;
+ sc_time getTrrdb_L();
+ unsigned int trrdbsclk = 0;
+ sc_time getTrrdb_S();
+ unsigned int trpbclk = 0;
+ sc_time getTrpb();
+ unsigned int trcbclk = 0;
+ sc_time getTrcb();
+ unsigned int tfawbclk = 0;
+ sc_time getTfawb();
+ 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 RowInc = 1;
+ bool getRGRBank(unsigned int);
+ unsigned int getNumAR(void);
+ unsigned int getRowInc(void);
bool ControllerCoreForceMaxRefBurst = false;
bool ControllerCoreEnableRefPostpone = false;
bool ControllerCoreEnableRefPullIn = false;
diff --git a/DRAMSys/library/src/controller/core/configuration/ConfigurationLoader.cpp b/DRAMSys/library/src/controller/core/configuration/ConfigurationLoader.cpp
index 8da5a85a..75049f56 100644
--- a/DRAMSys/library/src/controller/core/configuration/ConfigurationLoader.cpp
+++ b/DRAMSys/library/src/controller/core/configuration/ConfigurationLoader.cpp
@@ -116,8 +116,6 @@ void ConfigurationLoader::loadMemSpec(Configuration &config,
config.memSpec.MemoryId = queryStringParameter(memspec, "memoryId");
config.memSpec.MemoryType = queryStringParameter(memspec, "memoryType");
- std::cout << "Memtype: " << config.memSpec.MemoryType << std::endl;
-
if (config.memSpec.MemoryType == "DDR4") {
loadDDR4(config, memspec);
} else if (config.memSpec.MemoryType == "DDR3") {
diff --git a/DRAMSys/library/src/controller/core/configuration/MemSpec.h b/DRAMSys/library/src/controller/core/configuration/MemSpec.h
index b954e4b2..24a0b852 100644
--- a/DRAMSys/library/src/controller/core/configuration/MemSpec.h
+++ b/DRAMSys/library/src/controller/core/configuration/MemSpec.h
@@ -147,6 +147,10 @@ struct MemSpec {
{
return tNAW;
}
+ sc_time tActBHistory()
+ {
+ return tNAW;
+ }
sc_time tDataStrobeHistory()
{
return tWTR_L;
diff --git a/DRAMSys/library/src/controller/core/refresh/IRefreshManager.h b/DRAMSys/library/src/controller/core/refresh/IRefreshManager.h
index 5ab46989..1668ef61 100644
--- a/DRAMSys/library/src/controller/core/refresh/IRefreshManager.h
+++ b/DRAMSys/library/src/controller/core/refresh/IRefreshManager.h
@@ -41,6 +41,15 @@
#include
#include "../scheduling/ScheduledCommand.h"
+// Flex. refresh (pull-in, postpone)
+typedef enum {
+ ST_REFRESH = 0,
+ ST_PULLIN,
+ ST_POSTPONE,
+ ST_SKIP,
+ ST_BURST,
+ ST_ALIGN
+} ref_fsm_state_t;
class IRefreshManager
{
@@ -50,10 +59,8 @@ public:
virtual void scheduleRefresh(tlm::tlm_generic_payload &payload,
sc_time time) = 0;
virtual void reInitialize(Bank bank, sc_time time) = 0;
-
-
virtual bool isInvalidated(tlm::tlm_generic_payload &payload, sc_time time) = 0;
};
+#endif /* IREFRESHMANAGER_H_ */
-#endif
diff --git a/DRAMSys/library/src/controller/core/refresh/RGR.cpp b/DRAMSys/library/src/controller/core/refresh/RGR.cpp
new file mode 100644
index 00000000..3be8eeee
--- /dev/null
+++ b/DRAMSys/library/src/controller/core/refresh/RGR.cpp
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) 2017, 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: Éder F. Zulian
+ */
+
+#include "RGR.h"
+#include "../ControllerCore.h"
+#include "../TimingCalculation.h"
+#include "../../../common/Utils.h"
+
+using namespace std;
+
+RGR::RGR(sc_module_name, ControllerCore &ctrlcore) : ccore(ctrlcore),
+ timing(ctrlcore.config.memSpec.refreshTimings[ccore.getBanks()[0]])
+{
+ if (ccore.config.ControllerCoreEnableRefPostpone) {
+ maxpostpone = ccore.config.ControllerCoreMaxPostponedARCmd;
+ }
+ if (ccore.config.ControllerCoreEnableRefPullIn) {
+ maxpullin = ccore.config.ControllerCoreMaxPulledInARCmd;
+ }
+#if 0
+ if (Configuration::getInstance().BankwiseLogic) {
+ for (Bank b : ccore.getBanks()) {
+ sc_time refi = Configuration::getInstance().memSpec.refreshTimings[b].tREFI;
+ nextPlannedRefreshs[b] = b.ID() * refi /
+ Configuration::getInstance().memSpec.NumberOfBanks;
+ }
+ }
+#endif
+ for (Bank b : ccore.getBanks()) {
+ nextPlannedRefreshs[b] = SC_ZERO_TIME;
+ arCmdCounter[b] = 0;
+ alignValue[b] = 0;
+ currentState[b] = ST_REFRESH;
+ previousState[b] = ST_REFRESH;
+ nextState[b] = ST_REFRESH;
+ setUpDummy(rps[b], b);
+ }
+ if (Configuration::getInstance().BankwiseLogic) {
+ for (Bank b : ccore.getBanks()) {
+ planNextRefresh(b, timing.tREFI);
+ }
+ } else {
+ planNextRefresh(ccore.getBanks()[0], timing.tREFI);
+ }
+}
+
+RGR::~RGR()
+{
+}
+
+bool RGR::hasCollision(const ScheduledCommand __attribute__((unused)) &cmd)
+{
+#if 0
+ bool r = false;
+ nbs = Configuration::getInstance().memSpec.NumberOfBanks;
+ for (unsigned b = 0; b < nbs; b++) {
+ if (cmd.getStart() < currentRefresh[b] && cmd.getEnd() > currentRefresh[b])
+ r = true;
+
+ if (cmd.getStart() < nextPlannedRefreshs[b]
+ && cmd.getEnd() > nextPlannedRefreshs[b])
+ r = true;
+ }
+
+ return r;
+#else
+ return false;
+#endif
+}
+
+void RGR::doRefresh(tlm::tlm_generic_payload &p, sc_time t)
+{
+ sc_assert(!isInvalidated(p, t));
+ auto nr = Configuration::getInstance().memSpec.NumberOfRows;
+ auto nar = Configuration::getInstance().getNumAR();
+ auto ri = Configuration::getInstance().getRowInc();
+ assert((nr / nar) > 0);
+ Bank b = DramExtension::getExtension(p).getBank();
+ bool bwl = Configuration::getInstance().BankwiseLogic;
+ bool o = ccore.state->rowBufferStates->rowBufferIsOpen(b);
+ bool ac = ccore.state->rowBufferStates->allRowBuffersAreClosed();
+ bool pre = !!(bwl ? o : (!ac));
+
+ if (!bwl) {
+ for (Bank b : ccore.getBanks()) {
+ currentRefresh[b] = t;
+ }
+ } else {
+ currentRefresh[b] = t;
+ }
+
+ if (pre) {
+ if (!bwl) {
+ for (Bank b : ccore.getBanks()) {
+ auto rgrb = Configuration::getInstance().getRGRBank(b.ID());
+ if (ccore.state->rowBufferStates->rowBufferIsOpen(b) && rgrb) {
+ ccore.scheduleRequest(Command::PreB, rps[Bank(b)]);
+ }
+ }
+ } else {
+ if (Configuration::getInstance().getRGRBank(b.ID())) {
+ ccore.scheduleRequest(Command::PreB, rps[b]);
+ }
+ }
+ }
+
+ for (unsigned r = 0; r < (nr / nar); r += ri) {
+ if (!!bwl) {
+ if (Configuration::getInstance().getRGRBank(b.ID())) {
+ ccore.scheduleRequest(Command::ActB, rps[b]);
+ ccore.scheduleRequest(Command::PreB, rps[b]);
+ }
+ DramExtension::getExtension(p).incrementRow();
+ } else {
+ for (Bank b : ccore.getBanks()) {
+ if (Configuration::getInstance().getRGRBank(b.ID())) {
+ ccore.scheduleRequest(Command::ActB, rps[b]);
+ ccore.scheduleRequest(Command::PreB, rps[b]);
+ }
+ DramExtension::getExtension(rps[b]).incrementRow();
+ }
+ }
+ }
+}
+
+void RGR::scheduleRefresh(tlm::tlm_generic_payload &p, sc_time t)
+{
+ sc_time nrt;
+ Bank b = DramExtension::getExtension(p).getBank();
+ auto bwl = Configuration::getInstance().BankwiseLogic;
+ bool preq = bwl ? ccore.hasPendingRequests(b) : ccore.hasPendingRequests();
+ bool canPostpone = preq && (arCmdCounter[b] < maxpostpone);
+ bool canPullIn = !preq && (arCmdCounter[b] < maxpullin);
+ bool fmb = !!ccore.config.ControllerCoreForceMaxRefBurst;
+ previousState[b] = currentState[b];
+ currentState[b] = nextState[b];
+ switch (currentState[b]) {
+ case ST_REFRESH:
+ assert(arCmdCounter[b] == 0);
+ if (canPostpone) {
+ nextState[b] = ST_POSTPONE;
+ nrt = SC_ZERO_TIME;
+ } else if (canPullIn) {
+ nextState[b] = ST_PULLIN;
+ nrt = SC_ZERO_TIME;
+ } else {
+ doRefresh(p, t);
+ nrt = timing.tREFI;
+ nextState[b] = ST_REFRESH;
+ }
+ break;
+ case ST_PULLIN:
+ if (canPullIn) {
+ doRefresh(p, t);
+ arCmdCounter[b]++;
+ nextState[b] = ST_PULLIN;
+ nrt = SC_ZERO_TIME;
+ } else {
+ alignValue[b] = arCmdCounter[b];
+ nextState[b] = ST_ALIGN;
+ nrt = SC_ZERO_TIME;
+ }
+ break;
+ case ST_SKIP:
+ arCmdCounter[b]--;
+ if (arCmdCounter[b] == 0) {
+ nextState[b] = ST_REFRESH;
+ nrt = SC_ZERO_TIME;
+ } else {
+ nextState[b] = ST_SKIP;
+ nrt = timing.tREFI;
+ }
+ break;
+ case ST_POSTPONE:
+ if ((arCmdCounter[b] == maxpostpone) || ((!preq) && !fmb)) {
+ if (arCmdCounter[b] < maxpostpone) {
+ arCmdCounter[b]++;
+ }
+ alignValue[b] = arCmdCounter[b];
+ nextState[b] = ST_BURST;
+ nrt = SC_ZERO_TIME;
+ } else {
+ arCmdCounter[b]++;
+ nextState[b] = ST_POSTPONE;
+ nrt = timing.tREFI;
+ }
+ break;
+ case ST_BURST:
+ arCmdCounter[b]--;
+ doRefresh(p, t);
+ if (arCmdCounter[b] == 0) {
+ nextState[b] = ST_ALIGN;
+ nrt = SC_ZERO_TIME;
+ } else {
+ nextState[b] = ST_BURST;
+ nrt = SC_ZERO_TIME;
+ }
+ break;
+ case ST_ALIGN:
+ if (previousState[b] == ST_PULLIN) {
+ nrt = timing.tREFI;
+ nextState[b] = ST_SKIP;
+ } else {
+ nrt = timing.tREFI;
+ nextState[b] = ST_REFRESH;
+ }
+ break;
+ default:
+ SC_REPORT_FATAL(this->name(), "Invalid State in Flexible Refresh FSM. Stop.");
+ break;
+ }
+ planNextRefresh(!bwl ? ccore.getBanks()[0] : b, nrt);
+}
+
+void RGR::planNextRefresh(Bank b, sc_time t)
+{
+ nextPlannedRefreshs[b] += t;
+ ccore.controller.send(REFTrigger, nextPlannedRefreshs[b], rps[b]);
+}
+
+void RGR::reInitialize(Bank b, sc_time t)
+{
+ nextPlannedRefreshs[b] = clkAlign(t, Alignment::DOWN);
+ planNextRefresh(b, timing.tREFI);
+}
+
+bool RGR::isInvalidated(tlm::tlm_generic_payload &p, sc_time t)
+{
+ return nextPlannedRefreshs[DramExtension::getExtension(p).getBank()] > t;
+}
+
+void RGR::printDebugMessage(std::string msg)
+{
+ DebugManager::getInstance().printDebugMessage(this->name(), msg);
+}
diff --git a/DRAMSys/library/src/controller/core/refresh/RGR.h b/DRAMSys/library/src/controller/core/refresh/RGR.h
new file mode 100644
index 00000000..3cf31b10
--- /dev/null
+++ b/DRAMSys/library/src/controller/core/refresh/RGR.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2017, 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: Éder F. Zulian
+ */
+
+#ifndef RGR_MANAGER_H_
+#define RGR_MANAGER_H_
+#include "../../../common/dramExtension.h"
+#include "../configuration/MemSpec.h"
+#include "IRefreshManager.h"
+class ControllerCore;
+class RGR : public IRefreshManager, public sc_module
+{
+public:
+ RGR(sc_module_name, ControllerCore &ctrlcore);
+ virtual ~RGR();
+ virtual bool hasCollision(const ScheduledCommand __attribute__((
+ unused)) &command) override;
+ virtual void scheduleRefresh(tlm::tlm_generic_payload &p, sc_time t) override;
+ void reInitialize(Bank bank, sc_time time) override;
+ bool isInvalidated(tlm::tlm_generic_payload &payload, sc_time time) override;
+private:
+ ControllerCore &ccore;
+ RefreshTiming &timing;
+ std::map rps;
+ std::map nextPlannedRefreshs;
+ std::map currentRefresh;
+ unsigned int maxpostpone = 0;
+ unsigned int maxpullin = 0;
+ std::map arCmdCounter;
+ std::map alignValue;
+ std::map currentState;
+ std::map previousState;
+ std::map nextState;
+ void doRefresh(tlm::tlm_generic_payload &p, sc_time t);
+ void planNextRefresh(Bank b, sc_time t);
+ void printDebugMessage(std::string message);
+};
+#endif /* RGR_MANAGER_H_ */
+
diff --git a/DRAMSys/library/src/controller/core/refresh/RefreshManager.h b/DRAMSys/library/src/controller/core/refresh/RefreshManager.h
index ee28c25f..2ec5792d 100644
--- a/DRAMSys/library/src/controller/core/refresh/RefreshManager.h
+++ b/DRAMSys/library/src/controller/core/refresh/RefreshManager.h
@@ -40,15 +40,6 @@
#include "IRefreshManager.h"
#include "../configuration/MemSpec.h"
-typedef enum {
- ST_REFRESH = 0,
- ST_PULLIN,
- ST_POSTPONE,
- ST_SKIP,
- ST_BURST,
- ST_ALIGN
-} ref_fsm_state_t;
-
class ControllerCore;
class RefreshManager : public IRefreshManager, public sc_module
diff --git a/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.cpp b/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.cpp
index 3d71980f..76e69453 100644
--- a/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.cpp
+++ b/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.cpp
@@ -41,13 +41,25 @@
using namespace std;
-
-RefreshManagerBankwise::RefreshManagerBankwise(sc_module_name /*name*/,
- ControllerCore &controller) : controllerCore(controller)
+RefreshManagerBankwise::RefreshManagerBankwise(sc_module_name,
+ ControllerCore &controller) : controllerCore(controller),
+ timing(controller.config.memSpec.refreshTimings[Bank(0)])
{
+ if (controllerCore.config.ControllerCoreEnableRefPostpone) {
+ maxpostpone = controllerCore.config.ControllerCoreMaxPostponedARCmd;
+ }
+ if (controllerCore.config.ControllerCoreEnableRefPullIn) {
+ maxpullin = controllerCore.config.ControllerCoreMaxPulledInARCmd;
+ }
for (Bank bank : controller.getBanks()) {
+ nextPlannedRefreshs[bank] = SC_ZERO_TIME;
+ arCmdCounter[bank] = 0;
+ alignValue[bank] = 0;
+ currentState[bank] = ST_REFRESH;
+ previousState[bank] = ST_REFRESH;
+ nextState[bank] = ST_REFRESH;
setUpDummy(refreshPayloads[bank], bank);
- planNextRefresh(bank);
+ planNextRefresh(bank, timing.tREFI);
}
}
@@ -58,34 +70,28 @@ RefreshManagerBankwise::~RefreshManagerBankwise()
bool RefreshManagerBankwise::hasCollision(const ScheduledCommand &command)
{
Bank bank = command.getBank();
- // Get the last AutoRefresh command for this bank and the time of its end
- ScheduledCommand lastAutoRefreshCmd = controllerCore.state->getLastCommand(
- Command::AutoRefresh, bank);
- sc_time endTimeLastAutoRefreshCmd = lastAutoRefreshCmd.getEnd();
- // Get the time of the next planned refresh for this bank
- sc_time timeNextPlannedRefresh = nextPlannedRefreshs[command.getBank()];
- // Collision:
- // - the start time of the command is before the end time of the last auto refresh command for this bank
- // - the end time of the command is after the next planned refresh for this bank
- return command.getStart() < endTimeLastAutoRefreshCmd
- || command.getEnd() > timeNextPlannedRefresh;
+ bool collisionWithPreviousRefEnd = command.getStart() <
+ controllerCore.state->getLastCommand(Command::AutoRefresh, bank).getEnd();
+ bool collisionWithNextRefStart = command.getEnd() >= nextPlannedRefreshs[bank];
+ if (controllerCore.config.ControllerCoreEnableRefPostpone
+ && (arCmdCounter[bank] < maxpostpone)) {
+ collisionWithNextRefStart = false;
+ }
+ return collisionWithPreviousRefEnd || collisionWithNextRefStart;
}
-void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload,
- sc_time time)
+void RefreshManagerBankwise::doRefresh(tlm::tlm_generic_payload &payload,
+ sc_time time)
{
sc_assert(!isInvalidated(payload, time));
-
tlm::tlm_generic_payload &refreshPayload =
refreshPayloads[DramExtension::getExtension(payload).getBank()];
-
DramExtension &extension = DramExtension::getExtension(refreshPayload);
if (controllerCore.state->rowBufferStates->rowBufferIsOpen(
extension.getBank())) {
ScheduledCommand precharge(Command::Precharge, time,
getExecutionTime(Command::Precharge, refreshPayload), extension);
-
controllerCore.getCommandChecker(Command::Precharge).delayToSatisfyConstraints(
precharge);
controllerCore.state->change(precharge);
@@ -99,14 +105,135 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload,
controllerCore.state->change(refresh);
extension.incrementRow();
controllerCore.controller.send(refresh, refreshPayload);
-
- planNextRefresh(extension.getBank());
}
-void RefreshManagerBankwise::planNextRefresh(Bank bank)
+void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload,
+ sc_time time)
{
- nextPlannedRefreshs[bank] +=
- Configuration::getInstance().memSpec.refreshTimings[bank].tREFI;
+ sc_time nextRefTiming;
+ Bank bank = DramExtension::getExtension(payload).getBank();
+ bool pendingReq = controllerCore.hasPendingRequests(bank);
+ bool canPostpone = pendingReq && (arCmdCounter[bank] < maxpostpone);
+ bool canPullIn = !pendingReq && (arCmdCounter[bank] < maxpullin);
+
+ previousState[bank] = currentState[bank];
+ currentState[bank] = nextState[bank];
+
+ switch (currentState[bank]) {
+ case ST_REFRESH:
+ // Regular Refresh. It's possible to migrate from this to the flexible
+ // refresh states
+ // The arCmdCounter[bank] should always be equal to zero here
+ assert(arCmdCounter[bank] == 0);
+
+ if (canPostpone) {
+ nextState[bank] = ST_POSTPONE;
+ nextRefTiming = SC_ZERO_TIME;
+ } else if (canPullIn) {
+ nextState[bank] = ST_PULLIN;
+ nextRefTiming = SC_ZERO_TIME; // Attempt to burst pull-in
+ } else {
+ doRefresh(payload, time);
+ nextRefTiming = timing.tREFI;
+ nextState[bank] = ST_REFRESH;
+ }
+ break;
+
+ case ST_PULLIN:
+ // Pull-In Refresh. Try to pull-in refreshes as long as the limit
+ // hasn't been reached yet and has credits
+
+ if (canPullIn) {
+ doRefresh(payload, time);
+ arCmdCounter[bank]++;
+ nextState[bank] = ST_PULLIN;
+ nextRefTiming = timing.tRFC;
+ } else {
+ alignValue[bank] = arCmdCounter[bank]; // Saving value to be used by ST_ALIGN
+ nextState[bank] = ST_ALIGN;
+ nextRefTiming = SC_ZERO_TIME;
+ }
+ break;
+
+ case ST_SKIP:
+ // Skip Refresh. The arCmdCounter[bank] is used to skip the correct
+ // amount of refreshes
+
+ arCmdCounter[bank]--;
+ if (arCmdCounter[bank] == 0) {
+ nextState[bank] = ST_REFRESH;
+ nextRefTiming = SC_ZERO_TIME;
+ } else {
+ nextState[bank] = ST_SKIP;
+ nextRefTiming = timing.tREFI;
+ }
+ break;
+
+ case ST_POSTPONE:
+ // Postpone Refresh. Delaying refreshes as long as there are pending
+ // requests and credits to postpone. Should be followed by a burst
+ // refresh.
+
+ if ((arCmdCounter[bank] == maxpostpone) || ((!pendingReq)
+ && !controllerCore.config.ControllerCoreForceMaxRefBurst)) {
+ // Burst conditions met
+ if (arCmdCounter[bank] < maxpostpone) {
+ // In case the burst was started by inactivity, need to also
+ // count the current REF
+ arCmdCounter[bank]++;
+ }
+ // Will start a burst next, so the value is saved to be used by
+ // ST_ALIGN
+ alignValue[bank] = arCmdCounter[bank];
+ nextState[bank] = ST_BURST;
+ nextRefTiming = SC_ZERO_TIME;
+ } else {
+ arCmdCounter[bank]++;
+ nextState[bank] = ST_POSTPONE;
+ nextRefTiming = timing.tREFI;
+ }
+ break;
+
+ case ST_BURST:
+ // Burst Refresh. The arCmdCounter[bank] is used to issue the correct
+ // amount of refreshes
+
+ arCmdCounter[bank]--;
+ doRefresh(payload, time);
+ if (arCmdCounter[bank] == 0) {
+ // All bursts issued, next state will align to tREFI
+ nextState[bank] = ST_ALIGN;
+ nextRefTiming = SC_ZERO_TIME;
+ } else {
+ nextState[bank] = ST_BURST;
+ nextRefTiming = timing.tRFC;
+ }
+ break;
+
+ case ST_ALIGN:
+ // Align Refresh. Adjusting the timing so the next REF timing will be
+ // a in a time multiple of tREFI.
+
+ if (previousState[bank] == ST_PULLIN) {
+ nextRefTiming = timing.tREFI - (timing.tRFC * (alignValue[bank]));
+ nextState[bank] = ST_SKIP;
+ } else {
+ nextRefTiming = timing.tREFI - (timing.tRFC * (alignValue[bank] - 1));
+ nextState[bank] = ST_REFRESH;
+ }
+ break;
+
+ default:
+ SC_REPORT_FATAL(this->name(), "Invalid State in Flexible Refresh FSM. Stop.");
+ break;
+ }
+
+ planNextRefresh(bank, nextRefTiming);
+}
+
+void RefreshManagerBankwise::planNextRefresh(Bank bank, sc_time nextRefTiming)
+{
+ nextPlannedRefreshs[bank] += nextRefTiming;
controllerCore.controller.send(REFTrigger, nextPlannedRefreshs[bank],
refreshPayloads[bank]);
}
@@ -114,7 +241,7 @@ void RefreshManagerBankwise::planNextRefresh(Bank bank)
void RefreshManagerBankwise::reInitialize(Bank bank, sc_time time)
{
nextPlannedRefreshs[bank] = clkAlign(time, Alignment::DOWN);
- planNextRefresh(bank);
+ planNextRefresh(bank, timing.tREFI);
}
bool RefreshManagerBankwise::isInvalidated(tlm::tlm_generic_payload &payload,
diff --git a/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.h b/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.h
index f0f57070..b5c2fc80 100644
--- a/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.h
+++ b/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.h
@@ -53,19 +53,24 @@ public:
virtual bool hasCollision(const ScheduledCommand &command) override;
virtual void scheduleRefresh(tlm::tlm_generic_payload &payload,
sc_time time) override;
-
void reInitialize(Bank bank, sc_time time) override;
-
bool isInvalidated(tlm::tlm_generic_payload &payload, sc_time time) override;
private:
ControllerCore &controllerCore;
-
+ RefreshTiming &timing;
std::map refreshPayloads;
std::map nextPlannedRefreshs;
+ unsigned int maxpostpone = 0;
+ unsigned int maxpullin = 0;
+ std::map arCmdCounter;
+ std::map alignValue;
+ std::map currentState;
+ std::map previousState;
+ std::map nextState;
- void planNextRefresh(Bank bank);
-
+ void doRefresh(tlm::tlm_generic_payload &payload, sc_time time);
+ void planNextRefresh(Bank bank, sc_time nextRefTiming);
void printDebugMessage(std::string message);
};
diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/ActBChecker.cpp b/DRAMSys/library/src/controller/core/scheduling/checker/ActBChecker.cpp
new file mode 100644
index 00000000..841ba5a7
--- /dev/null
+++ b/DRAMSys/library/src/controller/core/scheduling/checker/ActBChecker.cpp
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2017, 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: Éder F. Zulian
+ */
+
+#include
+#include
+#include
+#include "ActBChecker.h"
+#include "../../TimingCalculation.h"
+#include "../../../../common/DebugManager.h"
+#include "../../../Command.h"
+#include "../../../../common/Utils.h"
+
+using namespace std;
+
+void ActBChecker::delayToSatisfyConstraints(ScheduledCommand &cmd) const
+{
+ sc_assert(cmd.getCommand() == Command::ActB);
+ ScheduledCommand lcb = state.getLastScheduledCommand(cmd.getBank());
+ if (lcb.isValidCommand()) {
+ if (lcb.getCommand() == Command::PreB) {
+ cmd.establishMinDistanceFromStart(lcb.getStart(),
+ Configuration::getInstance().getTrpb());
+ } else if (lcb.getCommand() == Command::Precharge
+ || lcb.getCommand() == Command::PrechargeAll) {
+ cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec.tRP);
+ } else if (lcb.getCommand() == Command::ReadA) {
+ cmd.establishMinDistanceFromStart(lcb.getStart(),
+ config.memSpec.tRTP + config.memSpec.tRP);
+ } else if (lcb.getCommand() == Command::WriteA) {
+ cmd.establishMinDistanceFromStart(lcb.getStart(),
+ config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR +
+ config.memSpec.tRP);
+ } else if (lcb.getCommand() == Command::AutoRefresh) {
+ cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec.tRFC);
+ } else if (lcb.getCommand() == Command::PDNPX
+ || lcb.getCommand() == Command::PDNAX) {
+ cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec.tXP);
+ } else if (lcb.getCommand() == Command::SREFX) {
+ cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec.tXSR);
+ } else {
+ reportFatal("ActB Checker",
+ "ActB can not follow " + commandToString(lcb.getCommand()));
+ }
+ }
+ ScheduledCommand lc;
+ if ((lc = state.getLastCommand(Command::PrechargeAll)).isValidCommand()) {
+ cmd.establishMinDistanceFromStart(lc.getStart(), config.memSpec.tRP);
+ }
+ delay_to_satisfy_activateToActivate_sameBank(cmd);
+ while (!(state.bus.isFree(cmd.getStart())
+ && satsfies_activateToActivate_differentBank(cmd)
+ && satisfies_nActivateWindow(cmd))) {
+ cmd.delayStart(config.memSpec.clk);
+ }
+}
+
+void ActBChecker::delay_to_satisfy_activateToActivate_sameBank(
+ ScheduledCommand &cmd) const
+{
+ ScheduledCommand lastActOnBank = state.getLastCommand(Command::Activate,
+ cmd.getBank());
+ if (lastActOnBank.isValidCommand()) {
+ cmd.establishMinDistanceFromStart(lastActOnBank.getStart(), config.memSpec.tRC);
+ }
+ ScheduledCommand lastActBOnBank = state.getLastCommand(Command::ActB,
+ cmd.getBank());
+ if (lastActBOnBank.isValidCommand()) {
+ cmd.establishMinDistanceFromStart(lastActBOnBank.getStart(),
+ Configuration::getInstance().getTrcb());
+ }
+}
+
+bool ActBChecker::satsfies_activateToActivate_differentBank(
+ ScheduledCommand &cmd) const
+{
+ for (auto act : state.lastActivatesB) {
+ sc_time t = act.first, tRRD = (cmd.getBankGroup() == act.second.getBankGroup() ?
+ Configuration::getInstance().getTrrdb_L() :
+ Configuration::getInstance().getTrrdb_S());
+ if ((t < cmd.getStart() && cmd.getStart() - t < tRRD) || (cmd.getStart() <= t
+ && t - cmd.getStart() < tRRD)) {
+ return false;
+ }
+ }
+ for (auto act : state.lastActivates) {
+ sc_time t = act.first, tRRD = (cmd.getBankGroup() == act.second.getBankGroup() ?
+ config.memSpec.tRRD_L : config.memSpec.tRRD_S);
+ if ((t < cmd.getStart() && cmd.getStart() - t < tRRD) || (cmd.getStart() <= t
+ && t - cmd.getStart() < tRRD)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool ActBChecker::satisfies_nActivateWindow(ScheduledCommand &cmd) const
+{
+ if (state.lastActivatesB.size() >= config.memSpec.nActivate) {
+ maplastActivates = state.lastActivatesB;
+ lastActivates.emplace(cmd.getStart(), cmd);
+ auto upper = lastActivates.begin();
+ advance(upper, config.memSpec.nActivate);
+ auto lower = lastActivates.begin();
+ while (upper != lastActivates.end()) {
+ if (upper->first - lower->first < Configuration::getInstance().getTfawb()) {
+ return false;
+ }
+ ++upper;
+ ++lower;
+ }
+ }
+ return true;
+}
diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/ActBChecker.h b/DRAMSys/library/src/controller/core/scheduling/checker/ActBChecker.h
new file mode 100644
index 00000000..023db94f
--- /dev/null
+++ b/DRAMSys/library/src/controller/core/scheduling/checker/ActBChecker.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2017, 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: Éder F. Zulian
+ */
+#ifndef ACTB_CHECKER_H_
+#define ACTB_CHECKER_H_
+#include