# Online Signature Verification Systems on a Low-Cost FPGA
## 4 Dtw
### Hardware Accelerator  
In the previous programming code, column data from the \(D\) and \(G\) matrices are sequentially allocated in external memory, as in floating-point vectors. Consequently, the FPBA can accelerate computations carried out on columns by launching a set of instructions. The throughput of all required instructions is one per clock cycle, except the square root instruction in the \(D\) matrix computation. The execution time on the FPBA is enhanced by the double control unit, which launches instructions for \(G\) and \(D\) matrices in a time-multiplexed way. Since \(G\) computation requires the previous calculus of \(D\), the computation of the \(G\) matrix at row \(i\) is virtually executed in parallel with the \(D\) matrix at the next row \(i+1\). For the sake of simplicity, the programming code for the first and last row is omitted as they are slightly different from the code shown. DTW_Init_G(); //Sets G-matrix g(i,j)==, except g(-1,-1)=0 CoproFPU_Scalar0(2.0); //Writes the constant 2 into the scalar S0 for(i=1, i<255; i++) { //G-matrix computation, from row 1 to 254 DTW_Region_D(i+1,&j0,&j1); //Computes column bounds for D-matrix at row i+1 FPBA_Length(j1-j0,&C01); //Sets vector length for C01 FPBA_V7(&d(i+1,j0)); //Output vector V7 pointer to D-matrix FPBA_V7(&d(i+1,j0)); FPBA_V7(&s_y(j0)); //Input vectors V5,V6 pointers to s_x,s_y FPDA_S5(t_x(i+1)); FPDA_S6(t_y(i+1)); // and scalars S5,S6 to store t_x,t_y DTW_Region_G(i,&j0,&j1); //Computes column bounds for G-matrix at row i FPBA_Length((j1-j0)/2,&C00); //Sets vector length for C01 FPBA_V4(&g(i,j0)); //Output vector V4 pointer to G-matrix FPBA_V0(&d(i,j0-1)); FPBA_V1(&d(i-1,j0)); //Input vectors V0,V1 pointers to D-matrix FPBA_V2(&g(i-1,j0-2)); FPBA_V3(&g(i-2,j0-1)); // and V2,V3 pointers to G-matrix FPGA_Run(CU0,CU1); } //Start CU0 and CU1  
The \(D\) matrix computation is performed by the following CU1 code, which consists of six instructions in a loop, generating \((j1-j0)\) iterations by controlling a \(k\) index, which starts at 0. The first instruction stores in register R14 the subtraction result from a scalar S5, which stores the \(t_{x}(i+1)\) sample, and a sample \(s_{x}(j)\) from the vector V5. The \(s_{x}(j)\) values are sequentially retrieved from memory according to \(j=j0+k\), since the vector pointer was configured to start at the \(s_{x}(j0)\) element. Similarly, another instruction stores in R15 the other required subtraction, and the following instructions complete the calculation. The last instruction stores the result \(d(i+1,j)\) sequentially on the V7 pointer, which was configured by MicroBlaze to the first element \(d(i+1,j0)\). BEGIN LOOP: //Loop for vectors(0<=k<j1-j0; j=j0+k) at row i+1  R14-S5-V5; R15-S6-V6; //R14=t_x(i+1)-s_x(j) R15=t_y(i+1)-s_y(j)  R14-R14*R14; R15-R15*R15; //R14=(t_x(i+1)-s_x(j))^2 R15=(t_y(i+1)-s_y(j))^2  R15-R14+R15; //R15-(t_x(i+1)-s_x(j))^2 +(t_y(i+1)-s_y(j))^2  V7-SORT(R15); //d(i+1,j)=sqrt((t_x(i+1)-s_x(j))^2+(t_y(i+1)-s_y(j))^2)  END_LOOP: //End of loop for vectors(0<=k<j1-j0; j=j0+k) at row i+1  R14-S5-V5; R15-S6-V6; //R14=t_x(i+1)-s_x(j) R15=t_y(i+1)-s_y(j)  R14-R14*R14; R15-R15*R15; //R14=(t_x(i+1)-s_x(j  
The \(D\) matrix circuit is quite simple. It devotes two BRAMs to retrieve the \(t_{x}(i+1)\), \(t_{y}(i+1)\), \(s_{x}(j)\), \(s_{y}(j)\) samples and a few arithmetic fixed-point circuits to calculate the distances \(d(i+1,j)\). The square root circuit is the CORDIC core from Xilinx's LogiCORE [25], which is configured to enhance the performance by fully parallel architecture with a single-cycle data throughput. The core is able to calculate one square root per clock cycle in fixed-point format after an initial latency of 22 clock cycles. Distance results are temporarily stored in BRAMs instead of the external RAM, since only the previous two rows of \(D\) are used. Figure 8: (a) Controller unit; (b) datapath of the \(D\) matrix computing circuit. Figure 9: Datapath of the \(G\) matrix computing circuit. are required during the computation of a row of \(G\).