Похоже, я немного поторопился с оправданием текущей V-модели, так как не учёл, что после eval_all_p() и eval_all_n() выполняются ещё и assign_all().
Если поставить отладочную печать после assign_all() :
Код:/* Выполнение модели по переднему фронту ТЧ */ void vm1_qbus::eval_p(int nClk, VM1_QBUS_INOUT *pINOUT) { m_pINOUTPins = pINOUT; m_nClk = nClk; InLog('p'); eval_all_p(); //выполняем все always для переднего фронта assign_all(); //вычисляем все assignы OutLog('p'); } /* Выполнение модели по заднему фронту ТЧ */ void vm1_qbus::eval_n(int nClk, VM1_QBUS_INOUT *pINOUT) { m_pINOUTPins = pINOUT; m_nClk = nClk; InLog(' '); eval_all_n(); //выполняем все always для заднего фронта assign_all(); //вычисляем все assignы OutLog(' '); }
То проблема с неправильным распределением сигналов по тактам встаёт во весь рост:
Код:clk ad bsy wtbt sync din dout rply p> 000019 000000 0 0 0 0 0 0 p< 000019 000000 0 0 0 0 0 0 > 000019 000000 0 0 0 0 0 0 < 000019 177716 1 0 0 0 0 0 p> 000020 177716 1 0 0 0 0 0 p< 000020 177716 1 0 0 0 0 0 > 000020 177716 1 0 0 0 0 0 < 000020 177716 1 0 1 0 0 0 p> 000021 177716 1 0 1 0 0 0 p< 000021 000000 1 0 1 1 0 0 > 000021 000000 1 0 1 1 0 0 < 000021 000000 1 0 1 1 0 1
Если же поменять местами выполнение eval и assign :
Код:/* Выполнение модели по переднему фронту ТЧ */ void vm1_qbus::eval_p(int nClk, VM1_QBUS_INOUT *pINOUT) { m_pINOUTPins = pINOUT; m_nClk = nClk; InLog('p'); assign_all(); //вычисляем все assignы eval_all_p(); //выполняем все always для переднего фронта OutLog('p'); } /* Выполнение модели по заднему фронту ТЧ */ void vm1_qbus::eval_n(int nClk, VM1_QBUS_INOUT *pINOUT) { m_pINOUTPins = pINOUT; m_nClk = nClk; InLog(' '); assign_all(); //вычисляем все assignы eval_all_n(); //выполняем все always для заднего фронта OutLog(' '); }
То распределение входных и выходных сигналов по фронтам становится идеальным:
Код:clk ad bsy wtbt sync din dout rply p> 000019 000000 0 0 0 0 0 0 p< 000019 177716 1 0 0 0 0 0 > 000019 177716 1 0 0 0 0 0 < 000019 177716 1 0 0 0 0 0 p> 000020 177716 1 0 0 0 0 0 p< 000020 177716 1 0 1 0 0 0 > 000020 177716 1 0 1 0 0 0 < 000020 000000 1 0 1 1 0 0 p> 000021 000000 1 0 1 1 0 0 p< 000021 000000 1 0 1 1 0 1 > 000021 000000 1 0 1 1 0 1 < 000021 000000 1 0 1 1 0 1
Но с синхронным адаптером процессор зависает в ходе выполнения первой же команды.
Кстати, при вычислении assign перед eval сигнал SEL1 должен корректно устанавливаться даже в исходной версии V-модели, что дополнительно указывает на верность такого подхода.
Чтобы воспроизвести проблему зависания модифицированной V-модели при работе с синхронным адаптером МПИ - достаточно убрать обработку сигналов шины между eval_p и eval_n :
Код:void tboard::maincycle() { m_pCPU->eval_p(m_nClk, m_pMPI); //отработаем передний фронт ТЧ // m_pMemory->eval(m_pMPI); // m_pIRPS->eval(m_pMPI); #ifdef OUT_VM1PIN_DBG_LOG OutLog(); #endif m_pCPU->eval_n(m_nClk, m_pMPI); //отработаем задний фронт ТЧ m_pMemory->eval(m_pMPI); m_pIRPS->eval(m_pMPI); #ifdef OUT_VM1PIN_DBG_LOG OutLog(); #endif m_nClk++; }




Ответить с цитированием
