Проблема обработки сигналов в приложении моделирования SystemC - PullRequest
2 голосов
/ 13 апреля 2011

Я моделирую процессор и делаю это с помощью инструментов моделирования высокого уровня. SystemC является хорошим ресурсом для этих целей. Я использую два модуля:

  • DataPath

  • Память

Путь к данным ЦПУ смоделирован как уникальный высокоуровневый объект, однако следующий код наверняка будет лучше, чем любое другое объяснение:

Ниже приведен datapath.hpp

SC_MODULE(DataPath) {
    sc_in_clk clk;
    sc_in<bool> rst;
    ///
    /// Outgoing data from memory.
    ///
    sc_in<w32> mem_data;
    ///
    /// Memory read enable control signal.
    ///
    sc_out<sc_logic> mem_ctr_memreadenable;
    ///
    /// Memory write enable control signal.
    ///
    sc_out<sc_logic> mem_ctr_memwriteenable;
    ///
    /// Data to be written in memory.
    ///
    sc_out<w32> mem_dataw; //w32 is sc_lv<32>
    ///
    /// Address in mem to read and write.
    ///
    sc_out<memaddr> mem_addr;
    ///
    /// Program counter.
    ///
    sc_signal<w32> pc;
    ///
    /// State signal.
    ///
    sc_signal<int> cu_state;
    ///
    /// Other internal signals mapping registers' value.
    /// ...

    // Defining process functions
    ///
    /// Clock driven process to change state.
    ///
    void state_process();
    ///
    /// State driven process to apply control signals.
    ///
    void control_process();

    // Constructors
    SC_CTOR(DataPath) {
        // Defining first process
        SC_CTHREAD(state_process, clk.neg());
        reset_signal_is(this->rst, true);
        // Defining second process
        SC_METHOD(control_process);
        sensitive << (this->cu_state) << (this->rst);
    }

    // Defining general functions
    void reset_signals();
};

Ниже приведен datapath.cpp

void DataPath::state_process() {
    // Useful variables
    w32 ir_value; /* Placing here IR register value */
    // Initialization phase
    this->cu_state.write(StateFetch); /* StateFetch is a constant */
    wait(); /* Wait next clock fall edge */
    // Cycling
    for (;;) {
        // Checking state
        switch (this->cu_state.read()) { // Basing on state, let's change the next one
        case StateFetch: /* FETCH */
            this->cu_state.write(StateDecode); /* Transition to DECODE */
            break;
        case StateDecode: /* DECODE */
            // Doing decode
            break;
        case StateExecR: /* EXEC R */
            // For every state, manage transition to the next state
            break;
        //...
        //...
        default: /* Possible not recognized state */
            this->cu_state.write(StateFetch); /* Come back to fetch */
        } /* switch */
        // After doing, wait for the next clock fall edge
        wait();
    } /* for */
} /* function */

// State driven process for managing signal assignment
// This is a method process
void DataPath::control_process() {
    // If reset signal is up then CU must be resetted
    if (this->rst.read()) {
        // Reset
        this->reset_signals(); /* Initializing signals */
    } else {
        // No Reset
        // Switching on state
        switch (this->cu_state.read()) {
        case StateFetch: /* FETCH */
            // Managing memory address and instruction fetch to place in IR
            this->mem_ctr_memreadenable.write(logic_sgm_1); /* Enabling memory to be read */
            this->mem_ctr_memwriteenable.write(logic_sgm_0); /* Disabling memory from being written */
            std::cout << "Entering fetch, memread=" << this->mem_ctr_memreadenable.read() << " memwrite=" << this->mem_ctr_memreadenable.read() << std::endl;
            // Here I read from memory and get the instruction with some code that you do not need to worry about because my problem occurs HERE ###
            break;
        case kCUStateDecode: /* DECODE */
            // ...
            break;
        //...
        //...
        default: /* Unrecognized */
            newpc = "00000000000000000000000000000000";
        } /* state switch */
    } /* rst if */
} /* function */

// Resetting signals
void DataPath::reset_signals() {
    // Out signals
    this->mem_ctr_memreadenable.write(logic_sgm_1);
    this->mem_ctr_memwriteenable.write(logic_sgm_0);
}

Как вы можете видеть, у нас есть процесс, управляемый часами, который обрабатывает переходы процессора (изменение состояния), и процесс, управляемый состоянием, который устанавливает сигналы для процессора.

Моя проблема в том, что когда я прихожу в ###, я ожидаю, что инструкция будет выпущена из памяти (вы не можете видеть инструкции, но они верны, компонент памяти подключен к каналу передачи данных с использованием входных и выходных сигналов, которые вы можете видеть в hpp файл). Память получает меня "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", потому что mem_ctr_memreadenable и mem_ctr_memwriteenable оба установлены на '0'. Модуль памяти написан для того, чтобы быть моментальным компонентом. Он записывается с использованием SC_METHOD, для которого sensitive определено на входных сигналах (включая чтение и включение записи). Компонент памяти получает "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", когда сигнал mem_ctr_memreadenable равен '0'.

Почему это '0'? Я сбрасываю сигналы и устанавливаю этот сигнал на '1'. Я не понимаю, почему у меня остается '0' для сигнала разрешения чтения.

Вы можете мне помочь? Thankyou.

Ответы [ 2 ]

3 голосов
/ 13 апреля 2011

Я не гуру SystemC, но похоже, что это может быть проблема, аналогичная общей проблеме VHDL сигналов, не обновляющихся до тех пор, пока не пройдет хотя бы дельта-цикл:

this->mem_ctr_memreadenable.write(logic_sgm_1); /* Enabling memory to be read */
this->mem_ctr_memwriteenable.write(logic_sgm_0); /* Disabling memory from being written */

Мое предположение: Между этими двумя строками и следующей строкой не проходит время:

std::cout << "Entering fetch, memread=" << this->mem_ctr_memreadenable.read() << " memwrite=" << this->mem_ctr_memreadenable.read() << std::endl;

Таким образом, память еще не видела изменения сигнала чтения.Кстати, должен ли один из вызовов read() подключиться к mem_ctr_memwriteenable - оба они, по-видимому, доступны для восстановления?

Если вы:

wait(1, SC_NS);

между этими двумя точками, улучшится ли он?вопросы?

0 голосов
/ 10 мая 2012

Чтобы получить нулевую синхронизацию с модулем памяти, вы должны использовать ждать (SC_ZERO_TIME); // ждать один дельта цикл не вводить произвольное потребление времени в вашей временной симуляции. Это также означает, что вы обновляете ваш control_process до SC_THREAD

...