OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [orpsocv2/] [bench/] [sysc/] [src/] [DebugUnitSC.cpp] - Diff between revs 63 and 462

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 63 Rev 462
Line 32... Line 32...
#include <iomanip>
#include <iomanip>
 
 
#include "DebugUnitSC.h"
#include "DebugUnitSC.h"
#include "Utils.h"
#include "Utils.h"
 
 
 
 
using sc_core::sc_event;
using sc_core::sc_event;
using sc_core::sc_fifo;
using sc_core::sc_fifo;
using sc_core::sc_module_name;
using sc_core::sc_module_name;
 
 
 
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//! Constructor for the Debug Unit
//! Constructor for the Debug Unit
 
 
//! This module is entirely subservient to the GDB server. It has no SystemC
//! This module is entirely subservient to the GDB server. It has no SystemC
//! processes of its own. It provides services via calls to its API.
//! processes of its own. It provides services via calls to its API.
Line 60... Line 58...
//! @param[in] name             Name of this module, passed to the parent
//! @param[in] name             Name of this module, passed to the parent
//!                             constructor. 
//!                             constructor. 
//! @param[in] _tapActionQueue  Pointer to fifo of actions to be performed by
//! @param[in] _tapActionQueue  Pointer to fifo of actions to be performed by
//!                             the JTAG interface
//!                             the JTAG interface
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
DebugUnitSC::DebugUnitSC (sc_module_name        name,
DebugUnitSC::DebugUnitSC(sc_module_name name, sc_fifo < TapAction * >*_tapActionQueue):
                          sc_fifo<TapAction *> *_tapActionQueue) :
 
  sc_module (name),
  sc_module (name),
  tapActionQueue (_tapActionQueue),
  tapActionQueue (_tapActionQueue),
  stallState (UNKNOWN),
stallState(UNKNOWN), currentScanChain(OR1K_SC_UNDEF)
  currentScanChain (OR1K_SC_UNDEF)
 
{
{
#ifdef NOCACHE
#ifdef NOCACHE
  npcCacheIsValid = false;              // Always cache NPC
  npcCacheIsValid = false;              // Always cache NPC
#else
#else
  sprCache = new SprCache ();
  sprCache = new SprCache ();
  memCache = new MemCache ();
  memCache = new MemCache ();
#endif
#endif
 
 
}       // DebugUnitSC ()
}       // DebugUnitSC ()
 
 
 
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//! Destructor
//! Destructor
 
 
//! Free up data structures
//! Free up data structures
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
Line 91... Line 86...
  delete  sprCache;
  delete  sprCache;
#endif
#endif
 
 
}       // ~DebugUnitSC
}       // ~DebugUnitSC
 
 
 
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//! Reset the Debug Unit
//! Reset the Debug Unit
 
 
//! This is just a reset of the JTAG. It is quite possible to reset the debug
//! This is just a reset of the JTAG. It is quite possible to reset the debug
//! unit without resetting the whole target.
//! unit without resetting the whole target.
Line 116... Line 110...
  delete resetAction;
  delete resetAction;
  delete done;
  delete done;
 
 
}       // resetDebugUnit ()
}       // resetDebugUnit ()
 
 
 
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//! Reset the processor
//! Reset the processor
 
 
//! Read the RISCOP register, OR in the reset bit and write it back.
//! Read the RISCOP register, OR in the reset bit and write it back.
 
 
//! After reset, the processor is known to be unstalled.
//! After reset, the processor is known to be unstalled.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void
void DebugUnitSC::reset()
DebugUnitSC::reset ()
 
{
{
  writeRiscop (readRiscop () | RISCOP_RESET);
  writeRiscop (readRiscop () | RISCOP_RESET);
  stallState = UNKNOWN;
  stallState = UNKNOWN;
 
 
}       // reset ()
}       // reset ()
 
 
 
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//! Stall the processor
//! Stall the processor
 
 
//! Read the RISCOP register, OR in the stall bit and write it back.
//! Read the RISCOP register, OR in the stall bit and write it back.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void
void DebugUnitSC::stall()
DebugUnitSC::stall ()
 
{
{
  writeRiscop (/*readRiscop () |*/ RISCOP_STALL);
  writeRiscop (/*readRiscop () |*/ RISCOP_STALL);
  stallState = STALLED;
  stallState = STALLED;
 
 
}       // stall ()
}       // stall ()
 
 
 
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//! Unstall the processor
//! Unstall the processor
 
 
//! Read the RISCOP register, AND out the stall bit and write it back. After
//! Read the RISCOP register, AND out the stall bit and write it back. After
//! this the NPC cache will be invalid.
//! this the NPC cache will be invalid.
 
 
//! @note Don't be tempted to read back for confirmation. Single stepping
//! @note Don't be tempted to read back for confirmation. Single stepping
//!       will already have stalled the processor again!
//!       will already have stalled the processor again!
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void
void DebugUnitSC::unstall()
DebugUnitSC::unstall ()
 
{
{
  writeRiscop (/*readRiscop () & ~RISCOP_STALL*/ 0);
  writeRiscop (/*readRiscop () & ~RISCOP_STALL*/ 0);
  stallState  = UNKNOWN;
  stallState  = UNKNOWN;
 
 
#ifdef NOCACHE
#ifdef NOCACHE
Line 172... Line 160...
  memCache->clear ();
  memCache->clear ();
#endif
#endif
 
 
}       // unstall ()
}       // unstall ()
 
 
 
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//! Report if the processor is stalled.
//! Report if the processor is stalled.
 
 
//! A stalled processor cannot spontaneously "unstall", so if the stallState
//! A stalled processor cannot spontaneously "unstall", so if the stallState
//! flag is STALLED, that value is returned. Otherwise the target is
//! flag is STALLED, that value is returned. Otherwise the target is
//! interrogated to determine the status.
//! interrogated to determine the status.
 
 
//! @return  TRUE if the processor is known to be stalled
//! @return  TRUE if the processor is known to be stalled
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
bool
bool DebugUnitSC::isStalled()
DebugUnitSC::isStalled ()
 
