Added comments
Reverted all configurations Adjusted resources.pri Added the enable switch for controllerECC to README.md
This commit is contained in:
@@ -12,11 +12,4 @@
|
||||
<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>
|
||||
|
||||
@@ -6,6 +6,7 @@ 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
|
||||
|
||||
# Simulator Files
|
||||
OTHER_FILES += resources/configs/simulator/wideio.xml
|
||||
@@ -13,7 +14,7 @@ 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
|
||||
|
||||
# Scripts
|
||||
OTHER_FILES += resources/scripts/address_scrambler.pl
|
||||
@@ -112,6 +113,7 @@ OTHER_FILES += resources/configs/memspecs/SAMSUNG_K4B1G1646E_1Gb_DDR3-1600_16bit
|
||||
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
|
||||
|
||||
@@ -1,22 +1,32 @@
|
||||
#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;
|
||||
|
||||
// n = 2^k - k - 1
|
||||
// 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 SEC-DED
|
||||
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)
|
||||
{
|
||||
@@ -24,17 +34,33 @@ void ECC::ExtendWord(CWord & v)
|
||||
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)
|
||||
{
|
||||
// Hamming-Code Prüfbits füllen
|
||||
unsigned i = 1, l = 0;
|
||||
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))
|
||||
@@ -51,21 +77,26 @@ void ECC::CalculateCheckbits(CWord & v, CWord & p)
|
||||
}
|
||||
}
|
||||
|
||||
// ************************************************************************************************
|
||||
// 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)
|
||||
{
|
||||
// Prüfbits einfügen
|
||||
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)
|
||||
{
|
||||
// Prüfbits extrahieren
|
||||
unsigned i = 1, j = 0;
|
||||
while(i <= v.GetLength()-1)
|
||||
{
|
||||
@@ -74,6 +105,9 @@ void ECC::ExtractCheckbits(CWord v, CWord & p)
|
||||
}
|
||||
}
|
||||
|
||||
// ************************************************************************************************
|
||||
// Function which calculates the overal parity
|
||||
// Simply XOR all bits
|
||||
void ECC::CalculateParityBit(CWord v, CBit & p)
|
||||
{
|
||||
// Paritybit
|
||||
@@ -84,11 +118,15 @@ void ECC::CalculateParityBit(CWord v, CBit & p)
|
||||
}
|
||||
}
|
||||
|
||||
// ************************************************************************************************
|
||||
// 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];
|
||||
|
||||
@@ -3,12 +3,30 @@
|
||||
#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);
|
||||
|
||||
// Erweitert das Wort um zusätzliche Bits für die Berechnung des Hamming-Codes
|
||||
// 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);
|
||||
|
||||
@@ -14,7 +14,7 @@ using namespace tlm;
|
||||
struct ControllerECC: sc_module
|
||||
{
|
||||
private:
|
||||
map<sc_dt::uint64, vector<uint8_t>> m_mBuffer;
|
||||
map<int, unsigned char*> m_mDataPointer;
|
||||
|
||||
public:
|
||||
tlm_utils::multi_passthrough_target_socket<ControllerECC> t_socket;
|
||||
@@ -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 && trans.get_response_status() == TLM_INCOMPLETE_RESPONSE)
|
||||
if(trans.get_command() == TLM_WRITE_COMMAND && phase == BEGIN_REQ)
|
||||
{
|
||||
// Get data and length
|
||||
unsigned nDataLength = trans.get_data_length();
|
||||
@@ -69,47 +69,37 @@ public:
|
||||
// Copy old data
|
||||
memcpy(&pDataECC[i*9], &pData[i<<3], 8);
|
||||
|
||||
// Save new data
|
||||
// Save hamming code + parity bit in the last byte
|
||||
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);
|
||||
|
||||
// delete old data
|
||||
delete[] trans.get_data_ptr();
|
||||
// store old data
|
||||
m_mDataPointer[id] = trans.get_data_ptr();
|
||||
|
||||
// Set new data
|
||||
trans.set_data_ptr(pDataECC);
|
||||
}
|
||||
else if(trans.get_response_status() == TLM_INCOMPLETE_RESPONSE)
|
||||
{
|
||||
// 64 -> 72
|
||||
else if(trans.get_command() == TLM_READ_COMMAND && phase == BEGIN_REQ)
|
||||
{
|
||||
// 64 -> 72
|
||||
|
||||
// Get data length
|
||||
unsigned nDataLength = trans.get_data_length();
|
||||
// Get data length
|
||||
unsigned nDataLength = trans.get_data_length();
|
||||
|
||||
// delete old data
|
||||
delete[] trans.get_data_ptr();
|
||||
// store old data
|
||||
m_mDataPointer[id] = trans.get_data_ptr();
|
||||
|
||||
// Set new data
|
||||
nDataLength += nDataLength>>3;
|
||||
trans.set_data_ptr(new unsigned char [nDataLength]);
|
||||
// Set new data
|
||||
nDataLength += nDataLength>>3;
|
||||
trans.set_data_ptr(new unsigned char [nDataLength]);
|
||||
|
||||
// Change transport data length
|
||||
trans.set_data_length(nDataLength);
|
||||
}
|
||||
|
||||
// Change transport data length
|
||||
trans.set_data_length(nDataLength);
|
||||
}
|
||||
return i_socket[id]->nb_transport_fw( trans, phase, delay );
|
||||
}
|
||||
|
||||
@@ -117,7 +107,7 @@ public:
|
||||
// Backward interface
|
||||
virtual tlm::tlm_sync_enum 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 == 3)
|
||||
if(trans.get_command() == TLM_READ_COMMAND && phase == BEGIN_RESP)
|
||||
{
|
||||
// Get data and length
|
||||
unsigned nDataLength = trans.get_data_length();
|
||||
@@ -126,17 +116,6 @@ public:
|
||||
// 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++)
|
||||
{
|
||||
@@ -209,8 +188,11 @@ public:
|
||||
// Change transport data length
|
||||
trans.set_data_length(nBlocks<<3);
|
||||
|
||||
// New Data
|
||||
unsigned char* pDataECC = new unsigned char[nBlocks<<3];
|
||||
// load data pointer
|
||||
auto it = m_mDataPointer.find(id);
|
||||
assert(it != m_mDataPointer.end());
|
||||
|
||||
unsigned char* pDataECC = it->second;
|
||||
|
||||
// Copy data
|
||||
memcpy(pDataECC, pData, nBlocks<<3);
|
||||
@@ -221,6 +203,26 @@ public:
|
||||
// Set new data
|
||||
trans.set_data_ptr(pDataECC);
|
||||
}
|
||||
else if(trans.get_command() == TLM_WRITE_COMMAND && phase == BEGIN_RESP)
|
||||
{
|
||||
// 72 -> 64
|
||||
|
||||
// delete old data
|
||||
delete[] trans.get_data_ptr();
|
||||
|
||||
// Get data length
|
||||
unsigned nDataLength = trans.get_data_length();
|
||||
|
||||
// load data pointer
|
||||
auto it = m_mDataPointer.find(id);
|
||||
assert(it != m_mDataPointer.end());
|
||||
|
||||
trans.set_data_ptr(it->second);
|
||||
|
||||
// Change transport data length
|
||||
trans.set_data_length((nDataLength/9)<<3);
|
||||
}
|
||||
|
||||
return t_socket[id]->nb_transport_bw( trans, phase, delay );
|
||||
}
|
||||
};
|
||||
|
||||
@@ -72,7 +72,7 @@ int sc_main(int argc, char **argv)
|
||||
}
|
||||
else
|
||||
{
|
||||
SimulationXML = resources + "simulations/ddr3-ecc.xml";
|
||||
SimulationXML = resources + "simulations/ddr3-example.xml";
|
||||
}
|
||||
|
||||
std::vector<StlPlayer*> players;
|
||||
|
||||
@@ -544,6 +544,7 @@ Below, the sub-configurations are listed and explained.
|
||||
<SimulationProgressBar value="1"/>
|
||||
<NumberOfMemChannels value="1"/>
|
||||
<NumberOfDevicesOnDIMM value = "8" />
|
||||
<EnableControllerECC value = "0" />
|
||||
</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
|
||||
- *EnableControllerECC* (boolean)
|
||||
- "1": enables the ECC Controller with classic SECDED implementation
|
||||
- "0": disables the ECC Controller with classic SECDED implementation
|
||||
|
||||
- **Temperature Simulator Configuration**
|
||||
|
||||
|
||||
Reference in New Issue
Block a user