Exemplo n.º 1
0
void LCDScreen::seeSamplingEdge(ticks_t time)
{
  ++edgeCounter;
  // TODO According to the AT043TN24 datasheet data should be sampled on the
  // falling edge. However the sc_lcd code drives on the falling edge so for
  // the moment sample on the rising to match that.
  if (DETracker.getSignal().getValue(time)) {
    // Thb
    const unsigned minHorizontalClks = 40;
    // Th * tvb
    const unsigned minVerticalClks = 5 * 520;
    ticks_t lowEdges = edgeCounter - (lastDEHighEdge + 1);
    if (lowEdges >= minVerticalClks) {
      // VSync
      x = y = 0;
      screen.flip();
    } else if (lowEdges >= minHorizontalClks) {
      // HSync
      x = 0;
      ++y;
    }
    if (x < screen.getWidth() && y < screen.getHeigth()) {
      screen.writePixel(x++, y, DataTracker.getSignal().getValue(time));
    }
    lastDEHighEdge = edgeCounter;
  }
}
Exemplo n.º 2
0
SDRAM::Command SDRAM::getCommand(ticks_t time) const
{
  uint32_t cmd = 0;
  if (WE.getSignal().getValue(time))
    cmd |= 0x1;
  if (CAS.getSignal().getValue(time))
    cmd |= 0x2;
  if (RAS.getSignal().getValue(time))
    cmd |= 0x4;
  switch (cmd) {
  default:
    assert(0 && "Unexpected cmd");
  case 0:
    return Command::LOAD_MODE_REGISTER;
  case 1:
    return Command::AUTO_REFRESH;
  case 2:
    return Command::PRECHARGE;
  case 3:
    return Command::ACTIVE;
  case 4:
    return Command::WRITE;
  case 5:
    return Command::READ;
  case 6:
    return Command::BURST_TERMINATE;
  case 7:
    return Command::NOP;
  }
}
Exemplo n.º 3
0
bool SDRAM::getUDQMValue(ticks_t time) const
{
  if (useUDQM)
    return UDQM.getSignal().getValue(time);
  // Otherwise use NOR of CAS and RAS signal to match the SDRAM slice.
  return CAS.getSignal().getValue(time) == 0 &&
         RAS.getSignal().getValue(time) == 0;
}
Exemplo n.º 4
0
void SDRAM::seeCLKChange(const Signal &value, ticks_t time)
{
  if (value.getValue(time)) {
    // Rising edge.
    Command newCommand = getCommand(time);
    switch (newCommand) {
    case Command::ACTIVE:
      currentRow = A.getSignal().getValue(time) & ((1 << config.rowBits) - 1);
      break;
    case Command::AUTO_REFRESH:
    case Command::NOP:
    case Command::PRECHARGE:
      break;
    case Command::LOAD_MODE_REGISTER:
      modeReg.set(A.getSignal().getValue(time));
      break;
    case Command::READ:
      currentColumn =
        A.getSignal().getValue(time) & ((1 << config.columnBits) - 1);
      currentBank =
        BA.getSignal().getValue(time) & ((1 << config.bankBits) - 1);
      counter = 0;
      break;
    case Command::WRITE:
      currentColumn =
        A.getSignal().getValue(time) & ((1 << config.columnBits) - 1);
      currentBank =
        BA.getSignal().getValue(time) & ((1 << config.bankBits) - 1);
      counter = 0;
      break;
    case Command::BURST_TERMINATE:
      break;
    }
    if (newCommand != Command::NOP) {
      currentCommand = newCommand;
    }
    switch (currentCommand) {
    default:
      break;
    case Command::READ:
      {
        uint16_t mask = getReadWriteMask(time);
        unsigned burstLength = modeReg.getReadBurstLength();
        uint16_t data = mem[getMemoryIndex(burstLength)] & mask;
        uint8_t readEdge = edgeNumber + modeReg.getCASLatency();
        pendingReads.push(std::make_pair(data, readEdge));
        ++counter;
        if (burstLength != 0 && counter == burstLength)
          currentCommand = Command::NOP;
      }
      break;
    case Command::WRITE:
      {
        unsigned burstLength = modeReg.getReadBurstLength();
        if (WE.getSignal().getValue(time)) {
          uint16_t mask = getReadWriteMask(time);
          uint32_t index = getMemoryIndex(burstLength);
          uint16_t old = mem[index];
          uint16_t data = DQ.getSignal().getValue(time);
          mem[index] ^= (old ^ data) & mask;
        }
        ++counter;
        if (burstLength != 0 && counter == burstLength)
          currentCommand = Command::NOP;
      }
      break;
    }
    ++edgeNumber;
  } else {
    // Falling edge.
    if (!pendingReads.empty() && pendingReads.front().second == edgeNumber) {
      DQPort->seePinsChange(Signal(pendingReads.front().first), time);
      pendingReads.pop();
    }
  }
}