{
 
  if (STALLED == stallState)
 
    {
    {
 
        if (STALLED == stallState) {
      return  true;
      return  true;
    }
    }
 
 
  uint32_t  riscop = readRiscop ();
  uint32_t  riscop = readRiscop ();
  /* For some reason the reset bit is skipped over somewhere, so we should
  /* For some reason the reset bit is skipped over somewhere, so we should
Line 201... Line 186...
 
 
  return  STALLED == stallState;
  return  STALLED == stallState;
 
 
}       // isStalled ()
}       // isStalled ()
 
 
 
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//! Read the value of an OpenRISC 1000 Special Purpose Register
//! Read the value of an OpenRISC 1000 Special Purpose Register
 
 
//! First see if we have the value in the cache, and if so return
//! First see if we have the value in the cache, and if so return
//! it. Otherwise, select the RISC_DEBUG scan chain and read from JTAG,
//! it. Otherwise, select the RISC_DEBUG scan chain and read from JTAG,
Line 213... Line 197...
 
 
//! @param[in]  sprNum  The SPR to read
//! @param[in]  sprNum  The SPR to read
 
 
//! @return  The value of the SPR
//! @return  The value of the SPR
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
uint32_t
uint32_t DebugUnitSC::readSpr(uint16_t sprNum)
DebugUnitSC::readSpr (uint16_t  sprNum)
 
{
{
  uint32_t  cachedValue;
  uint32_t  cachedValue;
 
 
#ifdef NOCACHE
#ifdef NOCACHE
  // Always check NPC cache
  // Always check NPC cache
  if ((STALLED == stallState) && (sprNum == SPR_NPC) && npcCacheIsValid)
        if ((STALLED == stallState) && (sprNum == SPR_NPC) && npcCacheIsValid) {
    {
 
      return  npcCachedValue;
      return  npcCachedValue;
    }
    }
#else
#else
  // Use any cached value if we are stalled.
  // Use any cached value if we are stalled.
  if ((STALLED == stallState) && sprCache->read (sprNum, cachedValue))
        if ((STALLED == stallState) && sprCache->read(sprNum, cachedValue)) {
    {
 
      return  cachedValue;              // Already there, no more to do
      return  cachedValue;              // Already there, no more to do
    }
    }
#endif
#endif
 
 
  // Read the value
  // Read the value
  selectDebugModule (OR1K_SC_CPU0);
  selectDebugModule (OR1K_SC_CPU0);
  cachedValue = readJtagReg (sprNum);
  cachedValue = readJtagReg (sprNum);
 
 
#ifdef NOCACHE
#ifdef NOCACHE
  // Always update the NPC cache
  // Always update the NPC cache
  if ((STALLED == stallState) && (sprNum == SPR_NPC))
        if ((STALLED == stallState) && (sprNum == SPR_NPC)) {
    {
 
      npcCachedValue  = cachedValue;
      npcCachedValue  = cachedValue;
      npcCacheIsValid = true;
      npcCacheIsValid = true;
    }
    }
#else
#else
  // Update the cache if we are stalled
  // Update the cache if we are stalled
  if (STALLED == stallState)
        if (STALLED == stallState) {
    {
 
      sprCache->write (sprNum, cachedValue, sprNum == SPR_NPC);
      sprCache->write (sprNum, cachedValue, sprNum == SPR_NPC);
    }
    }
#endif
#endif
 
 
  return  cachedValue;
  return  cachedValue;
 
 
}       // readSpr ()
}       // readSpr ()
 
 
 
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//! Write the value of an OpenRISC 1000 Special Purpose Register
//! Write the value of an OpenRISC 1000 Special Purpose Register
 
 
//! First look to see if we are stalled and the value is cached. If the value
//! First look to see if we are stalled and the value is cached. If the value
//! has not changed, then we need to no more. Otherwise cache the value prior
//! has not changed, then we need to no more. Otherwise cache the value prior
Line 268... Line 246...
//! Select the RISC_DEBUG scan chain and write to JTAG
//! Select the RISC_DEBUG scan chain and write to JTAG
 
 
//! @param[in] sprNum  The SPR to write
//! @param[in] sprNum  The SPR to write
//! @param[in] value   The value to write
//! @param[in] value   The value to write
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void
void DebugUnitSC::writeSpr(uint16_t sprNum, uint32_t value)
DebugUnitSC::writeSpr (uint16_t  sprNum,
 
                       uint32_t  value)
 
{
{
#ifdef NOCACHE
#ifdef NOCACHE
  // Always cache the NPC
  // Always cache the NPC
  if ((STALLED == stallState) && (SPR_NPC == sprNum))
        if ((STALLED == stallState) && (SPR_NPC == sprNum)) {
    {
 
      // Have we already cached this NPC value?
      // Have we already cached this NPC value?
      if (npcCacheIsValid && (value == npcCachedValue))
                if (npcCacheIsValid && (value == npcCachedValue)) {
        {
 
          return;
          return;
        }
                } else {
      else
 
        {
 
          npcCachedValue  = value;
          npcCachedValue  = value;
          npcCacheIsValid = true;
          npcCacheIsValid = true;
        }
        }
    }
    }
#else
#else
  if (STALLED == stallState)
        if (STALLED == stallState) {
    {
 
      // Have we already cached this value?
      // Have we already cached this value?
      uint32_t  cachedValue;
      uint32_t  cachedValue;
      if (sprCache->read (sprNum, cachedValue) &&
      if (sprCache->read (sprNum, cachedValue) &&
          (value == cachedValue))
                    (value == cachedValue)) {
        {
 
          return;                               // Already there, no more to do
          return;                               // Already there, no more to do
        }
                } else {
      else
 
        {
 
          sprCache->write (sprNum, value, sprNum == SPR_NPC);
          sprCache->write (sprNum, value, sprNum == SPR_NPC);
        }
        }
    }
    }
#endif
#endif
 
 
Line 310... Line 278...
  selectDebugModule (OR1K_SC_CPU0);
  selectDebugModule (OR1K_SC_CPU0);
  writeJtagReg (sprNum, value);
  writeJtagReg (sprNum, value);
 
 
}       // writeSpr ()
}       // writeSpr ()
 
 
 
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//! AND the contents of an SPR with a value
//! AND the contents of an SPR with a value
 
 
//! A convenience combination of read and write
//! A convenience combination of read and write
 
 
//! @param[in] sprNum  The SPR to write
//! @param[in] sprNum  The SPR to write
//! @param[in] value   The value to AND into the register
//! @param[in] value   The value to AND into the register
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void
void DebugUnitSC::andSpr(uint16_t sprNum, uint32_t value)
DebugUnitSC::andSpr (uint16_t  sprNum,
 
                     uint32_t  value)
 
{
{
  writeSpr (sprNum, readSpr (sprNum) & value);
  writeSpr (sprNum, readSpr (sprNum) & value);
 
 
}       // andSpr ()
}       // andSpr ()
 
 
 
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//! OR the contents of an SPR with a value
//! OR the contents of an SPR with a value
 
 
//! A convenience combination of read and write
//! A convenience combination of read and write
 
 
//! @param[in] sprNum  The SPR to write
//! @param[in] sprNum  The SPR to write
//! @param[in] value   The value to OR into the register
//! @param[in] value   The value to OR into the register
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void
void DebugUnitSC::orSpr(uint16_t sprNum, uint32_t value)
DebugUnitSC::orSpr (uint16_t  sprNum,
 
                   uint32_t  value)
 
{
{
  writeSpr (sprNum, readSpr (sprNum) | value);
  writeSpr (sprNum, readSpr (sprNum) | value);
 
 
}       // orSpr ()
}       // orSpr ()
 
 
 
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//! Read a 32-bit word from the OpenRISC 1000 memory
//! Read a 32-bit word from the OpenRISC 1000 memory
 
 
//! Select the WISHBONE scan chain, then write the register. The data is in
//! Select the WISHBONE scan chain, then write the register. The data is in
//! model endianness and passed on without modification.
//! model endianness and passed on without modification.
Line 357... Line 318...
 
 
//! @param[in] addr  The address to read from
//! @param[in] addr  The address to read from
 
 
//! @return  The 32-bit value read
//! @return  The 32-bit value read
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
uint32_t
uint32_t DebugUnitSC::readMem32(uint32_t addr)
DebugUnitSC::readMem32 (uint32_t  addr)
 
{
{
  uint32_t  cachedValue;
  uint32_t  cachedValue;
 
 
#ifndef NOCACHE
#ifndef NOCACHE
  // Use any cached value if we are stalled.
  // Use any cached value if we are stalled.
  if ((STALLED == stallState) && memCache->read (addr, cachedValue))
        if ((STALLED == stallState) && memCache->read(addr, cachedValue)) {
    {
 
      return  cachedValue;              // Already there, no more to do
      return  cachedValue;              // Already there, no more to do
    }
    }
#endif
#endif
 
 
  // Read the value
  // Read the value
  selectDebugModule (OR1K_SC_WISHBONE);
  selectDebugModule (OR1K_SC_WISHBONE);
  cachedValue = readJtagReg (addr);
  cachedValue = readJtagReg (addr);
 
 
#ifndef NOCACHE
#ifndef NOCACHE
  // Update the cache if we are stalled
  // Update the cache if we are stalled
  if (STALLED == stallState)
        if (STALLED == stallState) {
    {
 
      memCache->write (addr, cachedValue);
      memCache->write (addr, cachedValue);
    }
    }
#endif
#endif
 
 
  return  cachedValue;
  return  cachedValue;
 
 
}       // readMem32 ()
}       // readMem32 ()
 
 
 
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//! Write a 32-bit word to the OpenRISC 1000 memory
//! Write a 32-bit word to the OpenRISC 1000 memory
 
 
//! Select the WISHBONE scan chain, then write the register. The data is in
//! Select the WISHBONE scan chain, then write the register. The data is in
//! model endianness and passed on without modification.
//! model endianness and passed on without modification.
Line 401... Line 358...
//! @param[in] value  The 32-bit value to write
//! @param[in] value  The 32-bit value to write
 
 
//! @return  True if the write was successful. For now all writes are
//! @return  True if the write was successful. For now all writes are
//           successful.
//           successful.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
bool
bool DebugUnitSC::writeMem32(uint32_t addr, uint32_t value)
DebugUnitSC::writeMem32 (uint32_t  addr,
 
                         uint32_t  value)
 
{
{
#ifndef NOCACHE
#ifndef NOCACHE
  if (STALLED == stallState)
        if (STALLED == stallState) {
    {
 
      // Have we already cached this value?
      // Have we already cached this value?
      uint32_t  cachedValue;
      uint32_t  cachedValue;
      if (memCache->read (addr, cachedValue) &&
                if (memCache->read(addr, cachedValue) && (value == cachedValue)) {
          (value == cachedValue))
 
        {
 
          return  true;                         // Already there, no more to do
          return  true;                         // Already there, no more to do
        }
                } else {
      else
 
        {
 
          memCache->write (addr, value);        // Write for the future
          memCache->write (addr, value);        // Write for the future
        }
        }
    }
    }
#endif
#endif
 
 
Line 430... Line 380...
 
 
  return  true;
  return  true;
 
 
}       // writeMem32 ()
}       // writeMem32 ()
 
 
 
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//! Read a byte from the OpenRISC 1000 main memory
//! Read a byte from the OpenRISC 1000 main memory
 
 
//! All we can get are 32-bits words, so we have to unpick the value.
//! All we can get are 32-bits words, so we have to unpick the value.
 
 
Line 447... Line 396...
//! @note Read bytes from memory mapped devices at your peril!
//! @note Read bytes from memory mapped devices at your peril!
 
 
//! @param[in] addr  The address to read from
//! @param[in] addr  The address to read from
//! @return  The byte read
//! @return  The byte read
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
uint8_t
uint8_t DebugUnitSC::readMem8(uint32_t addr)
DebugUnitSC::readMem8 (uint32_t  addr)
 
{
{
  uint32_t  word   = Utils::ttohl (readMem32 (addr & 0xfffffffc));
  uint32_t  word   = Utils::ttohl (readMem32 (addr & 0xfffffffc));
  uint8_t  *bytes  = (uint8_t *)(&word);
  uint8_t  *bytes  = (uint8_t *)(&word);
  int       offset = addr & 0x3;
  int       offset = addr & 0x3;
 
 
  return  bytes[offset];
  return  bytes[offset];
 
 
}       // readMem8 ()
}       // readMem8 ()
 
 
 
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//! Write a byte to the OpenRISC 1000 main memory
//! Write a byte to the OpenRISC 1000 main memory
 
 
//! All we can get are 32-bits words, so we have to read the current value and
//! All we can get are 32-bits words, so we have to read the current value and
//! construct the new value to write back.
//! construct the new value to write back.
Line 479... Line 426...
//! @param[in] value  The byte to write
//! @param[in] value  The byte to write
 
 
//! @return  True if the write was successful. For now all writes are
//! @return  True if the write was successful. For now all writes are
//           successful.
//           successful.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
bool
bool DebugUnitSC::writeMem8(uint32_t addr, uint8_t value)
DebugUnitSC::writeMem8 (uint32_t  addr,
 
                        uint8_t   value)
 
{
{
  uint32_t  currWord  = Utils::ttohl (readMem32 (addr & 0xfffffffc));
  uint32_t  currWord  = Utils::ttohl (readMem32 (addr & 0xfffffffc));
  uint8_t  *currBytes = (uint8_t *)(&currWord);
  uint8_t  *currBytes = (uint8_t *)(&currWord);
  int       offset    = addr & 0x3;
  int       offset    = addr & 0x3;
 
 
Line 493... Line 438...
 
 
  return  writeMem32 (addr & 0xfffffffc, Utils::htotl (currWord));
  return  writeMem32 (addr & 0xfffffffc, Utils::htotl (currWord));
 
 
}       // writeMem8 ()
}       // writeMem8 ()
 
 
 
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//! Get the debug interface CPU0 control register value
//! Get the debug interface CPU0 control register value
 
 
//! @return  The value in the RISCOP register
//! @return  The value in the RISCOP register
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
uint32_t
uint32_t DebugUnitSC::readRiscop()
DebugUnitSC::readRiscop ()
 
{
{
  selectDebugModule (OR1K_SC_CPU0);
  selectDebugModule (OR1K_SC_CPU0);
 
 
  int  drLen;                   // Size of the data register
  int  drLen;                   // Size of the data register
 
 
Line 526... Line 469...
 
 
  // Allocate a SystemC completion event
  // Allocate a SystemC completion event
  sc_event *done  = new sc_event();
  sc_event *done  = new sc_event();
 
 
  // Loop until status is OK and CRCs match.
  // Loop until status is OK and CRCs match.
  do
        do {
    {
                TapActionDRScan *dRScan =
      TapActionDRScan *dRScan = new TapActionDRScan (done, dRegIn, drLen);
                    new TapActionDRScan(done, dRegIn, drLen);
      tapActionQueue->write (dRScan);
      tapActionQueue->write (dRScan);
      wait (*done);
      wait (*done);
      dRScan->getDRegOut (dRegOut);
      dRScan->getDRegOut (dRegOut);
      delete dRScan;
      delete dRScan;
      status_ret = unpackBits (dRegOut,1+4+32+52,4);
      status_ret = unpackBits (dRegOut,1+4+32+52,4);
      calc_recv_crc = crc32(dRegOut,52+4,1+4+32);
      calc_recv_crc = crc32(dRegOut,52+4,1+4+32);
      recv_crc = BITREV(unpackBits (dRegOut,1+4+32+52+4,32),32);
                recv_crc =
 
                    BITREV(unpackBits(dRegOut, 1 + 4 + 32 + 52 + 4, 32), 32);
    }
    }
  while ((0 != status_ret) || ( calc_recv_crc != recv_crc));
  while ((0 != status_ret) || ( calc_recv_crc != recv_crc));
 
 
  // All done
  // All done
  uint32_t  res = BITREV(unpackBits (dRegOut, (1+4+32),2),2);
  uint32_t  res = BITREV(unpackBits (dRegOut, (1+4+32),2),2);
Line 548... Line 492...
  delete [] dRegOut;
  delete [] dRegOut;
  delete  done;
  delete  done;
  return  res;
  return  res;
}       // readRiscop ()
}       // readRiscop ()
 
 
 
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//! Set the RISCOP control register
//! Set the RISCOP control register
 
 
//! Convenience function. Select the REGISTER scan chain, write the new value.
//! Convenience function. Select the REGISTER scan chain, write the new value.
 
 
//! @param[in] value  The value to write into the RISCOP register
//! @param[in] value  The value to write into the RISCOP register
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void
void DebugUnitSC::writeRiscop(uint32_t value)
DebugUnitSC::writeRiscop (uint32_t  value)
 
{
{
  selectDebugModule (OR1K_SC_CPU0);
  selectDebugModule (OR1K_SC_CPU0);
 
 
  int  drLen;                   // Size of the data register
  int  drLen;                   // Size of the data register
 
 
Line 586... Line 528...
 
 
  // Allocate a SystemC completion event
  // Allocate a SystemC completion event
  sc_event *done  = new sc_event();
  sc_event *done  = new sc_event();
 
 
  // Loop until status is OK and CRCs match.
  // Loop until status is OK and CRCs match.
  do
        do {
    {
                TapActionDRScan *dRScan =
      TapActionDRScan *dRScan = new TapActionDRScan (done, dRegIn, drLen);
                    new TapActionDRScan(done, dRegIn, drLen);
      tapActionQueue->write (dRScan);
      tapActionQueue->write (dRScan);
      wait (*done);
      wait (*done);
      dRScan->getDRegOut (dRegOut);
      dRScan->getDRegOut (dRegOut);
      delete dRScan;
      delete dRScan;
      status_ret = unpackBits (dRegOut,1+4+32+52,4);
      status_ret = unpackBits (dRegOut,1+4+32+52,4);
      calc_recv_crc = crc32(dRegOut,4,1+4+52+32);
      calc_recv_crc = crc32(dRegOut,4,1+4+52+32);
      recv_crc = BITREV(unpackBits (dRegOut,1+4+52+32+4,32),32);
                recv_crc =
 
                    BITREV(unpackBits(dRegOut, 1 + 4 + 52 + 32 + 4, 32), 32);
    }
    }
  while ((0 != status_ret) || ( calc_recv_crc != recv_crc));
  while ((0 != status_ret) || ( calc_recv_crc != recv_crc));
 
 
  delete [] dRegIn;
  delete [] dRegIn;
  delete [] dRegOut;
  delete [] dRegOut;
  delete  done;
  delete  done;
 
 
}       // writeRiscop ()
}       // writeRiscop ()
 
 
 
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//! Select a module attached to the debug module
//! Select a module attached to the debug module
 
 
//! @note Must be called from a SystemC thread, because of the use of wait()
//! @note Must be called from a SystemC thread, because of the use of wait()
 
 
//! @param[in] chain  The desired module
//! @param[in] chain  The desired module
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void
void DebugUnitSC::selectDebugModule(int module)
DebugUnitSC::selectDebugModule (int module)
 
{
{
 
 
  if (module == currentScanChain)
        if (module == currentScanChain) {
    {
 
      return;
      return;
    }
        } else {
  else
 
    {
 
      currentScanChain = module;
      currentScanChain = module;
    }
    }
 
 
  sc_event        *done = new sc_event();
  sc_event        *done = new sc_event();
  TapActionIRScan *iRScan;
  TapActionIRScan *iRScan;
Line 643... Line 581...
  uint64_t *dRegIn  = new uint64_t [(DUSEL_DR_LEN + 63) / 64];
  uint64_t *dRegIn  = new uint64_t [(DUSEL_DR_LEN + 63) / 64];
  uint64_t *dRegOut = new uint64_t [(DUSEL_DR_LEN + 63) / 64];
  uint64_t *dRegOut = new uint64_t [(DUSEL_DR_LEN + 63) / 64];
 
 
  clearBits (dRegIn, DUSEL_DR_LEN);
  clearBits (dRegIn, DUSEL_DR_LEN);
  packBits (dRegIn, DUSEL_SEL_OFF, DUSEL_SEL_LEN, 0x1);
  packBits (dRegIn, DUSEL_SEL_OFF, DUSEL_SEL_LEN, 0x1);
  packBits (dRegIn, DUSEL_OPCODE_OFF, DUSEL_OPCODE_LEN, bit_reverse_data(module,4));
        packBits(dRegIn, DUSEL_OPCODE_OFF, DUSEL_OPCODE_LEN,
 
                 bit_reverse_data(module, 4));
  uint32_t crc32_send = crc32 (dRegIn, DUSEL_CRC_OFF, 0);
  uint32_t crc32_send = crc32 (dRegIn, DUSEL_CRC_OFF, 0);
  packBits (dRegIn, DUSEL_CRC_OFF, DUSEL_CRC_LEN, bit_reverse_data(crc32_send,32) );
        packBits(dRegIn, DUSEL_CRC_OFF, DUSEL_CRC_LEN,
 
                 bit_reverse_data(crc32_send, 32));
  uint32_t calc_recv_crc = 0, recv_crc, status_ret;
  uint32_t calc_recv_crc = 0, recv_crc, status_ret;
  // Loop until status is OK and CRCs match.
  // Loop until status is OK and CRCs match.
  do
        do {
    {
                TapActionDRScan *dRScan =
      TapActionDRScan *dRScan = new TapActionDRScan (done, dRegIn, DUSEL_DR_LEN);
                    new TapActionDRScan(done, dRegIn, DUSEL_DR_LEN);
      tapActionQueue->write (dRScan);
      tapActionQueue->write (dRScan);
      wait (*done);
      wait (*done);
      dRScan->getDRegOut (dRegOut);
      dRScan->getDRegOut (dRegOut);
      delete dRScan;
      delete dRScan;
      status_ret = unpackBits (dRegOut, DUSEL_RESP_STATUS_OFF, DUSEL_RESP_STATUS_LEN);
                status_ret =
      calc_recv_crc = crc32(dRegOut, DUSEL_RESP_STATUS_LEN, DUSEL_RESP_STATUS_OFF);
                    unpackBits(dRegOut, DUSEL_RESP_STATUS_OFF,
      recv_crc = bit_reverse_data(unpackBits (dRegOut, DUSEL_RESP_CRC_OFF, DUSEL_RESP_CRC_LEN),32);
                               DUSEL_RESP_STATUS_LEN);
 
                calc_recv_crc =
 
                    crc32(dRegOut, DUSEL_RESP_STATUS_LEN,
 
                          DUSEL_RESP_STATUS_OFF);
 
                recv_crc =
 
                    bit_reverse_data(unpackBits
 
                                     (dRegOut, DUSEL_RESP_CRC_OFF,
 
                                      DUSEL_RESP_CRC_LEN), 32);
    }
    }
  while ((0 != status_ret) || ( calc_recv_crc != recv_crc));
  while ((0 != status_ret) || ( calc_recv_crc != recv_crc));
 
 
  delete [] dRegIn;
  delete [] dRegIn;
  delete [] dRegOut;
  delete [] dRegOut;
  delete done;
  delete done;
 
 
}       // selectDebugModule()
}       // selectDebugModule()
 
 
 
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//! Read a 32-bit value via the debug interface
//! Read a 32-bit value via the debug interface
 
 
//! @note Must be called from a SystemC thread, because of the use of wait()
//! @note Must be called from a SystemC thread, because of the use of wait()
 
 
//! @param[in] addr  The address of the register
//! @param[in] addr  The address of the register
 
 
//! @return  The register value read
//! @return  The register value read
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
uint32_t
uint32_t DebugUnitSC::readJtagReg(uint32_t addr)
DebugUnitSC::readJtagReg (uint32_t  addr)
 
{
{
  int  drLen;                   // Size of the data register
  int  drLen;                   // Size of the data register
 
 
  uint32_t calc_recv_crc = 0, recv_crc, status_ret;
  uint32_t calc_recv_crc = 0, recv_crc, status_ret;
 
 
Line 705... Line 650...
 
 
  // Allocate a SystemC completion event
  // Allocate a SystemC completion event
  sc_event *done  = new sc_event();
  sc_event *done  = new sc_event();
 
 
  // Loop until status is OK and CRCs match.
  // Loop until status is OK and CRCs match.
  do
        do {
    {
                TapActionDRScan *dRScan =
      TapActionDRScan *dRScan = new TapActionDRScan (done, dRegIn, 125);
                    new TapActionDRScan(done, dRegIn, 125);
      tapActionQueue->write (dRScan);
      tapActionQueue->write (dRScan);
      wait (*done);
      wait (*done);
      dRScan->getDRegOut (dRegOut);
      dRScan->getDRegOut (dRegOut);
      delete dRScan;
      delete dRScan;
      status_ret = unpackBits (dRegOut,1+4+4+32+16+32,4);
      status_ret = unpackBits (dRegOut,1+4+4+32+16+32,4);
      calc_recv_crc = crc32(dRegOut,4,1+4+4+32+16+32);
      calc_recv_crc = crc32(dRegOut,4,1+4+4+32+16+32);
      recv_crc = BITREV(unpackBits (dRegOut,1+4+4+32+16+32+4,32),32);
                recv_crc =
 
                    BITREV(unpackBits
 
                           (dRegOut, 1 + 4 + 4 + 32 + 16 + 32 + 4, 32), 32);
    }
    }
  while ((0 != status_ret) || ( calc_recv_crc != recv_crc));
  while ((0 != status_ret) || ( calc_recv_crc != recv_crc));
 
 
  clearBits (dRegIn, drLen);
  clearBits (dRegIn, drLen);
  packBits (dRegIn, 0, 1, 0);
  packBits (dRegIn, 0, 1, 0);
Line 726... Line 673...
  crc32_send = crc32 (dRegIn,1+4,0);
  crc32_send = crc32 (dRegIn,1+4,0);
  packBits (dRegIn, 1+4, 32, BITREV(crc32_send,32)); // CRC
  packBits (dRegIn, 1+4, 32, BITREV(crc32_send,32)); // CRC
 
 
  uint32_t  result;
  uint32_t  result;
  // Loop until status is OK and CRCs match.
  // Loop until status is OK and CRCs match.
  do
        do {
    {
                TapActionDRScan *dRScan = new TapActionDRScan(done, dRegIn,
      TapActionDRScan *dRScan = new TapActionDRScan (done, dRegIn, (1+4+32+36+((3+1)*8)));
                                                              (1 + 4 + 32 + 36 +
 
                                                               ((3 + 1) * 8)));
      tapActionQueue->write (dRScan);
      tapActionQueue->write (dRScan);
      wait (*done);
      wait (*done);
      dRScan->getDRegOut (dRegOut);
      dRScan->getDRegOut (dRegOut);
      delete dRScan;
      delete dRScan;
      status_ret = BITREV(unpackBits (dRegOut,1+4+32+((3+1)*8),4),4);
                status_ret =
      if (status_ret)
                    BITREV(unpackBits(dRegOut, 1 + 4 + 32 + ((3 + 1) * 8), 4),
        {
                           4);
          printf("readJtagReg(): Addr: 0x%.8x Status err: 0x%x\n",addr,status_ret);
                if (status_ret) {
 
                        printf("readJtagReg(): Addr: 0x%.8x Status err: 0x%x\n",
 
                               addr, status_ret);
          result = 0;
          result = 0;
          break;
          break;
        }
        }
      calc_recv_crc = crc32(dRegOut,((3+1)*8)+4,1+4+32);
      calc_recv_crc = crc32(dRegOut,((3+1)*8)+4,1+4+32);
      recv_crc = BITREV(unpackBits (dRegOut,1+4+32+((3+1)*8)+4,32),32);
                recv_crc =
      result = BITREV(unpackBits (dRegOut, (1+4+32), ((3+1)*8)),32);
                    BITREV(unpackBits
 
                           (dRegOut, 1 + 4 + 32 + ((3 + 1) * 8) + 4, 32), 32);
 
                result =
 
                    BITREV(unpackBits(dRegOut, (1 + 4 + 32), ((3 + 1) * 8)),
 
                           32);
 
 
    }
    }
  while ((0 != status_ret) || ( calc_recv_crc != recv_crc));
  while ((0 != status_ret) || ( calc_recv_crc != recv_crc));
 
 
  // All done
  // All done
Line 756... Line 710...
  delete  done;
  delete  done;
  return  result;
  return  result;
 
 
}       // readJtagReg ()
}       // readJtagReg ()
 
 
 
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//! Write a 32-bit value via the debug interface
//! Write a 32-bit value via the debug interface
 
 
//! @note Must be called from a SystemC thread, because of the use of wait()
//! @note Must be called from a SystemC thread, because of the use of wait()
 
 
//! @param[in] addr  The address of the register
//! @param[in] addr  The address of the register
//! @param[in] data  The register data to write
//! @param[in] data  The register data to write
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void
void DebugUnitSC::writeJtagReg(uint32_t addr, uint32_t data)
DebugUnitSC::writeJtagReg (uint32_t  addr,
 
                           uint32_t  data)
 
{
{
  int  drLen;                   // Size of the data register
  int  drLen;                   // Size of the data register
 
 
  uint32_t calc_recv_crc = 0, recv_crc, status_ret;
  uint32_t calc_recv_crc = 0, recv_crc, status_ret;
 
 
Line 794... Line 745...
 
 
  // Allocate a SystemC completion event
  // Allocate a SystemC completion event
  sc_event *done  = new sc_event();
  sc_event *done  = new sc_event();
 
 
  // Loop until status is OK and CRCs match.
  // Loop until status is OK and CRCs match.
  do
        do {
    {
                TapActionDRScan *dRScan =
      TapActionDRScan *dRScan = new TapActionDRScan (done, dRegIn, 125);
                    new TapActionDRScan(done, dRegIn, 125);
      tapActionQueue->write (dRScan);
      tapActionQueue->write (dRScan);
      wait (*done);
      wait (*done);
      dRScan->getDRegOut (dRegOut);
      dRScan->getDRegOut (dRegOut);
      delete dRScan;
      delete dRScan;
      status_ret = unpackBits (dRegOut,1+4+4+32+16+32,4);
      status_ret = unpackBits (dRegOut,1+4+4+32+16+32,4);
      calc_recv_crc = crc32(dRegOut,4,1+4+4+32+16+32);
      calc_recv_crc = crc32(dRegOut,4,1+4+4+32+16+32);
      recv_crc = BITREV(unpackBits (dRegOut,1+4+4+32+16+32+4,32),32);
                recv_crc =
 
                    BITREV(unpackBits
 
                           (dRegOut, 1 + 4 + 4 + 32 + 16 + 32 + 4, 32), 32);
    }
    }
  while ((0 != status_ret) || ( calc_recv_crc != recv_crc));
  while ((0 != status_ret) || ( calc_recv_crc != recv_crc));
 
 
  clearBits (dRegIn, drLen);
  clearBits (dRegIn, drLen);
  packBits (dRegIn, 0, 1, 0);
  packBits (dRegIn, 0, 1, 0);
Line 815... Line 768...
  packBits (dRegIn, 0+1+4, 32, BITREV(data,32)); // Add in data
  packBits (dRegIn, 0+1+4, 32, BITREV(data,32)); // Add in data
  crc32_send = crc32 (dRegIn,1+4+32,0);
  crc32_send = crc32 (dRegIn,1+4+32,0);
  packBits (dRegIn, 1+4+32, 32, BITREV(crc32_send,32)); // CRC
  packBits (dRegIn, 1+4+32, 32, BITREV(crc32_send,32)); // CRC
 
 
  // Loop until status is OK and CRCs match.
  // Loop until status is OK and CRCs match.
  do
        do {
    {
                TapActionDRScan *dRScan = new TapActionDRScan(done, dRegIn,
      TapActionDRScan *dRScan = new TapActionDRScan (done, dRegIn, (1+4+((3+1)*8)+32+36));
                                                              (1 + 4 +
 
                                                               ((3 + 1) * 8) +
 
                                                               32 + 36));
      tapActionQueue->write (dRScan);
      tapActionQueue->write (dRScan);
      wait (*done);
      wait (*done);
      dRScan->getDRegOut (dRegOut);
      dRScan->getDRegOut (dRegOut);
      delete dRScan;
      delete dRScan;
      status_ret = unpackBits (dRegOut,1+4+32+32,4);
      status_ret = unpackBits (dRegOut,1+4+32+32,4);
      calc_recv_crc = crc32(dRegOut,4,1+4+32+32);
      calc_recv_crc = crc32(dRegOut,4,1+4+32+32);
      recv_crc = BITREV(unpackBits (dRegOut,1+4+32+32+4,32),32);
                recv_crc =
 
                    BITREV(unpackBits(dRegOut, 1 + 4 + 32 + 32 + 4, 32), 32);
    }
    }
  while ((0 != status_ret) || ( calc_recv_crc != recv_crc));
  while ((0 != status_ret) || ( calc_recv_crc != recv_crc));
 
 
  delete [] dRegIn;
  delete [] dRegIn;
  delete [] dRegOut;
  delete [] dRegOut;
  delete  done;
  delete  done;
 
 
}       // writeJtagReg ()
}       // writeJtagReg ()
 
 
 
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//! Clear the bits in a data register
//! Clear the bits in a data register
 
 
//! We always clear whole 64-bit words, not just the minimum number of
//! We always clear whole 64-bit words, not just the minimum number of
//! bytes. It saves all sorts of confusion when debugging code.
//! bytes. It saves all sorts of confusion when debugging code.
Line 847... Line 802...
//!       array is large enough.
//!       array is large enough.
 
 
//! @param[in,out] regArray  The data register to clear
//! @param[in,out] regArray  The data register to clear
//! @param[in]     regBits  Size of the data register (in bits)
//! @param[in]     regBits  Size of the data register (in bits)
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void
void DebugUnitSC::clearBits(uint64_t regArray[], int regBits)
DebugUnitSC::clearBits (uint64_t  regArray[],
 
                        int       regBits)
 
{
{
  memset ((char *)regArray, 0, ((regBits + 63) / 64) * 8);
  memset ((char *)regArray, 0, ((regBits + 63) / 64) * 8);
 
 
}       // clearBits ()
}       // clearBits ()
 
 
 
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//! Set a bit field in a data register
//! Set a bit field in a data register
 
 
//! The field is cleared, the supplied value masked and then ored into the
//! The field is cleared, the supplied value masked and then ored into the
//! vector.
//! vector.
Line 870... Line 822...
//! @param[in,out] regArray     The data register
//! @param[in,out] regArray     The data register
//! @param[in]     fieldOffset  Start of the field (in bits)
//! @param[in]     fieldOffset  Start of the field (in bits)
//! @param[in]     fieldBits    Size of the field (in bits)
//! @param[in]     fieldBits    Size of the field (in bits)
//! @param[in]     fieldVal     Value to set in the field
//! @param[in]     fieldVal     Value to set in the field
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void
void DebugUnitSC::packBits(uint64_t regArray[],
DebugUnitSC::packBits (uint64_t  regArray[],
                           int fieldOffset, int fieldBits, uint64_t fieldVal)
                       int       fieldOffset,
 
                       int       fieldBits,
 
                       uint64_t  fieldVal)
 
{
{
  fieldVal &= (1ULL << fieldBits) - 1ULL;       // Mask the supplied value
  fieldVal &= (1ULL << fieldBits) - 1ULL;       // Mask the supplied value
 
 
  int  startWord =  fieldOffset / 64;
  int  startWord =  fieldOffset / 64;
  int  endWord   = (fieldOffset + fieldBits - 1) / 64;
  int  endWord   = (fieldOffset + fieldBits - 1) / 64;
Line 891... Line 840...
 
 
  regArray[startWord] &= ~startMask;
  regArray[startWord] &= ~startMask;
  regArray[startWord] |= fieldVal << fieldOffset;
  regArray[startWord] |= fieldVal << fieldOffset;
 
 
  // If we were all in one word, we can give up now.
  // If we were all in one word, we can give up now.
  if (startWord == endWord)
        if (startWord == endWord) {
    {
 
      return;
      return;
    }
    }
 
 
  // Deal with the endWord. Get enough bits for the mask. No need to shift
  // Deal with the endWord. Get enough bits for the mask. No need to shift
  // these up - they're always at the bottom of the word
  // these up - they're always at the bottom of the word
  int       bitsToDo = (fieldOffset + fieldBits) % 64;
  int       bitsToDo = (fieldOffset + fieldBits) % 64;
  uint64_t  endMask  = (1ULL << bitsToDo) - 1ULL;
  uint64_t  endMask  = (1ULL << bitsToDo) - 1ULL;
 
 
  regArray[endWord] &= ~endMask;
  regArray[endWord] &= ~endMask;
  regArray[endWord] |= fieldVal >> (fieldBits - bitsToDo);
  regArray[endWord] |= fieldVal >> (fieldBits - bitsToDo);
 
 
}       // packBits ()
}       // packBits ()
 
 
 
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//! Extract a bit field from a data register
//! Extract a bit field from a data register
 
 
//! The field is cleared, the supplied value masked and then ored into the
//! The field is cleared, the supplied value masked and then ored into the
//! vector.
//! vector.
Line 923... Line 869...
//! @param[in]     fieldBits    Size of the field (in bits)
//! @param[in]     fieldBits    Size of the field (in bits)
 
 
//! @return  The value in the field
//! @return  The value in the field
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
uint64_t
uint64_t
DebugUnitSC::unpackBits (uint64_t  regArray[],
    DebugUnitSC::unpackBits(uint64_t regArray[], int fieldOffset, int fieldBits)
                         int       fieldOffset,
 
                         int       fieldBits)
 
{
{
  int  startWord = fieldOffset / 64;
  int  startWord = fieldOffset / 64;
  int  endWord   = (fieldOffset + fieldBits - 1) / 64;
  int  endWord   = (fieldOffset + fieldBits - 1) / 64;
 
 
  fieldOffset = fieldOffset % 64;               // Now refers to target word
  fieldOffset = fieldOffset % 64;               // Now refers to target word
Line 938... Line 882...
  // right place
  // right place
  uint64_t  startMask = ((1ULL << fieldBits) - 1ULL) << fieldOffset;
  uint64_t  startMask = ((1ULL << fieldBits) - 1ULL) << fieldOffset;
  uint64_t  res       = (regArray[startWord] & startMask) >> fieldOffset;
  uint64_t  res       = (regArray[startWord] & startMask) >> fieldOffset;
 
 
  // If we were all in one word, we can give up now.
  // If we were all in one word, we can give up now.
  if (startWord == endWord)
        if (startWord == endWord) {
    {
 
      res &= (1ULL << fieldBits) - 1ULL;        // Mask off any unwanted bits
      res &= (1ULL << fieldBits) - 1ULL;        // Mask off any unwanted bits
      return  res;
      return  res;
    }
    }
 
 
  // Deal with the endWord. Get enough bits for the mask. No need to shift
  // Deal with the endWord. Get enough bits for the mask. No need to shift
  // these up - they're always at the bottom of the word
  // these up - they're always at the bottom of the word
  int       bitsToDo = (fieldOffset + fieldBits) % 64;
  int       bitsToDo = (fieldOffset + fieldBits) % 64;
  uint64_t  endMask  = (1ULL << bitsToDo) - 1ULL;
  uint64_t  endMask  = (1ULL << bitsToDo) - 1ULL;
 
 
Line 955... Line 897...
  res &= (1ULL << fieldBits) - 1ULL;            // Mask off any unwanted bits
  res &= (1ULL << fieldBits) - 1ULL;            // Mask off any unwanted bits
  return  res;
  return  res;
 
 
}       // unpackBits ()
}       // unpackBits ()
 
 
 
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//! Compute CRC-8-ATM
//! Compute CRC-8-ATM
 
 
//! The data is in an array of uint64_t, for which we use the first size bits
//! The data is in an array of uint64_t, for which we use the first size bits
//! to compute the CRC.
//! to compute the CRC.
Line 972... Line 913...
//!       is correct!
//!       is correct!
 
 
//! @param dataArray  The array of data whose CRC is desired
//! @param dataArray  The array of data whose CRC is desired
//! @param size       The number of bits in the data
//! @param size       The number of bits in the data
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
uint8_t
uint8_t DebugUnitSC::crc8(uint64_t dataArray[], int size)
DebugUnitSC::crc8 (uint64_t  dataArray[],
 
                   int       size)
 
{
{
  uint8_t    crc = 0;
  uint8_t    crc = 0;
 
 
  for (int  i = 0; i < size; i++)
        for (int i = 0; i < size; i++) {
    {
 
      uint8_t  d       = (dataArray[i / 64] >> (i % 64)) & 1;
      uint8_t  d       = (dataArray[i / 64] >> (i % 64)) & 1;
      uint8_t  oldCrc7 = (crc >> 7) & 1;
      uint8_t  oldCrc7 = (crc >> 7) & 1;
      uint8_t  oldCrc1 = (crc >> 1) & 1;
      uint8_t  oldCrc1 = (crc >> 1) & 1;
      uint8_t  oldCrc0 = (crc >> 0) & 1;
      uint8_t  oldCrc0 = (crc >> 0) & 1;
      uint8_t  newCrc2 = d ^ oldCrc1 ^ oldCrc7;         // Why d?
      uint8_t  newCrc2 = d ^ oldCrc1 ^ oldCrc7;         // Why d?
      uint8_t  newCrc1 = d ^ oldCrc0 ^ oldCrc7;         // Why d?
      uint8_t  newCrc1 = d ^ oldCrc0 ^ oldCrc7;         // Why d?
      uint8_t  newCrc0 = d ^ oldCrc7;
      uint8_t  newCrc0 = d ^ oldCrc7;
 
 
      crc = ((crc << 1) & 0xf8) | (newCrc2 << 2) | (newCrc1 << 1) | newCrc0;
                crc =
 
                    ((crc << 1) & 0xf8) | (newCrc2 << 2) | (newCrc1 << 1) |
 
                    newCrc0;
    }
    }
 
 
  return crc;
  return crc;
 
 
}       // crc8 ()
}       // crc8 ()
 
 
/* Crc of current read or written data.  */
/* Crc of current read or written data.  */
uint32_t crc_r, crc_w = 0;
uint32_t crc_r, crc_w = 0;
 
 
/* Generates new crc, sending in new bit input_bit */
/* Generates new crc, sending in new bit input_bit */
uint32_t
uint32_t DebugUnitSC::crc32(uint64_t dataArray[], int size, int offset)
DebugUnitSC::crc32(uint64_t dataArray[],
 
                   int size,
 
                   int offset)
 
{
{
  uint32_t crc = 0xffffffff;
  uint32_t crc = 0xffffffff;
  for (int  i = offset; i < size+offset; i++)
        for (int i = offset; i < size + offset; i++) {
    {
                uint32_t d =
      uint32_t d = ((dataArray[i / 64] >> (i % 64)) & 1) ? 0xfffffff : 0x0000000;
                    ((dataArray[i / 64] >> (i % 64)) & 1) ? 0xfffffff :
 
                    0x0000000;
      uint32_t crc_32 = ((crc >> 31)&1) ? 0xfffffff : 0x0000000;
      uint32_t crc_32 = ((crc >> 31)&1) ? 0xfffffff : 0x0000000;
      crc <<= 1;
      crc <<= 1;
      crc = crc ^ ((d ^ crc_32) & DBG_CRC32_POLY);
      crc = crc ^ ((d ^ crc_32) & DBG_CRC32_POLY);
    }
    }
 
 
  return crc;
  return crc;
}
}
 
 
uint32_t
uint32_t DebugUnitSC::bit_reverse_swar_2(uint32_t x)
DebugUnitSC::bit_reverse_swar_2(uint32_t x)
 
{
{
  return (((x&0xaaaaaaaa)>>1)|((x&0x55555555)<<1));
  return (((x&0xaaaaaaaa)>>1)|((x&0x55555555)<<1));
}
}
uint32_t
 
DebugUnitSC::bit_reverse_swar_4(uint32_t x)
uint32_t DebugUnitSC::bit_reverse_swar_4(uint32_t x)
{
{
  x=(((x&0xaaaaaaaa)>>1)|((x&0x55555555)<<1));
  x=(((x&0xaaaaaaaa)>>1)|((x&0x55555555)<<1));
  x=(((x&0xcccccccc)>>2)|((x&0x33333333)<<2));
  x=(((x&0xcccccccc)>>2)|((x&0x33333333)<<2));
  return x;
  return x;
}
}
uint32_t
 
DebugUnitSC::bit_reverse_swar_8(uint32_t x)
uint32_t DebugUnitSC::bit_reverse_swar_8(uint32_t x)
{
{
  x=(((x&0xaaaaaaaa)>>1)|((x&0x55555555)<<1));
  x=(((x&0xaaaaaaaa)>>1)|((x&0x55555555)<<1));
  x=(((x&0xcccccccc)>>2)|((x&0x33333333)<<2));
  x=(((x&0xcccccccc)>>2)|((x&0x33333333)<<2));
  x=(((x&0xf0f0f0f0)>>4)|((x&0x0f0f0f0f)<<4));
  x=(((x&0xf0f0f0f0)>>4)|((x&0x0f0f0f0f)<<4));
  return x;
  return x;
}
}
uint32_t
 
DebugUnitSC::bit_reverse_swar_16(uint32_t x)
uint32_t DebugUnitSC::bit_reverse_swar_16(uint32_t x)
{
{
  x=(((x&0xaaaaaaaa)>>1)|((x&0x55555555)<<1));
  x=(((x&0xaaaaaaaa)>>1)|((x&0x55555555)<<1));
  x=(((x&0xcccccccc)>>2)|((x&0x33333333)<<2));
  x=(((x&0xcccccccc)>>2)|((x&0x33333333)<<2));
  x=(((x&0xf0f0f0f0)>>4)|((x&0x0f0f0f0f)<<4));
  x=(((x&0xf0f0f0f0)>>4)|((x&0x0f0f0f0f)<<4));
  x=(((x&0xff00ff00)>>8)|((x&0x00ff00ff)<<8));
  x=(((x&0xff00ff00)>>8)|((x&0x00ff00ff)<<8));
  return x;
  return x;
}
}
uint32_t
 
DebugUnitSC::bit_reverse_swar_32(uint32_t x)
uint32_t DebugUnitSC::bit_reverse_swar_32(uint32_t x)
{
{
  x=(((x&0xaaaaaaaa)>>1)|((x&0x55555555)<<1));
  x=(((x&0xaaaaaaaa)>>1)|((x&0x55555555)<<1));
  x=(((x&0xcccccccc)>>2)|((x&0x33333333)<<2));
  x=(((x&0xcccccccc)>>2)|((x&0x33333333)<<2));
  x=(((x&0xf0f0f0f0)>>4)|((x&0x0f0f0f0f)<<4));
  x=(((x&0xf0f0f0f0)>>4)|((x&0x0f0f0f0f)<<4));
  x=(((x&0xff00ff00)>>8)|((x&0x00ff00ff)<<8));
  x=(((x&0xff00ff00)>>8)|((x&0x00ff00ff)<<8));
  x=(((x&0xffff0000)>>16)|((x&0x0000ffff)<<16)); // We could be on 64-bit arch!
  x=(((x&0xffff0000)>>16)|((x&0x0000ffff)<<16)); // We could be on 64-bit arch!
  return x;
  return x;
}
}
 
 
uint32_t
uint32_t DebugUnitSC::bit_reverse_data(uint32_t data, int length)
DebugUnitSC::bit_reverse_data(uint32_t data, int length){
{
  if (length == 2) return bit_reverse_swar_2(data);
        if (length == 2)
  if (length == 4) return bit_reverse_swar_4(data);
                return bit_reverse_swar_2(data);
  if (length == 8) return bit_reverse_swar_8(data);
        if (length == 4)
  if (length == 16) return bit_reverse_swar_16(data);
                return bit_reverse_swar_4(data);
  if (length == 32) return bit_reverse_swar_32(data);
        if (length == 8)
 
                return bit_reverse_swar_8(data);
 
        if (length == 16)
 
                return bit_reverse_swar_16(data);
 
        if (length == 32)
 
                return bit_reverse_swar_32(data);
  // Long and laborious way - hopefully never gets called anymore!
  // Long and laborious way - hopefully never gets called anymore!
  uint32_t reverse=0;
  uint32_t reverse=0;
  for (int i=0;i<length;i++) reverse |= (((data>>i)&1)<<(length-1-i));
        for (int i = 0; i < length; i++)
 
                reverse |= (((data >> i) & 1) << (length - 1 - i));
  return reverse;
  return reverse;
}
}
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.