OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

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

Show entire file | Details | Blame | View Log

Rev 63 Rev 462
Line 29... Line 29...
#include <iostream>
#include <iostream>
#include <iomanip>
#include <iomanip>
 
 
#include "JtagDriverSC.h"
#include "JtagDriverSC.h"
 
 
 
 
SC_HAS_PROCESS (JtagDriverSC);
SC_HAS_PROCESS (JtagDriverSC);
 
 
//! Constructor for the JTAG driver.
//! Constructor for the JTAG driver.
 
 
//! We create a SC_THREAD in which we can spit out some actions. Must be a
//! We create a SC_THREAD in which we can spit out some actions. Must be a
Line 41... Line 40...
 
 
//! @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 perform
//! @param[in] _tapActionQueue  Pointer to fifo of actions to perform
 
 
JtagDriverSC::JtagDriverSC (sc_core::sc_module_name        name,
JtagDriverSC::JtagDriverSC(sc_core::sc_module_name name, sc_core::sc_fifo < TapAction * >*_tapActionQueue):
                            sc_core::sc_fifo<TapAction *> *_tapActionQueue) :
 
  sc_module (name),
  sc_module (name),
  tapActionQueue (_tapActionQueue),
tapActionQueue(_tapActionQueue), currentScanChain(OR1K_SC_UNDEF)
  currentScanChain (OR1K_SC_UNDEF)
 
{
{
  SC_THREAD (queueActions);
  SC_THREAD (queueActions);
 
 
}       // JtagDriverSC ()
}       // JtagDriverSC ()
 
 
 
 
//! SystemC thread to queue some actions
//! SystemC thread to queue some actions
 
 
//! Have to use a thread, since we will end up waiting for actions to
//! Have to use a thread, since we will end up waiting for actions to
//! complete.
//! complete.
 
 
void
void JtagDriverSC::queueActions()
JtagDriverSC::queueActions ()
 
{
{
  uint32_t res;                 // General result variable
  uint32_t res;                 // General result variable
 
 
  // Reset the JTAG
  // Reset the JTAG
  reset ();
  reset ();
Line 70... Line 65...
  // Select the register scan chain to stall the processor, stall the
  // Select the register scan chain to stall the processor, stall the
  // processor and check it has stalled
  // processor and check it has stalled
  selectChain (OR1K_SC_REGISTER);
  selectChain (OR1K_SC_REGISTER);
  writeReg (OR1K_RSC_RISCOP, RISCOP_STALL);
  writeReg (OR1K_RSC_RISCOP, RISCOP_STALL);
 
 
  do
        do {
    {
 
      res = readReg (OR1K_RSC_RISCOP);
      res = readReg (OR1K_RSC_RISCOP);
      std::cout << sc_core::sc_time_stamp ().to_seconds () * 1000000
      std::cout << sc_core::sc_time_stamp ().to_seconds () * 1000000
                << "us: RISCOP = " << std::hex << res << std::endl;
                << "us: RISCOP = " << std::hex << res << std::endl;
    }
    }
  while ((res & RISCOP_STALL) != RISCOP_STALL);
  while ((res & RISCOP_STALL) != RISCOP_STALL);
Line 96... Line 90...
 
 
  // Unstall and check it has unstalled
  // Unstall and check it has unstalled
  selectChain (OR1K_SC_REGISTER);
  selectChain (OR1K_SC_REGISTER);
  writeReg (OR1K_RSC_RISCOP, 0);
  writeReg (OR1K_RSC_RISCOP, 0);
 
 
  do
        do {
    {
 
      res = readReg (OR1K_RSC_RISCOP);
      res = readReg (OR1K_RSC_RISCOP);
      std::cout << sc_core::sc_time_stamp ().to_seconds () * 1000000
      std::cout << sc_core::sc_time_stamp ().to_seconds () * 1000000
                << "us: RISCOP = " << std::hex << res << std::endl;
                << "us: RISCOP = " << std::hex << res << std::endl;
    }
    }
  while ((res & RISCOP_STALL) == RISCOP_STALL);
  while ((res & RISCOP_STALL) == RISCOP_STALL);
 
 
}       // queueActions ()
}       // queueActions ()
 
 
 
 
//! Reset the JTAG
//! Reset the JTAG
 
 
//! @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()
 
 
void
void JtagDriverSC::reset()
JtagDriverSC::reset ()
 
