Что означает предупреждение о попытке прогнозирования при доступе к регистру?

У меня среда проверки UVM.

В моей тестовой последовательности я читаю (зеркально) из REGA через FRONTDOOR (последовательная транзакция) при получении прерывания.

В моем табло я использовал методы .predict для обновления ожидаемых значений REGA.

Однако у меня следующая ошибка:

Register "regmodel.REGA" value read from DUT (0x00000000000000AA) does not match mirrored value (0x0000000000000000)

Значение, считанное с тестируемого устройства, правильное (AA), и если я печатаю значение, используемое в методе прогнозирования, то оно также правильное (AA).

Однако в моделировании у меня есть следующее предупреждение перед ошибкой:

Trying to predict value of register 'regmodel.REGA' while it is being accessed

Сначала я подумал, что это из-за гонки (прогнозирование и доступ к FRONTDOOR), поэтому я добавил задержку перед чтением из регистра, но это все равно такое же поведение.

Я хотел бы знать, что именно означает это предупреждение, и если я должен что-то изменить


person wisemonkey    schedule 05.03.2014    source источник
comment
Я использую IUS (острый) в качестве симулятора   -  person wisemonkey    schedule 06.03.2014


Ответы (3)


Это действительно означает, что вы предсказываете свой регистр во время чтения. Если вы вызываете predict(value) и одновременно читаете/записываете регистр, чтение/запись приведет к ошибке в модели регистра до того, как ваш прогноз завершится (во всяком случае, с доступом через переднюю дверь).

Лично я бы удостоверился, что чтение вашего регистра завершено полностью (показывая regmodel.REGA.is busy() == 0), прежде чем вы начнете операцию прогнозирования.

Если вам нужна дополнительная информация о модели регистров UVM, отлично подойдет эта ссылка: http://cluelogic.com/2013/02/uvm-tutorial-for-candy-lovers-register-access-methods/

person James Mackenzie    schedule 25.06.2014
comment
хорошо, но как пользователь узнает, когда прогноз завершен? Рассмотрим средство проверки, обновляющее прогнозируемые значения и чтение последовательности из регистров (оба работают в параллельных потоках и асинхронно друг с другом). Разве расписание не должно позаботиться о ситуации? Или есть флаг, указывающий, что прогноз «занят»? - person wisemonkey; 18.07.2014
comment
Я ошиблась в заказе, извините. Внутри модели регистра (uvm_reg::m_is_busy) во время чтения regmodel.REGA установлено поле. Это поле проверяется uvm_reg::do_predict(). Если для m_is_busy установлено высокое значение, когда начинается прогнозирование, вы получите сообщение Попытка прогнозирования значения регистра regmodel.REGA во время доступа к нему. Что касается того, как обойти это, вы можете использовать семафор, доступный обоим вашим асинхронным потокам, или вызвать regmodel.REGA.is_busy(), прежде чем пытаться предсказать. - person James Mackenzie; 19.07.2014
comment
Спасибо, я попробую это, я не работаю над частью кода в течение следующих нескольких дней, поэтому дам отзыв позже. - person wisemonkey; 22.07.2014
comment
Точно такая же проблема, с которой я также сталкиваюсь. В этой ветке решения не увидел. я сделал wait(!regmodel.REGA.is_busy()) и он просто завис. В любом случае я могу определить, кто держит regmodel занятым? - person justrajdeep; 09.05.2015

Когда вы вызываете функцию Predict, она вызывает do_predict(). Делайте прогнозные проверки, если регистр занят. Если окажется, что регистр занят, do_predict() не будет выполнять операцию прогнозирования.

Таким образом, пользователь должен проверить возвращаемое значение функции predict(), чтобы проверить, была ли операция выполнена успешно.

Predict возвращает 1 для операции SUCCESS и 0 для операции UN_SUCCESSFUL.

Вы можете написать что-то вроде следующего, чтобы убедиться, что операция прогнозирования выполнена

  while (! (REGISTER.predict(<value>))); 


           OR
 Declare a standard task something like the following, and call it whenever you need



task dac_reg_base_seq::predict_register(uvm_reg REGISTER, bit [31:0] predict_value ); 
      uvm_reg register_temp;
      predict_register = 0; //Unsuccessful
      if (!$cast(register_temp, REGISTER))
      begin
        `uvm_fatal("NOT_UVM_REG_TYPE","Provided REGISTER is not of the correct type")
      end

     `uvm_info("PREDICT_REGISTER", $psprintf(" Starting the predict function setting register %s with value %h", register_temp.get_name(),predict_value), UVM_HIGH);
    while(1) begin
          if(register_temp.is_busy == 1) begin
           `uvm_info("PREDICT_REGISTER", $psprintf(" register %s  is busy ", register_temp.get_name()), UVM_HIGH);
         // Adding Delay to avoid simulater gets locked up here
         #1;
         continue;
          end
      else begin
            register_temp.predict(register_temp.get()| predict_value); 
            break;
          end
        end
     `uvm_info("PREDICT_REGISTER", $psprintf(" Done with updating the predict value to the register %s", register_temp.get_name()), UVM_HIGH);
endtask : predict_register 
person Sunil Jasthi    schedule 12.02.2016
comment
Не могли бы вы добавить немного больше описания объяснения, которое вы даете? - person abarisone; 12.02.2016

Вот еще один пример того, как дождаться, пока входная дверь будет готова принимать прогнозы, используя функцию is_busy.

function void do_reset_key_registers(hmac_sha256_regblock parent_reg_block, uvm_reg      reg);
//$cast(parent_reg_block, this.get_parent());//this has been done outside
            fork 
                automatic uvm_reg reg=reg;//this is to copy the correct handle for each thread
                begin
                    if (reg.get_name=="inst_STATUS") begin
                        if  (reg.is_busy()) begin    wait(!reg.is_busy()); end//wait until this register is not busy 
                    end
                    assert( parent_reg_block.inst_STATUS.KEY_ERROR.predict(1));//key protect 0                                                    
                end
                begin
                    if (reg.get_name=="inst_KEY_0") begin
                        if  (reg.is_busy()) begin    wait(!reg.is_busy()); end//wait until this register is not busy 
                    end                    
                    assert( parent_reg_block.inst_KEY_0.KEY_0.predict(0));//reset KEYS 0
                end
            join_none
        endfunction: do_reset_key_registers
person Joniale    schedule 10.11.2017