uint32_t Port::computeSteadyStateInputShiftReg() { Signal current = getEffectiveDataPortInputPinsValue(); assert(!current.isClock()); uint32_t val = current.getValue(time); unsigned width = shiftRegEntries; unsigned shift = getPortWidth(); while (width > 1) { val = (val << shift) | val; width >>= 1; shift *= 2; } val &= makeMask(getTransferWidth()); return val; }
void UartRx::seePinsChange(const Signal &value, ticks_t time) { currentPinValue = value.getValue(time); switch (state) { default: break; case WAIT_FOR_HIGH: if (currentPinValue == 1) state = WAIT_FOR_START; break; case WAIT_FOR_START: if (currentPinValue == 0) { state = CHECK_START; scheduleUpdate(time + bitTime / 2); } break; } }
void LCDScreen::seeCLKChange(const Signal &newSignal, ticks_t time) { CLKSignal = newSignal; uint32_t newValue = CLKSignal.getValue(time); if (newValue != CLKValue) { CLKValue = newValue; if (CLKValue) seeSamplingEdge(time); } if (CLKSignal.isClock()) { EdgeIterator nextEdge = CLKSignal.getEdgeIterator(time); if (nextEdge->type != Edge::RISING) ++nextEdge; scheduleSamplingEdge(nextEdge->time); } else if (scheduleReason != SCHEDULE_POLL_FOR_EVENTS) { schedulePollForEvents(time + minUpdateTicks); } }
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(); } } }