Skip to content

Commit

Permalink
working on improved multichannel sample_discriminator which can be in…
Browse files Browse the repository at this point in the history
…terfaced with the banked_sample_buffer
  • Loading branch information
reed-foster committed Oct 11, 2023
1 parent 0931312 commit caa6aa1
Show file tree
Hide file tree
Showing 3 changed files with 379 additions and 452 deletions.
197 changes: 94 additions & 103 deletions dds_test.srcs/sim_1/new/sample_discriminator_test.sv
Original file line number Diff line number Diff line change
Expand Up @@ -6,158 +6,149 @@ localparam CLK_RATE_HZ = 100_000_000;
always #(0.5s/CLK_RATE_HZ) clk = ~clk;

logic reset;
logic signed [15:0] threshold_high, threshold_low;

Axis_If #(.DWIDTH(32)) config_in_if();
Axis_If #(.DWIDTH(16)) data_in_if();
Axis_If #(.DWIDTH(16)) data_out_if();
localparam int N_CHANNELS = 2;
localparam int SAMPLE_WIDTH = 16;
localparam int PARALLEL_SAMPLES = 4;
localparam int SAMPLE_INDEX_WIDTH = 14;
localparam int CLOCK_WIDTH = 50;

assign config_in_if.data = {threshold_high, threshold_low};
Axis_If #(.DWIDTH(N_CHANNELS*SAMPLE_WIDTH*2)) config_in();
Axis_Parallel_If #(.DWIDTH(SAMPLE_WIDTH*PARALLEL_SAMPLES), .PARALLEL_CHANNELS(N_CHANNELS)) data_in();
Axis_Parallel_If #(.DWIDTH(SAMPLE_WIDTH*PARALLEL_SAMPLES), .PARALLEL_CHANNELS(N_CHANNELS)) data_out();
Axis_Parallel_If #(.DWIDTH(SAMPLE_INDEX_WIDTH+CLOCK_WIDTH), .PARALLEL_CHANNELS(N_CHANNELS)) timestamps_out();

logic signed [N_CHANNELS-1:0][SAMPLE_WIDTH-1:0] threshold_high, threshold_low;
assign config_in.data = {threshold_high, threshold_low};

logic sample_index_reset;

sample_discriminator #(
.SAMPLE_WIDTH(16),
.CLOCK_WIDTH(56)
.SAMPLE_WIDTH(SAMPLE_WIDTH),
.PARALLEL_SAMPLES(PARALLEL_SAMPLES),
.N_CHANNELS(N_CHANNELS),
.SAMPLE_INDEX_WIDTH(SAMPLE_INDEX_WIDTH),
.CLOCK_WIDTH(CLOCK_WIDTH)
) dut_i (
.clk,
.reset,
.data_in(data_in_if),
.data_out(data_out_if),
.config_in(config_in_if)
.data_in,
.data_out,
.timestamps_out,
.config_in,
.sample_index_reset
);

logic [15:0] data_sent [$];
logic [55:0] timestamps_sent [$];
logic [15:0] data_received [$];
logic [15:0] timestamps_received [$];

logic [55:0] sample_count;
logic [15:0] data_in_d;
logic data_in_valid_d;
logic is_high, is_high_d;
logic new_is_high;
logic [SAMPLE_WIDTH*PARALLEL_SAMPLES-1:0] data_sent [N_CHANNELS][$];
logic [SAMPLE_WIDTH*PARALLEL_SAMPLES-1:0] data_received [N_CHANNELS][$];
logic [SAMPLE_INDEX_WIDTH+CLOCK_WIDTH-1:0] timestamps_received [N_CHANNELS][$];

assign new_is_high = is_high & (!is_high_d);

logic [15:0] data_range_low, data_range_high;
logic [N_CHANNELS-1:0][SAMPLE_WIDTH-1:0] data_range_low, data_range_high;

