diff --git a/rtl/sampler/src/sampler.sv b/rtl/sampler/src/sampler.sv index e69de29..d12d24e 100644 --- a/rtl/sampler/src/sampler.sv +++ b/rtl/sampler/src/sampler.sv @@ -0,0 +1,72 @@ +`timescale 1ns / 1ps + + + +module sampler +#( + parameter DATA_WIDTH = 12, + parameter PACK_FACTOR = 3, + parameter PROCESS_MODE = 1 + ) +( + input clk_in, + input rst, + input [DATA_WIDTH-1:0] data_in, + input out_of_range, + + output logic [DATA_WIDTH*PACK_FACTOR-1:0] m_axis_tdata, + output logic m_axis_tvalid + ); + logic [DATA_WIDTH-1:0] data_converted; + logic out_of_range_reg; + + always @( posedge clk_in) begin + if (rst) begin + data_converted <= '0; + end else begin + out_of_range_reg <= out_of_range; + if (PROCESS_MODE) begin + if (data_in == 12'b100000000000) begin + data_converted <= data_in; + end else begin + data_converted <= data_in[DATA_WIDTH-1] ? {1'b1, (~data_in[DATA_WIDTH-2:0] + 1'b1)} : data_in; + + end + end else begin + data_converted <= data_in; + end + end + end + + + logic [DATA_WIDTH*PACK_FACTOR-1:0] buffer; + logic buffer_ready; + + logic [$clog2(PACK_FACTOR):0] cnt; + + always @(posedge clk_in) begin + if (rst) begin + buffer <= '0; + cnt <= -1; // + buffer_ready <= 0; + end + else begin + buffer_ready <= 0; + if (!out_of_range_reg) begin + buffer <= {buffer[DATA_WIDTH*(PACK_FACTOR-1)-1:0], data_converted}; + if (cnt == PACK_FACTOR-1) begin + cnt <= 0; + buffer_ready <= 1; + buffer <= {buffer[DATA_WIDTH*(PACK_FACTOR-1)-1:0], data_converted}; + end + else begin + cnt <= cnt + 1; + end + end + end + end + + assign m_axis_tdata = buffer; + assign m_axis_tvalid = buffer_ready; + +endmodule diff --git a/rtl/sampler/tests/sampler_tb_advanced.sv b/rtl/sampler/tests/sampler_tb_advanced.sv new file mode 100644 index 0000000..601f0fd --- /dev/null +++ b/rtl/sampler/tests/sampler_tb_advanced.sv @@ -0,0 +1,120 @@ +`timescale 1ns / 1ps + +module sampler_tb; + + parameter DATA_WIDTH = 12; + parameter PACK_FACTOR = 3; + parameter PROCESS_MODE = 1; + parameter CLK_PERIOD = 15.3846; // 65 MHz + + logic clk; + logic rst; + logic [DATA_WIDTH-1:0] data_in; + logic out_of_range; + logic [DATA_WIDTH*PACK_FACTOR-1:0] m_axis_tdata; + logic m_axis_tvalid; + + sampler #( + .DATA_WIDTH(DATA_WIDTH), + .PACK_FACTOR(PACK_FACTOR), + .PROCESS_MODE(PROCESS_MODE) + ) dut ( + .clk_in(clk), + .rst(rst), + .data_in(data_in), + .out_of_range(out_of_range), + .m_axis_tdata(m_axis_tdata), + .m_axis_tvalid(m_axis_tvalid) + ); + + initial begin + clk = 0; + forever #(CLK_PERIOD/2) clk = ~clk; + end + + task send(input [DATA_WIDTH-1:0] word, input bit oor); + @(posedge clk); + data_in <= word; + out_of_range <= oor; + $display("Send: %h (%0d) OOR=%b", word, word, oor); + endtask + + initial begin + $display("\n=== SAMPLER TEST (MODE=%0d) ===\n", PROCESS_MODE); + + // Reset + rst = 1; + out_of_range = 0; + data_in = 0; +// send(12'h001, 0); + repeat(5) @(posedge clk); + rst = 0; + send(12'h001, 0); + repeat(1) @(posedge clk); + + // 1. Positive + $display("\n--- Positive numbers ---"); +// send(12'h001, 0); + send(12'h002, 0); + send(12'h003, 0); + + send(12'h004, 0); + send(12'h005, 0); + send(12'h806, 0); + + // 2. Negative + $display("\n--- Negative numbers ---"); + send(12'hFFF, 0); // -1 + send(12'hFFE, 0); // -2 + send(12'hFFD, 0); // -3 + + send(12'h800, 0); // -2048 + send(12'h801, 0); // -2047 + send(12'h802, 0); // -2046 + + // 3. Boundary + $display("\n--- Boundary values ---"); + send(12'h000, 0); // 0 + send(12'h001, 0); // 1 + send(12'h7FF, 0); // 2047 (max positive) + + send(12'h7FE, 0); // 2046 + send(12'h800, 0); // -2048 (min negative) + send(12'hFFF, 0); // -1 + + // 4. Out of range tests + $display("\n--- Out of range tests ---"); + + + send(12'h00A, 0); + send(12'h00B, 1); // + send(12'h00C, 0); + send(12'h00D, 0); + send(12'h00E, 0); + send(12'h00F, 0); + + send(12'h010, 0); + send(12'h011, 0); + send(12'h012, 1); // + + send(12'h013, 0); + send(12'h014, 0); + send(12'h015, 0); + + repeat(10) @(posedge clk); + $display("\n=== TEST FINISHED ==="); + $finish; + end + + // Results + always @(posedge clk) begin + if (m_axis_tvalid) begin + $display("\n>>> PACKET RECEIVED at %0t ns:", $time); + $display(" Full: %h", m_axis_tdata); + $display(" Word0: %h", m_axis_tdata[11:0]); + $display(" Word1: %h", m_axis_tdata[23:12]); + $display(" Word2: %h\n", m_axis_tdata[35:24]); + end + end + +endmodule \ No newline at end of file diff --git a/rtl/sampler/tests/sampler_tb_basic.sv b/rtl/sampler/tests/sampler_tb_basic.sv new file mode 100644 index 0000000..f574ce3 --- /dev/null +++ b/rtl/sampler/tests/sampler_tb_basic.sv @@ -0,0 +1,67 @@ +`timescale 1ns / 1ps + +module sampler_tb; + + parameter DATA_WIDTH = 12; + parameter PACK_FACTOR = 3; + parameter PROCESS_MODE = 0; + + parameter CLK_PERIOD = 15.3846; + + logic clk; + logic rst; + logic [DATA_WIDTH-1:0] data_in; + logic out_of_range; + + logic [DATA_WIDTH*PACK_FACTOR-1:0] m_axis_tdata; + logic m_axis_tvalid; + + // DUT + sampler #( + .DATA_WIDTH(DATA_WIDTH), + .PACK_FACTOR(PACK_FACTOR), + .PROCESS_MODE(PROCESS_MODE) + ) dut ( + .clk_in(clk), + .rst(rst), + .data_in(data_in), + .out_of_range(out_of_range), + .m_axis_tdata(m_axis_tdata), + .m_axis_tvalid(m_axis_tvalid) + ); + + // clock + initial begin + clk = 0; + forever #(CLK_PERIOD/2) clk = ~clk; + end + + integer i; + + initial begin + clk = 0; + rst = 1; + data_in = 0; + out_of_range = 0; + + #20; + rst = 0; + repeat(5) @(posedge clk); + + for (i = 1; i < 20; i++) begin + @(posedge clk); + + data_in <= i; + end + + #50; + $finish; + end + + always @(posedge clk) begin + if (m_axis_tvalid) begin + $display("TIME=%0t PACKED DATA = %h", $time, m_axis_tdata); + end + end + +endmodule \ No newline at end of file diff --git a/rtl/sampler/tests/sampler_tests.sv b/rtl/sampler/tests/sampler_tests.sv deleted file mode 100644 index e69de29..0000000