Full Extensibility with TIE
TIE offers a wide range of flexibility in adding multi-cycle, pipelined execution units, register files, state registers, SIMD arithmetic and logic units, creating wide (up to 128-bit) load-store instructions, and adding designer-defined I/O ports (GPIO) and queues (FIFO interfaces).
Full Extensibility with TIEFrom a RISC to a VLIW, Vector Machine
Additionally, the Xtensa processor can become a multi-issue VLIW processor. This coupled with the Xtensa C/C++ compiler’s ability to aggressively extract instruction-level parallelism from C/C++ code and bundle and schedule multiple operations in a VLIW instruction lead to an order of magnitude improvement in performance.
Adding TIE instructions never compromises the underlying base Xtensa instruction set, thereby ensuring availability of a robust ecosystem of third party application software and development tools. All configurable, extensible Xtensa processors are always compatible with major operating systems, debug probes and ICE solutions; and always come with an automatically generated, complete software development toolchain including an advanced integrated development environment based on the ECLIPSE framework, a world-class compiler, a cycle-accurate SystemC-compatible instruction set simulator, and the full industry-standard GNU toolchain.
Creating Multi-cycle Pipelined Execution Units
It is possible to create multi-cycle execution units using TIE that are pipelined up to 31 stages. The designer only has to specify the functionality of the units in the high-level TIE language and Tensilica tools automatically generate the decode, pipeline, control, and bypass logic and update the software tool chain (including compiler, debugger, ISS) to recognize the new instructions and registers associated with the execution unit.
For example, the figure below shows the TIE and corresponding TIE execution unit that performs a 16x16 multiply and saturates the result down to 16 bits:
operation MUL_SAT_16 {out AR z, in AR a, in AR b} {}
{
wire [31:0] m = TIEmul(a[15:0],b[15:0],1);
assign z = {16'b0,
m[31] ? ((m[31:23]==9'b1) ? m[23:8] : 16'h8000)
: ((m[31:23]==9'b0) ? m[23:8] : 16'h7fff) };
}
schedule ms {MUL_SAT_16} {def z 2;}

Creating Pipelined Instructions
Creating SIMD TIE Execution Units
Creating SIMD execution units with TIE is just as simple. Here is the same MUL-SAT from the previous example, but designed as a SIMD unit that does two multiply-saturates in a SIMD fashion.
operation MUL_SAT_16 {out AR z, in AR a, in AR b} {}
{
wire [31:0] m1 = TIEmul(a[31:16],b[31:16],1);
wire [31:0] m0 = TIEmul(a[15:0], b[15:0], 1);
assign z = {m1[31] ? ((m1[31:23]==9'b1) ? m1[23:8] : 16'h8000)
: ((m1[31:23]==9'b0) ? m1[23:8] : 16'h7fff),
{m0[30] ? ((m0[31:23]==9'b1) ? m0[23:8] : 16'h8000)
: ((m0[31:23]==9'b0) ? m0[23:8] : 16'h7fff) };
}
schedule ms {MUL_SAT_16} {def z 2;}

SIMD : Exploiting Data Parallelism
Creating Vector Register Files to Couple with SIMD Units
Designers can specify a new register file with the following simple one line TIE statement:
regfile VecReg 64 16 vr
This TIE statement instantiates a register file called “VecReg” that consists of 16 registers that are 64-bit wide and the assembler will refer to the registers in this register file as “vr0, vr1, vr2, …, vr15”.
Designer-defined vector register files are particularly useful when coupled with SIMD execution units as shown in the example below. In this example, we created a 4-way SIMD multiple-saturate execution unit (and corresponding instruction) that uses the 64-bit vector register file for source and destination operands.
regfile VR 64 16 vr
operation MUL_SAT_4x16 {out VR z, in VR a, in VR b} {}
{
wire [31:0] m3 = TIEmul(a[63:48],b[63:48],1);
wire [31:0] m2 = TIEmul(a[47:32],b[47:32],1);
wire [31:0] m1 = TIEmul(a[31:16],b[31:16],1);
wire [31:0] m0 = TIEmul(a[15:0], b[15:0], 1);
assign z = {m3[31] ? ((m3[31:23]==9'b1) ? m3[23:8] : 16'h8000)
: ((m3[31:23]==9'b0) ? m3[23:8] : 16'h7fff),
m2[31] ? ((m2[31:23]==9'b1) ? m2[23:8] : 16'h8000)
: ((m2[31:23]==9'b0) ? m2[23:8] : 16'h7fff),
m1[31] ? ((m1[31:23]==9'b1) ? m1[23:8] : 16'h8000)
: ((m1[31:23]==9'b0) ? m1[23:8] : 16'h7fff),
m0[31] ? ((m0[31:23]==9'b1) ? m0[23:8] : 16'h8000)
: ((m0[31:23]==9'b0) ? m0[23:8] : 16'h7fff) };
}
schedule ms {MUL_SAT_4x16} {def z 2;}

Using a Vector Register File with SIMD Instructions
|