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 +#include "ICommandChecker.h" +#include "../../configuration/Configuration.h" +#include "../../../ControllerState.h" +class ActBChecker: public ICommandChecker +{ +public: + ActBChecker(const Configuration &config, + ControllerState &state) : config(config), state(state) {} + virtual ~ActBChecker() {} + virtual void delayToSatisfyConstraints(ScheduledCommand &command) const + override; +private: + const Configuration &config; + ControllerState &state; + void delay_to_satisfy_activateToActivate_sameBank(ScheduledCommand &command) + const; + bool satsfies_activateToActivate_differentBank(ScheduledCommand &command) const; + bool satisfies_nActivateWindow(ScheduledCommand &command) const; +}; +#endif /* ACTB_CHECKER_H_ */ diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/ActivateChecker.cpp b/DRAMSys/library/src/controller/core/scheduling/checker/ActivateChecker.cpp index 4ce4b249..da2b67cb 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/ActivateChecker.cpp +++ b/DRAMSys/library/src/controller/core/scheduling/checker/ActivateChecker.cpp @@ -52,13 +52,20 @@ void ActivateChecker::delayToSatisfyConstraints(ScheduledCommand &command) const ScheduledCommand lastCommandOnBank = state.getLastScheduledCommand( command.getBank()); if (lastCommandOnBank.isValidCommand()) { - if (lastCommandOnBank.getCommand() == Command::Precharge + if (lastCommandOnBank.getCommand() == Command::PreB + || lastCommandOnBank.getCommand() == Command::Precharge || lastCommandOnBank.getCommand() == Command::PrechargeAll) { command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tRP); } else if (lastCommandOnBank.getCommand() == Command::ReadA) { command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tRTP + config.memSpec.tRP); + } else if (lastCommandOnBank.getCommand() == Command::WriteA) { + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), + config.memSpec.tRP); + } else if (lastCommandOnBank.getCommand() == Command::ReadA) { + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), + config.memSpec.tRTP + config.memSpec.tRP); } else if (lastCommandOnBank.getCommand() == Command::WriteA) { command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + @@ -97,6 +104,13 @@ void ActivateChecker::delay_to_satisfy_activateToActivate_sameBank( command.establishMinDistanceFromStart(lastActivateOnBank.getStart(), config.memSpec.tRC); } + + ScheduledCommand lastActBOnBank = state.getLastCommand(Command::ActB, + command.getBank()); + if (lastActBOnBank.isValidCommand()) { + command.establishMinDistanceFromStart(lastActivateOnBank.getStart(), + config.memSpec.tRC); + } } bool ActivateChecker::satsfies_activateToActivate_differentBank( diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/PreBChecker.cpp b/DRAMSys/library/src/controller/core/scheduling/checker/PreBChecker.cpp new file mode 100644 index 00000000..a8376a28 --- /dev/null +++ b/DRAMSys/library/src/controller/core/scheduling/checker/PreBChecker.cpp @@ -0,0 +1,80 @@ +/* + * 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 "PreBChecker.h" +#include "../../TimingCalculation.h" +void PreBChecker::delayToSatisfyConstraints(ScheduledCommand &cmd)const +{ + sc_assert(cmd.getCommand() == Command::PreB); + ScheduledCommand lastCmd = state.getLastScheduledCommand(cmd.getBank()); + if (lastCmd.isValidCommand()) { + if (lastCmd.getCommand() == Command::PreB) { + cmd.establishMinDistanceFromStart(lastCmd.getStart(), + Configuration::getInstance().getTrpb()); + } else if (lastCmd.getCommand() == Command::Precharge) { + cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec.tRP); + } else if (lastCmd.getCommand() == Command::PrechargeAll) { + cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec.tRP); + } else if (lastCmd.getCommand() == Command::ActB) { + cmd.establishMinDistanceFromStart(lastCmd.getStart(), + config.memSpec.tRCD); // XXX: trcd is less than the NEW! trasb! ok! + } else if (lastCmd.getCommand() == Command::Activate) { + cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec.tRCD); + } else if (lastCmd.getCommand() == Command::Read) { + cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec.tRTP); + } else if (lastCmd.getCommand() == Command::Write) { + cmd.establishMinDistanceFromStart(lastCmd.getStart(), + config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR); + } else if (lastCmd.getCommand() == Command::PDNAX) { + cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec.tXP); + } else { + reportFatal("PreB Checker", + "PreB can not follow " + commandToString(lastCmd.getCommand())); + } + } + ScheduledCommand lc; + if ((lc = state.getLastCommand(Command::PrechargeAll)).isValidCommand()) { + cmd.establishMinDistanceFromStart(lc.getStart(), config.memSpec.tRP); + } + if ((lc = state.getLastCommand(Command::Activate, + cmd.getBank())).isValidCommand()) { + cmd.establishMinDistanceFromStart(lc.getStart(), config.memSpec.tRAS); + } + if ((lc = state.getLastCommand(Command::ActB, + cmd.getBank())).isValidCommand()) { + cmd.establishMinDistanceFromStart(lc.getStart(), + Configuration::getInstance().getTrasb()); + } + state.bus.moveCommandToNextFreeSlot(cmd); +} diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/PreBChecker.h b/DRAMSys/library/src/controller/core/scheduling/checker/PreBChecker.h new file mode 100644 index 00000000..f37241d9 --- /dev/null +++ b/DRAMSys/library/src/controller/core/scheduling/checker/PreBChecker.h @@ -0,0 +1,51 @@ +/* + * 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 PREB_CHECKER_H_ +#define PREB_CHECKER_H_ +#include "ICommandChecker.h" +#include "../../configuration/Configuration.h" +#include "../../../ControllerState.h" +class PreBChecker: public ICommandChecker +{ +public: + PreBChecker(const Configuration &config, + ControllerState &state): config(config), state(state) {} + virtual ~PreBChecker() {} + virtual void delayToSatisfyConstraints(ScheduledCommand &command) const + override; +private: + const Configuration &config; + ControllerState &state; +}; +#endif /* PREB_CHECKER_H_ */ diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeAllChecker.cpp b/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeAllChecker.cpp index 297ad105..12f743c9 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeAllChecker.cpp +++ b/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeAllChecker.cpp @@ -48,10 +48,12 @@ const for (unsigned int bank = 0; bank < config.memSpec.NumberOfBanks; ++bank) { ScheduledCommand lastCommand = state.getLastScheduledCommand(Bank(bank)); if (lastCommand.isValidCommand()) { - if (lastCommand.getCommand() == Command::Precharge) { + if (lastCommand.getCommand() == Command::Precharge + || lastCommand.getCommand() == Command::PreB) { command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRP); - } else if (lastCommand.getCommand() == Command::Activate) { + } else if (lastCommand.getCommand() == Command::Activate + || lastCommand.getCommand() == Command::ActB) { command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRCD); } else if (lastCommand.getCommand() == Command::Read) { diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeChecker.cpp b/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeChecker.cpp index d6bfd8fd..c51fb2b1 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeChecker.cpp +++ b/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeChecker.cpp @@ -49,10 +49,12 @@ const if (lastCommand.isValidCommand()) { // the first two cases happen when a resfresh interrups the command sequence of a transaction // (e.g. commands to process transaction are PRE-ACT-RD and refresh happens after the PRE or after the ACT) - if (lastCommand.getCommand() == Command::Precharge) { + if (lastCommand.getCommand() == Command::Precharge + || lastCommand.getCommand() == Command::PreB) { command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRP); - } else if (lastCommand.getCommand() == Command::Activate) { + } else if (lastCommand.getCommand() == Command::Activate + || lastCommand.getCommand() == Command::ActB) { command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRCD); } diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/ReadChecker.cpp b/DRAMSys/library/src/controller/core/scheduling/checker/ReadChecker.cpp index 78c3cfe9..b5917e42 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/ReadChecker.cpp +++ b/DRAMSys/library/src/controller/core/scheduling/checker/ReadChecker.cpp @@ -49,7 +49,8 @@ void ReadChecker::delayToSatisfyConstraints(ScheduledCommand &command) const ScheduledCommand lastCommand = state.getLastScheduledCommand(command.getBank()); if (lastCommand.isValidCommand()) { - if (lastCommand.getCommand() == Command::Activate) { + if (lastCommand.getCommand() == Command::Activate + || lastCommand.getCommand() == Command::ActB) { command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRCD); } else if (lastCommand.getCommand() == Command::Read) { diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/RefreshChecker.cpp b/DRAMSys/library/src/controller/core/scheduling/checker/RefreshChecker.cpp index f05f308d..f7d110f0 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/RefreshChecker.cpp +++ b/DRAMSys/library/src/controller/core/scheduling/checker/RefreshChecker.cpp @@ -66,8 +66,6 @@ void RefreshChecker::delayToSatisfyConstraints(ScheduledCommand &command) const command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tXSR); } else if (lastCommandOnBank.getCommand() == Command::AutoRefresh) { - command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), - config.memSpec.tRFC); } else reportFatal("Refresh Checker", "Refresh can not follow " + commandToString(lastCommandOnBank.getCommand())); @@ -77,10 +75,12 @@ void RefreshChecker::delayToSatisfyConstraints(ScheduledCommand &command) const ScheduledCommand lastCommand = state.getLastScheduledCommand(Bank(bank)); if (lastCommand.isValidCommand()) { if (lastCommand.getCommand() == Command::Precharge - || lastCommand.getCommand() == Command::PrechargeAll) { + || lastCommand.getCommand() == Command::PrechargeAll + || lastCommand.getCommand() == Command::PreB) { command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRP); - } else if (lastCommand.getCommand() == Command::Activate) { + } else if (lastCommand.getCommand() == Command::Activate + || lastCommand.getCommand() == Command::ActB) { command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRCD); } else if (lastCommand.getCommand() == Command::ReadA) { @@ -98,8 +98,6 @@ void RefreshChecker::delayToSatisfyConstraints(ScheduledCommand &command) const command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tXSR); } else if (lastCommand.getCommand() == Command::AutoRefresh) { - command.establishMinDistanceFromStart(lastCommand.getStart(), - config.memSpec.tRFC); } else reportFatal("Refresh Checker", "Refresh can not follow " + commandToString(lastCommand.getCommand())); diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/WriteChecker.cpp b/DRAMSys/library/src/controller/core/scheduling/checker/WriteChecker.cpp index a356caa8..226d24aa 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/WriteChecker.cpp +++ b/DRAMSys/library/src/controller/core/scheduling/checker/WriteChecker.cpp @@ -49,7 +49,8 @@ void WriteChecker::delayToSatisfyConstraints(ScheduledCommand &command) const ScheduledCommand lastCommand = state.getLastScheduledCommand(command.getBank()); if (lastCommand.isValidCommand()) { - if (lastCommand.getCommand() == Command::Activate) { + if (lastCommand.getCommand() == Command::Activate + || lastCommand.getCommand() == Command::ActB) { command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRCD); } else if (lastCommand.getCommand() == Command::Read) { diff --git a/DRAMSys/library/src/simulation/DRAMSys.cpp b/DRAMSys/library/src/simulation/DRAMSys.cpp index 3d9829db..031e4bc4 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.cpp +++ b/DRAMSys/library/src/simulation/DRAMSys.cpp @@ -128,7 +128,8 @@ DRAMSys::DRAMSys(sc_module_name __attribute__((unused)) name, simName = Configuration::getInstance().SimulationName; tinyxml2::XMLDocument simulationdoc; loadXML(simulationToRun, simulationdoc); - tinyxml2::XMLElement *simulation = simulationdoc.FirstChildElement("simulation"); + tinyxml2::XMLElement *simulation = + simulationdoc.FirstChildElement("simulation"); if (simulation != NULL) { tinyxml2::XMLElement *simid = simulation->FirstChildElement("simulationid"); if (simid != NULL) { @@ -140,8 +141,6 @@ DRAMSys::DRAMSys(sc_module_name __attribute__((unused)) name, } } } - cout << "Simulation name set to: " << simName << endl; - // Instantiate all internal DRAMSys modules: instantiateModules(simName, pathToResources); // Connect all internal DRAMSys modules: @@ -149,6 +148,8 @@ DRAMSys::DRAMSys(sc_module_name __attribute__((unused)) name, // Setup the debug manager: setupDebugManager(Configuration::getInstance().SimulationName); + + report(headline); } void DRAMSys::logo() diff --git a/DRAMSys/library/src/simulation/Dram.h b/DRAMSys/library/src/simulation/Dram.h index c1e0a9cf..e81023a3 100644 --- a/DRAMSys/library/src/simulation/Dram.h +++ b/DRAMSys/library/src/simulation/Dram.h @@ -48,6 +48,7 @@ #include #include #include +#include #include "../common/DebugManager.h" #include "../common/dramExtension.h" #include "../controller/Controller.h" @@ -129,6 +130,13 @@ struct Dram : sc_module { memArchSpec.dll = Configuration::getInstance().memSpec.DLL; MemTimingSpec memTimingSpec; + memTimingSpec.FAWB = Configuration::getInstance().tfawbclk; + memTimingSpec.RASB = Configuration::getInstance().trasbclk; + memTimingSpec.RCB = Configuration::getInstance().trcbclk; + memTimingSpec.RPB = Configuration::getInstance().trpbclk; + memTimingSpec.RRDB = Configuration::getInstance().trrdblclk; + memTimingSpec.RRDB_L = Configuration::getInstance().trrdblclk; + memTimingSpec.RRDB_S = Configuration::getInstance().trrdblclk; memTimingSpec.AL = Configuration::getInstance().memSpec.tAL / clk; memTimingSpec.CCD = Configuration::getInstance().memSpec.tCCD_S / clk; memTimingSpec.CCD_L = Configuration::getInstance().memSpec.tCCD_L / clk; @@ -388,7 +396,13 @@ struct Dram : sc_module { cycle = sc_time_stamp().value() / Configuration::getInstance().memSpec.clk.value(); } - if (phase == BEGIN_PRE) { + if (phase == BEGIN_PREB) { + if (powerAnalysis == true) { + DRAMPower->doCommand(MemCommand::PREB, bank, cycle); + } + sendToController(payload, END_PREB, delay + getExecutionTime(Command::PreB, + payload)); + } else if (phase == BEGIN_PRE) { if (powerAnalysis == true) { DRAMPower->doCommand(MemCommand::PRE, bank, cycle); } @@ -400,6 +414,16 @@ struct Dram : sc_module { } sendToController(payload, END_PRE_ALL, delay + getExecutionTime(Command::PrechargeAll, payload)); + } else if (phase == BEGIN_ACTB) { + if (powerAnalysis == true) { + DRAMPower->doCommand(MemCommand::ACTB, bank, cycle); + } + sendToController(payload, END_ACTB, delay + getExecutionTime(Command::ActB, + payload)); + unsigned int row = DramExtension::getExtension(payload).getRow().ID(); + if (StoreMode == StorageMode::ErrorModel) { + ememory[bank]->activate(row); + } } else if (phase == BEGIN_ACT) { if (powerAnalysis == true) { DRAMPower->doCommand(MemCommand::ACT, bank, cycle); @@ -502,7 +526,7 @@ struct Dram : sc_module { else if (phase == BEGIN_REFB) { if (powerAnalysis == true) { - SC_REPORT_FATAL("DRAM", "Power calculation for bankwise logic not supported"); + DRAMPower->doCommand(MemCommand::REFB, bank, cycle); } sendToController(payload, END_REFB, delay + getExecutionTime(Command::AutoRefresh, payload)); diff --git a/DRAMSys/library/src/simulation/TracePlayer.cpp b/DRAMSys/library/src/simulation/TracePlayer.cpp index 581098a3..e46840b3 100644 --- a/DRAMSys/library/src/simulation/TracePlayer.cpp +++ b/DRAMSys/library/src/simulation/TracePlayer.cpp @@ -115,6 +115,7 @@ void TracePlayer::setNumberOfTransactions(unsigned int n) unsigned int TracePlayer::getNumberOfLines(string pathToTrace) { + // Reference: http://stackoverflow.com/questions/3482064/counting-the-number-of-lines-in-a-text-file ifstream newFile; newFile.open(pathToTrace); // new lines will be skipped unless we stop it from happening: diff --git a/DRAMSys/simulator/main.cpp b/DRAMSys/simulator/main.cpp index 39fb82d7..798e685a 100644 --- a/DRAMSys/simulator/main.cpp +++ b/DRAMSys/simulator/main.cpp @@ -69,7 +69,7 @@ int sc_main(int argc, char **argv) if (argc > 1) { SimulationXML = argv[1]; } else { - SimulationXML = resources + "simulations/ddr3-example.xml"; + SimulationXML = resources + "simulations/rgrsim.xml"; } std::vector players; diff --git a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h index 952e1f2c..5de756e0 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h +++ b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h @@ -142,6 +142,21 @@ protected: }; +class PREB: public Phase +{ +public: + using Phase::Phase; +protected: + virtual QColor getPhaseColor() const override + { + return ColorGenerator::getColor(1); + } + virtual QString Name() const override + { + return "PREB"; + } +}; + class PRE : public Phase { public: @@ -157,6 +172,20 @@ protected: } }; +class ACTB : public Phase +{ +public: + using Phase::Phase; +protected: + virtual QColor getPhaseColor() const override + { + return ColorGenerator::getColor(3); + } + virtual QString Name() const override + { + return "ACTB"; + } +}; class ACT : public Phase { diff --git a/DRAMSys/traceAnalyzer/businessObjects/phases/phasefactory.cpp b/DRAMSys/traceAnalyzer/businessObjects/phases/phasefactory.cpp index 1d3393a7..3f7dc143 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/phases/phasefactory.cpp +++ b/DRAMSys/traceAnalyzer/businessObjects/phases/phasefactory.cpp @@ -56,9 +56,15 @@ shared_ptr PhaseFactory::CreatePhase(ID id, const QString &dbPhaseName, return shared_ptr(new RESP(id, span, trans, {}, std::shared_ptr())); + else if (dbPhaseName == "PREB") return shared_ptr(new PREB(id, span, + trans, {Timespan(span.Begin(), span.Begin() + clk)}, + std::shared_ptr())); else if (dbPhaseName == "PRE") return shared_ptr(new PRE(id, span, trans, {Timespan(span.Begin(), span.Begin() + clk)}, std::shared_ptr())); + else if (dbPhaseName == "ACTB") return shared_ptr(new ACTB(id, span, + trans, {Timespan(span.Begin(), span.Begin() + clk)}, + std::shared_ptr())); else if (dbPhaseName == "ACT") return shared_ptr(new ACT(id, span, trans, {Timespan(span.Begin(), span.Begin() + clk)}, std::shared_ptr())); diff --git a/DRAMSys/traceAnalyzer/data/tracedb.cpp b/DRAMSys/traceAnalyzer/data/tracedb.cpp index b1b19a65..dbe3687a 100644 --- a/DRAMSys/traceAnalyzer/data/tracedb.cpp +++ b/DRAMSys/traceAnalyzer/data/tracedb.cpp @@ -172,6 +172,30 @@ shared_ptr TraceDB::getNextPrecharge(ID currentTransactionId) return parseTransactionFromQuery(query); } +shared_ptr TraceDB::getNextActb(ID currentTransactionId) +{ + QSqlQuery query(database); + QString queryText = queryTexts.queryHead + + "WHERE TransactionID > :currentID AND PhaseName = 'ACTB' LIMIT 1"; + + query.prepare(queryText); + query.bindValue(":currentID", currentTransactionId); + executeQuery(query); + return parseTransactionFromQuery(query); +} + +shared_ptr TraceDB::getNextPreb(ID currentTransactionId) +{ + QSqlQuery query(database); + QString queryText = queryTexts.queryHead + + "WHERE TransactionID > :currentID AND PhaseName = 'PREB' LIMIT 1"; + + query.prepare(queryText); + query.bindValue(":currentID", currentTransactionId); + executeQuery(query); + return parseTransactionFromQuery(query); +} + shared_ptr TraceDB::getNextRefresh(ID currentTransactionId) { QSqlQuery query(database); @@ -184,6 +208,18 @@ shared_ptr TraceDB::getNextRefresh(ID currentTransactionId) return parseTransactionFromQuery(query); } +shared_ptr TraceDB::getNextRefb(ID currentTransactionId) +{ + QSqlQuery query(database); + QString queryText = queryTexts.queryHead + + "WHERE TransactionID > :currentID AND PhaseName = 'REFB' LIMIT 1"; + + query.prepare(queryText); + query.bindValue(":currentID", currentTransactionId); + executeQuery(query); + return parseTransactionFromQuery(query); +} + ID TraceDB::getTransactionIDFromPhaseID(ID phaseID) { QSqlQuery query(database); diff --git a/DRAMSys/traceAnalyzer/data/tracedb.h b/DRAMSys/traceAnalyzer/data/tracedb.h index b4baf8bb..7ab07040 100644 --- a/DRAMSys/traceAnalyzer/data/tracedb.h +++ b/DRAMSys/traceAnalyzer/data/tracedb.h @@ -83,6 +83,9 @@ public: std::shared_ptr getNextPrecharge(ID currentTransactionId); std::shared_ptr getNextActivate(ID currentTransactionId); std::shared_ptr getNextRefresh(ID currentTransactionId); + std::shared_ptr getNextPreb(ID currentTransactionId); + std::shared_ptr getNextActb(ID currentTransactionId); + std::shared_ptr getNextRefb(ID currentTransactionId); std::shared_ptr getTransactionByID(ID id); diff --git a/DRAMSys/traceAnalyzer/presentation/tracenavigator.cpp b/DRAMSys/traceAnalyzer/presentation/tracenavigator.cpp index 4d2a15b2..01f7db86 100644 --- a/DRAMSys/traceAnalyzer/presentation/tracenavigator.cpp +++ b/DRAMSys/traceAnalyzer/presentation/tracenavigator.cpp @@ -234,7 +234,45 @@ void TraceNavigator::selectNextPrecharge() selectTransaction(nextPrecharge); } +void TraceNavigator::selectNextActb() +{ + shared_ptr nextActb; + if (!SelectedTransactions().empty()) + nextActb = traceFile.getNextActb(SelectedTransactions().front()->Id()); + else + nextActb = traceFile.getNextActb(0); + + if (nextActb) + selectTransaction(nextActb); +} + +void TraceNavigator::selectNextPreb() +{ + shared_ptr nextPreb; + + if (!SelectedTransactions().empty()) + nextPreb = traceFile.getNextPreb( + SelectedTransactions().front()->Id()); + else + nextPreb = traceFile.getNextPreb(0); + + if (nextPreb) + selectTransaction(nextPreb); +} + +void TraceNavigator::selectNextRefb() +{ + shared_ptr n; + + if (!SelectedTransactions().empty()) + n = traceFile.getNextRefb(SelectedTransactions().front()->Id()); + else + n = traceFile.getNextRefb(0); + + if (n) + selectTransaction(n); +} bool TraceNavigator::transactionIsSelected(const shared_ptr &transaction) const diff --git a/DRAMSys/traceAnalyzer/presentation/tracenavigator.h b/DRAMSys/traceAnalyzer/presentation/tracenavigator.h index a31591d7..357da700 100644 --- a/DRAMSys/traceAnalyzer/presentation/tracenavigator.h +++ b/DRAMSys/traceAnalyzer/presentation/tracenavigator.h @@ -87,6 +87,9 @@ public: void selectNextRefresh(); void selectNextActivate(); void selectNextPrecharge(); + void selectNextActb(); + void selectNextPreb(); + void selectNextRefb(); void addSelectedTransactions(const std::vector> &transactions); diff --git a/DRAMSys/traceAnalyzer/presentation/traceplot.cpp b/DRAMSys/traceAnalyzer/presentation/traceplot.cpp index f2020e7c..65434781 100644 --- a/DRAMSys/traceAnalyzer/presentation/traceplot.cpp +++ b/DRAMSys/traceAnalyzer/presentation/traceplot.cpp @@ -111,6 +111,24 @@ void TracePlot::setUpActions() QObject::connect(selectNextPrecharge, SIGNAL(triggered()), this, SLOT(on_selectNextPrecharge())); + selectNextActb = new QAction("Select next atcb", this); + selectNextActb->setShortcut(QKeySequence("alt+b")); + addAction(selectNextActb); + QObject::connect(selectNextActb, SIGNAL(triggered()), this, + SLOT(on_selectNextActb())); + + selectNextPreb = new QAction("Select next preb", this); + selectNextPreb->setShortcut(QKeySequence("alt+q")); + addAction(selectNextPreb); + QObject::connect(selectNextPreb, SIGNAL(triggered()), this, + SLOT(on_selectNextPreb())); + + selectNextRefb = new QAction("Select next refb", this); + selectNextRefb->setShortcut(QKeySequence("alt+s")); + addAction(selectNextRefb); + QObject::connect(selectNextRefb, SIGNAL(triggered()), this, + SLOT(on_selectNextRefb())); + setColorGroupingPhase = new QAction("Group by Phase", this); addAction(setColorGroupingPhase); QObject::connect(setColorGroupingPhase, SIGNAL(triggered()), this, @@ -148,7 +166,7 @@ void TracePlot::setUpContextMenu() contextMenu->addMenu(goToSubMenu); QMenu *selectSubMenu = new QMenu("Select", contextMenu); - selectSubMenu->addActions({selectNextRefresh, selectNextActivate, selectNextPrecharge}); + selectSubMenu->addActions({selectNextRefresh, selectNextActivate, selectNextPrecharge, selectNextActb, selectNextPreb, selectNextRefb}); contextMenu->addMenu(selectSubMenu); contextMenu->addActions({showQueryEditor, insertComment, exportToPdf}); @@ -365,6 +383,21 @@ void TracePlot::on_selectNextPrecharge() navigator->selectNextPrecharge(); } +void TracePlot::on_selectNextActb() +{ + navigator->selectNextActb(); +} + +void TracePlot::on_selectNextPreb() +{ + navigator->selectNextPreb(); +} + +void TracePlot::on_selectNextRefb() +{ + navigator->selectNextRefb(); +} + void TracePlot::on_colorGroupingPhase() { drawingProperties.colorGrouping = ColorGrouping::PhaseType; diff --git a/DRAMSys/traceAnalyzer/presentation/traceplot.h b/DRAMSys/traceAnalyzer/presentation/traceplot.h index 322102b2..5238b7ec 100644 --- a/DRAMSys/traceAnalyzer/presentation/traceplot.h +++ b/DRAMSys/traceAnalyzer/presentation/traceplot.h @@ -91,6 +91,9 @@ private Q_SLOTS: void on_selectNextRefresh(); void on_selectNextActivate(); void on_selectNextPrecharge(); + void on_selectNextActb(); + void on_selectNextPreb(); + void on_selectNextRefb(); void on_colorGroupingPhase(); void on_colorGroupingTransaction(); void on_colorGroupingThread(); @@ -154,6 +157,9 @@ private: QAction *selectNextRefresh; QAction *selectNextActivate; QAction *selectNextPrecharge; + QAction *selectNextActb; + QAction *selectNextPreb; + QAction *selectNextRefb; QAction *setColorGroupingPhase; QAction *setColorGroupingTransaction; QAction *setColorGroupingThread; diff --git a/README.md b/README.md index 75e7c5da..73078ec6 100644 --- a/README.md +++ b/README.md @@ -455,6 +455,12 @@ Below, the sub-configurations are listed and explained. - Size of the window in clock cycles used to evaluate average bandwidth and average power consumption - *NumberOfMemChannels* (unsigned int) - Number of memory channels + - *ControllerCoreDisableRefresh* (boolean) + - "1": disables refreshes + - "0": normal operation (refreshes enabled) + - *ControllerCoreRowGranularRef* (boolean) + - "1": enable row granular refresh + - "0": normal operation - *ThermalSimulation* (boolean) - "1": enables thermal simulation - "0": static temperature during simulation @@ -668,12 +674,10 @@ Below, the sub-configurations are listed and explained. - **Memory Controller Configuration** - The content of [fifo.xml](DRAMSys/library/resources/configs/mcconfigs/fifo.xml) is - presented below as an example. + An example follows. ``` xml - @@ -681,13 +685,44 @@ Below, the sub-configurations are listed and explained. - + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ``` @@ -740,8 +775,103 @@ Below, the sub-configurations are listed and explained. - Max AR commands to be postponed. - *ControllerCoreMaxPulledInARCmd* (unsigned int) - Max AR commands to be pulled-in. + - *ControllerCoreRowGranularRef* (boolean) + - "1": enables row granular refresh feature (RGR) + - "0": normal operation + - *ControllerCoreRowGranularRefNumAR* (unsigned int) + - Number of AR commands to to be issued in a refresh period tREFI + - *ControllerCoreRowGranularRefRowInc* (unsigned int) + - Row increment for each AR command (selective refresh) + - *ControllerCoreRowGranularRefB0* (boolean) + - "1": RGR this bank + - "0": skip this bank + - *ControllerCoreRowGranularRefB1* (boolean) + - "1": RGR this bank + - "0": skip this bank + - *ControllerCoreRowGranularRefB2* (boolean) + - "1": RGR this bank + - "0": skip this bank + - *ControllerCoreRowGranularRefB3* (boolean) + - "1": RGR this bank + - "0": skip this bank + - *ControllerCoreRowGranularRefB4* (boolean) + - "1": RGR this bank + - "0": skip this bank + - *ControllerCoreRowGranularRefB5* (boolean) + - "1": RGR this bank + - "0": skip this bank + - *ControllerCoreRowGranularRefB6* (boolean) + - "1": RGR this bank + - "0": skip this bank + - *ControllerCoreRowGranularRefB7* (boolean) + - "1": RGR this bank + - "0": skip this bank + - *ControllerCoreRowGranularRefB8* (boolean) + - "1": RGR this bank + - "0": skip this bank + - *ControllerCoreRowGranularRefB9* (boolean) + - "1": RGR this bank + - "0": skip this bank + - *ControllerCoreRowGranularRefB10* (boolean) + - "1": RGR this bank + - "0": skip this bank + - *ControllerCoreRowGranularRefB11* (boolean) + - "1": RGR this bank + - "0": skip this bank + - *ControllerCoreRowGranularRefB12* (boolean) + - "1": RGR this bank + - "0": skip this bank + - *ControllerCoreRowGranularRefB13* (boolean) + - "1": RGR this bank + - "0": skip this bank + - *ControllerCoreRowGranularRefB14* (boolean) + - "1": RGR this bank + - "0": skip this bank + - *ControllerCoreRowGranularRefB15* (boolean) + - "1": RGR this bank + - "0": skip this bank + - *ControllerCoreRowGranularRefRASBInClkCycles* (unsigned int) + - Timing can be changed to explore optimum row granular refresh (ORGR) + - *ControllerCoreRowGranularRefRRDB_LInClkCycles* (unsigned int) + - Timing can be changed to explore optimum row granular refresh (ORGR) + - *ControllerCoreRowGranularRefRRDB_SInClkCycles* (unsigned int) + - Timing can be changed to explore optimum row granular refresh (ORGR) + - *ControllerCoreRowGranularRefRPBInClkCycles* (unsigned int) + - Timing can be changed to explore optimum row granular refresh (ORGR) + - *ControllerCoreRowGranularRefRCBInClkCycles* (unsigned int) + - Timing can be changed to explore optimum row granular refresh (ORGR) + - *ControllerCoreRowGranularRefFAWBInClkCycles* (unsigned int) + - Timing can be changed to explore optimum row granular refresh (ORGR) + +- **Flexible Refresh** + +The feature can be used together with regular refresh and also with row +granular refresh (RGR). + +**Pull-In Refresh** + +A Pull-In is started when there are no pending requests in the buffer, meaning +the memory is in an idle state. Therefore, in order to prepare for possible +accesses that might happen in the future, a burst of REF commands is +initiated. If, at any point, requests start coming in, the burst is +interrupted, meaning that the maximum amount of time, considering the worst +case scenario (a request arrives at the same time a REF was issued), is tRFC. +The advantage of pulling-in refreshes is that they will not issued in the +near future (in their actual times), allowing for more efficient accesses to +the memory. + +**Postpone Refresh** + +Similarly, the decision to postpone a refresh is done if there are pending +requests on the buffer. Given that having requests might mean a hit, we want +to postpone the refresh to minimize the PREA commands needed. If the memory +enters an idle state, a burst is issued for the same number of REF commands +that were postponed. + +**The Flexible Refresh FSM** + +![Flexible](DRAMSys/docs/images/flexreffsm.png) -For further details on the Flexible Refresh feature, please refer to [this](DRAMSys/docs/flexible-refresh.pdf) document. - **Trace Setups** - *clkMhz* (unsigned int)