diff --git a/banked_sample_buffer_test_behav.wcfg b/banked_sample_buffer_test_behav.wcfg
index 3788fb2..71f9173 100644
--- a/banked_sample_buffer_test_behav.wcfg
+++ b/banked_sample_buffer_test_behav.wcfg
@@ -11,13 +11,13 @@
-
-
-
+
+
+
-
+
@@ -75,11 +75,6 @@
banks_full[7:0]
banks_full[7:0]
-
-
-
- first
- first
banks_first[7:0]
@@ -157,6 +152,7 @@
data[7:0][15:0]
data[7:0][15:0]
+
ready[7:0]
@@ -165,15 +161,16 @@
valid[7:0]
valid[7:0]
-
last[7:0]
last[7:0]
+
ok[7:0]
ok[7:0]
+
DWIDTH[31:0]
@@ -200,7 +197,6 @@
valid[7:0]
valid[7:0]
-
last[7:0]
@@ -300,6 +296,10 @@
full
full
+
+ first
+ first
+
state[31:0]
state[31:0]
@@ -352,67 +352,68 @@
SAMPLE_WIDTH[31:0]
SAMPLE_WIDTH[31:0]
-
- din
+
+ data_in
label
-
-
- data[15:0]
- data[15:0]
-
-
- ready
- ready
-
-
- valid
- valid
-
-
- last
- last
-
-
- ok
- ok
-
-
- DWIDTH[31:0]
- DWIDTH[31:0]
-
-
- dout
+
+
+ data[15:0]
+ data[15:0]
+
+
+ ready
+ ready
+
+
+ valid
+ valid
+
+
+ last
+ last
+
+
+ ok
+ ok
+
+
+ DWIDTH[31:0]
+ DWIDTH[31:0]
+
+
+
+ data_out
label
-
-
- data[15:0]
- data[15:0]
-
-
- ready
- ready
-
-
- valid
- valid
-
-
- last
- last
-
-
- ok
- ok
-
-
- DWIDTH[31:0]
- DWIDTH[31:0]
+
+
+ data[15:0]
+ data[15:0]
+
+
+ ready
+ ready
+
+
+ valid
+ valid
+
+
+ last
+ last
+
+
+ ok
+ ok
+
+
+ DWIDTH[31:0]
+ DWIDTH[31:0]
+
bank_1
label
-
clk
clk
@@ -579,7 +580,6 @@
bank_2
label
-
clk
clk
@@ -1124,7 +1124,6 @@
bank_6
label
-
clk
clk
@@ -1261,7 +1260,6 @@
bank_7
label
-
clk
clk
diff --git a/dds_test.srcs/sim_1/new/banked_sample_buffer_test.sv b/dds_test.srcs/sim_1/new/banked_sample_buffer_test.sv
index 1ea397f..76fe218 100644
--- a/dds_test.srcs/sim_1/new/banked_sample_buffer_test.sv
+++ b/dds_test.srcs/sim_1/new/banked_sample_buffer_test.sv
@@ -35,11 +35,11 @@ banked_sample_buffer #(
.config_in
);
-
int sample_count [N_CHANNELS];
logic [PARALLEL_SAMPLES*SAMPLE_WIDTH-1:0] data_sent [N_CHANNELS][$];
logic [PARALLEL_SAMPLES*SAMPLE_WIDTH-1:0] data_received [$];
+// send data to DUT and save sent/received data
always @(posedge clk) begin
for (int i = 0; i < N_CHANNELS; i++) begin
if (reset) begin
@@ -63,61 +63,6 @@ always @(posedge clk) begin
end
end
-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
- // reset
- done = '0;
- for (int i = 0; i < N_CHANNELS; i++) begin
- samples_sent[i] = 0;
- end
- while (~done) begin
- for (int i = 0; i < N_CHANNELS; i++) begin
- if (data_in.valid[i]) begin
- 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
- data_in.valid <= $urandom_range((1< 0) begin
current_channel = data_received.pop_back();
n_samples = data_received.pop_back();
- //current_channel = temp_sample & 3'h7;
- //n_samples = temp_sample >> 3;
$display("processing new bank with %0d samples from channel %0d", n_samples, current_channel);
for (int i = 0; i < n_samples; i++) begin
if (data_sent[current_channel][$] != data_received[$]) begin
$display("data mismatch error (channel = %0d, sample = %0d, received %x, sent %x)", current_channel, i, data_received[$], data_sent[current_channel][$]);
+ error_count = error_count + 1;
end
data_sent[current_channel].pop_back();
data_received.pop_back();
@@ -144,6 +88,7 @@ task check_results(input int banking_mode);
// corresponding to channels which are enabled as per banking_mode
if (data_sent[i].size() > 0) begin
$warning("leftover samples in data_sent[%0d]: %0d", i, data_sent[i].size());
+ error_count = error_count + 1;
end
end
for (int i = (1 << banking_mode); i < N_CHANNELS; i++) begin
@@ -160,9 +105,20 @@ task start_acq_with_banking_mode(input int mode);
@(posedge clk);
start <= 1'b0;
config_in.valid <= 1'b0;
- repeat (100) @(posedge clk);
endtask
+task stop_acq();
+ stop <= 1'b1;
+ start <= 1'b0;
+ config_in.valid <= 1'b1;
+ @(posedge clk);
+ config_in.valid <= 1'b0;
+ start <= 1'b0;
+ stop <= 1'b0;
+endtask
+
+int samples_to_send;
+
initial begin
reset <= 1'b1;
start <= 1'b0;
@@ -173,11 +129,31 @@ initial begin
reset <= 1'b0;
repeat (50) @(posedge clk);
- for (int i = 0; i < 2; i++) begin
+ for (int in_valid_rand = 0; in_valid_rand < 2; in_valid_rand++) begin
+ for (int bank_mode = 0; bank_mode < 4; bank_mode++) begin
+ for (int samp_count = 0; samp_count < 3; samp_count++) begin
+ start_acq_with_banking_mode(bank_mode);
+ unique case (samp_count)
+ 0: samples_to_send = $urandom_range(4, 10); // a few samples
+ 1: samples_to_send = (1024 / (1 << bank_mode))*7 + 24 / (1 << bank_mode);
+ 2: samples_to_send = (1024 / (1 << bank_mode))*8; // fill all buffers
+ endcase
+ data_in.send_samples(clk, samples_to_send, 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 for test with %d samples", samples_to_send);
+ $display("# and banking mode %d", bank_mode);
+ $display("# samples sent with rand_valid = %d", in_valid_rand);
+ $display("######################################################");
+ end
+ end
start_acq_with_banking_mode(0);
- send_samples(37, i);
- repeat (50) @(posedge clk);
- do_readout(1'b1, 500);
+ data_in.send_samples(clk, 37, i & 1'b1, 1'b1);
+ repeat (10) @(posedge clk);
+ stop_acq();
+ data_out.do_readout(clk, 1'b1, 100000);
$display("######################################################");
$display("# checking results for test with a few samples at #");
$display("# full rate, with only channel 0 enabled #");
@@ -185,9 +161,10 @@ initial begin
check_results(0);
start_acq_with_banking_mode(0);
- send_samples(1024*7+24, i);
- repeat (8000) @(posedge clk);
- do_readout(1'b1, 500);
+ data_in.send_samples(clk, 1024*7+24, i & 1'b1, 1'b1);
+ repeat (10) @(posedge clk);
+ stop_acq();
+ data_out.do_readout(clk, 1'b1, 100000);
$display("######################################################");
$display("# checking results for test with many samples at #");
$display("# full rate, with only channel 0 enabled #");
@@ -195,9 +172,10 @@ initial begin
check_results(0);
start_acq_with_banking_mode(1);
- send_samples(25, i);
- repeat (50) @(posedge clk);
- do_readout(1'b1, 500);
+ data_in.send_samples(clk, 25, i & 1'b1, 1'b1);
+ repeat (10) @(posedge clk);
+ stop_acq();
+ data_out.do_readout(clk, 1'b1, 100000);
$display("######################################################");
$display("# checking results for test with a few samples at #");
$display("# full rate, with channels 0 and 1 enabled #");
@@ -205,9 +183,10 @@ initial begin
check_results(1);
start_acq_with_banking_mode(1);
- send_samples(512*7+12, i);
- repeat (4000) @(posedge clk);
- do_readout(1'b1, 500);
+ data_in.send_samples(clk, 512*7+12, i & 1'b1, 1'b1);
+ repeat (10) @(posedge clk);
+ stop_acq();
+ data_out.do_readout(clk, 1'b1, 100000);
$display("######################################################");
$display("# checking results for test with many samples at #");
$display("# full rate, with channels 0 and 1 enabled #");
@@ -215,9 +194,10 @@ initial begin
check_results(1);
start_acq_with_banking_mode(2);
- send_samples(40, i);
- repeat (50) @(posedge clk);
- do_readout(1'b1, 500);
+ data_in.send_samples(clk, 40, i & 1'b1, 1'b1);
+ repeat (10) @(posedge clk);
+ stop_acq();
+ data_out.do_readout(clk, 1'b1, 100000);
$display("######################################################");
$display("# checking results for test with a few samples at #");
$display("# full rate, with channels 0-3 enabled #");
@@ -225,9 +205,10 @@ initial begin
check_results(2);
start_acq_with_banking_mode(2);
- send_samples(256*7+6, i);
- repeat (2000) @(posedge clk);
- do_readout(1'b1, 500);
+ data_in.send_samples(clk, 256*7+6, i & 1'b1, 1'b1);
+ repeat (10) @(posedge clk);
+ stop_acq();
+ data_out.do_readout(clk, 1'b1, 100000);
$display("######################################################");
$display("# checking results for test with many samples at #");
$display("# full rate, with channels 0-3 enabled #");
@@ -235,9 +216,10 @@ initial begin
check_results(2);
start_acq_with_banking_mode(3);
- send_samples(49, i);
- repeat (50) @(posedge clk);
- do_readout(1'b1, 500);
+ data_in.send_samples(clk, 49, i & 1'b1, 1'b1);
+ repeat (10) @(posedge clk);
+ stop_acq();
+ data_out.do_readout(clk, 1'b1, 100000);
$display("######################################################");
$display("# checking results for test with a few samples at #");
$display("# full rate, with all channels enabled #");
@@ -245,15 +227,25 @@ initial begin
check_results(3);
start_acq_with_banking_mode(3);
- send_samples(128*7+3, i);
- repeat (1000) @(posedge clk);
- do_readout(1'b1, 500);
+ data_in.send_samples(clk, 128*7+3, i & 1'b1, 1'b1);
+ repeat (10) @(posedge clk);
+ stop_acq();
+ data_out.do_readout(clk, 1'b1, 100000);
$display("######################################################");
$display("# checking results for test with many samples at #");
$display("# full rate, with all channels enabled #");
$display("######################################################");
check_results(3);
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;
end
@@ -325,27 +317,6 @@ task send_samples(input int n_samples, input int delay);
end
endtask
-task automatic do_readout(input bit rand_ready, input int timeout);
- int cycle_count;
- cycle_count = 0;
- data_out.ready <= 1'b0;
- stop <= 1'b1;
- @(posedge clk);
- stop <= 1'b0;
- // wait a bit before actually doing the readout
- repeat (500) @(posedge clk);
- data_out.ready <= 1'b1;
- // give up after timeout clock cycles if last is not achieved
- while ((!(data_out.last & data_out.ok)) & (cycle_count < timeout)) begin
- @(posedge clk);
- cycle_count = cycle_count + 1;
- if (rand_ready) begin
- data_out.ready <= $urandom() & 1'b1;
- end
- end
- @(posedge clk);
- data_out.ready <= 1'b0;
-endtask
// check that the DUT correctly saved everything
task check_results();
@@ -392,7 +363,10 @@ initial begin
data_in.send_samples(clk, 64, 1'b0, 1'b1);
data_in.send_samples(clk, 32, 1'b1, 1'b1);
repeat (50) @(posedge clk);
- do_readout(1'b1, 100000);
+ stop <= 1'b1;
+ @(posedge clk);
+ stop <= 1'b0;
+ data_out.do_readout(clk, 1'b1, 100000);
$display("######################################################");
$display("# checking results for test with a few samples #");
$display("######################################################");
@@ -408,7 +382,10 @@ initial begin
// send samples
data_in.send_samples(clk, 1, 1'b0, 1'b1);
repeat (50) @(posedge clk);
- do_readout(1'b1, 1000);
+ stop <= 1'b1;
+ @(posedge clk);
+ stop <= 1'b0;
+ data_out.do_readout(clk, 1'b1, 1000);
$display("######################################################");
$display("# checking results for test with one sample #");
$display("######################################################");
@@ -422,7 +399,10 @@ initial begin
repeat (100) @(posedge clk);
// don't send samples
repeat (50) @(posedge clk);
- do_readout(1'b1, 1000);
+ stop <= 1'b1;
+ @(posedge clk);
+ stop <= 1'b0;
+ data_out.do_readout(clk, 1'b1, 1000);
$display("######################################################");
$display("# checking results for test with no samples #");
$display("######################################################");
@@ -439,7 +419,10 @@ initial begin
data_in.send_samples(clk, 512, 1'b0, 1'b1);
data_in.send_samples(clk, 256, 1'b1, 1'b1);
repeat (50) @(posedge clk);
- do_readout(1'b1, 100000);
+ stop <= 1'b1;
+ @(posedge clk);
+ stop <= 1'b0;
+ data_out.do_readout(clk, 1'b1, 100000);
$display("######################################################");
$display("# checking results for test with 1024 samples #");
$display("# (full buffer) #");
diff --git a/dds_test.srcs/sources_1/new/axis.sv b/dds_test.srcs/sources_1/new/axis.sv
index 800d45c..e1f0a11 100644
--- a/dds_test.srcs/sources_1/new/axis.sv
+++ b/dds_test.srcs/sources_1/new/axis.sv
@@ -147,4 +147,27 @@ task automatic send_samples(
end
endtask
+task automatic do_readout(
+ ref clk,
+ input bit rand_ready,
+ input int timeout
+);
+ int cycle_count;
+ cycle_count = 0;
+ ready <= 1'b0;
+ // wait a bit before actually doing the readout
+ repeat (500) @(posedge clk);
+ ready <= 1'b1;
+ // give up after timeout clock cycles if last is not achieved
+ while ((!(last & ok)) & (cycle_count < timeout)) begin
+ @(posedge clk);
+ cycle_count = cycle_count + 1;
+ if (rand_ready) begin
+ ready <= $urandom() & 1'b1;
+ end
+ end
+ @(posedge clk);
+ ready <= 1'b0;
+endtask
+
endinterface
diff --git a/dds_test.srcs/sources_1/new/banked_sample_buffer.sv b/dds_test.srcs/sources_1/new/banked_sample_buffer.sv
index 991f578..66206b9 100644
--- a/dds_test.srcs/sources_1/new/banked_sample_buffer.sv
+++ b/dds_test.srcs/sources_1/new/banked_sample_buffer.sv
@@ -88,46 +88,44 @@ always_ff @(posedge clk) begin
end
end
-// select which buffer we're actively reading out
-logic [$clog2(N_CHANNELS)-1:0] bank_select;
-logic [$clog2(N_CHANNELS)-1:0] active_channel_id;
-assign active_channel_id = bank_select % n_active_channels;
// bundle of axistreams for each bank output
Axis_Parallel_If #(.DWIDTH(SAMPLE_WIDTH*PARALLEL_SAMPLES), .PARALLEL_CHANNELS(N_CHANNELS)) all_banks_out ();
-logic first;
-logic [PARALLEL_SAMPLES*SAMPLE_WIDTH-1:0] data_out_reg;
-
-// output the active channel id at the beginning of the transfer
-assign data_out.data = first ? active_channel_id : data_out_reg;
-// delay by a clock cycle to match latency of data_out_reg
+// select which bank we're actively reading out
+logic [$clog2(N_CHANNELS)-1:0] bank_select;
always_ff @(posedge clk) begin
if (reset) begin
- first <= 1'b0;
+ bank_select <= '0;
end else begin
- first <= banks_first[bank_select];
+ if (start) begin
+ bank_select <= '0;
+ end else if (all_banks_out.ok[bank_select] && all_banks_out.last[bank_select]) begin
+ if (bank_select == N_CHANNELS - 1) begin
+ bank_select <= '0;
+ end else begin
+ bank_select <= bank_select + 1'b1;
+ end
+ end
end
end
// mux outputs from banks
always_ff @(posedge clk) begin
if (reset) begin
- data_out_reg <= '0;
+ data_out.data <= '0;
data_out.valid <= 1'b0;
+ data_out.last <= '0;
end else begin
if (data_out.ready) begin
- data_out_reg <= all_banks_out.data[bank_select];
+ data_out.data <= all_banks_out.data[bank_select];
data_out.valid <= all_banks_out.valid[bank_select];
+ // only take last signal from the final bank, and only when the final bank is selected
+ data_out.last <= (bank_select == N_CHANNELS - 1) && all_banks_out.last[bank_select];
end
end
end
-// only take last signal from the final bank, and only when the final bank is selected
-always_ff @(posedge clk) begin
- data_out.last <= (bank_select == N_CHANNELS - 1) && all_banks_out.last[bank_select];
-end
-
// only supply a ready signal to the bank currently selected for readout
always_comb begin
for (int i = 0; i < N_CHANNELS; i++) begin
@@ -139,23 +137,6 @@ always_comb begin
end
end
-// update which bank is selected for the output
-always_ff @(posedge clk) begin
- if (reset) begin
- bank_select <= '0;
- end else begin
- if (start) begin
- bank_select <= '0;
- end else if (all_banks_out.ok[bank_select] && all_banks_out.last[bank_select]) begin
- if (bank_select == N_CHANNELS - 1) begin
- bank_select <= '0;
- end else begin
- bank_select <= bank_select + 1'b1;
- end
- end
- end
-end
-
// generate banks
genvar i;
generate
@@ -166,7 +147,8 @@ generate
Axis_If #(.DWIDTH(SAMPLE_WIDTH*PARALLEL_SAMPLES)) bank_out ();
// connect bank_out to all_banks_out
- assign all_banks_out.data[i] = bank_out.data;
+ // mux first sample from the bank with the channel ID
+ assign all_banks_out.data[i] = banks_first[i] ? (i % n_active_channels) : bank_out.data;
assign all_banks_out.valid[i] = bank_out.valid;
assign all_banks_out.last[i] = bank_out.last;
assign bank_out.ready = all_banks_out.ready[i];
@@ -332,7 +314,7 @@ always_ff @(posedge clk) begin
end
TRANSFER: begin
first <= '0;
- if (data_out.ready || (!data_out.valid)) begin
+ if (data_out.ok || (!data_out.valid)) begin
// in case the entire buffer was filled, we would never read anything out if we don't add
// the option to increment the address when readout hasn't been begun but the read/write
// addresses are both zero