From 3920cbac4e4cc597941e6cb87434578ed06b454b Mon Sep 17 00:00:00 2001 From: Reed Foster Date: Fri, 13 Oct 2023 13:19:54 -0400 Subject: [PATCH] working on new design for timetagging buffer --- .../sources_1/new/axis_width_converter.sv | 19 ++++ .../new/banked_sample_buffer_wrapper.v | 52 +++++++++ .../sources_1/new/sample_discriminator.sv | 92 +++++++++++++++- .../new/sample_discriminator_wrapper.v | 80 ++++++++++++++ .../new/timetagging_discriminating_buffer.sv | 103 ++++++++++++++++++ ...imetagging_discriminating_buffer_wrapper.v | 58 ++++++++++ src/rtl/axis_width_converter.sv | 1 + src/rtl/banked_sample_buffer_wrapper.v | 1 + src/rtl/sample_discriminator_wrapper.v | 1 + src/rtl/timetagging_discriminating_buffer.sv | 1 + ...imetagging_discriminating_buffer_wrapper.v | 1 + 11 files changed, 408 insertions(+), 1 deletion(-) create mode 100644 dds_test.srcs/sources_1/new/axis_width_converter.sv create mode 100644 dds_test.srcs/sources_1/new/banked_sample_buffer_wrapper.v create mode 100644 dds_test.srcs/sources_1/new/sample_discriminator_wrapper.v create mode 100644 dds_test.srcs/sources_1/new/timetagging_discriminating_buffer.sv create mode 100644 dds_test.srcs/sources_1/new/timetagging_discriminating_buffer_wrapper.v create mode 120000 src/rtl/axis_width_converter.sv create mode 120000 src/rtl/banked_sample_buffer_wrapper.v create mode 120000 src/rtl/sample_discriminator_wrapper.v create mode 120000 src/rtl/timetagging_discriminating_buffer.sv create mode 120000 src/rtl/timetagging_discriminating_buffer_wrapper.v diff --git a/dds_test.srcs/sources_1/new/axis_width_converter.sv b/dds_test.srcs/sources_1/new/axis_width_converter.sv new file mode 100644 index 0000000..dca4376 --- /dev/null +++ b/dds_test.srcs/sources_1/new/axis_width_converter.sv @@ -0,0 +1,19 @@ +// width converter +module axis_width_converter #( + parameter int DWIDTH_IN = 16, + parameter int DWIDTH_OUT = 128 +) ( + input wire clk, reset, + Axis_If.Slave_Full data_in, + Axis_If.Master_Full data_out +); + +generate + if (DWIDTH_IN > DWIDTH_OUT) begin + // downsizer + end else begin + // upsizer + end +endgenerate + +endmodule diff --git a/dds_test.srcs/sources_1/new/banked_sample_buffer_wrapper.v b/dds_test.srcs/sources_1/new/banked_sample_buffer_wrapper.v new file mode 100644 index 0000000..c6c8501 --- /dev/null +++ b/dds_test.srcs/sources_1/new/banked_sample_buffer_wrapper.v @@ -0,0 +1,52 @@ +module banked_sample_buffer_wrapper #( + parameter N_CHANNELS = 2, + parameter BUFFER_DEPTH = 8192, + parameter PARALLEL_SAMPLES = 16, + parameter SAMPLE_WIDTH = 16 +) ( + input wire clk, reset_n, + + input [SAMPLE_WIDTH*PARALLEL_SAMPLES-1:0] s00_axis_tdata, + input s00_axis_tvalid, + output s00_axis_tready, + + input [SAMPLE_WIDTH*PARALLEL_SAMPLES-1:0] s01_axis_tdata, + input s01_axis_tvalid, + output s01_axis_tready, + + output [SAMPLE_WIDTH*PARALLEL_SAMPLES-1:0] m_axis_tdata, + output m_axis_tvalid, + input m_axis_tready, + + input [$clog2($clog2(N_CHANNELS)+1)+2-1:0] cfg_axis_tdata, + input cfg_axis_tvalid, + output cfg_axis_tready, + + output capture_started +); + +banked_sample_buffer_sv #( + .N_CHANNELS(N_CHANNELS), + .BUFFER_DEPTH(BUFFER_DEPTH), + .PARALLEL_SAMPLES(PARALLEL_SAMPLES), + .SAMPLE_WIDTH(SAMPLE_WIDTH) +) buffer_i ( + .clk(clk), + .reset(~reset_n), + .s00_axis_tdata(s00_axis_tdata), + .s00_axis_tvalid(s00_axis_tvalid), + .s00_axis_tready(s00_axis_tready), + .s01_axis_tdata(s01_axis_tdata), + .s01_axis_tvalid(s01_axis_tvalid), + .s01_axis_tready(s01_axis_tready), + .m_axis_tdata(m_axis_tdata), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tlast(m_axis_tlast), + .m_axis_tready(m_axis_tready), + .cfg_axis_tdata(cfg_axis_tdata), + .cfg_axis_tvalid(cfg_axis_tvalid), + .cfg_axis_tready(cfg_axis_tready), + .capture_started(capture_started) +); + +endmodule diff --git a/dds_test.srcs/sources_1/new/sample_discriminator.sv b/dds_test.srcs/sources_1/new/sample_discriminator.sv index 3e42872..5f240ac 100644 --- a/dds_test.srcs/sources_1/new/sample_discriminator.sv +++ b/dds_test.srcs/sources_1/new/sample_discriminator.sv @@ -11,7 +11,7 @@ module sample_discriminator #( parameter int PARALLEL_SAMPLES = 16, parameter int N_CHANNELS = 8, parameter int SAMPLE_INDEX_WIDTH = 14, // ideally keep the sum of this and CLOCK_WIDTH at most 64 - parameter int CLOCK_WIDTH = 50 // rolls over roughly every 3 days at 4GS/s + parameter int CLOCK_WIDTH = 50 // rolls over roughly every 3 days at 4GS/s (100 days at 32MS/s) ) ( input wire clk, reset, Axis_Parallel_If.Slave_Simple data_in, @@ -121,3 +121,93 @@ always_ff @(posedge clk) begin end endmodule + +module sample_discriminator_sv #( + parameter SAMPLE_WIDTH = 16, + parameter PARALLEL_SAMPLES = 1, + parameter SAMPLE_INDEX_WIDTH = 14, + parameter CLOCK_WIDTH = 50 +) ( + input wire clk, reset, + + input [SAMPLE_WIDTH*PARALLEL_SAMPLES-1:0] s00_axis_tdata, + input s00_axis_tvalid, + output s00_axis_tready, + + input [SAMPLE_WIDTH*PARALLEL_SAMPLES-1:0] s01_axis_tdata, + input s01_axis_tvalid, + output s01_axis_tready, + + output [SAMPLE_WIDTH*PARALLEL_SAMPLES-1:0] m00_data_axis_tdata, + output m00_data_axis_tvalid, + input m00_data_axis_tready, + + output [SAMPLE_WIDTH*PARALLEL_SAMPLES-1:0] m01_data_axis_tdata, + output m01_data_axis_tvalid, + input m01_data_axis_tready, + + output [SAMPLE_INDEX_WIDTH+CLOCK_WIDTH-1:0] m00_tstamp_axis_tdata, + output m00_tstamp_axis_tvalid, + input m00_tstamp_axis_tready, + + output [SAMPLE_INDEX_WIDTH+CLOCK_WIDTH-1:0] m01_tstamp_axis_tdata, + output m01_tstamp_axis_tvalid, + input m01_tstamp_axis_tready, + + input [2*2*SAMPLE_WIDTH-1:0] cfg_axis_tdata, + input cfg_axis_tvalid, + output cfg_axis_tready, + + input sample_index_reset +); + +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(); + +assign data_in.data[0] = s00_axis_tdata; +assign data_in.valid[0] = s00_axis_tvalid; +assign s00_axis_tready = data_in.ready[0]; + +assign data_in.data[1] = s01_axis_tdata; +assign data_in.valid[1] = s01_axis_tvalid; +assign s01_axis_tready = data_in.ready[1]; + +assign m00_data_axis_tdata = data_out.data[0]; +assign m00_data_axis_tvalid = data_out.valid[0]; +assign data_out.ready[0] = m00_data_axis_tready; + +assign m01_data_axis_tdata = data_out.data[1]; +assign m01_data_axis_tvalid = data_out.valid[1]; +assign data_out.ready[1] = m01_data_axis_tready; + +assign m00_tstamp_axis_tdata = timestamps_out.data[0]; +assign m00_tstamp_axis_tvalid = timestamps_out.valid[0]; +assign timestamps_out.ready[0] = m00_tstamp_axis_tready; + +assign m01_tstamp_axis_tdata = timestamps_out.data[1]; +assign m01_tstamp_axis_tvalid = timestamps_out.valid[1]; +assign timestamps_out.ready[1] = m01_tstamp_axis_tready; + +assign config_in.data = cfg_axis_tdata; +assign config_in.valid = cfg_axis_tvalid; +assign cfg_axis_tready = config_in.ready; + +sample_discriminator #( + .SAMPLE_WIDTH(SAMPLE_WIDTH), + .PARALLEL_SAMPLES(PARALLEL_SAMPLES), + .N_CHANNELS(N_CHANNELS), + .SAMPLE_INDEX_WIDTH(SAMPLE_INDEX_WIDTH), + .CLOCK_WIDTH(CLOCK_WIDTH), +) disc_i ( + .clk, + .reset, + .data_in, + .data_out, + .timestamps_out, + .config_in, + .sample_index_reset +); + +endmodule diff --git a/dds_test.srcs/sources_1/new/sample_discriminator_wrapper.v b/dds_test.srcs/sources_1/new/sample_discriminator_wrapper.v new file mode 100644 index 0000000..7d9d7a6 --- /dev/null +++ b/dds_test.srcs/sources_1/new/sample_discriminator_wrapper.v @@ -0,0 +1,80 @@ +module sample_discriminator_wrapper #( + parameter SAMPLE_WIDTH = 16, + parameter PARALLEL_SAMPLES = 1, + parameter SAMPLE_INDEX_WIDTH = 14, + parameter CLOCK_WIDTH = 50 +) ( + input wire clk, reset_n, + + input [SAMPLE_WIDTH*PARALLEL_SAMPLES-1:0] s00_axis_tdata, + input s00_axis_tvalid, + output s00_axis_tready, + + input [SAMPLE_WIDTH*PARALLEL_SAMPLES-1:0] s01_axis_tdata, + input s01_axis_tvalid, + output s01_axis_tready, + + output [SAMPLE_WIDTH*PARALLEL_SAMPLES-1:0] m00_data_axis_tdata, + output m00_data_axis_tvalid, + input m00_data_axis_tready, + + output [SAMPLE_WIDTH*PARALLEL_SAMPLES-1:0] m01_data_axis_tdata, + output m01_data_axis_tvalid, + input m01_data_axis_tready, + + output [SAMPLE_INDEX_WIDTH+CLOCK_WIDTH-1:0] m00_tstamp_axis_tdata, + output m00_tstamp_axis_tvalid, + input m00_tstamp_axis_tready, + + output [SAMPLE_INDEX_WIDTH+CLOCK_WIDTH-1:0] m01_tstamp_axis_tdata, + output m01_tstamp_axis_tvalid, + input m01_tstamp_axis_tready, + + input [2*2*SAMPLE_WIDTH-1:0] cfg_axis_tdata, + input cfg_axis_tvalid, + output cfg_axis_tready, + + input sample_index_reset +); + +sample_discriminator_sv #( + .SAMPLE_WIDTH(SAMPLE_WIDTH), + .PARALLEL_SAMPLES(PARALLEL_SAMPLES), + .SAMPLE_INDEX_WIDTH(SAMPLE_INDEX_WIDTH), + .CLOCK_WIDTH(CLOCK_WIDTH) +) ( + .clk(clk), + .reset(~reset_n), + + .s00_axis_tdata(s00_axis_tdata), + .s00_axis_tvalid(s00_axis_tvalid), + .s00_axis_tready(s00_axis_tready), + + .s01_axis_tdata(s01_axis_tdata), + .s01_axis_tvalid(s01_axis_tvalid), + .s01_axis_tready(s01_axis_tready), + + .m00_data_axis_tdata(m00_data_axis_tdata), + .m00_data_axis_tvalid(m00_data_axis_tvalid), + .m00_data_axis_tready(m00_data_axis_tready), + + .m01_data_axis_tdata(m01_data_axis_tdata), + .m01_data_axis_tvalid(m01_data_axis_tvalid), + .m01_data_axis_tready(m01_data_axis_tready), + + .m00_tstamp_axis_tdata(m00_tstamp_axis_tdata), + .m00_tstamp_axis_tvalid(m00_tstamp_axis_tvalid), + .m00_tstamp_axis_tready(m00_tstamp_axis_tready), + + .m01_tstamp_axis_tdata(m01_tstamp_axis_tdata), + .m01_tstamp_axis_tvalid(m01_tstamp_axis_tvalid), + .m01_tstamp_axis_tready(m01_tstamp_axis_tready), + + .cfg_axis_tdata(cfg_axis_tdata), + .cfg_axis_tvalid(cfg_axis_tvalid), + .cfg_axis_tready(cfg_axis_tready), + + .sample_index_reset(sample_index_reset) +); + +endmodule diff --git a/dds_test.srcs/sources_1/new/timetagging_discriminating_buffer.sv b/dds_test.srcs/sources_1/new/timetagging_discriminating_buffer.sv new file mode 100644 index 0000000..c23d677 --- /dev/null +++ b/dds_test.srcs/sources_1/new/timetagging_discriminating_buffer.sv @@ -0,0 +1,103 @@ +// timetagging_discriminating_buffer - Reed Foster +// performs threshold-based sample discrimination +module timetagging_discriminating_buffer #( + parameter int N_CHANNELS = 2, + parameter int TSTAMP_BUFFER_DEPTH = 1024, + parameter int DATA_BUFFER_DEPTH = 32768, + parameter int AXI_MM_WIDTH = 128, + parameter int PARALLEL_SAMPLES = 1, + parameter int SAMPLE_WIDTH = 16, + parameter int APPROX_CLOCK_WIDTH = 48 +) ( + input wire clk, reset, + Axis_Parallel_If.Slave_Simple data_in, // all channels in parallel + Axis_If.Master_Full data_out, + Axis_If.Slave_Simple disc_cfg_in, // {threshold_high, threshold_low} for each channel + Axis_If.Slave_Simple buffer_cfg_in // {banking_mode, start, stop} +); + +localparam int SAMPLE_INDEX_WIDTH = $clog2(DATA_BUFFER_DEPTH*N_CHANNELS); +localparam int TIMESTAMP_WIDTH = SAMPLE_WIDTH * ((SAMPLE_INDEX_WIDTH + APPROX_CLOCK_WIDTH + (SAMPLE_WIDTH - 1)) / SAMPLE_WIDTH); + +// when either buffer fills up, it triggers a stop on the other with the stop_aux input +logic [1:0] buffer_full; + +// axi-stream interfaces +Axis_Parallel_If #(.DWIDTH(TIMESTAMP_WIDTH), .PARALLEL_CHANNELS(N_CHANNELS)) disc_tstamps(); +Axis_Parallel_If #(.DWIDTH(SAMPLE_WIDTH*PARALLEL_SAMPLES), .PARALLEL_CHANNELS(N_CHANNELS)) disc_data(); +Axis_If #(.DWIDTH($clog2($clog2(N_CHANNELS)+1)+2)) buf_tstamp_cfg (); +Axis_If #(.DWIDTH($clog2($clog2(N_CHANNELS)+1)+2)) buf_data_cfg (); +Axis_If #(.DWIDTH(TIMESTAMP_WIDTH)) buf_tstamp_out (); +Axis_If #(.DWIDTH(SAMPLE_WIDTH*PARALLEL_SAMPLES)) buf_data_out (); + +// share buffer_cfg_in between both buffers so their configuration is synchronized +assign buf_tstamp_cfg.data = buffer_cfg_in.data; +assign buf_tstamp_cfg.valid = buffer_cfg_in.valid; +assign buf_data_cfg.data = buffer_cfg_in.data; +assign buf_data_cfg.valid = buffer_cfg_in.valid; +assign buffer_cfg_in.ready = 1'b1; // doesn't matter what we do here, since both modules hold ready = 1'b1 + +// whenever a buffer capture is triggered through the buffer_cfg_in interface, +// reset the sample_index counter in the sample discriminator +logic start; +always_ff @(posedge clk) begin + if (reset) begin + start <= '0; + end else begin + if (buffer_cfg_in.ok) begin + start <= buffer_cfg_in.data[1]; + end + end +end + +// merge both buffer outputs into a word that is AXI_MM_WIDTH bits + +sample_discriminator #( + .SAMPLE_WIDTH(SAMPLE_WIDTH), + .PARALLEL_SAMPLES(PARALLEL_SAMPLES), + .N_CHANNELS(N_CHANNELS), + .SAMPLE_INDEX_WIDTH($clog2(DATA_BUFFER_DEPTH*N_CHANNELS)), + .CLOCK_WIDTH(TIMESTAMP_WIDTH - SAMPLE_INDEX_WIDTH) +) disc_i ( + .clk, + .reset, + .data_in, + .data_out(disc_data), + .timestamps_out(disc_tstamps), + .config_in(disc_cfg_in), + .sample_index_reset(start) +); + +banked_sample_buffer #( + .SAMPLE_WIDTH(SAMPLE_WIDTH), + .BUFFER_DEPTH(DATA_BUFFER_DEPTH), + .PARALLEL_SAMPLES(PARALLEL_SAMPLES), + .N_CHANNELS(N_CHANNELS) +) data_buffer_i ( + .clk, + .reset, + .data_in(disc_data), + .data_out(buf_data_out), + .config_in(buf_data_cfg), + .stop_aux(buffer_full[0]), + .capture_started(), + .buffer_full(buffer_full[1]) +); + +banked_sample_buffer #( + .SAMPLE_WIDTH(TIMESTAMP_WIDTH), + .BUFFER_DEPTH(TSTAMP_BUFFER_DEPTH), + .PARALLEL_SAMPLES(1), + .N_CHANNELS(N_CHANNELS) +) data_buffer_i ( + .clk, + .reset, + .data_in(disc_tstamps), + .data_out(buf_tstamp_out), + .config_in(buf_tstamp_cfg), + .stop_aux(buffer_full[1]), + .capture_started(), + .buffer_full(buffer_full[0]) +); + +endmodule diff --git a/dds_test.srcs/sources_1/new/timetagging_discriminating_buffer_wrapper.v b/dds_test.srcs/sources_1/new/timetagging_discriminating_buffer_wrapper.v new file mode 100644 index 0000000..964c0f9 --- /dev/null +++ b/dds_test.srcs/sources_1/new/timetagging_discriminating_buffer_wrapper.v @@ -0,0 +1,58 @@ +module timetagging_discriminating_buffer_wrapper #( + parameter N_CHANNELS = 2, + parameter TSTAMP_BUFFER_DEPTH = 1024, + parameter DATA_BUFFER_DEPTH = 32768, + parameter AXI_MM_WIDTH = 128, + parameter PARALLEL_SAMPLES = 1, + parameter SAMPLE_WIDTH = 16 +) ( + input wire clk, reset_n, + + input [SAMPLE_WIDTH*PARALLEL_SAMPLES-1:0] s00_axis_tdata, + input s00_axis_tvalid, + output s00_axis_tready, + + input [SAMPLE_WIDTH*PARALLEL_SAMPLES-1:0] s01_axis_tdata, + input s01_axis_tvalid, + output s01_axis_tready, + + output [AXI_MM_WIDTH-1:0] m_axis_tdata, + output m_axis_tvalid, + input m_axis_tready, + + input [$clog2($clog2(N_CHANNELS)+1)+2-1:0] cfg_buf_axis_tdata, + input cfg_buf_axis_tvalid, + output cfg_buf_axis_tready, + + input [2*2*SAMPLE_WIDTH-1:0] cfg_disc_axis_tdata, + input cfg_disc_axis_tvalid, + output cfg_disc_axis_tready, + + output capture_started +); + +banked_sample_buffer_sv #( + .N_CHANNELS(N_CHANNELS), + .BUFFER_DEPTH(BUFFER_DEPTH), + .PARALLEL_SAMPLES(PARALLEL_SAMPLES), + .SAMPLE_WIDTH(SAMPLE_WIDTH) +) buffer_i ( + .clk(clk), + .reset(~reset_n), + .s00_axis_tdata(s00_axis_tdata), + .s00_axis_tvalid(s00_axis_tvalid), + .s00_axis_tready(s00_axis_tready), + .s01_axis_tdata(s01_axis_tdata), + .s01_axis_tvalid(s01_axis_tvalid), + .s01_axis_tready(s01_axis_tready), + .m_axis_tdata(m_axis_tdata), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tlast(m_axis_tlast), + .m_axis_tready(m_axis_tready), + .cfg_axis_tdata(cfg_axis_tdata), + .cfg_axis_tvalid(cfg_axis_tvalid), + .cfg_axis_tready(cfg_axis_tready), + .capture_started(capture_started) +); + +endmodule diff --git a/src/rtl/axis_width_converter.sv b/src/rtl/axis_width_converter.sv new file mode 120000 index 0000000..ee46e92 --- /dev/null +++ b/src/rtl/axis_width_converter.sv @@ -0,0 +1 @@ +../../dds_test.srcs/sources_1/new/axis_width_converter.sv \ No newline at end of file diff --git a/src/rtl/banked_sample_buffer_wrapper.v b/src/rtl/banked_sample_buffer_wrapper.v new file mode 120000 index 0000000..a96cddf --- /dev/null +++ b/src/rtl/banked_sample_buffer_wrapper.v @@ -0,0 +1 @@ +../../dds_test.srcs/sources_1/new/banked_sample_buffer_wrapper.v \ No newline at end of file diff --git a/src/rtl/sample_discriminator_wrapper.v b/src/rtl/sample_discriminator_wrapper.v new file mode 120000 index 0000000..86f5efe --- /dev/null +++ b/src/rtl/sample_discriminator_wrapper.v @@ -0,0 +1 @@ +../../dds_test.srcs/sources_1/new/sample_discriminator_wrapper.v \ No newline at end of file diff --git a/src/rtl/timetagging_discriminating_buffer.sv b/src/rtl/timetagging_discriminating_buffer.sv new file mode 120000 index 0000000..45ceb46 --- /dev/null +++ b/src/rtl/timetagging_discriminating_buffer.sv @@ -0,0 +1 @@ +../../dds_test.srcs/sources_1/new/timetagging_discriminating_buffer.sv \ No newline at end of file diff --git a/src/rtl/timetagging_discriminating_buffer_wrapper.v b/src/rtl/timetagging_discriminating_buffer_wrapper.v new file mode 120000 index 0000000..8abfc86 --- /dev/null +++ b/src/rtl/timetagging_discriminating_buffer_wrapper.v @@ -0,0 +1 @@ +../../dds_test.srcs/sources_1/new/timetagging_discriminating_buffer_wrapper.v \ No newline at end of file