{
{
  sc_core::sc_event *actionDone = new sc_core::sc_event();
  sc_core::sc_event *actionDone = new sc_core::sc_event();
  TapActionReset    *resetAction;
  TapActionReset    *resetAction;
 
 
  // Create and queue the reset action and wait for it to complete
  // Create and queue the reset action and wait for it to complete
Line 127... Line 118...
  delete resetAction;
  delete resetAction;
  delete actionDone;
  delete actionDone;
 
 
}       // reset ()
}       // reset ()
 
 
 
 
//! Select an OpenRISC 1000 scan chain
//! Select an OpenRISC 1000 scan chain
 
 
//! Built on top of the JTAG commands to shift registers
//! Built on top of the JTAG commands to shift registers
//! We only do something if the scan chain needs to be changed.
//! We only do something if the scan chain needs to be changed.
//! - Shift-IR the CHAIN_SELECT instruction
//! - Shift-IR the CHAIN_SELECT instruction
Line 140... Line 130...
 
 
//! @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 scan chain
//! @param[in] chain  The desired scan chain
 
 
 
void JtagDriverSC::selectChain(int chain)
void
 
JtagDriverSC::selectChain (int chain)
 
{
 
  if (chain == currentScanChain)
 
    {
    {
 
        if (chain == currentScanChain) {
      return;
      return;
    }
        } else {
  else
 
    {
 
      currentScanChain = chain;
      currentScanChain = chain;
    }
    }
 
 
  sc_core::sc_event *actionDone = new sc_core::sc_event();
  sc_core::sc_event *actionDone = new sc_core::sc_event();
  TapActionIRScan   *iRScan;
  TapActionIRScan   *iRScan;
Line 167... Line 152...
  delete iRScan;
  delete iRScan;
 
 
  // Create and queue the DR-Scan action for the specified chain (which we
  // Create and queue the DR-Scan action for the specified chain (which we
  // know will fit into 64 bits)
  // know will fit into 64 bits)
  uint64_t  chainReg = crc8 (chain, CHAIN_DR_LEN) << (CHAIN_DR_LEN) | chain;
  uint64_t  chainReg = crc8 (chain, CHAIN_DR_LEN) << (CHAIN_DR_LEN) | chain;
  dRScan = new TapActionDRScan (actionDone, chainReg, CHAIN_DR_LEN + CRC_LEN);
        dRScan =
 
            new TapActionDRScan(actionDone, chainReg, CHAIN_DR_LEN + CRC_LEN);
  tapActionQueue->write (dRScan);
  tapActionQueue->write (dRScan);
  wait (*actionDone);
  wait (*actionDone);
 
 
  delete dRScan;
  delete dRScan;
 
 
Line 183... Line 169...
  delete iRScan;
  delete iRScan;
  delete actionDone;
  delete actionDone;
 
 
}       // selectChain()
}       // selectChain()
 
 
 
 
//! Read an OpenRISC 1000 JTAG register
//! Read an OpenRISC 1000 JTAG register
 
 
//! Built on top of the JTAG commands to shift registers
//! Built on top of the JTAG commands to shift registers
//! - Shift-DR the specified address with R/W field unset
//! - Shift-DR the specified address with R/W field unset
//! - read out the data shifted out.
//! - read out the data shifted out.
Line 217... Line 202...
 
 
//! @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 JtagDriverSC::readReg(uint32_t addr)
JtagDriverSC::readReg (uint32_t  addr)
 
