diff --git a/rtl/generator/src/generator.sv b/rtl/generator/src/generator.sv index dfbf5c3..58d150a 100644 --- a/rtl/generator/src/generator.sv +++ b/rtl/generator/src/generator.sv @@ -68,10 +68,10 @@ module generator dac_out <= pulse_height_reg; else dac_out <= ZERO_LEVEL; - cnt_pulse_period <= cnt_pulse_period + 1; + cnt_pulse_period++; end else if (cnt_pulse_period == pulse_period_reg) begin - cnt_pulse_num <= cnt_pulse_num + 1; + cnt_pulse_num++; cnt_pulse_period <= 0; synced <= 0; dac_out <= ZERO_LEVEL; diff --git a/rtl/generator/tests/generator_tb.sv b/rtl/generator/tests/generator_tb.sv index d70ceec..621766a 100644 --- a/rtl/generator/tests/generator_tb.sv +++ b/rtl/generator/tests/generator_tb.sv @@ -24,6 +24,15 @@ module generator_tb; wire [DATA_WIDTH-1:0] dac_out; // DAC input logic signal wire generator_done; // generator request for synchronization + // === Переменные === + int current_zero_level; + initial begin + if (ZERO_LEVEL == "true") + current_zero_level = VOLTAGE_ZERO_LEVEL; + else + current_zero_level = LOGIC_ZERO_LEVEL; + end + // DUT generate if (ZERO_LEVEL == "true") begin : gen_dut_true @@ -202,19 +211,73 @@ module generator_tb; end end join - repeat(pulse_p) @(posedge clk); + repeat(pulse_p+5) @(posedge clk); disable counter_proc; // Ожидание завершения переходных процессов repeat(10) @(posedge clk); if (total_impulse_cycles == pulse_w*pulse_n) - $display("[TB] -check_impulses- Pulse generation correct"); + $display("[TB] -check_impulses- Pulse generation CORRECT"); else begin - $display("[ERROR] -check_impulses- Pulse generation incorrect. Total number of pulses: %d, must be: %d", total_impulse_cycles, pulse_w*pulse_n); + $display("[ERROR] -check_impulses- Pulse generation INCORRECT. Total number of pulses: %d, must be: %d", total_impulse_cycles, pulse_w*pulse_n); $finish; end $display("[TB] -check_impulses- Done"); endtask + task automatic run_test_case( + input int pulse_w, + input int pulse_p, + input int pulse_n, + input int pulse_h, + input bit skip_reset + ); + int total_impulse_cycles = 0; + + if (!skip_reset) begin + reset_dut(1); + @(posedge clk); + end + + set_config( + .w(pulse_w), + .p(pulse_p), + .n(pulse_n), + .h(pulse_h) + ); + @(posedge clk); + + start_dut(1); + + // Фоновый процесс подсчета тактов импульса + fork + begin : counter_proc + forever begin + @(posedge dac_wrt); + if (dac_out == pulse_h) begin + total_impulse_cycles++; + end + end + end + join_none + + repeat(pulse_n) begin + synchronize( + .sampler_first(0), + .delay_before_ack(1), + .ack_duration(2) + ); + end + repeat(pulse_p+5) @(posedge clk); + disable counter_proc; + repeat(10) @(posedge clk); + + if (total_impulse_cycles == pulse_w*pulse_n) + $display("[TB] -run_test_case- Pulse generation CORRECT"); + else begin + $display("[ERROR] -run_test_case- Pulse generation INCORRECT. Total number of pulses: %d, must be: %d", total_impulse_cycles, pulse_w*pulse_n); + $finish; + end + endtask // --- ОСНОВНОЙ ПРОЦЕСС ТЕСТИРОВАНИЯ --- initial begin @@ -229,7 +292,39 @@ module generator_tb; pulse_num = 0; sampler_done = 0; + $display("[TB] Test 1. Random latency for control signals"); check_impulses(); + $display("[TB] Test 1 complete"); + + $display("[TB] Test 2. Random configs"); + for (int i = 0; i < 25; i++) begin + int r_w, r_p, r_n, r_h; + bit r_skip; + + // Генерируем параметры + r_p = $urandom_range(5, 50); // Период от 5 до 50 + r_w = $urandom_range(0, r_p); // Ширина не больше периода + r_n = $urandom_range(1, 10); // Количество импульсов + r_h = $urandom_range(1, 2**DATA_WIDTH-1); // Высота (для 14 бит) + r_skip = $urandom_range(0, 1); // Случайный сброс (0 - сброс, 1 - пропуск) + + // Защита от "нулевого" импульса. Невозможно проверить длительность. + if (r_h == current_zero_level) begin + r_h += $urandom_range(1, 10); + end + + $display("[TB] --- Test #%0d (Config: W=%0d, P=%0d, N=%0d, H=%0d, SkipReset=%0b) ---", + i+1, r_w, r_p, r_n, r_h, r_skip); + + run_test_case( + .pulse_w(r_w), + .pulse_p(r_p), + .pulse_n(r_n), + .pulse_h(r_h), + .skip_reset(r_skip) + ); + end + $display("[TB] Test 2 complete"); $display("[TB] All Tests complete!"); $finish;