Дешифрация адреса
Вы узнаете
Сколько адресных бит стоит количество периферии и что проверяет стенд моста.
Адресация на APB — вопрос бит: сколько слуг сидит за мостом, столько бит дешифрация тратит. Спека отвечает по счёту — addr_bits_for_1_peripheral, addr_bits_for_4_peripherals, addr_bits_for_8_peripherals — а её тестбенч гоняет результат: test_reset_state, test_apb_write, test_apb_read, test_write_read_roundtrip, test_multiple_apb_writes, восемь тестов. Запись опускает тестбенч-спеку моста APB в Verilog.
Попробовать
В записи найдите тесты стенда; затем в спеке вычислите, сколько адресных бит спека тратит на 8 периферий.

The APB bridge testbench spec lowered to Verilog: what a bench looks like when the compiler emits it.
specs/fpga/testbench/apb_bridge_tb.t27
// SPDX-License-Identifier: Apache-2.0
// t27/specs/fpga/testbench/apb_bridge_tb.t27
// APB Bridge Testbench
// Tests APB bus protocol: setup, access, wait states
// phi^2 + 1/phi^2 = 3 | TRINITY
module APB_Bridge_Testbench {
use fpga::apb_bridge::ApbBridge;
const CLK_PERIOD : u32 = 20;
const SIM_TIMEOUT : u32 = 5_000_000;
const APB_ADDR_WIDTH : u32 = 12;
const APB_DATA_WIDTH : u32 = 32;
var clk : bool = false;
var rst_n : bool = false;
var psel : bool = false;
var penable : bool = false;
var pwrite : bool = false;
var paddr : u32 = 0;
var pwdata : u32 = 0;
var prdata : u32 = 0;
var pready : bool = false;
var pslverr : bool = false;
var test_passed : u32 = 0;
var test_failed : u32 = 0;
fn tick() {
clk = false;
clk = true;
}
fn reset() {
rst_n = false;
tick();
tick();
rst_n = true;
tick();
}
fn apb_write(addr : u32, data : u32) -> bool {
paddr = addr;
pwdata = data;
pwrite = true;
psel = true;
penable = false;
tick();
penable = true;
tick();
while !pready { tick(); }
psel = false;
penable = false;
pwrite = false;
return !pslverr;
}
fn apb_read(addr : u32) -> u32 {
paddr = addr;
pwrite = false;
psel = true;
penable = false;
tick();
penable = true;
tick();
while !pready { tick(); }
var data : u32 = prdata;
psel = false;
penable = false;
return data;
}
test test_reset_state {
reset();
invariant pready == true || pready == false;
invariant pslverr == false;
}
test test_apb_write {
reset();
var ok : bool = apb_write(0x100, 0xDEAD);
invariant ok == true;
invariant pslverr == false;
}
test test_apb_read {
reset();
var val : u32 = apb_read(0x100);
invariant pslverr == false;
}
test test_write_read_roundtrip {
reset();
apb_write(0x200, 0xCAFEBABE);
var val : u32 = apb_read(0x200);
invariant val == 0xCAFEBABE;
}
test test_multiple_apb_writes {
reset();
var i : u32 = 0;
while i < 8 {
apb_write(0x000 + i * 4, i * 0x10);
i = i + 1;
}
i = 0;
while i < 8 {
var val : u32 = apb_read(0x000 + i * 4);
invariant val == i * 0x10;
i = i + 1;
}
}
test test_protocol_phases {
reset();
psel = true;
penable = false;
tick();
invariant psel == true;
penable = true;
tick();
invariant penable == true;
psel = false;
penable = false;
}
invariant addr_width_valid : APB_ADDR_WIDTH > 0;
invariant data_width_valid : APB_DATA_WIDTH == 32;
test test_tick_functionality {
reset();
var initial_clk : bool = clk;
tick();
var after_tick_clk : bool = clk;
invariant after_tick_clk != initial_clk;
}
bench bench_apb_throughput {
reset();
var i : u32 = 0;
while i < 64 {
apb_write(i * 4, i);
i = i + 1;
}
i = 0;
while i < 64 {
apb_read(i * 4);
i = i + 1;
}
}
test "tick_function" {
reset();
var initial_clk : bool = clk;
tick();
invariant initial_clk != clk;
}
}
Все уроки
Модуль 1 · Что такое шина
Зачем вообще существует шина: разговор по проводам, с кадрами и адресами, и кому позволено говорить.
Модуль 2 · Разговор по UART
Двухпроводная шина без такта: кадр, делитель, задающий скорость, и статус, который опрашивает драйвер.
Модуль 3 · SPI под тактом
Разговор под тактом: четыре режима, лестница предделителей и выбор кристалла на каждого подчинённого.
Модуль 4 · Регистровая шина APB
Шина регистров: PSEL и PENABLE, строобы и ожидания, и сколько адресных бит стоит количество периферии.
Модуль 5 · Пять каналов AXI4
Пять каналов: адрес, данные и отклик в обе стороны, lite или full, пакеты и идентификаторы.
Модуль 6 · Память
Что находится на дальнем конце каждой шины: карты памяти, типы портов и задержка, которую должно покрывать ожидание.
Модуль 7 · Мосты
Почему в дизайне появляется больше одной шины и пакетный мост, переносящий работу между ними.
Модуль 8 · Ethernet: кадры и тайминг
Кадры, контрольная сумма кадра, тайминг RGMII и заранее зарегистрированные шаги настоящего запуска.
Модуль 9 · Стенд
Дисциплина, оберегающая настоящее железо: кто держит IO, как взять и вернуть захват, и что запускается дальше.