{
{
  bool  firstTime = true;
  bool  firstTime = true;
  int   bitSizeNoCrc;           // Size of reg w/o its CRC field
  int   bitSizeNoCrc;           // Size of reg w/o its CRC field
 
 
  // Determine the size of register to read.
  // Determine the size of register to read.
  switch (currentScanChain)
        switch (currentScanChain) {
    {
 
    case OR1K_SC_RISC_DEBUG:
    case OR1K_SC_RISC_DEBUG:
      bitSizeNoCrc  = RISC_DEBUG_DR_LEN;
      bitSizeNoCrc  = RISC_DEBUG_DR_LEN;
      break;
      break;
 
 
    case OR1K_SC_REGISTER:
    case OR1K_SC_REGISTER:
Line 241... Line 224...
      break;
      break;
    }
    }
 
 
  // Read the register twice. Use an optimized version if the register is
  // Read the register twice. Use an optimized version if the register is
  // "small".
  // "small".
  if ((bitSizeNoCrc + CRC_LEN) < 64)
        if ((bitSizeNoCrc + CRC_LEN) < 64) {
    {
 
      (void)readReg1 (addr, bitSizeNoCrc);
      (void)readReg1 (addr, bitSizeNoCrc);
      return  readReg1 (addr, bitSizeNoCrc);
      return  readReg1 (addr, bitSizeNoCrc);
    }
        } else {
  else
                uint64_t *dReg =
    {
                    new uint64_t[(bitSizeNoCrc + CRC_LEN + 63) / 64];
      uint64_t *dReg = new uint64_t [(bitSizeNoCrc + CRC_LEN + 63) / 64];
 
      (void)readReg1 (dReg, addr, bitSizeNoCrc);
      (void)readReg1 (dReg, addr, bitSizeNoCrc);
      uint32_t  res = readReg1 (dReg, addr, bitSizeNoCrc);
      uint32_t  res = readReg1 (dReg, addr, bitSizeNoCrc);
      delete [] dReg;
      delete [] dReg;
 
 
      return  res;
      return  res;
    }
    }
}       // readReg ()
}       // readReg ()
 
 
 
 
//! Single read of an OpenRISC 1000 JTAG register
//! Single read of an OpenRISC 1000 JTAG register
 
 
//! Built on top of the JTAG commands to shift registers
//! Built on top of the JTAG commands to shift registers
//! - Shift-DR the specified address with R/W field unset
//! - Shift-DR the specified address with R/W field unset
//! - read out the data shifted out.
//! - read out the data shifted out.
Line 273... Line 253...
//! @param[in]     addr          The address to read
//! @param[in]     addr          The address to read
//! @param[in]     bitSizeNoCrc  Size of the register excluding its CRC field
//! @param[in]     bitSizeNoCrc  Size of the register excluding its CRC field
 
 
//! @return  The register value read
//! @return  The register value read
 
 
uint32_t
uint32_t JtagDriverSC::readReg1(uint32_t addr, int bitSizeNoCrc)
JtagDriverSC::readReg1 (uint32_t   addr,
 
                        int        bitSizeNoCrc)
 
{
{
  // Useful fields and sizes and the register itself
  // Useful fields and sizes and the register itself
  int                fullBitSize = bitSizeNoCrc + CRC_LEN;
  int                fullBitSize = bitSizeNoCrc + CRC_LEN;
  int                dataOffset  = bitSizeNoCrc - DR_DATA_LEN;
  int                dataOffset  = bitSizeNoCrc - DR_DATA_LEN;
  uint64_t           dReg;
  uint64_t           dReg;
 
 
  // Allocate space for the shifted reg and a SystemC completion event
  // Allocate space for the shifted reg and a SystemC completion event
  sc_core::sc_event *actionDone  = new sc_core::sc_event();
  sc_core::sc_event *actionDone  = new sc_core::sc_event();
 
 
  // Loop until CRCs match
  // Loop until CRCs match
  while (true)
        while (true) {
    {
 
      // Create the data to shift in
      // Create the data to shift in
      dReg  = 0ULL;
      dReg  = 0ULL;
      dReg |= addr;
      dReg |= addr;
      uint8_t crc_in = crc8 (dReg, bitSizeNoCrc);
      uint8_t crc_in = crc8 (dReg, bitSizeNoCrc);
      dReg |= (uint64_t)crc_in << bitSizeNoCrc;
      dReg |= (uint64_t)crc_in << bitSizeNoCrc;
Line 307... Line 284...
      // Check CRCs
      // Check CRCs
      uint8_t  crc_out  = dReg >> bitSizeNoCrc;
      uint8_t  crc_out  = dReg >> bitSizeNoCrc;
      uint8_t  crc_calc = crc8 (dReg, bitSizeNoCrc);
      uint8_t  crc_calc = crc8 (dReg, bitSizeNoCrc);
 
 
      // All done if CRC matches
      // All done if CRC matches
      if (crc_out == crc_calc)
                if (crc_out == crc_calc) {
        {
 
          delete    actionDone;
          delete    actionDone;
          return  (dReg >> dataOffset) & ((1ULL << DR_DATA_LEN) - 1);
                        return (dReg >> dataOffset) & ((1ULL << DR_DATA_LEN) -
 
                                                       1);
        }
        }
    }
    }
}       // readReg1 ()
}       // readReg1 ()
 
 
 
 
//! Single read of an OpenRISC 1000 JTAG register
//! Single read of an OpenRISC 1000 JTAG register
 
 
//! Built on top of the JTAG commands to shift registers
//! Built on top of the JTAG commands to shift registers
//! - Shift-DR the specified address with R/W field unset
//! - Shift-DR the specified address with R/W field unset
//! - read out the data shifted out.
//! - read out the data shifted out.
Line 334... Line 310...
 
 
//! @return  The register value read
//! @return  The register value read
 
 
uint32_t
uint32_t
JtagDriverSC::readReg1 (uint64_t  *dRegArray,
JtagDriverSC::readReg1 (uint64_t  *dRegArray,
                        uint32_t   addr,
                           uint32_t addr, int bitSizeNoCrc)
                        int        bitSizeNoCrc)
 