always @(posedge clk) begin
if (reset) begin
sample_count <= '0;
data_in_if.data <= '0;
is_high_d <= '0;
is_high <= '0;
data_in.data <= '0;
end else begin
data_in_valid_d <= data_in_if.valid;
if (data_in_if.valid && data_in_if.ready) begin
data_in_d <= data_in_if.data;
is_high_d <= is_high;
if (signed'(data_in_if.data) > threshold_high) begin
is_high <= 1'b1;
end else if (signed'(data_in_if.data) < threshold_low) begin
is_high <= 1'b0;
end
sample_count <= sample_count + 1'b1;
data_in_if.data <= $urandom_range(data_range_low, data_range_high);
end
if (data_in_valid_d) begin
if (is_high) begin
data_sent.push_front(data_in_d & 16'hfff8);
for (int i = 0; i < N_CHANNELS; i++) begin
if (data_in.ok[i]) begin
data_sent[i].push_front(data_in.data[i]);
data_in.data[i] <= $urandom_range(data_range_low[i], data_range_high[i]);
end
if (new_is_high) begin
timestamps_sent.push_front(sample_count);
if (data_out.ok[i]) begin
data_received[i].push_front(data_out.data[i]);
end
end
if (data_out_if.valid && data_out_if.ready) begin
if (data_out_if.data[1]) begin
// timestamp
timestamps_received.push_front(data_out_if.data & 16'hfffc);
end else begin
// data
data_received.push_front(data_out_if.data & 16'hfff8);
if (timestamps_out.ok[i]) begin
timestamps_received[i].push_front(timestamps_out.data[i]);
end
end
end
end

// not 100% activity on output
always @(posedge clk) begin
data_out_if.ready <= $urandom_range(0,1);
end
assign data_out.ready = '1;
assign timestamps_out.ready = '1;

task send_samples(input int n_samples);
repeat (n_samples) begin
data_in_if.valid <= 1'b1;
task send_samples(input int n_samples, input bit rand_arrivals);
int samples_sent [N_CHANNELS];
logic [N_CHANNELS-1:0] done;
if (rand_arrivals) begin
done = '0;
while (~done) begin
data_in.valid <= $urandom_range((1<<N_CHANNELS) - 1) & (~done);
for (int i = 0; i < N_CHANNELS; i++) begin
if (data_in.valid[i]) begin
samples_sent[i] <= samples_sent[i] + 1'b1;
if (samples_sent[i] == n_samples - 1) begin
done[i] = 1'b1;
end else begin
samples_sent[i] <= samples_sent[i] + 1'b1;
end
end
end
@(posedge clk);
end
data_in.valid <= '0;
@(posedge clk);
data_in_if.valid <= 1'b0;
repeat (4) @(posedge clk);
end else begin
data_in.valid <= '1;
repeat (n_samples) begin
@(posedge clk);
end
data_in.valid <= '0;
end
endtask

task check_results();
logic [55:0] tstamp_temp;
$display("data_sent.size() = %0d", data_sent.size());
$display("data_received.size() = %0d", data_received.size());
if (data_sent.size() != data_received.size()) begin
$display("mismatch in amount of sent/received data");
for (int i = data_sent.size() - 1; i >= 0; i--) begin
$display("data_sent[%0d] = %x", i, data_sent[i]);
end
for (int i = data_received.size() - 1; i >= 0; i--) begin
$display("data_received[%0d] = %x", i, data_received[i]);
end
for (int i = 0; i < N_CHANNELS; i++) begin
$display("data_sent[%0d].size() = %0d", i, data_sent[i].size());
$display("data_received[%0d].size() = %0d", i, data_received[i].size());
$display("timestamps_received[%0d].size() = %0d", i, timestamps_received[i].size());
end
$display("timestamps_sent.size() = %0d", timestamps_sent.size());
$display("timestamps_received.size() = %0d", timestamps_received.size());
if (timestamps_sent.size()*4 != timestamps_received.size()) begin
$display("mismatch in amount of sent/received timestamps");
for (int i = timestamps_sent.size() - 1; i >= 0; i--) begin
$display("timestamps_sent[%0d] = %x", i, timestamps_sent[i]);
for (int i = 0; i < N_CHANNELS; i++) begin
for (int j = 0; j < data_sent[i].size(); j++) begin
$display("data_sent[%0d][%0d] = %x", i, data_sent[i].size() - j - 1, data_sent[i][$-j]);
end
for (int i = timestamps_received.size() - 1; i >= 0; i--) begin
$display("timestamps_received[%0d] = %x", i, timestamps_received[i]);
for (int j = 0; j < data_received[i].size(); j++) begin
$display("data_received[%0d][%0d] = %x", i, data_received[i].size() - j - 1, data_received[i][$-j]);
end
end
while (data_sent.size() > 0 && data_received.size() > 0) begin
if (data_sent[$] != data_received[$]) begin
$display("data mismatch error (received %x, sent %x)", data_received[$], data_sent[$]);
for (int j = 0; j < timestamps_received[i].size(); j++) begin
$display("timestamps_received[%0d][%0d] = %x", i, timestamps_received[i].size() - j - 1, timestamps_received[i][$-j]);
end
data_sent.pop_back();
data_received.pop_back();
end
while (timestamps_sent.size() > 0 && timestamps_received.size() > 0) begin
for (int i = 0; i < 4; i++) begin
tstamp_temp[i*14+:14] = timestamps_received.pop_back() >> 2;
end
if (timestamps_sent[$] != tstamp_temp) begin
$display("timestamp mismatch error (received %x, sent %x)", tstamp_temp, timestamps_sent[$]);
end
timestamps_sent.pop_back();
end
endtask

initial begin
reset <= 1'b1;
data_range_low <= 16'h0000;
data_range_high <= 16'hffff;
data_range_low <= '0;
data_range_high <= '1;
threshold_low <= '0;
threshold_high <= '0;
data_in_if.valid <= '0;
data_in.valid <= '0;
sample_index_reset <= '0;
repeat (100) @(posedge clk);
reset <= 1'b0;
sample_index_reset <= 1'b1;
@(posedge clk);
sample_index_reset <= '0;
repeat (50) @(posedge clk);
send_samples(10, 1);
repeat (50) @(posedge clk);
send_samples(50);
send_samples(10, 0);
repeat (50) @(posedge clk);
check_results();
$finish;
// change amplitudes and threshold to check sample-rejection
// first, try sending small signals that shouldn't make it through
data_range_low <= 16'h00ff;
data_range_high <= 16'h0fff;
data_range_high <= 16'h02ff;
threshold_low <= 16'h03ff;
threshold_high <= 16'h07ff;
config_in_if.valid <= 1'b1;
config_in.valid <= 1'b1;
@(posedge clk);
config_in_if.valid <= 1'b0;
config_in.valid <= 1'b0;
repeat (50) @(posedge clk);
send_samples(200);
send_samples(200, 0);
repeat (50) @(posedge clk);
// should have 200 samples
check_results();
$finish;
end
Expand Down
Loading

0 comments on commit caa6aa1

Please sign in to comment.