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