32 / 37 · Практика
Комплексная практика: периодические импульсы и разрешаемый накопитель
Опишите передачу старых значений и проверьте паузы, непрерывные импульсы и одновременный сброс.
Уроки доступны бесплатно. Запишитесь, чтобы сохранять прогресс.
До композиции определите связь
Принимайте беззнаковый четырёхбитовый sample на каждом нарастающем фронте с enable=1. Каждый N-й принятый отсчёт создаёт регистрируемый pulse. Накопитель использует pulse и сохранённый соответствующий sample на следующем нарастающем фронте, даже при enable=0 в тот момент. Восьмибитовый total работает по модулю 256. Синхронный сброс очищает ступени и отбрасывает ожидающие данные. Задержка в один фронт входит в контракт: накопитель читает старые pulse/saved_sample, не новые неблокирующие значения того же фронта. Сохраните modulo_tick.sv и этот periodic_accumulator.sv; N положителен.
module periodic_accumulator #(parameter integer N = 3) (
input logic clk, rst, enable,
input logic [3:0] sample,
output logic pulse,
output logic [7:0] total
);
localparam integer CW = (N <= 1) ? 1 : $clog2(N);
wire [CW-1:0] count;
logic [3:0] saved_sample;
modulo_tick #(.N(N)) tick_u (
.clk(clk), .rst(rst), .enable(enable),
.count(count), .pulse(pulse)
);
always_ff @(posedge clk) begin
if (rst) saved_sample <= 4'b0;
else if (enable) saved_sample <= sample;
end
always_ff @(posedge clk) begin
if (rst) total <= 8'b0;
else if (pulse) total <= total + {4'b0, saved_sample};
end
endmoduleСледите за данными и событием вместе
N=3, входы до, выходы после фронта.
| Фронт | rst | enable | sample | pulse после | total после |
|---|---|---|---|---|---|
| E0 | 1 | 1 | 9 | 0 | 0 |
| E1 | 0 | 1 | 2 | 0 | 0 |
| E2 | 0 | 1 | 4 | 0 | 0 |
| E3 | 0 | 1 | 7 | 1 | 0 |
| E4 | 0 | 0 | 9 | 0 | 7 |
| E5 | 0 | 1 | 1 | 0 | 7 |
| E6 | 0 | 1 | 3 | 0 | 7 |
| E7 | 0 | 1 | 5 | 1 | 7 |
| E8 | 1 | 1 | 15 | 0 | 0 |
E4 добавляет 7, а не внешний sample=9. enable управляет только новым приёмом и не отменяет ожидающее действие. E8 отбрасывает 5 и очищает total. Условие enable && pulse при потреблении потеряло бы E4.
Эталон на границе системы
Храните количество принятых отсчётов, необязательное ожидающее значение и целочисленный total. Без сброса сначала потребите старое ожидающее по модулю 256; затем из текущих enable/sample сформируйте ожидание при N-м приёме. Сброс очищает всё. Не читайте tick_u.count или saved_sample. Задавайте стимулы на спадающем фронте и затем проверяйте pulse, total, удержание без события и удаление использованного.
Покройте ошибки соединения
- N=1 создаёт подряд идущие импульсы: каждый sample используется ровно один раз на следующем фронте.
- N=3 с паузами до/после конечного sample: считайте приёмы, не все такты.
- Меняйте внешний sample при потреблении с enable=0: используются сохранённые данные.
- Сброс при ожидающих данных удаляет событие и total.
- Сложите больше 255 и проверьте модуль 256.
Замените saved_sample на sample: E4 должен дать ошибку. Ограничьте потребление enable и подтвердите другой отказ. Восстановите до PASS. Проверен функциональный, однотактовый контракт конечной ширины; CDC, закрытие физических временных требований и бесплатное выполнение DDS не доказаны.