From fddad349dc6105feec368db6ce6f249e64f2b90f Mon Sep 17 00:00:00 2001 From: Reed Foster Date: Mon, 4 Dec 2023 15:29:00 -0500 Subject: [PATCH] added printing utils to sim_util_pkg, also fixed small 'bug' in sample discriminator that would drop the first sample immediately after coming out of reset. Not sure how much of a bug this really is though, since it's a pretty rare edge case that we generally wouldn't even run into let alone care about --- dds_test.srcs/sim_1/new/sim_util_pkg.sv | 33 +++++ .../timetagging_discriminating_buffer_test.sv | 120 ++++++++++-------- .../sources_1/new/sample_discriminator.sv | 34 +++-- ...ging_discriminating_buffer_test_behav.wcfg | 12 +- 4 files changed, 126 insertions(+), 73 deletions(-) diff --git a/dds_test.srcs/sim_1/new/sim_util_pkg.sv b/dds_test.srcs/sim_1/new/sim_util_pkg.sv index 9184be3..abcb263 100644 --- a/dds_test.srcs/sim_1/new/sim_util_pkg.sv +++ b/dds_test.srcs/sim_1/new/sim_util_pkg.sv @@ -52,4 +52,37 @@ package sim_util_pkg; endclass + typedef enum {DEFAULT=0, VERBOSE=1, DEBUG=2} verbosity_t; + + class debug #( + parameter verbosity_t VERBOSITY = DEFAULT + ); + + int error_count = 0; + + function display(input string message, input verbosity_t verbosity); + if (VERBOSITY >= verbosity) begin + $display(message); + end + endfunction + + function error(input string message); + $warning(message); + error_count = error_count + 1; + endfunction + + function finish(); + $display("#################################################"); + if (error_count == 0) begin + $display("# finished with zero errors"); + end else begin + $error("# finished with %0d errors", error_count); + $display("#################################################"); + end + $display("#################################################"); + $finish; + endfunction + + endclass + endpackage diff --git a/dds_test.srcs/sim_1/new/timetagging_discriminating_buffer_test.sv b/dds_test.srcs/sim_1/new/timetagging_discriminating_buffer_test.sv index b53461b..26a1f6c 100644 --- a/dds_test.srcs/sim_1/new/timetagging_discriminating_buffer_test.sv +++ b/dds_test.srcs/sim_1/new/timetagging_discriminating_buffer_test.sv @@ -3,7 +3,8 @@ import sim_util_pkg::*; `timescale 1ns / 1ps module timetagging_discriminating_buffer_test (); -sim_util_pkg::generic #(int) util; +sim_util_pkg::generic #(int) util; // abs, max functions on integers +sim_util_pkg::debug #(.VERBOSITY(DEFAULT)) dbg = new; // printing, error tracking logic clk = 0; localparam CLK_RATE_HZ = 100_000_000; @@ -11,8 +12,6 @@ always #(0.5s/CLK_RATE_HZ) clk = ~clk; logic reset; -int error_count = 0; - localparam int N_CHANNELS = 8; localparam int TSTAMP_BUFFER_DEPTH = 128; localparam int DATA_BUFFER_DEPTH = 1024; @@ -126,9 +125,9 @@ task check_results( // first report the size of the buffers for (int i = 0; i < N_CHANNELS; i++) begin - $display("data_sent[%0d].size() = %0d", i, data_sent[i].size()); + dbg.display($sformatf("data_sent[%0d].size() = %0d", i, data_sent[i].size()), DEFAULT); end - $display("data_received.size() = %0d", data_received.size()); + dbg.display($sformatf("data_received.size() = %0d", data_received.size()), DEFAULT); /////////////////////////////////////////////////////////////////// // organize DMA output into data structures for easier analysis @@ -207,27 +206,29 @@ task check_results( // first check that we didn't get any extra samples or timestamps for (int channel = 1 << banking_mode; channel < N_CHANNELS; channel++) begin if (timestamps[channel].size() > 0) begin - $warning( + dbg.error($sformatf( "received too many timestamps for channel %0d with banking mode %0d (got %0d, expected 0)", channel, banking_mode, timestamps[channel].size() - ); - error_count = error_count + 1; + )); end while (timestamps[channel].size() > 0) timestamps[channel].pop_back(); if (samples[channel].size() > 0) begin - $warning( + dbg.error($sformatf( "received too many samples for channel %0d with banking mode %0d (got %0d, expected 0)", channel, banking_mode, samples[channel].size() - ); - error_count = error_count + 1; + )); end while (samples[channel].size() > 0) samples[channel].pop_back(); // clean up data sent - $display("removing %0d samples from data_sent[%0d]", data_sent[channel].size(), channel); + dbg.display($sformatf( + "removing %0d samples from data_sent[%0d]", + data_sent[channel].size(), + channel + ), VERBOSE); while (data_sent[channel].size() > 0) begin data_sent[channel].pop_back(); timer[channel] = timer[channel] + 1'b1; @@ -236,17 +237,24 @@ task check_results( for (int channel = 0; channel < (1 << banking_mode); channel++) begin // report timestamp/sample queue sizes - $display("timestamps[%0d].size() = %0d", channel, timestamps[channel].size()); - $display("samples[%0d].size() = %0d", channel, samples[channel].size()); + dbg.display($sformatf( + "timestamps[%0d].size() = %0d", + channel, + timestamps[channel].size() + ), VERBOSE); + dbg.display($sformatf( + "samples[%0d].size() = %0d", + channel, + samples[channel].size() + ), VERBOSE); if (samples[channel].size() > data_sent[channel].size()) begin - $warning( + dbg.error($sformatf( "too many samples for channel %0d with banking mode %0d: got %0d, expected at most %0d", channel, banking_mode, samples[channel].size(), data_sent[channel].size() - ); - error_count = error_count + 1; + )); end ///////////////////////////// // check all the samples @@ -256,37 +264,35 @@ task check_results( is_high = 0; sample_index = 0; // index of sample in received samples buffer while (data_sent[channel].size() > 0) begin - $display( + dbg.display($sformatf( "processing sample %0d from channel %0d: samp = %0x, timer = %0x", data_sent[channel].size(), channel, data_sent[channel][$], timer[channel] - ); + ), DEBUG); if (disc_util.any_above_high(data_sent[channel][$], threshold_high[channel])) begin - $display( + dbg.display($sformatf( "%x contains a sample greater than %x", data_sent[channel][$], threshold_high[channel] - ); + ), DEBUG); if (!is_high) begin // new sample, should get a timestamp if (timestamps[channel].size() > 0) begin if (timestamps[channel][$] !== {timer[channel], sample_index}) begin - $warning( + dbg.error($sformatf( "mismatched timestamp: got %x, expected %x", timestamps[channel][$], {timer[channel], sample_index} - ); - error_count = error_count + 1; + )); end timestamps[channel].pop_back(); end else begin - $warning( + dbg.error($sformatf( "expected a timestamp (with value %x), but no more timestamps left", {timer[channel], sample_index} - ); - error_count = error_count + 1; + )); end end is_high = 1'b1; @@ -295,12 +301,11 @@ task check_results( end if (is_high) begin if (data_sent[channel][$] !== samples[channel][$]) begin - $warning( + dbg.error($sformatf( "mismatched data: got %x, expected %x", samples[channel][$], data_sent[channel][$] - ); - error_count = error_count + 1; + )); end samples[channel].pop_back(); sample_index = sample_index + 1'b1; @@ -310,33 +315,46 @@ task check_results( end // check to make sure we didn't miss any data if (timestamps[channel].size() > 0) begin - $warning( + dbg.error($sformatf( "too many timestamps leftover for channel %0d with banking mode %0d (got %0d, expected 0)", channel, banking_mode, timestamps[channel].size() - ); - error_count = error_count + 1; + )); end // flush out remaining timestamps - while (timestamps[channel].size() > 0) timestamps[channel].pop_back(); + while (timestamps[channel].size() > 0) begin + dbg.display($sformatf( + "extra timestamp %x", + timestamps[channel].pop_back() + ), DEBUG); + end if (samples[channel].size() > 0) begin - $warning( + dbg.error($sformatf( "too many samples leftover for channel %0d with banking mode %0d (got %0d, expected 0)", channel, banking_mode, samples[channel].size() - ); - error_count = error_count + 1; + )); end // flush out remaining samples - while (samples[channel].size() > 0) samples[channel].pop_back(); + while (samples[channel].size() > 0) begin + dbg.display($sformatf( + "extra sample %x", + samples[channel].pop_back() + ), DEBUG); + end // should not be any leftover data_sent samples, since the while loop // won't terminate until data_sent[channel] is empty. therefore don't // bother checking end for (int channel = 0; channel < N_CHANNELS; channel++) begin - $display("timer[%0d] = %0d (0x%x)", channel, timer[channel], timer[channel]); + dbg.display($sformatf( + "timer[%0d] = %0d (0x%x)", + channel, + timer[channel], + timer[channel] + ), DEBUG); end endtask @@ -413,7 +431,7 @@ initial begin threshold_high[i] <= 16'h0400; end end - 5: begin + 4: begin // send stuff that mostly gets filtered out for (int i = 0; i < N_CHANNELS; i++) begin data_range_low[i] <= 16'h0000; @@ -432,31 +450,21 @@ initial begin repeat (10) @(posedge clk); start_acq_with_banking_mode(bank_mode); - repeat (10) @(posedge clk); data_in.send_samples(clk, $urandom_range(50,500), in_valid_rand & 1'b1, 1'b1); repeat (10) @(posedge clk); stop_acq(); data_out.do_readout(clk, 1'b1, 100000); - $display("######################################################"); - $display("# checking results amplitude_mode = %d", amplitude_mode); - $display("# banking mode = %d", bank_mode); - $display("# samples sent with rand_valid = %d", in_valid_rand); - $display("######################################################"); + dbg.display("######################################################", DEFAULT); + dbg.display($sformatf("# checking results amplitude_mode = %d", amplitude_mode), DEFAULT); + dbg.display($sformatf("# banking mode = %d", bank_mode), DEFAULT); + dbg.display($sformatf("# samples sent with rand_valid = %d", in_valid_rand), DEFAULT); + dbg.display("######################################################", DEFAULT); check_results(bank_mode, threshold_high, threshold_low, timer); end end end - - $display("#################################################"); - if (error_count == 0) begin - $display("# finished with zero errors"); - end else begin - $error("# finished with %0d errors", error_count); - $display("#################################################"); - end - $display("#################################################"); - $finish; + dbg.finish(); end endmodule diff --git a/dds_test.srcs/sources_1/new/sample_discriminator.sv b/dds_test.srcs/sources_1/new/sample_discriminator.sv index c1a0183..0515a1a 100644 --- a/dds_test.srcs/sources_1/new/sample_discriminator.sv +++ b/dds_test.srcs/sources_1/new/sample_discriminator.sv @@ -85,9 +85,6 @@ always_ff @(posedge clk) begin data_in_valid <= data_in.valid; data_in_reg <= data_in.data; - // is_high_d - is_high_d <= is_high; - // match delay of sample_index data_out.data <= data_in_reg; data_out.valid <= data_in_valid & is_high; @@ -99,19 +96,36 @@ always_ff @(posedge clk) begin timer <= '0; sample_index <= '0; end else begin + // update sample_index, timer and is_high for each channel for (int i = 0; i < N_CHANNELS; i++) begin - // update sample_index and is_high - // don't reset timer, since we want - // to be able to track the arrival time of - // samples between multiple captures if (reset_state) begin + // don't reset timer, since we want + // to be able to track the arrival time of + // samples between multiple captures + // + // reset is_high_d so that we can correctly capture a + // new sample if it arrives immediately after reset_state + // is deasserted + is_high_d[i] <= 1'b0; + // reset sample_index sample_index[i] <= '0; - is_high[i] <= 1'b0; + if (data_in.ok[i] && any_above_high[i]) begin + // keep is_high if input data is valid and above threshold + // that way we don't miss the first sample + is_high[i] <= 1'b1; + end else begin + // only reset is_high if the current data is not high + is_high[i] <= 1'b0; + end end else begin + // update is_high_d every cycle + is_high_d[i] <= is_high[i]; if (data_in_valid[i] && is_high[i]) begin + // only update sample index when we send out a valid sample that has + // met the criteria of the discriminator sample_index[i] <= sample_index[i] + 1'b1; end - // update is_high only when we get a new sample + // update is_high only when we get a new, valid sample if (data_in.ok[i]) begin if (any_above_high[i]) begin is_high[i] <= 1'b1; @@ -120,7 +134,7 @@ always_ff @(posedge clk) begin end end end - // update timer + // update timer (input sample counter) if (data_in.ok[i]) begin timer[i] <= timer[i] + 1'b1; end diff --git a/timetagging_discriminating_buffer_test_behav.wcfg b/timetagging_discriminating_buffer_test_behav.wcfg index a299d0c..c87f038 100644 --- a/timetagging_discriminating_buffer_test_behav.wcfg +++ b/timetagging_discriminating_buffer_test_behav.wcfg @@ -12,9 +12,9 @@ - - - + + + @@ -32,10 +32,6 @@ reset reset - - error_count[31:0] - error_count[31:0] - start start @@ -463,10 +459,12 @@ threshold_low[7:0][15:0] threshold_low[7:0][15:0] + threshold_high[7:0][15:0] threshold_high[7:0][15:0] + data_in_reg[7:0][15:0]