diff --git a/DRAMSys/simulator/resources/configs/memspecs/MICRON_1Gb_DDR3-1600_8bit_G_less_refresh.xml b/DRAMSys/simulator/resources/configs/memspecs/MICRON_1Gb_DDR3-1600_8bit_G_less_refresh.xml
new file mode 100644
index 00000000..7a94a932
--- /dev/null
+++ b/DRAMSys/simulator/resources/configs/memspecs/MICRON_1Gb_DDR3-1600_8bit_G_less_refresh.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DRAMSys/simulator/resources/configs/simulator/ddr3_ecc.xml b/DRAMSys/simulator/resources/configs/simulator/ddr3_ecc.xml
new file mode 100644
index 00000000..f1f7bcf8
--- /dev/null
+++ b/DRAMSys/simulator/resources/configs/simulator/ddr3_ecc.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DRAMSys/simulator/resources/resources.pri b/DRAMSys/simulator/resources/resources.pri
index 37b75724..3d02ddb8 100644
--- a/DRAMSys/simulator/resources/resources.pri
+++ b/DRAMSys/simulator/resources/resources.pri
@@ -140,4 +140,7 @@ DISTFILES += \
$$PWD/configs/mcconfigs/fifo_ecc.xml \
$$PWD/simulations/wideio-ecc.xml \
$$PWD/traces/test_ecc.stl \
- $$PWD/configs/memspecs/wideio_less_refresh.xml
+ $$PWD/configs/memspecs/wideio_less_refresh.xml \
+ $$PWD/simulations/ddr3-ecc.xml \
+ $$PWD/configs/simulator/ddr3_ecc.xml \
+ $$PWD/configs/memspecs/MICRON_1Gb_DDR3-1600_8bit_G_less_refresh.xml
diff --git a/DRAMSys/simulator/resources/simulations/ddr3-ecc.xml b/DRAMSys/simulator/resources/simulations/ddr3-ecc.xml
new file mode 100644
index 00000000..5760612c
--- /dev/null
+++ b/DRAMSys/simulator/resources/simulations/ddr3-ecc.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ test_ecc.stl
+
+
diff --git a/DRAMSys/simulator/src/error/ECC/ECC.cpp b/DRAMSys/simulator/src/error/ECC/ECC.cpp
index a041496e..b8e15743 100644
--- a/DRAMSys/simulator/src/error/ECC/ECC.cpp
+++ b/DRAMSys/simulator/src/error/ECC/ECC.cpp
@@ -31,13 +31,17 @@ void ECC::CalculateCheckbits(CWord & v, CWord & p)
{
// Hamming-Code Prüfbits füllen
unsigned i = 1, l = 0;
- while (i < v.GetLength())
+
+ // Last bit is the parity bit - don't use this in the algorithm for hamming code
+ unsigned len = v.GetLength()-1;
+
+ while (i < len)
{
- for (unsigned j = (i - 1); j < v.GetLength(); j += (i << 1))
+ for (unsigned j = (i - 1); j < len; j += (i << 1))
{
for (unsigned k = 0; k < (i); k++)
{
- if(j + k >= v.GetLength())
+ if(j + k >= len)
break;
p[l] ^= v[j + k];
}
@@ -51,7 +55,7 @@ void ECC::InsertCheckbits(CWord& v, CWord p)
{
// Prüfbits einfügen
unsigned i = 1, j = 0;
- while (i <= v.GetLength())
+ while (i <= v.GetLength()-1)
{
v[i - 1] = p[j++];
i <<= 1;
@@ -63,7 +67,7 @@ void ECC::ExtractCheckbits(CWord v, CWord & p)
{
// Prüfbits extrahieren
unsigned i = 1, j = 0;
- while(i <= v.GetLength())
+ while(i <= v.GetLength()-1)
{
p[j++] = v[i - 1];
i <<= 1;
diff --git a/DRAMSys/simulator/src/error/controllerECC.h b/DRAMSys/simulator/src/error/controllerECC.h
index 94a2ce6e..509e1036 100644
--- a/DRAMSys/simulator/src/error/controllerECC.h
+++ b/DRAMSys/simulator/src/error/controllerECC.h
@@ -31,7 +31,7 @@ public:
// Forward interface
virtual tlm::tlm_sync_enum nb_transport_fw( int id, tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay )
{
- if(trans.get_command() == TLM_WRITE_COMMAND)
+ if(trans.get_command() == TLM_WRITE_COMMAND && trans.get_response_status() == TLM_INCOMPLETE_RESPONSE)
{
// Get data and length
unsigned nDataLength = trans.get_data_length();
@@ -53,10 +53,12 @@ public:
// Fill in current data block
dataword.Set(&pData[i<<3], 64);
- dataword.Print();
+
// Extend data word
ECC::ExtendWord(dataword);
+ checkbits = 0;
+
// Calculate Checkbits
ECC::CalculateCheckbits(dataword, checkbits);
ECC::InsertCheckbits(dataword, checkbits);
@@ -67,13 +69,21 @@ public:
// Copy old data
memcpy(&pDataECC[i*9], &pData[i<<3], 8);
- dataword.Print();
- checkbits.Print();
-
// Save new data
checkbits.Copy(&pDataECC[i*9+8]);
}
+ // Print all
+// for(unsigned i = 0; i < nBlocks; i++)
+// {
+// for(unsigned j = 0; j < 9; j++)
+// {
+// cout << setw(2) << setfill('0') << hex << uppercase << (int)pDataECC[i*9+j];
+// }
+// cout << endl;
+// }
+// cout << endl;
+
// Change transport data length
trans.set_data_length(nBlocks*9);
@@ -82,14 +92,24 @@ public:
// Set new data
trans.set_data_ptr(pDataECC);
-
- // Allocate memory if necessary
- //if(m_mBuffer[trans.get_address()].size() != trans.get_data_length())
- // m_mBuffer[trans.get_address()].resize(trans.get_data_length());
-
- // Copy data
- //memcpy(m_mBuffer[trans.get_address()].data(), trans.get_data_ptr(), trans.get_data_length());
}
+ else if(trans.get_response_status() == TLM_INCOMPLETE_RESPONSE)
+ {
+ // 64 -> 72
+
+ // Get data length
+ unsigned nDataLength = trans.get_data_length();
+
+ // delete old data
+ delete[] trans.get_data_ptr();
+
+ // Set new data
+ nDataLength += nDataLength>>3;
+ trans.set_data_ptr(new unsigned char [nDataLength]);
+
+ // Change transport data length
+ trans.set_data_length(nDataLength);
+ }
return i_socket[id]->nb_transport_fw( trans, phase, delay );
}
@@ -99,27 +119,108 @@ public:
{
if(trans.get_command() == TLM_READ_COMMAND && phase == 3)
{
- if(m_mBuffer[trans.get_address()].size() == trans.get_data_length())
- {
- // Data can be compared, they got the same size
- int error = memcmp(m_mBuffer[trans.get_address()].data(), trans.get_data_ptr(), trans.get_data_length());
- if(error)
- {
- // Data not equal
- cout << "\nError Detected: Address: 0x" << hex << trans.get_address();
+ // Get data and length
+ unsigned nDataLength = trans.get_data_length();
+ unsigned char* pData = trans.get_data_ptr();
- for(unsigned n = 0; n < trans.get_data_length(); n++)
- {
- if(m_mBuffer[trans.get_address()].data()[n] != trans.get_data_ptr()[n])
- {
- cout << "\n\t\tError Byte " << dec << n << " Orig: 0x" << hex << (int)m_mBuffer[trans.get_address()].data()[n]
- << " Read: 0x" << hex << (int)trans.get_data_ptr()[n];
- }
- }
- cout << endl;
- }
- }
- }
+ // Calculate how many 72 bit blocks are there
+ unsigned nBlocks = nDataLength/9;
+
+ // Print all
+// for(unsigned i = 0; i < nBlocks; i++)
+// {
+// for(unsigned j = 0; j < 9; j++)
+// {
+// cout << setw(2) << setfill('0') << hex << uppercase << (int)pData[i*9+j];
+// }
+// cout << endl;
+// }
+// cout << endl;
+
+ // Verify ECC data for every block
+ for(unsigned i = 0; i < nBlocks; i++)
+ {
+ // Create all variables needed for calulation
+ CWord dataword(64);
+ CWord checkbits(8);
+
+ // Fill in current data block
+ dataword.Set(&pData[i*9], 64);
+ checkbits.Set(&pData[i*9+8], 8);
+
+ // Extend data word
+ ECC::ExtendWord(dataword);
+
+ // Insert old checkbits
+ ECC::InsertCheckbits(dataword, checkbits);
+ ECC::InsertParityBit(dataword, checkbits[7]);
+
+ checkbits = 0;
+
+ // Calculate Checkbits
+ ECC::CalculateCheckbits(dataword, checkbits);
+
+ // Calculate Parity
+ ECC::CalculateParityBit(dataword, checkbits[7]);
+
+ // Translate Checkbits
+ bool bParity = checkbits[7] == CBit::ONE;
+
+ unsigned char c = 0;
+ checkbits.Rotate();
+ checkbits.Copy(&c);
+ c &= 0x7F;
+
+ // Parity Error?
+ if(bParity)
+ {
+ // Parity Error
+
+ if(c == 0)
+ {
+ // Only Parity Bit broken - continue
+ cout << "Parity Bit error" << endl;
+ continue;
+ }
+ else
+ {
+ // Data or Hamming Code Bit broken
+ cout << "Single Error Detected" << endl;
+ continue;
+ }
+ }
+ else
+ {
+ // No Parity Error
+
+ if(c == 0)
+ {
+ // No error at all - continue
+ continue;
+ }
+ else
+ {
+ // Double error detected
+ cout << "Double Error Detected (Block " << i << ")." << endl;
+ continue;
+ }
+ }
+ }
+ // Change transport data length
+ trans.set_data_length(nBlocks<<3);
+
+ // New Data
+ unsigned char* pDataECC = new unsigned char[nBlocks<<3];
+
+ // Copy data
+ memcpy(pDataECC, pData, nBlocks<<3);
+
+ // delete old data
+ delete[] trans.get_data_ptr();
+
+ // Set new data
+ trans.set_data_ptr(pDataECC);
+ }
return t_socket[id]->nb_transport_bw( trans, phase, delay );
}
};
diff --git a/DRAMSys/simulator/src/error/errormodel.cpp b/DRAMSys/simulator/src/error/errormodel.cpp
index 91eb789b..5ff3693f 100644
--- a/DRAMSys/simulator/src/error/errormodel.cpp
+++ b/DRAMSys/simulator/src/error/errormodel.cpp
@@ -49,7 +49,12 @@ void errorModel::init()
burstLenght = Configuration::getInstance().memSpec.BurstLength;
numberOfColumns = Configuration::getInstance().memSpec.NumberOfColumns;
bytesPerColumn = xmlAddressDecoder::getInstance().amount["bytes"];
- numberOfRows = Configuration::getInstance().memSpec.NumberOfRows;
+ if(Configuration::getInstance().EnableControllerECC)
+ {
+ bytesPerColumn += bytesPerColumn>>3;
+ }
+
+ numberOfRows = Configuration::getInstance().memSpec.NumberOfRows;
numberOfBitErrorEvents = 0;
diff --git a/DRAMSys/simulator/src/simulation/main.cpp b/DRAMSys/simulator/src/simulation/main.cpp
index 18b474e9..0bb75469 100644
--- a/DRAMSys/simulator/src/simulation/main.cpp
+++ b/DRAMSys/simulator/src/simulation/main.cpp
@@ -72,7 +72,7 @@ int sc_main(int argc, char **argv)
}
else
{
- SimulationXML = resources + "simulations/wideio-ecc.xml";
+ SimulationXML = resources + "simulations/ddr3-ecc.xml";
}
std::vector players;