{
{
  // Useful fields and sizes
  // Useful fields and sizes
  int                fullBitSize = bitSizeNoCrc + CRC_LEN;
  int                fullBitSize = bitSizeNoCrc + CRC_LEN;
  int                dataOffset  = bitSizeNoCrc - DR_DATA_LEN;
  int                dataOffset  = bitSizeNoCrc - DR_DATA_LEN;
 
 
  // Allocate a SystemC completion event
  // Allocate a SystemC completion event
  sc_core::sc_event *actionDone  = new sc_core::sc_event();
  sc_core::sc_event *actionDone  = new sc_core::sc_event();
 
 
  // Loop until CRCs match
  // Loop until CRCs match
  while (true)
        while (true) {
    {
 
      // Create the data to shift in
      // Create the data to shift in
      memset (dRegArray, 0, fullBitSize / 8);
      memset (dRegArray, 0, fullBitSize / 8);
      dRegArray[0] |= addr;
      dRegArray[0] |= addr;
      uint8_t crc_in = crc8 (dRegArray, bitSizeNoCrc);
      uint8_t crc_in = crc8 (dRegArray, bitSizeNoCrc);
      insertBits (crc_in, CRC_LEN, dRegArray, bitSizeNoCrc);
      insertBits (crc_in, CRC_LEN, dRegArray, bitSizeNoCrc);
 
 
      // Prepare the action, queue it and wait for it to complete
      // Prepare the action, queue it and wait for it to complete
      TapActionDRScan *dRScan = new TapActionDRScan (actionDone, dRegArray,
                TapActionDRScan *dRScan =
 
                    new TapActionDRScan(actionDone, dRegArray,
                                                     fullBitSize);
                                                     fullBitSize);
      tapActionQueue->write (dRScan);
      tapActionQueue->write (dRScan);
      wait (*actionDone);
      wait (*actionDone);
      dRScan->getDRegOut (dRegArray);
      dRScan->getDRegOut (dRegArray);
      delete dRScan;
      delete dRScan;
Line 366... Line 341...
      // Check CRCs
      // Check CRCs
      uint8_t  crc_out  = extractBits (dRegArray, bitSizeNoCrc, CRC_LEN);
      uint8_t  crc_out  = extractBits (dRegArray, bitSizeNoCrc, CRC_LEN);
      uint8_t  crc_calc = crc8 (dRegArray, bitSizeNoCrc);
      uint8_t  crc_calc = crc8 (dRegArray, bitSizeNoCrc);
 
 
      // All done if CRC matches
      // All done if CRC matches
      if (crc_out == crc_calc)
                if (crc_out == crc_calc) {
        {
 
          delete  actionDone;
          delete  actionDone;
          return  extractBits (dRegArray, dataOffset, DR_DATA_LEN);
          return  extractBits (dRegArray, dataOffset, DR_DATA_LEN);
        }
        }
    }
    }
}       // readReg1 ()
}       // readReg1 ()
 
 
 
 
//! Write an OpenRISC 1000 JTAG register
//! Write an OpenRISC 1000 JTAG register
 
 
//! Built on top of the JTAG commands to shift registers
//! Built on top of the JTAG commands to shift registers
//! - Shift-DR the specified address with R/W field set and data to write
//! - Shift-DR the specified address with R/W field set and data to write
 
 
Line 398... Line 371...
 
 
//! @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
JtagDriverSC::writeReg (uint32_t  addr,
 JtagDriverSC::writeReg(uint32_t addr, uint32_t data)
                        uint32_t  data)
 
