Опубликован: 04.08.2025 | Доступ: свободный | Студентов: 12 / 0 | Длительность: 02:58:00
Лекция 3:

Разработка цифровых ИС на примере микроконтроллерного ядра SCR1 - верификация и тестирование

GTKWave

Для возможности просматривать временные диаграммы необходимо установить ПО "GTKWave"

sudo apt install gtkwave

Тестовое окружение

Микропроцессорное ядро "SCR1" поставляется с рядом тестовых программ:

  • hello - простая программа "Hello", выводящая в консоль "Hello from SCR1!".
  • isr_sample - пример программы обработки прерываний.
  • riscv_isa - RISC-V ISA тест.
  • riscv_arch - RISC-V архитектурный тест.
  • riscv_compliance - тест на соответствие требованиям RISC-V
  • dhrystone21 - Dhrystone 2.1 бенчмарк.
  • coremark - EEMBC's CoreMark бенчмарк.

Запуск тестов

Запуск тестов осуществляется из корневой директории "scr1" с использованием команды "make" и поддерживает следующие опции:

  • Выбор симулятора - run_<SIMULATOR>
  • Архитектурная настройка - CFG (конфигурация), BUS (внешняя шина), ARCH (поддерживаемая ISA), VECT_IRQ (векторный режим обработки прерываний), IPIC (включение/выключение IPIC), TCM (включение/выключение IPIC).
  • Выбор теста - TARGETS.
  • Включение лога выполнения программы - TRACE.
  • Дополнительные опции симулятора - SIM_BUILD_OPTS.

Для описания работы ядра будет использоваться тест "riscv_isa". Конфигурация ядра - MAX с шиной AHB.

Команда для запуска тестов:

make run_verilator_wf TARGETS=&riscv_isa" TRACE=1

Между запусками тестов необходимо выполнять команду "make clean" для корректного перезапуска.

Обработка инструкций конвейером

Далее будут рассмотрена обработка инструкций различных типов:

  • R-тип;
  • I-тип;
  • S-тип;
  • B-тип;
  • U-тип;
  • J-тип.

Будет использоваться конфигурация "MAX" с шиной AHB.

Так как некоторые стадии обработки инструкций, например, запрос и получение инструкции, одинаковы для всех типов инструкций, их описание будет обобщено. Все сигналы, представленные на временных диаграммах, соответствуют одному периоду тактового сигнала.

Запрос инструкции


На стадии запроса инструкции блок выборки выставляет в "1" сигнал запроса инструкции (core2imem_req) и формирует адрес в памяти (core2imem_addr). При этом сигнал (core2imem_cmd) имеет значение "0", что означает запрос на чтение. Блок выборки ждет подтверждения запроса от памяти инструкций (imem2core_req_ack_i), в случае подтверждения запроса в блоке выборки выставляется в "1" сигнал imem_handshake_done.


Подтверждение транзакции также означает, что на следующем такте будет изменен адрес запроса к памяти инструкций.

Поскольку на текущем такте статус ответа памяти инструкций (imem2core_resp_i) равен "00", что означает отсутствие данных, также будет инкрементирован счетчик отложенных транзакций (imem_pnd_txns_cnt). Данный счетчик показывает сколько слов данных ожидает ядро от памяти инструкций.

Получение инструкции


Ответ от памяти инструкций приходит с задержкой в один такт или больше, в зависимости от латентности (англ. latency) используемой памяти. Для TCM задержка всегда равна одному такту.

Сигнал imem2core_resp_i содержит статус ответа от памяти инструкций, "01" соответствует чтению без ошибки, "10" чтению с ошибкой.

Полученное слово данных (imem2core_rdata_i) предварительно декодируется.


Предварительное декодирование представляет собой определение типов инструкций, содержащихся в считанном слове данных, например две 16-битных инструкции или одна 32-битная. В данном случае тип инструкции (instr_type) - 001, т.е. одна 32-битная инструкция.

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


В случае использования отдельной стадии конвейера для декодирования в очередь инструкций зачастую будет записываться целое слово данных, за исключением случаев считывания инструкции по не выровненному адресу.

В данном примере значение "01" сигнала q_wr_size и значение "1" сигнала "q_wr_full" означает запись целого слова данных. Сигнал q_wr_en разрешает запись в очередь инструкций.


Очередь инструкций представляет собой буфер FIFO шириной 16 бит и глубиной 4.

Так как записываться будет целое слово данных, указатель записи увеличивается на 2 (с 00 до 01). По адресу "00" будет записано значение сигнала imem_rdata_lo (2573), а по адресу "01" значение сигнала imem_rdata_hi (F140).

Декодирование инструкции


Если декодер готов принять данные (idu2ifu_rdy_i = 1), а очередь инструкций готова их предоставить (ifu2idu_vd_o), происходит считывание данных из очереди инструкций (q_rd_vd).

В зависимости от типа инструкции, содержащейся по текущему адресу чтения из буфера (сигналы q_head_is_rvi или q_head_is_rvc), рассчитывается ширина считываемой инструкции. В данном случае значение "01" сигнала q_rd_size означает, что считывается 32-битная инструкция.


Отметим, что в буфере FIFO используется память с асинхронным чтением, т.е. считываемые данные уже находятся на выходе во время чтения. Т.о. запрос на чтение данных и само чтение происходят в одном такте.

Поскольку считывалось 32 бита, указатель на чтение q_rptr увеличится на 2 (с 00 на 10). Считываемую инструкцию содержит сигнал ifu2idu_instr_o.

Во время декодирования инструкции заполняется структура типа "type_scr1_exu_cmd_s".

typedef struct packed {
   logic                         instr_rvc; Тип инструкции
   type_scr1_ialu_op_sel_e           ialu_op; Операнды АЛУ
   type_scr1_ialu_cmd_sel_e          ialu_cmd; Тип операции АЛУ
   type_scr1_ialu_sum2_op_sel_e       sum2_op; Операнды для вычисления целей ветвления/прыжка и 
                                                                              адресов чтения/записи
   type_scr1_lsu_cmd_sel_e               lsu_cmd; Тип операции с памятью
…
   type_scr1_rd_wb_sel                     _e rd_wb_sel; Источник данных для записи в MPRF
   logic                               jump_req; Флаг инструкции прыжка (безусловного ветвления)
   logic                               branch_req; Флаг инструкции ветвления
…
   logic [SCR1_GPR_FIELD_WIDTH-1:0]      rs1_addr; Адрес первого операнда в MPRF
   logic [SCR1_GPR_FIELD_WIDTH-1:0]      rs2_addr; Адрес второго операнда в MPRF
   logic [SCR1_GPR_FIELD_WIDTH-1:0]      rd_addr; Адрес регистра-назначения в MPRF
   logic [`SCR1_XLEN-1:0]                imm;             Непосредственное значение
…
} type_scr1_exu_cmd_s;