ECC implementierung fertig gestellt.

This commit is contained in:
Johannes Feldmann
2017-04-13 18:59:56 +02:00
parent 20e6d4e615
commit 11d428c1d5
8 changed files with 252 additions and 40 deletions

View File

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

View File

@@ -0,0 +1,22 @@
<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" />
<EnableControllerECC value = "1" />
<gem5 value = "0" />
<!-- 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
<AddressOffset value = "214748364c8" />
<gem5 value = "1" />
-->
</simconfig>

View File

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

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

View File

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

View File

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

View File

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

View File

@@ -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<StlPlayer*> players;