{
{
  int       bitSizeNoCrc;               // Size of reg w/o its CRC field
  int       bitSizeNoCrc;               // Size of reg w/o its CRC field
  uint64_t  writeBit;                   // Mask for the write enable bit
  uint64_t  writeBit;                   // Mask for the write enable bit
 
 
  // Determine the size of register to write.
  // Determine the size of register to write.
  switch (currentScanChain)
        switch (currentScanChain) {
    {
 
    case OR1K_SC_RISC_DEBUG:
    case OR1K_SC_RISC_DEBUG:
      bitSizeNoCrc  = RISC_DEBUG_DR_LEN;
      bitSizeNoCrc  = RISC_DEBUG_DR_LEN;
      writeBit      = RISC_DEBUG_RW;
      writeBit      = RISC_DEBUG_RW;
      break;
      break;
 
 
Line 447... Line 418...
  delete dRScan;
  delete dRScan;
  delete actionDone;
  delete actionDone;
 
 
}       // writeReg ()
}       // writeReg ()
 
 
 
 
//! Compute CRC-8-ATM
//! Compute CRC-8-ATM
 
 
//! The data is in a uint64_t, for which we use the first size bits to compute
//! The data is in a uint64_t, for which we use the first size bits to compute
//! the CRC.
//! the CRC.
 
 
Line 463... Line 433...
//!       is correct!
//!       is correct!
 
 
//! @param data  The data whose CRC is desired
//! @param data  The 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 JtagDriverSC::crc8(uint64_t data, int size)
JtagDriverSC::crc8 (uint64_t  data,
 
                    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         = data & 1;            // Latest data bit
      uint8_t  d         = data & 1;            // Latest data bit
      data             >>= 1;
      data             >>= 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 ()
 
 
 
 
//! 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 504... Line 472...
//!       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 JtagDriverSC::crc8(uint64_t dataArray[], int size)
JtagDriverSC::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 ()
 
 
 
 
//! Utility to insert a string of bits into array
//! Utility to insert a string of bits into array
 
 
//! This is a simple overwriting
//! This is a simple overwriting
 
 
//! @param  str       Bits to insert
//! @param  str       Bits to insert
//! @param  strLen    Number of bits to insert
//! @param  strLen    Number of bits to insert
//! @param  array     Array into which to insert
//! @param  array     Array into which to insert
//! @param  startBit  Offset at which to insert bits
//! @param  startBit  Offset at which to insert bits
 
 
void
void JtagDriverSC::insertBits(uint64_t str,
JtagDriverSC::insertBits (uint64_t  str,
                              int strLen, uint64_t * array, int startBit)
                          int       strLen,
 
                          uint64_t *array,
 
                          int       startBit)
 
{
{
  int  startWord = startBit / 64;
  int  startWord = startBit / 64;
  int  endWord   = (startBit + strLen - 1) / 64;
  int  endWord   = (startBit + strLen - 1) / 64;
 
 
  startBit       = startBit % 64;
  startBit       = startBit % 64;
Line 556... Line 519...
 
 
  array[startWord] &= ~startMask;
  array[startWord] &= ~startMask;
  array[startWord] |= str << startBit;
  array[startWord] |= str << startBit;
 
 
  // 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 = (startBit + strLen) % 64;
  int  bitsToDo = (startBit + strLen) % 64;
 
 
  uint64_t  endMask = (1ULL << bitsToDo) - 1ULL;
  uint64_t  endMask = (1ULL << bitsToDo) - 1ULL;
Line 572... Line 533...
  array[endWord] &= ~endMask;
  array[endWord] &= ~endMask;
  array[endWord] |= str >> (strLen - bitsToDo);
  array[endWord] |= str >> (strLen - bitsToDo);
 
 
}       // insertBits()
}       // insertBits()
 
 
 
 
//! Utility to extract a string of bits from an array
//! Utility to extract a string of bits from an array
 
 
//! @param  array     Array from which to extract
//! @param  array     Array from which to extract
//! @param  startBit  Offset at which to extract bits
//! @param  startBit  Offset at which to extract bits
//! @param  strLen    Number of bits to extract
//! @param  strLen    Number of bits to extract
 
 
//! @return  Extracted bits
//! @return  Extracted bits
 
 
uint64_t
uint64_t JtagDriverSC::extractBits(uint64_t * array, int startBit, int strLen)
JtagDriverSC::extractBits (uint64_t *array,
 
                           int       startBit,
 
                           int       strLen)
 
{
{
  int  startWord = startBit / 64;
  int  startWord = startBit / 64;
  int  endWord   = (startBit + strLen - 1) / 64;
  int  endWord   = (startBit + strLen - 1) / 64;
 
 
  startBit       = startBit % 64;
  startBit       = startBit % 64;
Line 597... Line 554...
  // right place
  // right place
  uint64_t  startMask = ((1ULL << strLen) - 1ULL) << startBit;
  uint64_t  startMask = ((1ULL << strLen) - 1ULL) << startBit;
  uint64_t  res       = (array[startWord] & startMask) >> startBit;
  uint64_t  res       = (array[startWord] & startMask) >> startBit;
 
 
  // 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  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 = (startBit + strLen) % 64;
  int       bitsToDo = (startBit + strLen) % 64;
  uint64_t  endMask  = (1ULL << bitsToDo) - 1ULL;
  uint64_t  endMask  = (1ULL << bitsToDo) - 1ULL;
 
 

powered by: WebSVN 2.1.0

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