Merge pull request #164 from jfeldman/master
ECC Controller implementation with basic Hamming code
This commit is contained in:
@@ -112,7 +112,12 @@ SOURCES += \
|
||||
src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.cpp \
|
||||
src/simulation/TraceSetup.cpp \
|
||||
src/simulation/DRAMSys.cpp \
|
||||
src/simulation/Setup.cpp
|
||||
src/simulation/Setup.cpp \
|
||||
src/error/ECC/Bit.cpp \
|
||||
src/error/ECC/ECC.cpp \
|
||||
src/error/ECC/Word.cpp \
|
||||
src/error/eccbaseclass.cpp \
|
||||
src/error/ecchamming.cpp
|
||||
|
||||
HEADERS += \
|
||||
src/common/third_party/tinyxml2/tinyxml2.h \
|
||||
@@ -176,7 +181,12 @@ HEADERS += \
|
||||
src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.h \
|
||||
src/simulation/TraceSetup.h \
|
||||
src/simulation/DRAMSys.h \
|
||||
src/simulation/Setup.h
|
||||
src/simulation/Setup.h \
|
||||
src/error/ECC/Bit.h \
|
||||
src/error/ECC/ECC.h \
|
||||
src/error/ECC/Word.h \
|
||||
src/error/eccbaseclass.h \
|
||||
src/error/ecchamming.h
|
||||
|
||||
thermalsim = $$(THERMALSIM)
|
||||
isEmpty(thermalsim) {
|
||||
|
||||
@@ -8,13 +8,5 @@
|
||||
<PowerDownMode value="NoPowerDown" />
|
||||
<PowerDownTimeout value="100" />
|
||||
<!-- Error Modelling -->
|
||||
<ErrorChipSeed value="42" />
|
||||
<ErrorCSVFile value="../../DRAMSys/simulator/src/error/error.csv" />
|
||||
<!-- Modes:
|
||||
- NoStorage,
|
||||
- Store (store data without errormodel),
|
||||
- ErrorModel (store data with errormodel)
|
||||
-->
|
||||
<StoreMode value="NoStorage" />
|
||||
<ControllerCoreDisableRefresh value="0"/>
|
||||
</mcconfig>
|
||||
|
||||
@@ -8,13 +8,5 @@
|
||||
<PowerDownMode value="NoPowerDown" />
|
||||
<PowerDownTimeout value="100" />
|
||||
<!-- Error Modelling -->
|
||||
<ErrorChipSeed value="42" />
|
||||
<ErrorCSVFile value="../../DRAMSys/simulator/src/error/error.csv" />
|
||||
<!-- Modes:
|
||||
- NoStorage,
|
||||
- Store (store data without errormodel),
|
||||
- ErrorModel (store data with errormodel)
|
||||
-->
|
||||
<StoreMode value="NoStorage" />
|
||||
<ControllerCoreDisableRefresh value="0"/>
|
||||
</mcconfig>
|
||||
|
||||
12
DRAMSys/simulator/resources/configs/mcconfigs/fifo_ecc.xml
Normal file
12
DRAMSys/simulator/resources/configs/mcconfigs/fifo_ecc.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<mcconfig>
|
||||
<BankwiseLogic value="0"/>
|
||||
<OpenPagePolicy value="1" />
|
||||
<MaxNrOfTransactions value="8" />
|
||||
<Scheduler value="FIFO" />
|
||||
<Capsize value="5" />
|
||||
<!-- 4 Modes: NoPowerDown, Staggered, TimeoutPDN, TimeoutSREF -->
|
||||
<PowerDownMode value="NoPowerDown" />
|
||||
<PowerDownTimeout value="100" />
|
||||
<!-- Error Modelling -->
|
||||
<ControllerCoreDisableRefresh value="0"/>
|
||||
</mcconfig>
|
||||
@@ -8,14 +8,6 @@
|
||||
<PowerDownMode value="NoPowerDown" />
|
||||
<PowerDownTimeout value="100" />
|
||||
<!-- Error Model: -->
|
||||
<ErrorChipSeed value="42" />
|
||||
<ErrorCSVFile value="../../DRAMSys/simulator/src/error/error.csv" />
|
||||
<!-- Modes:
|
||||
- NoStorage,
|
||||
- Store (store data without errormodel),
|
||||
- ErrorModel (store data with errormodel)
|
||||
-->
|
||||
<StoreMode value="NoStorage" />
|
||||
<ControllerCoreDisableRefresh value="0"/>
|
||||
</mcconfig>
|
||||
|
||||
|
||||
@@ -8,13 +8,5 @@
|
||||
<PowerDownMode value="NoPowerDown" />
|
||||
<PowerDownTimeout value="100" />
|
||||
<!-- Error Modelling -->
|
||||
<ErrorChipSeed value="42" />
|
||||
<ErrorCSVFile value="../../DRAMSys/simulator/src/error/error.csv" />
|
||||
<!-- Modes:
|
||||
- NoStorage,
|
||||
- Store (store data without errormodel),
|
||||
- ErrorModel (store data with errormodel)
|
||||
-->
|
||||
<StoreMode value="NoStorage" />
|
||||
<ControllerCoreDisableRefresh value="0"/>
|
||||
</mcconfig>
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
<!DOCTYPE memspec SYSTEM "memspec.dtd">
|
||||
<memspec>
|
||||
|
||||
<parameter id="memoryId" type="string" value="MICRON_1Gb_DDR3-1600_8bit_G" />
|
||||
<parameter id="memoryType" type="string" value="DDR3" />
|
||||
<memarchitecturespec>
|
||||
<parameter id="width" type="uint" value="8" />
|
||||
<parameter id="nbrOfBanks" type="uint" value="8" />
|
||||
<parameter id="nbrOfRanks" type="uint" value="1" />
|
||||
<parameter id="nbrOfColumns" type="uint" value="1024" />
|
||||
<parameter id="nbrOfRows" type="uint" value="16384" />
|
||||
<parameter id="dataRate" type="uint" value="2" />
|
||||
<parameter id="burstLength" type="uint" value="8" />
|
||||
</memarchitecturespec>
|
||||
<memtimingspec>
|
||||
<parameter id="clkMhz" type="double" value="800" />
|
||||
<parameter id="RC" type="uint" value="38" />
|
||||
<parameter id="RCD" type="uint" value="10" />
|
||||
<parameter id="RL" type="uint" value="10" />
|
||||
<parameter id="RP" type="uint" value="10" />
|
||||
<parameter id="RFC" type="uint" value="88" />
|
||||
<parameter id="RAS" type="uint" value="28" />
|
||||
<parameter id="WL" type="uint" value="8" />
|
||||
<parameter id="AL" type="uint" value="0" />
|
||||
<parameter id="DQSCK" type="uint" value="0" />
|
||||
<parameter id="RTP" type="uint" value="6" />
|
||||
<parameter id="WR" type="uint" value="12" />
|
||||
<parameter id="XP" type="uint" value="6" />
|
||||
<parameter id="XPDLL" type="uint" value="20" />
|
||||
<parameter id="XS" type="uint" value="96" />
|
||||
<parameter id="XSDLL" type="uint" value="512" />
|
||||
<parameter id="REFI" type="uint" value="300000000" />
|
||||
<parameter id="CL" type="uint" value="10" />
|
||||
<parameter id="FAW" type="uint" value="24" />
|
||||
<parameter id="RRD" type="uint" value="5" />
|
||||
<parameter id="CCD" type="uint" value="4" />
|
||||
<parameter id="WTR" type="uint" value="6" />
|
||||
<parameter id="CKE" type="uint" value="3" />
|
||||
<parameter id="CKESR" type="uint" value="4" />
|
||||
</memtimingspec>
|
||||
<mempowerspec>
|
||||
<parameter id="idd0" type="double" value="70.0" />
|
||||
<parameter id="idd2p0" type="double" value="12.0" />
|
||||
<parameter id="idd2p1" type="double" value="30.0" />
|
||||
<parameter id="idd2n" type="double" value="45.0" />
|
||||
<parameter id="idd3p0" type="double" value="35.0" />
|
||||
<parameter id="idd3p1" type="double" value="35.0" />
|
||||
<parameter id="idd3n" type="double" value="45.0" />
|
||||
<parameter id="idd4w" type="double" value="145.0" />
|
||||
<parameter id="idd4r" type="double" value="140.0" />
|
||||
<parameter id="idd5" type="double" value="170.0" />
|
||||
<parameter id="idd6" type="double" value="8.0" />
|
||||
<parameter id="vdd" type="double" value="1.5" />
|
||||
</mempowerspec>
|
||||
</memspec>
|
||||
@@ -0,0 +1,61 @@
|
||||
<!DOCTYPE memspec SYSTEM "memspec.dtd">
|
||||
<memspec>
|
||||
<parameter id="memoryId" type="string" value="wideio_less_refresh" />
|
||||
<parameter id="memoryType" type="string" value="WIDEIO_SDR" />
|
||||
<memarchitecturespec>
|
||||
<parameter id="width" type="uint" value="128" />
|
||||
<parameter id="nbrOfBanks" type="uint" value="8" />
|
||||
<parameter id="nbrOfColumns" type="uint" value="128" />
|
||||
<parameter id="nbrOfRows" type="uint" value="8192" />
|
||||
<parameter id="dataRate" type="uint" value="1" />
|
||||
<parameter id="burstLength" type="uint" value="4" />
|
||||
</memarchitecturespec>
|
||||
<memtimingspec>
|
||||
<parameter id="clkMhz" type="double" value="166" />
|
||||
<parameter id="RC" type="uint" value="9" /><!--tRP+tRAS-->
|
||||
<parameter id="RCD" type="uint" value="3" />
|
||||
<parameter id="RL" type="uint" value="3" />
|
||||
<parameter id="RP" type="uint" value="3" />
|
||||
<parameter id="RFC" type="uint" value="22" />
|
||||
<parameter id="RAS" type="uint" value="6" />
|
||||
<parameter id="WL" type="uint" value="1" />
|
||||
<parameter id="AL" type="uint" value="0" />
|
||||
<parameter id="RTP" type="uint" value="4" />
|
||||
<parameter id="WR" type="uint" value="2" />
|
||||
<parameter id="XP" type="uint" value="2" />
|
||||
<parameter id="XS" type="uint" value="20" /><!--tRFC+2clk-->
|
||||
<parameter id="REFI" type="uint" value="166000000000" />
|
||||
<parameter id="TAW" type="uint" value="10" />
|
||||
<parameter id="RRD" type="uint" value="2" />
|
||||
<parameter id="CCD" type="uint" value="1" />
|
||||
<parameter id="WTR" type="uint" value="3" />
|
||||
<parameter id="CKE" type="uint" value="3" />
|
||||
<parameter id="CKESR" type="uint" value="3" />
|
||||
</memtimingspec>
|
||||
<mempowerspec>
|
||||
<parameter id="idd0" type="double" value="5.88" />
|
||||
<parameter id="idd02" type="double" value="21.18" />
|
||||
<parameter id="idd2p0" type="double" value="0.05" />
|
||||
<parameter id="idd2p02" type="double" value="0.17" />
|
||||
<parameter id="idd2p1" type="double" value="0.05" />
|
||||
<parameter id="idd2p12" type="double" value="0.17" />
|
||||
<parameter id="idd2n" type="double" value="0.13" />
|
||||
<parameter id="idd2n2" type="double" value="4.04" />
|
||||
<parameter id="idd3p0" type="double" value="0.25" />
|
||||
<parameter id="idd3p02" type="double" value="1.49" />
|
||||
<parameter id="idd3p1" type="double" value="0.25" />
|
||||
<parameter id="idd3p12" type="double" value="1.49" />
|
||||
<parameter id="idd3n" type="double" value="0.52" />
|
||||
<parameter id="idd3n2" type="double" value="6.55" />
|
||||
<parameter id="idd4r" type="double" value="1.41" />
|
||||
<parameter id="idd4r2" type="double" value="85.73" />
|
||||
<parameter id="idd4w" type="double" value="1.42" />
|
||||
<parameter id="idd4w2" type="double" value="60.79" />
|
||||
<parameter id="idd5" type="double" value="14.43" />
|
||||
<parameter id="idd52" type="double" value="48.17" />
|
||||
<parameter id="idd6" type="double" value="0.07" />
|
||||
<parameter id="idd62" type="double" value="0.27" />
|
||||
<parameter id="vdd" type="double" value="1.8" />
|
||||
<parameter id="vdd2" type="double" value="1.2" />
|
||||
</mempowerspec>
|
||||
</memspec>
|
||||
@@ -11,4 +11,13 @@
|
||||
<NumberOfDevicesOnDIMM value = "8" />
|
||||
<CheckTLM2Protocol value = "0" />
|
||||
<AddressOffset value = "0" />
|
||||
<ECCControllerMode value = "Disabled" />
|
||||
<ErrorChipSeed value="42" />
|
||||
<ErrorCSVFile value="" />
|
||||
<!-- Modes:
|
||||
- NoStorage,
|
||||
- Store (store data without errormodel),
|
||||
- ErrorModel (store data with errormodel)
|
||||
-->
|
||||
<StoreMode value="NoStorage" />
|
||||
</simconfig>
|
||||
|
||||
@@ -11,6 +11,15 @@
|
||||
<NumberOfDevicesOnDIMM value = "8" />
|
||||
<CheckTLM2Protocol value = "0" />
|
||||
<AddressOffset value = "0" />
|
||||
<ECCControllerMode value = "Disabled" />
|
||||
<ErrorChipSeed value="42" />
|
||||
<ErrorCSVFile value="" />
|
||||
<!-- Modes:
|
||||
- NoStorage,
|
||||
- Store (store data without errormodel),
|
||||
- ErrorModel (store data with errormodel)
|
||||
-->
|
||||
<StoreMode value="NoStorage" />
|
||||
<!-- Gem5 Related Configuration:
|
||||
In the memory controller file the storage mode should be set to Store
|
||||
E.g. the DRAM is located at 0x80000000 for gem5
|
||||
|
||||
23
DRAMSys/simulator/resources/configs/simulator/ddr3_ecc.xml
Normal file
23
DRAMSys/simulator/resources/configs/simulator/ddr3_ecc.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<simconfig>
|
||||
<SimulationName value="ddr3" />
|
||||
<Debug value="0" />
|
||||
<DatabaseRecording value="1" />
|
||||
<PowerAnalysis value="1" />
|
||||
<EnableWindowing value = "1" />
|
||||
<WindowSize value="1000" />
|
||||
<ThermalSimulation value="0"/>
|
||||
<SimulationProgressBar value="1"/>
|
||||
<NumberOfMemChannels value="1"/>
|
||||
<NumberOfDevicesOnDIMM value = "8" />
|
||||
<CheckTLM2Protocol value = "0" />
|
||||
<AddressOffset value = "0" />
|
||||
<ECCControllerMode value = "Hamming" />
|
||||
<ErrorChipSeed value="42" />
|
||||
<ErrorCSVFile value="" />
|
||||
<!-- Modes:
|
||||
- NoStorage,
|
||||
- Store (store data without errormodel),
|
||||
- ErrorModel (store data with errormodel)
|
||||
-->
|
||||
<StoreMode value="ErrorModel" />
|
||||
</simconfig>
|
||||
@@ -10,5 +10,14 @@
|
||||
<NumberOfMemChannels value="4"/>
|
||||
<NumberOfDevicesOnDIMM value = "1" />
|
||||
<CheckTLM2Protocol value = "0" />
|
||||
<ECCControllerMode value = "Disabled" />
|
||||
<ErrorChipSeed value="42" />
|
||||
<ErrorCSVFile value="../../DRAMSys/simulator/resources/error/wideio.csv" />
|
||||
<!-- Modes:
|
||||
- NoStorage,
|
||||
- Store (store data without errormodel),
|
||||
- ErrorModel (store data with errormodel)
|
||||
-->
|
||||
<StoreMode value="NoStorage" />
|
||||
</simconfig>
|
||||
|
||||
|
||||
23
DRAMSys/simulator/resources/configs/simulator/wideio_ecc.xml
Normal file
23
DRAMSys/simulator/resources/configs/simulator/wideio_ecc.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<simconfig>
|
||||
<SimulationName value="wideio_ecc" />
|
||||
<Debug value="0" />
|
||||
<DatabaseRecording value="1" />
|
||||
<PowerAnalysis value="1" />
|
||||
<EnableWindowing value = "1" />
|
||||
<WindowSize value="1000" />
|
||||
<ThermalSimulation value="0"/>
|
||||
<SimulationProgressBar value="1"/>
|
||||
<NumberOfMemChannels value="1"/>
|
||||
<NumberOfDevicesOnDIMM value = "1" />
|
||||
<CheckTLM2Protocol value = "0" />
|
||||
<ECCControllerMode value = "Hamming" />
|
||||
<ErrorChipSeed value="42" />
|
||||
<ErrorCSVFile value="../../DRAMSys/simulator/resources/error/wideio.csv" />
|
||||
<!-- Modes:
|
||||
- NoStorage,
|
||||
- Store (store data without errormodel),
|
||||
- ErrorModel (store data with errormodel)
|
||||
-->
|
||||
<StoreMode value="ErrorModel" />
|
||||
</simconfig>
|
||||
|
||||
@@ -10,5 +10,14 @@
|
||||
<NumberOfMemChannels value="1"/>
|
||||
<NumberOfDevicesOnDIMM value = "1" />
|
||||
<CheckTLM2Protocol value = "0" />
|
||||
<ECCControllerMode value = "Disabled" />
|
||||
<ErrorChipSeed value="42" />
|
||||
<ErrorCSVFile value="../../DRAMSys/simulator/resources/error/wideio.csv" />
|
||||
<!-- Modes:
|
||||
- NoStorage,
|
||||
- Store (store data without errormodel),
|
||||
- ErrorModel (store data with errormodel)
|
||||
-->
|
||||
<StoreMode value="NoStorage" />
|
||||
</simconfig>
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
OTHER_FILES += resources/simulations/ddr3-example.xml
|
||||
OTHER_FILES += resources/simulations/ddr3-single-device.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
|
||||
|
||||
# Simulator Files
|
||||
@@ -12,6 +14,8 @@ OTHER_FILES += resources/configs/simulator/wideio.xml
|
||||
OTHER_FILES += resources/configs/simulator/ddr3.xml
|
||||
OTHER_FILES += resources/configs/simulator/ddr3-single-device.xml
|
||||
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
|
||||
|
||||
# Scripts
|
||||
@@ -60,6 +64,7 @@ OTHER_FILES += resources/traces/mediabench-adpcmdecode_32.stl
|
||||
OTHER_FILES += resources/traces/ddr3_example.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
|
||||
OTHER_FILES += resources/traces/sms_t1.stl
|
||||
OTHER_FILES += resources/traces/sms_t2.stl
|
||||
OTHER_FILES += resources/traces/sms_t3.stl
|
||||
@@ -70,6 +75,7 @@ OTHER_FILES += resources/configs/mcconfigs/fifoStrict.xml
|
||||
OTHER_FILES += resources/configs/mcconfigs/fifo.xml
|
||||
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
|
||||
|
||||
# Memspecs
|
||||
@@ -113,6 +119,8 @@ 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/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
|
||||
|
||||
# Address Mapping Configs
|
||||
OTHER_FILES += resources/configs/amconfigs/am_ddr3.xml
|
||||
@@ -139,3 +147,6 @@ OTHER_FILES += resources/configs/thermalsim/mem.flp
|
||||
OTHER_FILES += resources/configs/thermalsim/powerInfo.xml
|
||||
OTHER_FILES += resources/configs/thermalsim/stack.stk
|
||||
OTHER_FILES += resources/configs/thermalsim/config.xml
|
||||
|
||||
# Error Simulation data
|
||||
OTHER_FILES += resources/error/wideio.csv
|
||||
|
||||
22
DRAMSys/simulator/resources/simulations/ddr3-ecc.xml
Normal file
22
DRAMSys/simulator/resources/simulations/ddr3-ecc.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<simulation>
|
||||
<!-- Configuration for the DRAMSys Simulator -->
|
||||
<simconfig src="ddr3_ecc.xml" />
|
||||
<!-- Temperature Simulator Configuration -->
|
||||
<thermalconfig src="config.xml" />
|
||||
<!-- Memory Device Specification: Which Device is used for Wide I/O -->
|
||||
<memspec src="MICRON_1Gb_DDR3-1600_8bit_G_less_refresh.xml"></memspec>
|
||||
<!-- Addressmapping Configuration of the Memory Controller -->
|
||||
<addressmapping src="am_ddr3_8x1Gbx8_dimm_p1KB_brc.xml"></addressmapping>
|
||||
<!-- Memory Controller Configuration -->
|
||||
<mcconfig src="fifo_ecc.xml"/>
|
||||
<!--
|
||||
The following trace setup is only used in standalone mode.
|
||||
In library mode e.g. in Platform Architect the trace setup is ignored.
|
||||
-->
|
||||
<tracesetup>
|
||||
<!--
|
||||
This device mimics an processor running at 1 GHz.
|
||||
-->
|
||||
<device clkMhz="1000">test_ecc.stl</device>
|
||||
</tracesetup>
|
||||
</simulation>
|
||||
22
DRAMSys/simulator/resources/simulations/wideio-ecc.xml
Normal file
22
DRAMSys/simulator/resources/simulations/wideio-ecc.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<simulation>
|
||||
<!-- Configuration for the DRAMSys Simulator -->
|
||||
<simconfig src="wideio_ecc.xml" />
|
||||
<!-- Temperature Simulator Configuration -->
|
||||
<thermalconfig src="config.xml" />
|
||||
<!-- Memory Device Specification: Which Device is used for Wide I/O -->
|
||||
<memspec src="wideio_less_refresh.xml"></memspec>
|
||||
<!-- Addressmapping Configuration of the Memory Controller -->
|
||||
<addressmapping src="am_wideio.xml"></addressmapping>
|
||||
<!-- Memory Controller Configuration -->
|
||||
<mcconfig src="fifo_ecc.xml"/>
|
||||
<!--
|
||||
The following trace setup is only used in standalone mode.
|
||||
In library mode e.g. in Platform Architect the trace setup is ignored.
|
||||
-->
|
||||
<tracesetup>
|
||||
<!--
|
||||
This device mimics an processor running at 1 GHz.
|
||||
-->
|
||||
<device clkMhz="1000">test_ecc.stl</device>
|
||||
</tracesetup>
|
||||
</simulation>
|
||||
@@ -110,6 +110,19 @@ EPowerDownMode string2PDNMode(string s)
|
||||
}
|
||||
}
|
||||
|
||||
ECCControllerMode string2ECCControllerMode(string s)
|
||||
{
|
||||
if(s == "Disabled")
|
||||
return ECCControllerMode::Disabled;
|
||||
else if(s == "Hamming")
|
||||
return ECCControllerMode::Hamming;
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("Configuration", ("Unknown ECCControllerMode: " + s).c_str());
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
enum sc_time_unit string2TimeUnit(string s)
|
||||
{
|
||||
if (s == "s")
|
||||
@@ -209,6 +222,8 @@ void Configuration::setParameter(std::string name, std::string value)
|
||||
}
|
||||
else if(name == "CheckTLM2Protocol")
|
||||
CheckTLM2Protocol = string2bool(value);
|
||||
else if(name == "ECCControllerMode")
|
||||
ECCMode = string2ECCControllerMode(value);
|
||||
// Specification for ErrorChipSeed, ErrorCSVFile path and StoreMode
|
||||
else if(name == "ErrorChipSeed")
|
||||
ErrorChipSeed = string2int(value);
|
||||
@@ -317,3 +332,15 @@ unsigned int Configuration::getBytesPerBurst()
|
||||
return bytesPerBurst;
|
||||
}
|
||||
|
||||
// Changes the number of bytes depeding on the ECC Controller. This function is needed for modules which get data directly or indirectly from the ECC Controller
|
||||
unsigned int Configuration::adjustNumBytesAfterECC(unsigned nBytes)
|
||||
{
|
||||
// Manipulate the number of bytes only if there is an ECC Controller selected
|
||||
if(ECCMode == ECCControllerMode::Disabled)
|
||||
return nBytes;
|
||||
else
|
||||
{
|
||||
assert(pECC != nullptr);
|
||||
return pECC->AllocationSize(nBytes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,10 +45,14 @@
|
||||
#include "thermalSimConfig.h"
|
||||
#include "../../../common/Utils.h"
|
||||
|
||||
#include "../../../error/eccbaseclass.h"
|
||||
|
||||
enum class StorageMode{NoStorage, Store, ErrorModel};
|
||||
|
||||
enum class EPowerDownMode{NoPowerDown, Staggered, TimeoutPDN, TimeoutSREF};
|
||||
|
||||
enum class ECCControllerMode{Disabled, Hamming};
|
||||
|
||||
struct Configuration
|
||||
{
|
||||
static std::string memspecUri;
|
||||
@@ -83,6 +87,9 @@ struct Configuration
|
||||
bool SimulationProgressBar = false;
|
||||
unsigned int NumberOfDevicesOnDIMM = 1;
|
||||
bool CheckTLM2Protocol = false;
|
||||
ECCControllerMode ECCMode = ECCControllerMode::Disabled;
|
||||
ECCBaseClass* pECC = nullptr;
|
||||
bool gem5 = false;
|
||||
unsigned long long int AddressOffset = 0;
|
||||
|
||||
// MemSpec (from DRAM-Power XML)
|
||||
@@ -102,6 +109,7 @@ struct Configuration
|
||||
std::uint64_t getSimMemSizeInBytes();
|
||||
unsigned int getDataBusWidth();
|
||||
unsigned int getBytesPerBurst();
|
||||
unsigned int adjustNumBytesAfterECC(unsigned bytes);
|
||||
void setPathToResources(std::string path);
|
||||
std::string getPathToResources();
|
||||
|
||||
|
||||
27
DRAMSys/simulator/src/error/ECC/Bit.cpp
Normal file
27
DRAMSys/simulator/src/error/ECC/Bit.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "Bit.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using std::cout;
|
||||
|
||||
CBit::CBit(VALUE nVal)
|
||||
{
|
||||
m_nValue = nVal;
|
||||
}
|
||||
|
||||
|
||||
CBit::~CBit()
|
||||
{
|
||||
}
|
||||
|
||||
void CBit::Print()
|
||||
{
|
||||
if (m_nValue == ZERO)
|
||||
{
|
||||
cout <<"0";
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "1";
|
||||
}
|
||||
}
|
||||
73
DRAMSys/simulator/src/error/ECC/Bit.h
Normal file
73
DRAMSys/simulator/src/error/ECC/Bit.h
Normal file
@@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
class CBit
|
||||
{
|
||||
public:
|
||||
enum VALUE
|
||||
{
|
||||
ZERO = 0,
|
||||
ONE = 1
|
||||
};
|
||||
|
||||
protected:
|
||||
VALUE m_nValue;
|
||||
|
||||
public:
|
||||
CBit(VALUE nVal = ZERO);
|
||||
virtual ~CBit();
|
||||
|
||||
inline void Set() { m_nValue = ONE; };
|
||||
inline void Clear() { m_nValue = ZERO; };
|
||||
inline unsigned Get()
|
||||
{
|
||||
if(m_nValue == ONE)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
};
|
||||
|
||||
void Print();
|
||||
|
||||
CBit& operator=(unsigned d)
|
||||
{
|
||||
if (d == 0 )
|
||||
{
|
||||
m_nValue = ZERO;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_nValue = ONE;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend CBit operator^(CBit l, const CBit& r)
|
||||
{
|
||||
if (l.m_nValue == r.m_nValue)
|
||||
{
|
||||
return CBit(ZERO);
|
||||
}
|
||||
else
|
||||
{
|
||||
return CBit(ONE);
|
||||
}
|
||||
}
|
||||
|
||||
CBit& operator^=(const CBit& r)
|
||||
{
|
||||
if (m_nValue == r.m_nValue)
|
||||
{
|
||||
m_nValue = ZERO;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_nValue = ONE;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool operator==(const CBit::VALUE& r)
|
||||
{
|
||||
return m_nValue == r;
|
||||
}
|
||||
};
|
||||
|
||||
133
DRAMSys/simulator/src/error/ECC/ECC.cpp
Normal file
133
DRAMSys/simulator/src/error/ECC/ECC.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
#include "ECC.h"
|
||||
|
||||
// ************************************************************************************************
|
||||
// Function which calculates the number of additional bits needed for a given number of data bits
|
||||
// to store the hamming code and parity bit for a SECDED implementation
|
||||
unsigned ECC::GetNumParityBits(unsigned nDataBits)
|
||||
{
|
||||
unsigned nParityBits = 0;
|
||||
|
||||
// Function to calculate the nube of bits: n = 2^k - k - 1
|
||||
// ( Source: Hacker's Delight; p. 310; math. function 1 )
|
||||
while (nDataBits > ((1 << nParityBits) - nParityBits - 1))
|
||||
{
|
||||
++nParityBits;
|
||||
}
|
||||
|
||||
return nParityBits+1; // +1 for the parity bit
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************************************
|
||||
// Function which extends a given data word to the needed length for a SECDED code
|
||||
void ECC::ExtendWord(CWord & v)
|
||||
{
|
||||
unsigned end = v.GetLength() + ECC::GetNumParityBits(v.GetLength());
|
||||
|
||||
// Insert x bits for the hamming code at positions where pos = 2^a; a = [0..N]
|
||||
// In "Hacker's Delight" the smallest index is 1 - But in this beautiful C-Code it's 0 as it
|
||||
// should be. That's why there is a '-1' in the call of v.Insert.
|
||||
unsigned i = 1;
|
||||
while (i < end)
|
||||
{
|
||||
v.Insert(i-1, CBit());
|
||||
i <<= 1;
|
||||
}
|
||||
|
||||
// Append one bit for the parity
|
||||
v.Append(CBit());
|
||||
}
|
||||
|
||||
// ************************************************************************************************
|
||||
// Function which calculates the Hamming Code bits of an extended Data word.
|
||||
// Function ExtendWord must be called before calling this function
|
||||
// The calculated bits are stored in p, so the length of p should be at least
|
||||
// 'GetNumParityBits(#data bits)-1'
|
||||
void ECC::CalculateCheckbits(CWord & v, CWord & p)
|
||||
{
|
||||
unsigned i = 1, l = 0;
|
||||
|
||||
// Last bit is the parity bit - don't use this in the algorithm for hamming code
|
||||
unsigned len = v.GetLength()-1;
|
||||
|
||||
// Following Graph should show you the behaviour of this algorithm
|
||||
// #Data bits: 11 #Hamming bits: 4 -> SECDED bits: 16 (incl. parity bit)
|
||||
// Hamming Code Bit: | Bits used -> data(X)/Hamming Code(H) // Bit unused -
|
||||
// 0 | H-X-X-X-X-X-X-X
|
||||
// 1 | -HX--XX--XX--XX
|
||||
// 2 | ---HXXX----XXXX
|
||||
// 3 | -------HXXXXXXX
|
||||
// For further information read "Hacker's delight" chapter 15
|
||||
// ATTENTION: The order of indices is different from the one in the book,
|
||||
// but it doesn't matter in which order your data or check bits are.
|
||||
// But it should be the same for encoding and decoding
|
||||
while (i < len)
|
||||
{
|
||||
for (unsigned j = (i - 1); j < len; j += (i << 1))
|
||||
{
|
||||
for (unsigned k = 0; k < (i); k++)
|
||||
{
|
||||
if(j + k >= len)
|
||||
break;
|
||||
p[l] ^= v[j + k];
|
||||
}
|
||||
}
|
||||
l++;
|
||||
i <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// ************************************************************************************************
|
||||
// Function which inserts the checkbits which were calculated with 'CalculateCheckbits' in the
|
||||
// extended data word. This is needed to calculate a proper parity of ALL bits to achive a SECDED
|
||||
// behaviour.
|
||||
void ECC::InsertCheckbits(CWord& v, CWord p)
|
||||
{
|
||||
unsigned i = 1, j = 0;
|
||||
while (i <= v.GetLength()-1)
|
||||
{
|
||||
v[i - 1] = p[j++];
|
||||
i <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************************************
|
||||
// Function which extracts the checkbits out of an extended data word. This is needed to check for
|
||||
// bit error in the data word.
|
||||
void ECC::ExtractCheckbits(CWord v, CWord & p)
|
||||
{
|
||||
unsigned i = 1, j = 0;
|
||||
while(i <= v.GetLength()-1)
|
||||
{
|
||||
p[j++] = v[i - 1];
|
||||
i <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// ************************************************************************************************
|
||||
// Function which calculates the overal parity
|
||||
// Simply XOR all bits
|
||||
void ECC::CalculateParityBit(CWord v, CBit & p)
|
||||
{
|
||||
// Paritybit
|
||||
p = CBit::ZERO;
|
||||
for (unsigned i = 0; i < v.GetLength(); i++)
|
||||
{
|
||||
p ^= v[i];
|
||||
}
|
||||
}
|
||||
|
||||
// ************************************************************************************************
|
||||
// Function to insert the parity bit into the extended data word
|
||||
void ECC::InsertParityBit(CWord& v, CBit p)
|
||||
{
|
||||
v[v.GetLength() - 1] = p;
|
||||
}
|
||||
|
||||
// ************************************************************************************************
|
||||
// Function to extract the parity bit out of an extended data word.
|
||||
void ECC::ExtractParityBit(CWord v, CBit & p)
|
||||
{
|
||||
p = v[v.GetLength() - 1];
|
||||
}
|
||||
39
DRAMSys/simulator/src/error/ECC/ECC.h
Normal file
39
DRAMSys/simulator/src/error/ECC/ECC.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include "Word.h"
|
||||
#include "Bit.h"
|
||||
|
||||
// ************************************************************************************************
|
||||
//
|
||||
// | __/ __/ __| | __| _ _ _ __| |_(_)___ _ _ ___
|
||||
// | _| (_| (__ | _| || | ' \/ _| _| / _ \ ' \(_-<
|
||||
// |___\___\___| |_| \_,_|_||_\__|\__|_\___/_||_/__/
|
||||
//
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ECC Implementation as described in "Hacker's Delight - second Edition" by Henry S. Warren, Jr.
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// This namespace gives you some handy functions to get a SEC-DED implementation.
|
||||
//
|
||||
// SEC-DED: Single Error Correction - Double Error Detection
|
||||
// This is the most common error correction code (ECC).
|
||||
// It consists of two different correction codes: Haming code + parity code.
|
||||
//
|
||||
// For further details read chapter 15 of "Hacker's Delight - second Edition"
|
||||
// ************************************************************************************************
|
||||
|
||||
namespace ECC
|
||||
{
|
||||
unsigned GetNumParityBits(unsigned nDataBits);
|
||||
|
||||
// Extends the data word that it can be used with hamming code
|
||||
// Several bits will be included at specific places
|
||||
void ExtendWord(CWord &v);
|
||||
|
||||
void CalculateCheckbits(CWord &v, CWord & p);
|
||||
void InsertCheckbits(CWord& v, CWord p);
|
||||
void ExtractCheckbits(CWord v, CWord& p);
|
||||
|
||||
void CalculateParityBit(CWord v, CBit& p);
|
||||
void InsertParityBit(CWord& v, CBit p);
|
||||
void ExtractParityBit(CWord v, CBit& p);
|
||||
}
|
||||
128
DRAMSys/simulator/src/error/ECC/ECC_Test.cpp
Normal file
128
DRAMSys/simulator/src/error/ECC/ECC_Test.cpp
Normal file
@@ -0,0 +1,128 @@
|
||||
// ECC_Test.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include <time.h>
|
||||
#include "ECC.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
// Random number init
|
||||
srand(time(NULL));
|
||||
|
||||
// Erstellen
|
||||
unsigned size = 4;
|
||||
CWord p(ECC::GetNumParityBits(size)), v(size);
|
||||
|
||||
// Daten eingeben
|
||||
for (unsigned a = 0; a < 16; a++)
|
||||
{
|
||||
v = a;
|
||||
v.Rotate();
|
||||
|
||||
ECC::ExtendWord(v);
|
||||
printf("%d:\t", a);
|
||||
|
||||
p = 0;
|
||||
ECC::CalculateCheckbits(v, p);
|
||||
ECC::InsertCheckbits(v, p);
|
||||
ECC::CalculateParityBit(v, p[3]);
|
||||
ECC::InsertParityBit(v, p[3]);
|
||||
|
||||
v.Print();
|
||||
|
||||
v.Resize(size);
|
||||
}
|
||||
|
||||
printf("\r\n");
|
||||
|
||||
for (unsigned x = 0; x < 100; x++)
|
||||
{
|
||||
//Get random number
|
||||
unsigned a = rand() % 16;
|
||||
|
||||
v.Resize(size);
|
||||
v = a;
|
||||
v.Rotate();
|
||||
|
||||
ECC::ExtendWord(v);
|
||||
|
||||
p = 0;
|
||||
ECC::CalculateCheckbits(v, p);
|
||||
ECC::InsertCheckbits(v, p);
|
||||
ECC::CalculateParityBit(v, p[3]);
|
||||
ECC::InsertParityBit(v, p[3]);
|
||||
v.Print();
|
||||
|
||||
// Insert error
|
||||
unsigned pos = rand() % 8;
|
||||
v[pos] ^= CBit(CBit::ONE);
|
||||
|
||||
printf("Data: %d, Error at pos %d: ", a, pos + 1);
|
||||
v[pos].Print();
|
||||
printf("\r\n");
|
||||
v.Print();
|
||||
|
||||
p = 0;
|
||||
ECC::CalculateCheckbits(v, p);
|
||||
ECC::CalculateParityBit(v, p[3]);
|
||||
|
||||
printf("%d:\t", a);
|
||||
|
||||
p.Print();
|
||||
|
||||
// Interpreting Data
|
||||
|
||||
unsigned syndrome = 0;
|
||||
for (unsigned i = 0; i < p.GetLength() - 1; i++)
|
||||
{
|
||||
if (p[i] == CBit::ONE)
|
||||
syndrome += (1 << i);
|
||||
}
|
||||
|
||||
if (p[3] == CBit::ZERO)
|
||||
{
|
||||
// Parity even
|
||||
|
||||
if (syndrome)
|
||||
{
|
||||
// Double error
|
||||
printf("Double error detected.\r\n");
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No Error
|
||||
printf("No error detected.\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Parity odd
|
||||
|
||||
if (syndrome)
|
||||
{
|
||||
// Bit error
|
||||
printf("Error detected in Bit %d.\r\n", syndrome);
|
||||
if (syndrome == pos + 1)
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Overall parity Error
|
||||
printf("Overall parity error detected.\r\n");
|
||||
if (pos == 7 || pos == 3 || pos == 1 || pos == 0)
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
system("pause");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
157
DRAMSys/simulator/src/error/ECC/Word.cpp
Normal file
157
DRAMSys/simulator/src/error/ECC/Word.cpp
Normal file
@@ -0,0 +1,157 @@
|
||||
#include "Word.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
|
||||
using std::cout;
|
||||
|
||||
CWord::CWord(unsigned nBitLength)
|
||||
: m_nBitLength(nBitLength)
|
||||
{
|
||||
m_word.resize(nBitLength);
|
||||
}
|
||||
|
||||
|
||||
CWord::~CWord()
|
||||
{
|
||||
}
|
||||
|
||||
CBit * CWord::GetAt(unsigned nBitPos)
|
||||
{
|
||||
if (nBitPos < m_nBitLength)
|
||||
{
|
||||
return &m_word.at(nBitPos);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CWord::Set(unsigned data)
|
||||
{
|
||||
deque<CBit>::iterator it;
|
||||
if (m_nBitLength < sizeof(data))
|
||||
{
|
||||
it = m_word.begin();
|
||||
for (unsigned i = 0; i < m_nBitLength; i++)
|
||||
{
|
||||
(*it++) = data & 1;
|
||||
data >>= 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (it = m_word.begin(); it != m_word.end(); it++)
|
||||
{
|
||||
(*it) = data & 1;
|
||||
data >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CWord::Set(const unsigned char* data, unsigned lengthInBits)
|
||||
{
|
||||
deque<CBit>::iterator it;
|
||||
if (m_nBitLength < lengthInBits)
|
||||
{
|
||||
it = m_word.begin();
|
||||
for (unsigned pos = 0; pos < m_nBitLength; pos++)
|
||||
{
|
||||
(*it) = data[pos>>3] & (1 << (7-(pos&7)));
|
||||
it++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned pos = 0;
|
||||
for (it = m_word.begin(); it != m_word.end(); it++)
|
||||
{
|
||||
(*it) = data[pos>>3] & (1 << (7-(pos&7)));
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CWord::Rotate()
|
||||
{
|
||||
deque<CBit> buffer = m_word;
|
||||
for (unsigned i = 0; i < m_nBitLength; i++)
|
||||
{
|
||||
m_word.at(m_nBitLength -i -1) = buffer.at(i);
|
||||
}
|
||||
}
|
||||
|
||||
bool CWord::Insert(unsigned npos, CBit b)
|
||||
{
|
||||
if (npos >= m_nBitLength)
|
||||
return false;
|
||||
|
||||
deque<CBit>::iterator it = m_word.begin() + npos;
|
||||
m_word.insert(it, b);
|
||||
|
||||
m_nBitLength++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CWord::Delete(unsigned npos)
|
||||
{
|
||||
if (npos >= m_nBitLength)
|
||||
return false;
|
||||
|
||||
deque<CBit>::iterator it = m_word.begin() + npos;
|
||||
m_word.erase(it);
|
||||
|
||||
m_nBitLength++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CWord::Append(CBit b)
|
||||
{
|
||||
m_word.push_back(b);
|
||||
|
||||
m_nBitLength++;
|
||||
}
|
||||
|
||||
void CWord::Resize(unsigned nsize)
|
||||
{
|
||||
m_word.resize(nsize);
|
||||
m_nBitLength = nsize;
|
||||
}
|
||||
|
||||
bool CWord::PartShiftRight(unsigned nPos, unsigned nShift)
|
||||
{
|
||||
if(nPos >= m_nBitLength)
|
||||
return false;
|
||||
|
||||
/*for (unsigned i = 0; i < nShift; i++)
|
||||
{
|
||||
m_word.insert()
|
||||
}*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CWord::Print()
|
||||
{
|
||||
deque<CBit>::iterator it;
|
||||
for (it = m_word.begin(); it != m_word.end(); it++)
|
||||
{
|
||||
(*it).Print();
|
||||
}
|
||||
cout << "\r\n";
|
||||
}
|
||||
|
||||
void CWord::Copy(unsigned char* ptr)
|
||||
{
|
||||
unsigned len = ceil(m_word.size()/8);
|
||||
memset(ptr, 0, len);
|
||||
|
||||
unsigned pos = 0;
|
||||
for(auto it = m_word.begin(); it != m_word.end(); it++)
|
||||
{
|
||||
ptr[pos>>3] |= (*it).Get() << (7-(pos&7));
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
63
DRAMSys/simulator/src/error/ECC/Word.h
Normal file
63
DRAMSys/simulator/src/error/ECC/Word.h
Normal file
@@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
#include <deque>
|
||||
#include "Bit.h"
|
||||
|
||||
using std::deque;
|
||||
|
||||
|
||||
class CWord
|
||||
{
|
||||
protected:
|
||||
|
||||
unsigned m_nBitLength;
|
||||
deque<CBit> m_word;
|
||||
|
||||
|
||||
public:
|
||||
CWord(unsigned nBitLength);
|
||||
virtual ~CWord();
|
||||
|
||||
CBit* GetAt(unsigned nBitPos);
|
||||
|
||||
void Set(unsigned data);
|
||||
void Set(const unsigned char* data, unsigned lengthInBits);
|
||||
void Rotate();
|
||||
|
||||
bool Insert(unsigned npos, CBit b);
|
||||
bool Delete(unsigned npos);
|
||||
|
||||
void Copy(unsigned char* ptr);
|
||||
|
||||
void Append(CBit b);
|
||||
|
||||
void Resize(unsigned nsize);
|
||||
|
||||
bool PartShiftRight(unsigned nPos, unsigned nShift);
|
||||
|
||||
inline unsigned GetLength() const { return m_nBitLength; };
|
||||
|
||||
void Print();
|
||||
|
||||
CWord& operator=(unsigned d)
|
||||
{
|
||||
Set(d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CBit& operator[](unsigned nPos)
|
||||
{
|
||||
return m_word.at(nPos);
|
||||
}
|
||||
|
||||
friend CWord operator >> (CWord l, const unsigned& r)
|
||||
{
|
||||
for (unsigned i = 0; i < r; i++)
|
||||
{
|
||||
l.m_word.pop_front();
|
||||
l.m_word.push_back(CBit(CBit::VALUE::ZERO));
|
||||
}
|
||||
return l;
|
||||
}
|
||||
};
|
||||
|
||||
83
DRAMSys/simulator/src/error/eccbaseclass.cpp
Normal file
83
DRAMSys/simulator/src/error/eccbaseclass.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
#include "eccbaseclass.h"
|
||||
|
||||
tlm::tlm_sync_enum ECCBaseClass::nb_transport_fw( int id, tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay )
|
||||
{
|
||||
if(trans.get_command() == TLM_WRITE_COMMAND && phase == BEGIN_REQ)
|
||||
{
|
||||
// Allocate memory for encoded data using the size provided by AllocationEncode
|
||||
unsigned nEncodedDataSize = AllocationSize(trans.get_data_length());
|
||||
assert(nEncodedDataSize != 0);
|
||||
unsigned char* pEncodedData = new unsigned char[nEncodedDataSize];
|
||||
|
||||
// Save memory pointer and size
|
||||
m_mDataPointer[pEncodedData].pData = trans.get_data_ptr();
|
||||
m_mDataPointer[pEncodedData].nDataSize = trans.get_data_length();
|
||||
|
||||
// Data Encoding
|
||||
Encode(trans.get_data_ptr(), trans.get_data_length(), pEncodedData, nEncodedDataSize);
|
||||
|
||||
// Change transport data length and pointer
|
||||
trans.set_data_length(nEncodedDataSize);
|
||||
trans.set_data_ptr(pEncodedData);
|
||||
}
|
||||
else if(trans.get_command() == TLM_READ_COMMAND && phase == BEGIN_REQ)
|
||||
{
|
||||
// Allocate memory for reading data using the size provided by AllocationEncode
|
||||
unsigned nReadDataSize = AllocationSize(trans.get_data_length());
|
||||
assert(nReadDataSize != 0);
|
||||
unsigned char* pReadData = new unsigned char[nReadDataSize];
|
||||
|
||||
// Save memory pointer and size
|
||||
m_mDataPointer[pReadData].pData = trans.get_data_ptr();
|
||||
m_mDataPointer[pReadData].nDataSize = trans.get_data_length();
|
||||
|
||||
// Change transport data length and pointer
|
||||
trans.set_data_length(nReadDataSize);
|
||||
trans.set_data_ptr(pReadData);
|
||||
}
|
||||
|
||||
return i_socket[id]->nb_transport_fw( trans, phase, delay );
|
||||
}
|
||||
|
||||
|
||||
// Backward interface
|
||||
tlm::tlm_sync_enum ECCBaseClass::nb_transport_bw( int id, tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay )
|
||||
{
|
||||
if(trans.get_command() == TLM_READ_COMMAND && phase == BEGIN_RESP)
|
||||
{
|
||||
//Look for the corresponding data pointer for decoding
|
||||
auto it = m_mDataPointer.find(trans.get_data_ptr());
|
||||
assert(it != m_mDataPointer.end());
|
||||
|
||||
// Data Decoding
|
||||
Decode(trans.get_data_ptr(), trans.get_data_length(), it->second.pData, it->second.nDataSize);
|
||||
|
||||
// delete data pointer from map
|
||||
m_mDataPointer.erase(it);
|
||||
|
||||
// Delete data pointer used for encoded data
|
||||
delete[] trans.get_data_ptr();
|
||||
|
||||
// Set data pointer and size for decoded data
|
||||
trans.set_data_ptr(it->second.pData);
|
||||
trans.set_data_length(it->second.nDataSize);
|
||||
}
|
||||
else if(trans.get_command() == TLM_WRITE_COMMAND && phase == BEGIN_RESP)
|
||||
{
|
||||
//Look for the corresponding data pointer for decoding
|
||||
auto it = m_mDataPointer.find(trans.get_data_ptr());
|
||||
assert(it != m_mDataPointer.end());
|
||||
|
||||
// delete data pointer from map
|
||||
m_mDataPointer.erase(it);
|
||||
|
||||
// Delete data pointer used for encoded data
|
||||
delete[] trans.get_data_ptr();
|
||||
|
||||
// Set data pointer and size for decoded data
|
||||
trans.set_data_ptr(it->second.pData);
|
||||
trans.set_data_length(it->second.nDataSize);
|
||||
}
|
||||
|
||||
return t_socket[id]->nb_transport_bw( trans, phase, delay );
|
||||
}
|
||||
67
DRAMSys/simulator/src/error/eccbaseclass.h
Normal file
67
DRAMSys/simulator/src/error/eccbaseclass.h
Normal file
@@ -0,0 +1,67 @@
|
||||
#ifndef ECCBASECLASS_H
|
||||
#define ECCBASECLASS_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include <tlm.h>
|
||||
#include <tlm_utils/multi_passthrough_initiator_socket.h>
|
||||
#include <tlm_utils/multi_passthrough_target_socket.h>
|
||||
|
||||
#include "ECC/ECC.h"
|
||||
|
||||
#include "../common/xmlAddressdecoder.h"
|
||||
#include "../common/DebugManager.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace tlm;
|
||||
|
||||
class ECCBaseClass : sc_module
|
||||
{
|
||||
public:
|
||||
struct DataStruct
|
||||
{
|
||||
unsigned char* pData;
|
||||
unsigned int nDataSize;
|
||||
};
|
||||
|
||||
private:
|
||||
map<unsigned char*, DataStruct> m_mDataPointer;
|
||||
|
||||
public:
|
||||
// Function prototype for calculated the size of memory needed for saving the encoded data
|
||||
// Input nBytes: Number of bytes which have to be encoded
|
||||
// Return value: Number of bytes which have to be allocated for storing the encoded data
|
||||
virtual unsigned AllocationSize(unsigned nBytes) = 0;
|
||||
|
||||
protected:
|
||||
// Function prototype for encoding data.
|
||||
// Data pointer is provided in pDataIn, length in Bytes provided in nDataIn
|
||||
// Result should be written in pDataOut, which has a size of nDataOut.
|
||||
// pDataOut is already allocated with a size given by function AllocationEncode
|
||||
virtual void Encode(const unsigned char* pDataIn, const unsigned nDataIn, unsigned char* pDataOut, const unsigned nDataOut) = 0;
|
||||
|
||||
|
||||
// Function prototype for decoding data.
|
||||
// Data pointer is provided in pDataIn, length in Bytes provided in nDataIn
|
||||
// Result should be written in pDataOut, which has a size of nDataOut.
|
||||
// pDataOut is already allocated with a size given by function AllocationDecode
|
||||
virtual void Decode(const unsigned char* pDataIn, const unsigned nDataIn, unsigned char* pDataOut, const unsigned nDataOut) = 0;
|
||||
|
||||
public:
|
||||
tlm_utils::multi_passthrough_target_socket<ECCBaseClass> t_socket;
|
||||
tlm_utils::multi_passthrough_initiator_socket<ECCBaseClass> i_socket;
|
||||
|
||||
SC_CTOR(ECCBaseClass)
|
||||
: t_socket("t_socket")
|
||||
, i_socket("i_socket")
|
||||
{
|
||||
t_socket.register_nb_transport_fw(this, &ECCBaseClass::nb_transport_fw);
|
||||
i_socket.register_nb_transport_bw(this, &ECCBaseClass::nb_transport_bw);
|
||||
}
|
||||
// Forward interface
|
||||
tlm::tlm_sync_enum nb_transport_fw( int id, tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay );
|
||||
|
||||
// Backward interface
|
||||
tlm::tlm_sync_enum nb_transport_bw( int id, tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay );
|
||||
};
|
||||
|
||||
#endif // ECCBASECLASS_H
|
||||
134
DRAMSys/simulator/src/error/ecchamming.cpp
Normal file
134
DRAMSys/simulator/src/error/ecchamming.cpp
Normal file
@@ -0,0 +1,134 @@
|
||||
#include "ecchamming.h"
|
||||
|
||||
#include "ECC/ECC.h"
|
||||
|
||||
unsigned ECCHamming::AllocationSize(unsigned nBytes)
|
||||
{
|
||||
// For this hamming for 8 bytes one extra byte is needed:l
|
||||
return nBytes + ceil(nBytes / m_nDatawordSize) * m_nCodewordSize;
|
||||
}
|
||||
|
||||
void ECCHamming::Encode(const unsigned char* pDataIn, const unsigned nDataIn, unsigned char* pDataOut, const unsigned nDataOut)
|
||||
{
|
||||
// Calculate how many 8 byte blocks are there
|
||||
unsigned nBlocks = nDataIn/m_nDatawordSize;
|
||||
|
||||
// No partly filled blocks are supported
|
||||
assert(nDataIn % m_nDatawordSize == 0);
|
||||
|
||||
// Create ECC data for every block
|
||||
for(unsigned i = 0; i < nBlocks; i++)
|
||||
{
|
||||
// Create all variables needed for calulation
|
||||
CWord dataword(InBits(m_nDatawordSize)); // Size in bits
|
||||
CWord codeword(InBits(m_nCodewordSize)); // Size in bits
|
||||
|
||||
// Fill in current data block
|
||||
dataword.Set(&pDataIn[i*m_nDatawordSize], InBits(m_nDatawordSize));
|
||||
|
||||
// Extend data word. It grows from m_nDatawordSize to m_nDatawordSize + m_nCodewordSize
|
||||
ECC::ExtendWord(dataword);
|
||||
|
||||
// Initialize the codeword with zeros
|
||||
codeword = 0;
|
||||
|
||||
// Calculate Checkbits
|
||||
ECC::CalculateCheckbits(dataword, codeword);
|
||||
ECC::InsertCheckbits(dataword, codeword);
|
||||
|
||||
// Calculate Parity
|
||||
ECC::CalculateParityBit(dataword, codeword[7]);
|
||||
|
||||
// Check if there is enough space in the output array (should always be)
|
||||
assert((i+1)*(m_nDatawordSize + m_nCodewordSize) <= nDataOut);
|
||||
|
||||
// Copy old data
|
||||
memcpy(&pDataOut[i*(m_nDatawordSize + m_nCodewordSize)], &pDataIn[i*m_nDatawordSize], m_nDatawordSize);
|
||||
|
||||
// Save hamming code + parity bit in the last byte
|
||||
codeword.Copy(&pDataOut[i*(m_nDatawordSize + m_nCodewordSize)+m_nDatawordSize]);
|
||||
}
|
||||
}
|
||||
|
||||
void ECCHamming::Decode(const unsigned char* pDataIn, const unsigned nDataIn, unsigned char* pDataOut, const unsigned nDataOut)
|
||||
{
|
||||
// Calculate how many 9 byte blocks are there
|
||||
unsigned nBlocks = nDataIn/(m_nDatawordSize + m_nCodewordSize);
|
||||
|
||||
// No partly filled blocks are supported
|
||||
assert(nDataIn % (m_nDatawordSize + m_nCodewordSize) == 0);
|
||||
|
||||
// Verify ECC data for every block
|
||||
for(unsigned i = 0; i < nBlocks; i++)
|
||||
{
|
||||
// Create all variables needed for calulation
|
||||
CWord dataword(InBits(m_nDatawordSize)); // Size in bits
|
||||
CWord codeword(InBits(m_nCodewordSize)); // Size in bits
|
||||
|
||||
// Fill in current data block
|
||||
dataword.Set(&pDataIn[i*(m_nDatawordSize + m_nCodewordSize)], InBits(m_nDatawordSize));
|
||||
codeword.Set(&pDataIn[i*(m_nDatawordSize + m_nCodewordSize)+m_nDatawordSize], InBits(m_nCodewordSize));
|
||||
|
||||
// Extend data word. It grows from m_nDatawordSize to m_nDatawordSize + m_nCodewordSize
|
||||
ECC::ExtendWord(dataword);
|
||||
|
||||
// Insert old codeword
|
||||
ECC::InsertCheckbits(dataword, codeword);
|
||||
ECC::InsertParityBit(dataword, codeword[7]);
|
||||
|
||||
// Reset codeword
|
||||
codeword = 0;
|
||||
|
||||
// Calculate Checkbits again
|
||||
ECC::CalculateCheckbits(dataword, codeword);
|
||||
|
||||
// Calculate Parity again
|
||||
ECC::CalculateParityBit(dataword, codeword[7]);
|
||||
|
||||
// Translate codeword
|
||||
bool bParity = codeword[7] == CBit::ONE;
|
||||
|
||||
// calculate syndrome
|
||||
unsigned char c = 0;
|
||||
codeword.Rotate();
|
||||
codeword.Copy(&c);
|
||||
c &= 0x7F;
|
||||
|
||||
// Parity Error?
|
||||
if(bParity)
|
||||
{
|
||||
// Parity Error
|
||||
|
||||
if(c == 0)
|
||||
{
|
||||
// Only Parity Bit broken - continue
|
||||
cout << "Parity Bit error" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Data or Hamming Code Bit broken
|
||||
cout << "Single Error Detected" << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No Parity Error
|
||||
|
||||
if(c == 0)
|
||||
{
|
||||
// No error at all - continue
|
||||
}
|
||||
else
|
||||
{
|
||||
// Double error detected
|
||||
cout << "Double Error Detected (Block " << i << ")." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if there is enough space in the output array (should always be)
|
||||
assert((i+1)*(m_nDatawordSize) <= nDataOut);
|
||||
|
||||
// Copy data
|
||||
memcpy(&pDataOut[i*m_nDatawordSize], &pDataIn[i*(m_nDatawordSize + m_nCodewordSize)], m_nDatawordSize);
|
||||
}
|
||||
}
|
||||
41
DRAMSys/simulator/src/error/ecchamming.h
Normal file
41
DRAMSys/simulator/src/error/ecchamming.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef ECCHAMMIMG_H
|
||||
#define ECCHAMMIMG_H
|
||||
|
||||
#include "eccbaseclass.h"
|
||||
|
||||
|
||||
class ECCHamming : public ECCBaseClass
|
||||
{
|
||||
private:
|
||||
// Hamming constants for this special implementation
|
||||
const unsigned m_nDatawordSize = 8; // bytes
|
||||
const unsigned m_nCodewordSize = 1; // bytes
|
||||
|
||||
inline unsigned InBits(unsigned n){return n<<3;}; // use this if constants are needed in bits
|
||||
|
||||
public:
|
||||
// Function prototype for calculated the size of memory needed for saving the encoded data
|
||||
// Input nBytes: Number of bytes which have to be encoded
|
||||
// Return value: Number of bytes which have to be allocated for storing the encoded data
|
||||
virtual unsigned AllocationSize(unsigned nBytes);
|
||||
|
||||
protected:
|
||||
// Function prototype for encoding data.
|
||||
// Data pointer is provided in pDataIn, length in Bytes provided in nDataIn
|
||||
// Result should be written in pDataOut, which has a size of nDataOut.
|
||||
// pDataOut is already allocated with a size given by function AllocationEncode
|
||||
virtual void Encode(const unsigned char* pDataIn, const unsigned nDataIn, unsigned char* pDataOut, const unsigned nDataOut);
|
||||
|
||||
|
||||
// Function prototype for decoding data.
|
||||
// Data pointer is provided in pDataIn, length in Bytes provided in nDataIn
|
||||
// Result should be written in pDataOut, which has a size of nDataOut.
|
||||
// pDataOut is already allocated with a size given by function AllocationDecode
|
||||
virtual void Decode(const unsigned char* pDataIn, const unsigned nDataIn, unsigned char* pDataOut, const unsigned nDataOut);
|
||||
|
||||
public:
|
||||
ECCHamming(::sc_core::sc_module_name name) : ECCBaseClass(name)
|
||||
{};
|
||||
};
|
||||
|
||||
#endif // ECCHAMMIMG_H
|
||||
@@ -49,7 +49,11 @@ void errorModel::init()
|
||||
burstLenght = Configuration::getInstance().memSpec.BurstLength;
|
||||
numberOfColumns = Configuration::getInstance().memSpec.NumberOfColumns;
|
||||
bytesPerColumn = xmlAddressDecoder::getInstance().amount["bytes"];
|
||||
numberOfRows = Configuration::getInstance().memSpec.NumberOfRows;
|
||||
|
||||
// Adjust number of bytes per column dynamically to the selected ecc controller
|
||||
bytesPerColumn = Configuration::getInstance().adjustNumBytesAfterECC(bytesPerColumn);
|
||||
|
||||
numberOfRows = Configuration::getInstance().memSpec.NumberOfRows;
|
||||
numberOfBitErrorEvents = 0;
|
||||
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "../common/Utils.h"
|
||||
#include "../simulation/TemperatureController.h"
|
||||
#include "../controller/Controller.h"
|
||||
#include "../error/ecchamming.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -58,6 +59,9 @@ DRAMSys::DRAMSys(sc_module_name __attribute__((unused)) name,
|
||||
string simulationToRun,
|
||||
string pathToResources) : tSocket("DRAMSys_tSocket")
|
||||
{
|
||||
// Initialize ecc pointer
|
||||
ecc = nullptr;
|
||||
|
||||
logo();
|
||||
|
||||
// Read Configuration Setup:
|
||||
@@ -185,9 +189,25 @@ void DRAMSys::instantiateModules(const string &traceName,
|
||||
// They need to be ready before creating some modules.
|
||||
setupTlmRecorders(traceName, pathToResources);
|
||||
|
||||
// Create new ECC Controller
|
||||
switch (Configuration::getInstance().ECCMode)
|
||||
{
|
||||
case ECCControllerMode::Hamming:
|
||||
ecc = new ECCHamming("ECCHamming");
|
||||
break;
|
||||
default:
|
||||
ecc = nullptr;
|
||||
break;
|
||||
}
|
||||
|
||||
// Save ECC Controller into the configuration struct to adjust it dynamically
|
||||
Configuration::getInstance().pECC = ecc;
|
||||
|
||||
// Create arbiter
|
||||
arbiter = new Arbiter("arbiter");
|
||||
arbiter->setTlmRecorders(tlmRecorders);
|
||||
|
||||
// Create DRAM
|
||||
for (size_t i = 0;
|
||||
i < Configuration::getInstance().NumberOfMemChannels;
|
||||
i++)
|
||||
@@ -214,34 +234,46 @@ void DRAMSys::instantiateModules(const string &traceName,
|
||||
|
||||
void DRAMSys::bindSockets()
|
||||
{
|
||||
tSocket.bind(arbiter->tSocket);
|
||||
// If ECC Controller enabled, put it between Trace and arbiter
|
||||
if(Configuration::getInstance().ECCMode != ECCControllerMode::Disabled)
|
||||
{
|
||||
assert(ecc != nullptr);
|
||||
tSocket.bind(ecc->t_socket);
|
||||
ecc->i_socket.bind(arbiter->tSocket);
|
||||
}
|
||||
else
|
||||
{
|
||||
tSocket.bind(arbiter->tSocket);
|
||||
}
|
||||
|
||||
if(Configuration::getInstance().CheckTLM2Protocol)
|
||||
if(Configuration::getInstance().CheckTLM2Protocol)
|
||||
{
|
||||
for (size_t i = 0;
|
||||
i < Configuration::getInstance().NumberOfMemChannels;
|
||||
i++)
|
||||
{
|
||||
for (size_t i = 0;
|
||||
i < Configuration::getInstance().NumberOfMemChannels;
|
||||
i++)
|
||||
{
|
||||
arbiter->iSocket.bind(controllersTlmCheckers[i]->target_socket);
|
||||
controllersTlmCheckers[i]->initiator_socket.bind(
|
||||
controllers[i]->tSocket);
|
||||
controllers[i]->iSocket.bind(drams[i]->tSocket);
|
||||
}
|
||||
arbiter->iSocket.bind(controllersTlmCheckers[i]->target_socket);
|
||||
controllersTlmCheckers[i]->initiator_socket.bind(
|
||||
controllers[i]->tSocket);
|
||||
controllers[i]->iSocket.bind(drams[i]->tSocket);
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t i = 0;
|
||||
i < Configuration::getInstance().NumberOfMemChannels;
|
||||
i++)
|
||||
{
|
||||
for (size_t i = 0;
|
||||
i < Configuration::getInstance().NumberOfMemChannels;
|
||||
i++)
|
||||
{
|
||||
arbiter->iSocket.bind(controllers[i]->tSocket);
|
||||
controllers[i]->iSocket.bind(drams[i]->tSocket);
|
||||
}
|
||||
arbiter->iSocket.bind(controllers[i]->tSocket);
|
||||
controllers[i]->iSocket.bind(drams[i]->tSocket);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DRAMSys::~DRAMSys()
|
||||
{
|
||||
if(ecc)
|
||||
delete ecc;
|
||||
|
||||
delete arbiter;
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "../controller/Controller.h"
|
||||
#include "../common/third_party/tinyxml2/tinyxml2.h"
|
||||
#include "../common/tlm2_base_protocol_checker.h"
|
||||
#include "../error/eccbaseclass.h"
|
||||
|
||||
class DRAMSys: public sc_module
|
||||
{
|
||||
@@ -78,9 +79,10 @@ private:
|
||||
std::vector<tlm_utils::tlm2_base_protocol_checker<>*>
|
||||
controllersTlmCheckers;
|
||||
|
||||
// All transactions pass first through the ECC Controller
|
||||
ECCBaseClass *ecc;
|
||||
// All transactions pass through the same arbiter
|
||||
Arbiter *arbiter;
|
||||
|
||||
// Each DRAM unit has a controller
|
||||
std::vector<Controller*> controllers;
|
||||
|
||||
|
||||
@@ -92,6 +92,8 @@ struct Dram : sc_module
|
||||
|
||||
SC_CTOR(Dram) : tSocket("socket")
|
||||
{
|
||||
// Adjust number of bytes per burst dynamically to the selected ecc controller
|
||||
bytesPerBurst = Configuration::getInstance().adjustNumBytesAfterECC(bytesPerBurst);
|
||||
dramController = NULL;
|
||||
tlmRecorder = NULL;
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ void StlPlayer::nextPayload()
|
||||
unsigned long long addr = std::stoull(address.c_str(), 0, 16);
|
||||
|
||||
// Get the data if necessary.
|
||||
if (Configuration::getInstance().StoreMode != StorageMode::NoStorage) {
|
||||
if (Configuration::getInstance().StoreMode != StorageMode::NoStorage && cmd != TLM_READ_COMMAND) {
|
||||
// The input trace file must provide the data to be stored into the memory.
|
||||
iss >> dataStr;
|
||||
if (dataStr.empty())
|
||||
|
||||
@@ -544,6 +544,7 @@ Below, the sub-configurations are listed and explained.
|
||||
<SimulationProgressBar value="1"/>
|
||||
<NumberOfMemChannels value="1"/>
|
||||
<NumberOfDevicesOnDIMM value = "8" />
|
||||
<ECCControllerMode value = "Disabled" />
|
||||
</simconfig>
|
||||
```
|
||||
|
||||
@@ -578,6 +579,9 @@ Below, the sub-configurations are listed and explained.
|
||||
- *CheckTLM2Protocol* (boolean)
|
||||
- "1": enables the TLM 2.0 Protocol Checking
|
||||
- "0": disables the TLM 2.0 Protocol Checking
|
||||
- *ECCControllerMode* (string)
|
||||
- "Disabled": No ECC Controller is used
|
||||
- "Hamming": Enables an ECC Controller with classic SECDED implementation using Hamming Code
|
||||
|
||||
- **Temperature Simulator Configuration**
|
||||
|
||||
|
||||
Reference in New Issue
Block a user