summaryrefslogtreecommitdiff
path: root/python/openvino/demo/ip/intel_ai_ip/verilog/dla_lt_data_conversion.sv
diff options
context:
space:
mode:
Diffstat (limited to 'python/openvino/demo/ip/intel_ai_ip/verilog/dla_lt_data_conversion.sv')
-rw-r--r--python/openvino/demo/ip/intel_ai_ip/verilog/dla_lt_data_conversion.sv154
1 files changed, 154 insertions, 0 deletions
diff --git a/python/openvino/demo/ip/intel_ai_ip/verilog/dla_lt_data_conversion.sv b/python/openvino/demo/ip/intel_ai_ip/verilog/dla_lt_data_conversion.sv
new file mode 100644
index 0000000..7fe65c6
--- /dev/null
+++ b/python/openvino/demo/ip/intel_ai_ip/verilog/dla_lt_data_conversion.sv
@@ -0,0 +1,154 @@
+// Copyright 2020-2024 Intel Corporation.
+//
+// This software and the related documents are Intel copyrighted materials,
+// and your use of them is governed by the express license under which they
+// were provided to you ("License"). Unless the License provides otherwise,
+// you may not use, modify, copy, publish, distribute, disclose or transmit
+// this software or the related documents without Intel's prior written
+// permission.
+//
+// This software and the related documents are provided as is, with no express
+// or implied warranties, other than those that are expressly stated in the
+// License.
+
+/**
+ * dla_lt_data_conversion.sv
+ *
+ * The LT data conversion is responsible for converting U8 integers to FP16 values
+ * for inference in the PE array.
+ *
+ */
+`resetall
+`undefineall
+`default_nettype none
+
+module dla_lt_data_conversion #(
+ parameter int DDR_BYTES,
+ parameter int DATA_ELEMENT_WIDTH=8,
+ parameter int ELEMENTS_PER_CYCLE
+) (
+ input wire clk,
+ input wire i_valid,
+ input wire [8*DDR_BYTES-1:0] i_data,
+ output wire [ELEMENTS_PER_CYCLE-1:0][15:0] o_fp16_val,
+ output wire o_valid
+);
+
+ parameter BASE_EXP = 15 - 1;
+ logic [ELEMENTS_PER_CYCLE-1:0][15:0] fp16_val;
+ assign o_fp16_val = fp16_val;
+
+ logic data_valid;
+ assign o_valid = data_valid;
+
+ always_ff @( posedge clk ) begin
+ data_valid <= i_valid;
+ // data_valid[1] <= data_valid[0];
+ end
+
+ for (genvar in_token = 0; in_token < ELEMENTS_PER_CYCLE; in_token++)
+ begin : g_fp16
+ logic [7:0] sample;
+ logic [1:0][3:0] exp_offset_nib;
+ logic [1:0][7:0] shifted_val_nib;
+ logic token_in_progress;
+ assign sample = i_data[(in_token*DATA_ELEMENT_WIDTH)+:DATA_ELEMENT_WIDTH];
+ // split token into nibbles and mux calculation...
+
+ always_ff @(posedge clk)
+ begin
+ token_in_progress <= 0; // so that the last value is still converted.
+ if (i_valid)
+ begin
+ token_in_progress <= 1;
+ exp_offset_nib[0] <= 0;
+ shifted_val_nib[0] <= 0;
+
+ if (sample[3])
+ begin
+ exp_offset_nib[0] <= 4;
+ shifted_val_nib[0] <= {sample[2:0], 5'b0};
+ end
+ else if (sample[2])
+ begin
+ exp_offset_nib[0] <= 3;
+ shifted_val_nib[0] <= {sample[1:0], 6'b0};
+ end
+ else if (sample[1])
+ begin
+ exp_offset_nib[0] <= 2;
+ shifted_val_nib[0] <= {sample[0], 7'b0};
+ end
+ else if (sample[0])
+ begin
+ exp_offset_nib[0] <= 1;
+ shifted_val_nib[0] <= 0;
+ end
+ end
+ end
+
+ always_ff @(posedge clk)
+ begin
+ if (i_valid)
+ begin
+ exp_offset_nib[1] <= 0;
+ shifted_val_nib[1] <= 0;
+ if (sample[7])
+ begin
+ exp_offset_nib[1] <= 8;
+ shifted_val_nib[1] <= {sample[6:0], 1'b0};
+ end
+ else if (sample[6])
+ begin
+ exp_offset_nib[1] <= 7;
+ shifted_val_nib[1] <= {sample[5:0], 2'b0};
+ end
+ else if (sample[5])
+ begin
+ exp_offset_nib[1] <= 6;
+ shifted_val_nib[1] <= {sample[4:0], 3'b0};
+ end
+ else if (sample[4])
+ begin
+ exp_offset_nib[1] <= 5;
+ shifted_val_nib[1] <= {sample[3:0], 4'b0};
+ end
+ end
+ end
+
+ logic [4:0] exp_offset;
+ logic [4:0] exp_offset_reversed;
+ logic [7:0] shifted_val;
+
+ always_ff @(posedge clk)
+ begin
+ if ((i_valid) || token_in_progress)
+ begin
+ if (exp_offset_nib[1] > exp_offset_nib[0])
+ begin
+ exp_offset <= exp_offset_nib[1] + BASE_EXP;
+ shifted_val <= shifted_val_nib[1];
+ end
+ else if (exp_offset_nib[0] > 0)
+ begin
+ exp_offset <= exp_offset_nib[0] + BASE_EXP;
+ shifted_val <= shifted_val_nib[0];
+ end
+ else
+ begin
+ exp_offset <= 0;
+ shifted_val <= 0;
+ end
+ end
+ end
+
+
+
+ assign fp16_val[in_token] = {
+ 1'b0,
+ exp_offset,
+ shifted_val,
+ 2'b0
+ };
+ end
+endmodule