[Identification d'empreintes digitales] Mise en œuvre de la simulation d'un algorithme d'identification d'empreintes digitales basé sur MATLAB/FPGA

1. Version du logiciel

MATLAB2013b,vivado2019.2

2. Connaissance théorique de cet algorithme

       La technologie d'identification d'empreintes digitales fait référence à l'utilisation d'un équipement d'imagerie pour lire l'image d'empreintes digitales, extraire les données caractéristiques de l'image d'empreintes digitales via un logiciel d'identification, puis identifier l'identité du propriétaire de l'empreinte digitale en fonction du résultat obtenu par l'algorithme de correspondance. Le système de reconnaissance d'empreintes digitales comprend principalement trois étapes : le prétraitement de l'image d'empreintes digitales, l'extraction des caractéristiques et la correspondance des caractéristiques. L'organigramme du système est illustré à la Figure 1-1. Une brève introduction à ces trois parties est donnée ci-dessous.

 

  1. Caractéristiques de base des empreintes digitales

Les empreintes digitales sont en fait plus compliquées. Contrairement au traitement manuel, de nombreuses entreprises de technologie biométrique ne stockent pas directement les images des empreintes digitales. Au fil des ans, de nombreux algorithmes numériques ont été produits dans diverses entreprises et leurs instituts de recherche (les lois pertinentes aux États-Unis estiment que les images d'empreintes digitales appartiennent à la vie privée, de sorte que les images d'empreintes digitales ne peuvent pas être stockées directement). Mais l'algorithme de reconnaissance d'empreintes digitales se résume finalement à trouver et à comparer les caractéristiques de l'empreinte digitale sur l'image de l'empreinte digitale.

Dans les systèmes de reconnaissance d'empreintes digitales, des caractéristiques structurelles à deux niveaux, global et local, sont généralement utilisées. Deux empreintes digitales peuvent avoir les mêmes caractéristiques globales, mais les caractéristiques locales peuvent ne pas être exactement les mêmes.

  1. fonctionnalités globales

Les caractéristiques globales font référence aux caractéristiques qui peuvent être directement observées par l'œil humain, notamment : la boucle de motif de base (boucle), l'arc (arc) et la spirale (verticille), comme illustré à la Figure 2-1. D'autres modèles d'empreintes digitales sont basés sur ces trois modèles de base. Il ne suffit pas de distinguer les empreintes digitales uniquement par type de motif. Il ne s'agit que d'une classification approximative, mais la classification facilite la recherche d'empreintes digitales dans de grandes bases de données.

 

La zone de motif fait référence à la zone de l'empreinte digitale qui comprend les caractéristiques générales, c'est-à-dire que le type d'empreinte digitale peut être identifié à partir de la zone de motif. Certains algorithmes de reconnaissance d'empreintes digitales n'utilisent que les données de la zone de motif. L'algorithme d'identification d'empreintes digitales de Secure Touch utilise l'empreinte digitale complète obtenue au lieu de simplement la zone de motif pour l'analyse et l'identification, comme illustré à la figure 2.

 Figure 2 Zone Mode

Le point central est situé au centre progressif du motif d'empreintes digitales, qui sert de point de référence lors de la lecture et de la comparaison des empreintes digitales. De nombreux algorithmes sont basés sur des points centraux, qui ne peuvent traiter et reconnaître les empreintes digitales qu'avec des points centraux. Les points centraux sont importants pour l'algorithme de reconnaissance d'empreintes digitales de Secure Touch, mais il peut toujours gérer les empreintes digitales sans points centraux, comme le montre la figure 3.

 Point central de la figure 3

Le point triangulaire est situé à la première bifurcation ou point d'arrêt à partir du point central, ou à la convergence des deux bandes, le point isolé, le point tournant, ou pointe vers ces singularités. Les points triangulaires fournissent le début du suivi du comptage des lignes d'empreintes digitales, comme le montre la figure 4.

 Fait référence au nombre de lignes d'empreintes digitales dans la zone du motif. Lors du calcul du nombre de lignes dans une empreinte digitale, connectez généralement le point central et le point triangulaire en premier, et le nombre d'intersections entre cette ligne et les lignes d'empreinte digitale peut être considéré comme le nombre de lignes dans l'empreinte digitale, comme le montre la figure 2 -5.

 

Il existe deux méthodes d'extraction de caractéristiques détaillées : l'une consiste à extraire des caractéristiques d'images en niveaux de gris et l'autre consiste à extraire des caractéristiques d'images binaires raffinées. L'algorithme d'extraction de caractéristiques directement à partir d'une image en niveaux de gris consiste généralement à suivre les crêtes d'empreintes digitales en niveaux de gris, à trouver l'emplacement de la caractéristique et à déterminer le type de caractéristique en fonction du résultat du suivi. Cette méthode permet d'économiser le processus complexe de prétraitement des images d'empreintes digitales, mais l'algorithme d'extraction des caractéristiques est très compliqué et, en raison de l'influence du bruit et d'autres facteurs, les informations sur les caractéristiques (position, direction, etc.) ne sont pas suffisamment précises. À l'heure actuelle, la plupart des systèmes utilisent la deuxième méthode pour extraire les caractéristiques de l'image binaire amincie. Cette méthode est relativement simple. Après avoir obtenu une image binaire amincie fiable, seul un modèle 3 × 3 peut être utilisé pour extraire les extrémités et les points. point est extrait.

La qualité de l'extraction des points caractéristiques affectera directement le résultat de la correspondance. En réalité, lorsque les empreintes digitales sont entrées, en raison de l'influence de la sueur, de la sécheresse, de la force de pression différente, etc., les images d'empreintes digitales obtenues contiennent principalement des problèmes de qualité tels que des lignes brisées, des rides, du flou, des niveaux de gris inégaux, etc. Bien que la qualité de l'image sera améliorée après le prétraitement. , mais l'adaptabilité et l'efficacité de l'algorithme de prétraitement à chaque empreinte digitale seront différentes, et un nouveau bruit sera introduit, de sorte que l'image binaire raffinée obtenue contient souvent un grand nombre de pseudo points caractéristiques. Les pseudo-points caractéristiques n'affecteront pas seulement la vitesse de correspondance, mais affecteront également sérieusement la précision de l'ensemble de la reconnaissance. Par conséquent, après l'extraction des points caractéristiques, un traitement de pseudo-suppression doit être effectué pour filtrer autant que possible les points pseudo-caractéristiques et conserver les vrais points caractéristiques. En pratique, on constate que le nombre de pseudo-points caractéristiques représente généralement plus de la moitié du nombre total de caractéristiques, de sorte que la pseudo-suppression est un processus essentiel. Le processus de dé-faux peut être effectué en deux étapes : l'une consiste à lisser l'image binaire amincie, à supprimer les bavures, à relier les lignes brisées et d'autres opérations avant l'extraction des caractéristiques, puis à extraire les caractéristiques en tant que véritables caractéristiques ; l'autre consiste à extraire les caractéristiques après Selon la relation entre les caractéristiques, les pseudo-points caractéristiques sont identifiés aussi précisément que possible et ils sont filtrés. Le premier répare directement l'image, l'opération est plus compliquée et il est facile d'introduire de nouvelles pseudo-caractéristiques ; le second juge les données après extraction des caractéristiques, et l'identification est plus gênante, mais la vitesse est plus rapide. Cet article adopte le deuxième méthode, c'est-à-dire à partir des caractéristiques extraites Filtrez les fausses caractéristiques et conservez les vraies caractéristiques.

3. Une partie du code de base

`timescale 1ns / 1ps
//
// Company: 
// Engineer:       ThinkSpark(CJY)
// 
// Create Date:    10:46:32 08/21/2009 
// Design Name: 
// Module Name:    spisensor 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//

`define effectvalue   1


module spisensor(//Output
                 cmd2tx_din_w,
				 rd_data_cmd_w,
				 send_rd_spidata_cmd_n_w,
                 clk180,        //spi transfer enable
				 SCK_CPOL_0,               //clk for slave
				 send_n_w,               
                 tx_rd_en_w,
                 tx_wr_en_w,
                 rx_wr_en_w,
                 locked_out0,
                 clk_24MHz,
				 div10_cnt_w,
				 sck_cnt8_w,
				 //Input
				 rx_full_n,
				 rx_first_n,
				 rx_empty_n,
				 
				 clk,                //system clock
				 rst
				              
				);
	 
output [7:0]     cmd2tx_din_w;
output [7:0]     rd_data_cmd_w;
output           SCK_CPOL_0;
output           clk180;
output           send_n_w;
output           tx_wr_en_w;
output           tx_rd_en_w;
output           rx_wr_en_w;
output           locked_out0;
output           clk_24MHz;
output [3:0]     div10_cnt_w;
output [2:0]     sck_cnt8_w;
output           send_rd_spidata_cmd_n_w;

input            clk;
input            rst;

input            rx_full_n;
input            rx_empty_n;
input            rx_first_n;



reg   [7:0]      cmdpad[31:0];    //filled with commands to be sent to slave after initialization
reg   [7:0]      rd_data_cmd_pad[1:0];
reg   [7:0]      cmd2tx_din;
reg   [7:0]      rd_data_cmd;
reg   [3:0]      div10_cnt;      //the time while div10_cnt=0 and div10_cnt=0- equals to an SCK period 
reg   [2:0]      sck_cnt8;       //sck_cnt8=7 indicates that 8bits have been transferred

reg   [3:0]      dcm_rst_delaycnt;
reg   [1:0]      rd_spidata_cmd_cnt;
reg              rd_spidata_cmd_cnt_en;
reg              send_rd_spidata_cmd_n;
reg              rd_data_cmd_rd_en;

reg   [15:0]     bytecnt;
reg   [5:0]      incr;
reg              tx_wr_en;
reg              tx_rd_en;
reg              rx_wr_en;
reg              transmision_done;
reg              addr;

reg              delaycnt_ctrl_n;
reg              transfer_n;    //data transfer enable bit,active low
reg              send_n;        //data send enable bit,active low
reg              recv_n;        //data receive enable bit,active low

reg    [7:0]     pre_state;
reg    [7:0]     nx_state;

wire             clk0_out0;
wire             locked_out0;
wire             clk0_out1;
wire             locked_out1;

wire             clk_24MHz;
wire             clk180;
wire             SCK_CPOL_0;
wire             SCK_CPOL_1;
wire             send_n_w;
//wire             transfer_n_w;
wire             tx_rd_en_w;
wire             tx_wr_en_w;
wire             rx_wr_en_w;
wire  [7:0]      cmd2tx_din_w; 
wire  [3:0]      div10_cnt_w;
wire  [2:0]      sck_cnt8_w; 
wire             send_rd_spidata_cmd_n_w;       

parameter        idle                     = 8'b00000000,
                 cmd2fifo                 = 8'b00000001,
                 sensor_initial           = 8'b00000010,
				 rd_sensor                = 8'b00000100,
				 rd_spistat               = 8'b00001000,
				 rd_spidata               = 8'b00010000,
				 send_data2uart           = 8'b00100000,
				 last_data2uart           = 8'b01000000,
				 spi_stop                 = 8'b10000000;
				 
				 

	 
dcm0 mydcm0 (
    .CLKIN_IN(clk), 
    .RST_IN(transfer_n), 
    .CLKFX_OUT(SCK_CPOL_1), 
    .CLKFX180_OUT(SCK_CPOL_0),    
    .CLK0_OUT(), 
    .LOCKED_OUT(locked_out0)
    );	 
 

dcm1 mydcm1 (
    .CLKIN_IN(clk), 
    .CLKFX_OUT(clk_24MHz),    
    .CLK0_OUT(), 
    .CLK180_OUT(clk180), 
    .LOCKED_OUT(locked_out1)
    );
//assign transfer_n_w =transfer_n; 

assign tx_wr_en_w=tx_wr_en;
assign tx_rd_en_w=tx_rd_en;
assign rx_wr_en_w=rx_wr_en;
assign send_n_w  =send_n;
assign cmd2tx_din_w=cmd2tx_din;
assign rd_data_cmd_w = rd_data_cmd;

assign div10_cnt_w = div10_cnt;
assign sck_cnt8_w  = sck_cnt8;
assign send_rd_spidata_cmd_n_w = send_rd_spidata_cmd_n;

//initialize cmdpad and transfer data in pad to Tx_fifo
always @(posedge clk)
begin
   if(rst == `effectvalue)
   begin
   cmdpad[0] <= 8'h75;
   cmdpad[1] <= 8'h7F;
   cmdpad[2] <= 8'h76;
   cmdpad[3] <= 8'h02;
   cmdpad[4] <= 8'h77;
   cmdpad[5] <= 8'h01;
   cmdpad[6] <= 8'h11;
   cmdpad[7] <= 8'h00;
   cmdpad[8] <= 8'h21;
   cmdpad[9] <= 8'h00;
   cmdpad[10] <= 8'h20;
   cmdpad[11] <= 8'h00;
   cmdpad[12] <= 8'h50;   
   cmdpad[13] <= 8'h00;
   cmdpad[14] <= 8'h00;
   cmdpad[15] <= 8'h00;
   end
   
end 	

always @(posedge clk)
begin
   if(rst == `effectvalue)
      begin
	     rd_data_cmd_pad[0] <= 8'h20;
		 rd_data_cmd_pad[1] <= 8'h00;
	  end
end


always @(posedge clk)
begin
   if(rst == `effectvalue)
      cmd2tx_din <= 8'b0;
   else 	   
	  cmd2tx_din <= cmdpad[incr];
end


//address point to data be wrote to Tx_fifo 
always @(posedge clk)
begin
   if(rst == `effectvalue)
      incr <= 6'b0;   
   else if(incr == 31)  
      incr <= 31 ;
   else	  
      incr <= incr + 1;   
end




//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//transfer_n-\________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
//clk        |--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|
//div10_cnt   [  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ]    
//SCK       XXXXXXX________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/
//sck_cnt8         [00000000000000000000000000000000000000000000000000000][1111111111111111111111111111111111111111111111111111111111][2222222222222222222222222222222222222222222222222222222222][3333333333333333333333333333333333333333333333333333333333][4444444444444444444444444444444444444444444444444444444444][5555555555555555555555555555555555555555555555555555555555][6666666666666666666666666666666666666666666666666666666666][7777777777777777777777777777777777777777777777777777777777][0000000000000000000000000000000000000000000000000000000000][11111111111111111111111111111111111111]
//tx_rd_en      ------|_____|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\_____/----------------------------------------------------------------------------------
//tx_shifterOOOOOOOOOOOOOOOOOOO[            d7 d6 d5 d4 d3 d2 d1 d0      ][         d6 d5 d4 d3 d2 d1 d0 0                           ][                  d5 d4 d3 d2 d1 d0 0 0                   ][                  d4 d3 d2 d1 d0 0 0 0                    ][                    d3 d2 d1 d0 0 0 0 0                   ][                        d2 d1 d0 0 0 0 0 0                ][                  d1  d0  0  0  0  0  0  0                ][                      d0  0  0  0  0  0  0  0                               ][     d7 d6 d5 d4 d3 d2 d1 d0            ][           d6 d5 d4 d3 d2 d1 d0 0 ] 
//MOSI     OOOOOOOOOOOOOO000000000000000000[----------------------------d7----------------------------][----------------------------d6----------------------------][----------------------------d5----------------------------][----------------------------d4----------------------------][----------------------------d3----------------------------][----------------------------d2----------------------------][----------------------------d1----------------------------][----------------------------d0----------------------------][----------------------------d7----------------------------][--d6--]
//MISO  XXXXX[----------------------------D7-----------------------------][----------------------------D6----------------------------][----------------------------D5----------------------------][----------------------------D4----------------------------][----------------------------D3----------------------------][----------------------------D2----------------------------][----------------------------D1----------------------------][----------------------------D0----------------------------][----------------------------D7----------------------------][----------------------------D7--------
//rx_shifter0000000000000000000000000000000[                        0 0 0 0 0 0 0 D7                  ][                        0 0 0 0 0 0 D7 D6                 ][                       0 0 0 0 0 D7 D6 D5                 ][                        0 0 0 0 D7 D6 D5 D4               ][                      0 0 0 D7 D6 D5 D4 D3                ][                    0 0 D7 D6 D5 D4 D3 D2                 ][                       0 D7 D6 D5 D4 D3 D2 D1             ][                     D7 D6 D5 D4 D3 D2 D1 D0              ][                        0 0 0 0 0 0 0 D7                  ] 
//rx_wr_en------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\_____/-----------------------------------------------------------------
//----------------------------------------------------------------------------------------

//----------------------------------------------------------------------------------------
//the time while div10_cnt=0 and div10_cnt=0- equals to an SCK period 	
always @(posedge clk)
begin
   if( (rst == `effectvalue) || (transfer_n == 1'b1) )
      div10_cnt <= 4'b0;
   else if(div10_cnt == 9)
      div10_cnt <= 4'b0;
   else if(locked_out0 == 1'b1)
      div10_cnt <= div10_cnt + 1;
end
	
//----------------------------------------------------------------------------------------	
//3bits counter for SCK cycles, one counting cycle indicates one Byte transmission done	
always @ (posedge clk)
begin
   if( (rst == `effectvalue) || (transfer_n == 1'b1) )
      sck_cnt8 <= 3'b0;
   else if( (div10_cnt == 9) && (locked_out0 == 1'b1) )          //?????????????????????
      sck_cnt8 <= sck_cnt8 + 1;
   
end

//--------------------------------------------------------------------------------------------------
//------------control reading from tx_fifo and writing to rx_fifo----------------------------------
//---------------------------------begin-----------------------------------------------------------
always @(posedge clk180)                      //---- @posedge clk180 will work more precisely-----
begin
   if( (rst == `effectvalue) || (send_n == 1'b1) )        //not to read data from tx_fifo when send_n=1
      tx_rd_en <= 1'b1;
   else if( (locked_out0 == 1'b1) && (sck_cnt8 == 0) &&
            (div10_cnt == 0) )
      tx_rd_en <= 1'b0;
   else
      tx_rd_en <= 1'b1;   
end


always @(posedge clk180)
begin
   if( (rst == `effectvalue) || (send_rd_spidata_cmd_n == 1'b1) )
     rd_data_cmd_rd_en <= 1'b1;
   else if( (locked_out0 == 1'b1) && (sck_cnt8 == 0) &&
            (div10_cnt == 0) )
	 rd_data_cmd_rd_en <= 1'b0;
   else
     rd_data_cmd_rd_en <= 1'b1;
end

always @(posedge clk)
begin
   if(rst == `effectvalue)
      rd_data_cmd <= 8'b0;
   else if(rd_data_cmd_rd_en == 1'b0)
      rd_data_cmd <= rd_data_cmd_pad[addr];
end

always @(posedge clk)
begin
   if(rst == `effectvalue)
      addr <= 1'b0;
   else if (rd_data_cmd_rd_en == 1'b0) 
      addr <= ~addr;
end

always @(posedge clk)
begin
   if( (rst == `effectvalue) || (rx_full_n == 1'b0) )
      rd_spidata_cmd_cnt <= 2'b0;
   else if(rd_spidata_cmd_cnt == 2)
      rd_spidata_cmd_cnt <= 2;
   else if( (rd_spidata_cmd_cnt_en == 1'b0) && ( sck_cnt8 == 7 ) &&
             (div10_cnt == 9) )
      rd_spidata_cmd_cnt <= rd_spidata_cmd_cnt + 1;
end
///

always @(posedge clk180)                                 //---- @posedge clk180 will work more precisely-----
begin
   if( (rst == `effectvalue) || (recv_n == 1'b1) )       //not to write to rx_fifo when recv_n=1
      rx_wr_en <= 1'b1;
   else if( (locked_out0 == 1'b1) && (sck_cnt8 == 7) &&
            (div10_cnt == 6)  )                          //rx_wr_en be active while div10_cnt=6 and sck_cnt8=7 can 
	  rx_wr_en <= 1'b0;                                  //leave some time space for bytecnt
   else
      rx_wr_en <= 1'b1;
end

//------------control reading from tx_fifo and writing to rx_fifo----------------------------------
//---------------------------------end-----------------------------------------------------------

always @(posedge clk)
begin
   if( (rst == `effectvalue) || 
       ( (transfer_n == 1'b1) && (transmision_done == 1'b1) ) )
     bytecnt <= 16'b0;   
   else if( (sck_cnt8 == 7) && ( div10_cnt == 7 ) )            // one more byte has been sent and received the moment
     bytecnt <= bytecnt + 1;                                   //sck_cnt8=7 and div10_cnt=7(as the wave showed following)
   else 
     bytecnt <= bytecnt;
end	


always @(posedge clk)
begin
   if( rst == `effectvalue )
      transmision_done <= 1'b0;
   else if( (transmision_done == 1'b1) && (div10_cnt == 0) )
      transmision_done <= 1'b0;
   else if( (pre_state == sensor_initial) && (bytecnt == 6) )
      transmision_done <= 1'b1;
   else if( (pre_state == rd_sensor) && (bytecnt == 370) )
      transmision_done <= 1'b1;
   else if( (pre_state == rd_spistat) && (bytecnt == 3) )
      transmision_done <= 1'b1;
   //else if( (pre_state == rd_regs) && (bytecnt == 18) )
      //transmision_done <= 1'b1;
   else if( (pre_state == rd_spidata) && (bytecnt == 31352) )
      transmision_done <= 1'b1;
   
end

always @( posedge clk )
begin
   if( (rst == `effectvalue) || (transmision_done == 1'b1) || (rx_full_n == 1'b0) )
      dcm_rst_delaycnt <= 4'b0;
   else if( dcm_rst_delaycnt == 9 )
      dcm_rst_delaycnt <= 9;
   else if( delaycnt_ctrl_n == 1'b0 )
      dcm_rst_delaycnt <= dcm_rst_delaycnt + 1;
end

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//transfer_n-\________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
//clk        |--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|
//div10_cnt   [  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ]    
//SCK       XXXXXXX________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/
//sck_cnt8         [00000000000000000000000000000000000000000000000000000][1111111111111111111111111111111111111111111111111111111111][2222222222222222222222222222222222222222222222222222222222][3333333333333333333333333333333333333333333333333333333333][4444444444444444444444444444444444444444444444444444444444][5555555555555555555555555555555555555555555555555555555555][6666666666666666666666666666666666666666666666666666666666][7777777777777777777777777777777777777777777777777777777777][0000000000000000000000000000000000000000000000000000000000][11111111111111111111111111111111111111]
//tx_rd_en      ------\_____/-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\_____/----------------------------------------------------------------------------------
//tx_shifterOOOOOOOOOOOOOOOOOOO[            d7 d6 d5 d4 d3 d2 d1 d0      ][         d6 d5 d4 d3 d2 d1 d0 0                           ][                  d5 d4 d3 d2 d1 d0 0 0                   ][                  d4 d3 d2 d1 d0 0 0 0                    ][                    d3 d2 d1 d0 0 0 0 0                   ][                        d2 d1 d0 0 0 0 0 0                ][                  d1  d0  0  0  0  0  0  0                ][                      d0  0  0  0  0  0  0  0                               ][     d7 d6 d5 d4 d3 d2 d1 d0            ][           d6 d5 d4 d3 d2 d1 d0 0 ] 
//MOSI     OOOOOOOOOOOOOO000000000000000000[----------------------------d7----------------------------][----------------------------d6----------------------------][----------------------------d5----------------------------][----------------------------d4----------------------------][----------------------------d3----------------------------][----------------------------d2----------------------------][----------------------------d1----------------------------][----------------------------d0----------------------------][----------------------------d7----------------------------][--d6--]
//MISO  XXXXX[----------------------------D7-----------------------------][----------------------------D6----------------------------][----------------------------D5----------------------------][----------------------------D4----------------------------][----------------------------D3----------------------------][----------------------------D2----------------------------][----------------------------D1----------------------------][----------------------------D0----------------------------][----------------------------D7----------------------------][----------------------------D7--------
//rx_shifter0000000000000000000000000000000[                        0 0 0 0 0 0 0 D7                  ][                        0 0 0 0 0 0 D7 D6                 ][                       0 0 0 0 0 D7 D6 D5                 ][                        0 0 0 0 D7 D6 D5 D4               ][                      0 0 0 D7 D6 D5 D4 D3                ][                    0 0 D7 D6 D5 D4 D3 D2                 ][                       0 D7 D6 D5 D4 D3 D2 D1             ][                     D7 D6 D5 D4 D3 D2 D1 D0              ][                        0 0 0 0 0 0 0 D7                  ] 
//rx_wr_en------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\_____/-------------------------------------------------------------
//----------------------------------------------------------------------------------------


//-------------------------------------------------------------------------------
//-------------------------------FSM---------------------------------------------
always @(posedge clk)
begin
   if(rst == `effectvalue)
      pre_state <= idle;
   else
      pre_state <= nx_state;
end

//-----------------------------------------------------------------------
//FSM state transform---------------------------------------------------
always @(pre_state or div10_cnt or incr or transmision_done or 
         rx_empty_n or rx_full_n)
begin
   case(pre_state)
   
      idle          : nx_state = cmd2fifo;
	  
	  cmd2fifo      : begin
	                  if( incr == 31)                      //all 16 commands in cmdpad were wrote to Tx_fifo when incr=15
					     nx_state = sensor_initial;
					  else
					     nx_state = cmd2fifo;					     
					  end
      
      sensor_initial: begin
	                  if( (transmision_done == 1'b1) && (div10_cnt == 0))
					     nx_state = rd_sensor;
					  else
					     nx_state = sensor_initial;					     
					  end
      
      rd_sensor      :begin
                      if( (transmision_done == 1'b1) && (div10_cnt == 0))
					     nx_state = rd_spistat;
					  else
					     nx_state = rd_sensor;
					  end
	  
	  rd_spistat     :begin
	                  if( (transmision_done == 1'b1) && (div10_cnt == 0))
					     nx_state = rd_spidata;
					  else
					     nx_state = rd_spistat;
					  end
	  
	  rd_spidata     :begin
	                  if( (transmision_done == 1'b1) && (div10_cnt == 0))
					     nx_state = last_data2uart;
					  else if(rx_full_n == 1'b0)                             //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!               
					     nx_state = send_data2uart;
					  else
					     nx_state = rd_spidata;
					  end
	  send_data2uart:begin
	                 if(rx_empty_n == 1'b0)
					    nx_state = rd_spidata;
					 else
					    nx_state = send_data2uart;
					 end
					 
	 last_data2uart:begin
	                if(rx_empty_n == 1'b0)
					  nx_state = spi_stop;
					else
					  nx_state = last_data2uart;
					end
						
      spi_stop       :   nx_state = spi_stop; 
	  default        :   nx_state = idle;
					  
   endcase
end
//---------FSM state transform-----------------------------------------------
//-----------------------------------------------------------------------------


//-------------------------------------------
//FSM control signals output
always @(pre_state  or rx_full_n or div10_cnt or
          incr  or bytecnt or dcm_rst_delaycnt or
		  rd_spidata_cmd_cnt or rx_empty_n or rx_first_n )
begin
   case(pre_state)
   
      idle            :begin
	                   tx_wr_en    = 1'b1;
					   transfer_n  = 1'b1;
					   send_n      = 1'b1;
					   recv_n      = 1'b1;
					   delaycnt_ctrl_n = 1'b1;
					   send_rd_spidata_cmd_n = 1'b1;
					   rd_spidata_cmd_cnt_en = 1'b1;
					   end
	  
	  cmd2fifo        :begin
	                   if( (incr == 0) && (incr == 31) )
					      begin
						     tx_wr_en    = 1'b1;
							 transfer_n  = 1'b1;
							 send_n      = 1'b1;
							 recv_n      = 1'b1;
							 delaycnt_ctrl_n = 1'b1;
							 send_rd_spidata_cmd_n = 1'b1;
							 rd_spidata_cmd_cnt_en = 1'b1;
						  end
					   else
					      begin       
							 tx_wr_en    = 1'b0;
							 transfer_n  = 1'b1;
							 send_n      = 1'b1;
							 recv_n      = 1'b1;
							 delaycnt_ctrl_n = 1'b1;
							 send_rd_spidata_cmd_n = 1'b1;
							 rd_spidata_cmd_cnt_en = 1'b1;
                          end							 
					   end
	  sensor_initial  :begin
	                   if( (bytecnt == 6) && ( div10_cnt == 9) )
					      begin
						     tx_wr_en    = 1'b1;
							 transfer_n  = 1'b1;            // this will reset bytecnt when div10_cnt=9 
							 send_n      = 1'b1;
							 recv_n      = 1'b1;
							 delaycnt_ctrl_n = 1'b1;
							 send_rd_spidata_cmd_n = 1'b1;
							 rd_spidata_cmd_cnt_en = 1'b1;							 
						     
						  end
					   else if( dcm_rst_delaycnt <= 8)
					      begin
                       		 tx_wr_en    = 1'b1;
							 transfer_n  = 1'b1;                   
							 send_n      = 1'b1;
							 recv_n      = 1'b1;
                             delaycnt_ctrl_n = 1'b0;
                             send_rd_spidata_cmd_n = 1'b1;
                             rd_spidata_cmd_cnt_en = 1'b1;							 
					      end
					   else if(dcm_rst_delaycnt == 9)
					      begin
						     tx_wr_en    = 1'b1;
							 transfer_n  = 1'b0;                   
							 send_n      = 1'b0;
							 recv_n      = 1'b1;
                             delaycnt_ctrl_n = 1'b1;
							 send_rd_spidata_cmd_n = 1'b1;
							 rd_spidata_cmd_cnt_en = 1'b1;
						  end
					   else 
					      begin
						     tx_wr_en    = 1'b1;
							 transfer_n  = 1'b1;            // this will reset bytecnt when div10_cnt=9 
							 send_n      = 1'b1;
							 recv_n      = 1'b1;
							 delaycnt_ctrl_n = 1'b1;
							 send_rd_spidata_cmd_n = 1'b1;
							 rd_spidata_cmd_cnt_en = 1'b1;
						     
						  end
					   
					   end
	  rd_sensor       :begin
	                   if( dcm_rst_delaycnt <= 8)
					      begin
						     tx_wr_en    = 1'b1;
							 transfer_n  = 1'b1;                   
							 send_n      = 1'b1;
							 recv_n      = 1'b1;
                             delaycnt_ctrl_n = 1'b0;
							 send_rd_spidata_cmd_n = 1'b1;
							 rd_spidata_cmd_cnt_en = 1'b1;
						  end
					   else if( (bytecnt < 2 ) && (dcm_rst_delaycnt == 9) )
					      begin 
  						     tx_wr_en    = 1'b1;
						     transfer_n  = 1'b0;                   
						     send_n      = 1'b0;
						     recv_n      = 1'b1;
							 delaycnt_ctrl_n = 1'b1;
							 send_rd_spidata_cmd_n = 1'b1;
							 rd_spidata_cmd_cnt_en = 1'b1;
					      end
					   else if( (bytecnt >=2) && (bytecnt <=370) && (dcm_rst_delaycnt == 9))
					      begin
						     tx_wr_en    = 1'b1;
						     transfer_n  = 1'b0;                   
						     send_n      = 1'b1;
						     recv_n      = 1'b1;
							 delaycnt_ctrl_n = 1'b1;
							 send_rd_spidata_cmd_n = 1'b1;
							 rd_spidata_cmd_cnt_en = 1'b1;
						  end
					   else
					      begin
						     tx_wr_en    = 1'b1;
						     transfer_n  = 1'b1;                   
						     send_n      = 1'b1;
						     recv_n      = 1'b1;
							 delaycnt_ctrl_n = 1'b1;
							 send_rd_spidata_cmd_n = 1'b1;
							 rd_spidata_cmd_cnt_en = 1'b1;
						  end
					   end
      rd_spistat      :begin
	                   if( dcm_rst_delaycnt <= 8)
					      begin
						     tx_wr_en    = 1'b1;
							 transfer_n  = 1'b1;                   
							 send_n      = 1'b1;
							 recv_n      = 1'b1;
                             delaycnt_ctrl_n = 1'b0;
							 send_rd_spidata_cmd_n = 1'b1;
							 rd_spidata_cmd_cnt_en = 1'b1;
						  end
	                   else if( (bytecnt < 2) && (dcm_rst_delaycnt == 9) )
					      begin 
  						     tx_wr_en    = 1'b1;
						     transfer_n  = 1'b0;                   
						     send_n      = 1'b0;
						     recv_n      = 1'b1;
							 delaycnt_ctrl_n = 1'b1;
							 send_rd_spidata_cmd_n = 1'b1;
							 rd_spidata_cmd_cnt_en = 1'b1;
						  end
					   else if( (bytecnt >= 2) && (dcm_rst_delaycnt == 9) )
					      begin						      
  						     tx_wr_en    = 1'b1;
						     transfer_n  = 1'b0;                   
						     send_n      = 1'b1;
						     recv_n      = 1'b0;
							 delaycnt_ctrl_n = 1'b1;
							 send_rd_spidata_cmd_n = 1'b1;
							 rd_spidata_cmd_cnt_en = 1'b1;
						  end
					   else
					      begin						      
  						     tx_wr_en    = 1'b1;
						     transfer_n  = 1'b1;                   
						     send_n      = 1'b1;
						     recv_n      = 1'b1;
							 delaycnt_ctrl_n = 1'b1;
							 send_rd_spidata_cmd_n = 1'b1;
							 rd_spidata_cmd_cnt_en = 1'b1;
						  end
					   end
      rd_spidata      :begin
	                   if( dcm_rst_delaycnt <= 8)
					      begin
						     tx_wr_en    = 1'b1;
							 transfer_n  = 1'b1;                   
							 send_n      = 1'b1;
							 recv_n      = 1'b1;
                             delaycnt_ctrl_n = 1'b0;
							 send_rd_spidata_cmd_n = 1'b1;
							 rd_spidata_cmd_cnt_en = 1'b1;
						  end
	                   
					   else if( (bytecnt > 10) && (rx_first_n == 1'b1) &&
					            (rx_empty_n == 1'b0) && ( rd_spidata_cmd_cnt < 2 ) )
						  begin   
							 tx_wr_en    = 1'b1;
						     transfer_n  = 1'b0;                   
						     send_n      = 1'b1;
						     recv_n      = 1'b1;
							 delaycnt_ctrl_n = 1'b1;
							 send_rd_spidata_cmd_n = 1'b0;
							 rd_spidata_cmd_cnt_en = 1'b0;
					      end
					   else if( (bytecnt > 10) && (rd_spidata_cmd_cnt == 2) )
					      begin
						     tx_wr_en    = 1'b1;
						     transfer_n  = 1'b0;                   
						     send_n      = 1'b1;
						     recv_n      = 1'b0;
							 delaycnt_ctrl_n = 1'b1;
							 send_rd_spidata_cmd_n = 1'b1;
							 rd_spidata_cmd_cnt_en = 1'b1;
						  
						  end
					   else if( (bytecnt < 2) && (dcm_rst_delaycnt == 9)  )  
						  begin 
  						     tx_wr_en    = 1'b1;
						     transfer_n  = 1'b0;                   
						     send_n      = 1'b0;
						     recv_n      = 1'b1;
							 delaycnt_ctrl_n = 1'b1;
							 send_rd_spidata_cmd_n = 1'b1;
							 rd_spidata_cmd_cnt_en = 1'b1;
						  end
					   else if( (bytecnt >= 2) && (rx_full_n == 1'b1) )
					      begin						      
  						     tx_wr_en    = 1'b1;
						     transfer_n  = 1'b0;                   
						     send_n      = 1'b1;
						     recv_n      = 1'b0;
							 delaycnt_ctrl_n = 1'b1;
							 send_rd_spidata_cmd_n = 1'b1;
							 rd_spidata_cmd_cnt_en = 1'b1;
						  end
					   else
					      begin						      
  						     tx_wr_en    = 1'b1;
						     transfer_n  = 1'b1;                   
						     send_n      = 1'b1;
						     recv_n      = 1'b1;
							 delaycnt_ctrl_n = 1'b1;
							 send_rd_spidata_cmd_n = 1'b1;
							 rd_spidata_cmd_cnt_en = 1'b1;
						  end
					   end
					   
	  send_data2uart,
	  last_data2uart, 
      spi_stop        :begin
	                      tx_wr_en    = 1'b1;
						  transfer_n  = 1'b1;                   
						  send_n      = 1'b1;
						  recv_n      = 1'b1;
						  delaycnt_ctrl_n = 1'b1;
						  send_rd_spidata_cmd_n = 1'b1;
						  rd_spidata_cmd_cnt_en = 1'b1;
					   end
     default         : begin
	                      tx_wr_en    = 1'b1;
						  transfer_n  = 1'b1;                   
						  send_n      = 1'b1;
						  recv_n      = 1'b1;
						  delaycnt_ctrl_n = 1'b1;
						  send_rd_spidata_cmd_n = 1'b1;
						  rd_spidata_cmd_cnt_en = 1'b1;
					   end
	 
  endcase
end
//FSM control signals output
//--------------------------------------------


endmodule
%ProcessOfFingerPrint.m
clc;
clear;
clear all;
%--------------加载指纹文本文件-----------------------
fid=fopen('1x1.txt','r');
dd=fscanf(fid,'%x');
fclose(fid);
array=dd';
for i=0:199
    OriginFingerPrint(i+1,1:152)=array(i*152+1:i*152+152);
end
figure('name','OriginFingerPrint');
imshow(uint8(OriginFingerPrint));
%---------------灰度图像取反--------------------------
ReverseFingerPrint=255-OriginFingerPrint;
figure('name','ReverseFingerPrint');
imshow(uint8(ReverseFingerPrint));
%---------------进行二维适应性去噪过滤处理------------
FrontFilt=wiener2(ReverseFingerPrint,[3 3]);
figure('name','FrontFilt');
imshow(uint8(FrontFilt));
%---------------扩大图像的像素至400x304---------------
EnhanceFingerPrint=enhance_finger(FrontFilt);
%---------------取图像的中心点------------------------
[XofCenter,YofCenter] = centralizing(EnhanceFingerPrint);
figure('name','EnhanceFingerPrint');
imshow(uint8(EnhanceFingerPrint));
hold on;
plot(XofCenter,YofCenter,'or');
hold off;
%---------------二值化图像-----------------------------
[BinarizationFingerPrint,theta]=orientation(EnhanceFingerPrint);
figure('name','BinarizationFingerPrint');
imshow(uint8(BinarizationFingerPrint));
%----------------进行中值滤波处理----------------------
AfterFilt=median_filter(BinarizationFingerPrint);
figure('name','AfterFilt');
imshow(uint8(AfterFilt));
%----------------二值化图像细化处理--------------------
ThinFingerPrint=thinning(AfterFilt);
figure('name','ThinFingerPrint');
imshow(uint8(ThinFingerPrint));
%----------------找寻细化图像的特征点------------------
[Dpx,Dpy,Dpcount,Fpx,Fpy,Fpcount]=characterpoint(ThinFingerPrint);
hold on;
plot(Dpy,Dpx,'o');%特征端点用'o'标注
plot(Fpy,Fpx,'+');%特征分叉点用'+'标注
plot(XofCenter,YofCenter,'*r');%中心点用红色'*'标注
hold off;
%-----------------生成各特征点相对中心点的距离向量---------------
Dpcount=size(Dpx,2);
Fpcount=size(Fpx,2);
for i=1:Dpcount
    Dpdistant(i)=sqrt((Dpx(i)-YofCenter)^2+(Dpy(i)-XofCenter)^2);
end
for j=1:Fpcount
    Fpdistant(j)=sqrt((Fpx(j)-YofCenter)^2+(Fpy(j)-XofCenter)^2);
end   
%------------------特征模板建立----------------------------------------------
for i=1:Dpcount
    PointOfModel(i,1)=1;%特征端点分类为1
    PointOfModel(i,2)=Dpdistant(i);%特征端点相对中心点的距离向量
    PointOfModel(i,3)=theta(Dpx(i),Dpy(i))-theta(YofCenter,XofCenter);%特征端点相对中心点的方向向量
end
for i=Dpcount+1:Dpcount+Fpcount
    PointOfModel(i,1)=2;%特征分叉点分类为2
    PointOfModel(i,2)=Fpdistant(i-Dpcount);%特征分叉点相对中心点的距离向量
    PointOfModel(i,3)=theta(Fpx(i-Dpcount),Fpy(i-Dpcount))-theta(YofCenter,XofCenter);%特征分叉点相对中心点的方向向量
end    
%--------------------------------------------------------

4. Étapes de l'opération et conclusion de la simulation

 

  1. Module FSM : sa fonction principale est d'initialiser le Tx FIFO (transmettre FIFO) après la réinitialisation du système, c'est-à-dire d'écrire la commande à envoyer au capteur SPI dans le Tx FIFO, puis sous le principe de rencontrer le capteur SPI synchronisation, le module FSM contrôle le Le signal Tx_rd_en lit la commande dans le FIFO Tx et le transmet au module SPI ; lorsque le FIFO Rx reçoit les données d'empreinte digitale, lorsque le drapeau complet Rx_full_n est valide, cela signifie que les données dans le le FIFO de réception est plein, alors le FSM le contrôlera via le signal correspondant Le SPI arrête de recevoir des données. Lorsqu'il détecte que Rx_empty_n est valide (le FIFO de réception est vide), le FSM enverra un signal correspondant pour démarrer le SPI afin de continuer à recevoir des données jusqu'à ce que toutes les données d'empreintes digitales soient reçues.
  2. Module Tx FIFO : la fonction principale est de charger la commande à envoyer lors de l'initialisation, puis d'envoyer la commande sous le contrôle du signal Tx_rd_en. Le nombre total de commandes ne dépassant pas la profondeur de la FIFO, il n'est pas nécessaire pour vider le drapeau plein.
  3. Module SPI : sa fonction principale est de fournir au capteur le signal d'horloge SCK et le signal de sélection de puce SS lors de la communication avec le capteur externe, où les signaux SCK et SS sont initialement générés et contrôlés par le FSM ; lorsqu'il est nécessaire d'envoyer commandes au capteur, le FSM démarre les signaux SCK et SS, et le SPI accepte la commande lue à partir du FIFO Tx et la stocke temporairement dans un registre à décalage 8 bits tx_shifter[7:0].Après chaque cycle SCK, un Le bit est envoyé à MOSI et 1 octet est envoyé. Après que le tx_shifter rechargera la nouvelle commande et continuera à envoyer jusqu'à ce que la commande soit envoyée ; lorsque le SPI reçoit des données du capteur, le FSM démarre les signaux SCK et SS, et le registre à décalage rx_shifter[7:0] dans le SPI collectera le port d'entrée sur le front montant de SCK Les données de MISO sont décalées d'un bit, et les données dans le rx_shifter seront écrites dans le Rx FIFO sous le contrôle de le FSM tous les 8 cycles d'horloge SCK jusqu'à ce que les données soient reçues.
  4. Module Rx FIFO : la fonction principale de ce module est de mettre en cache les données d'empreintes digitales reçues pour éviter la perte de données d'empreintes digitales, car la fréquence de fonctionnement du port série SPI dans ce système est de 5 MHz, tandis que la fréquence de fonctionnement du port série UART est 38400 Hz. La vitesse d'extraction des données de la FIFO est bien inférieure à la vitesse d'écriture des données dans la FIFO Rx par le SPI. Rx FIFO peut fournir des bits d'indicateur vides et pleins rx_empty_n et rx_full_n à UART et FSM, de sorte que SPI et UART peuvent fonctionner ensemble.
  5. Module UART : La fonction principale de ces modules est de communiquer avec l'ordinateur et d'afficher les données d'empreintes digitales reçues via le terminal de l'ordinateur. Lorsque l'UART détecte que rx_full_n est valide, il enverra un signal de lecture Rx_rd_en pour lire les données dans le FIFO et l'envoyer à l'ordinateur, et s'arrêtera lorsqu'il détectera que rx_empty_n est valide.

5. Références 

[1] Zhao Jinming, Qian Lei, Wu Dong. Conception et implémentation d'une structure d'accélération de reconnaissance d'empreintes digitales basée sur FPGA [J]. Cyberspace Security, 2016, 7(005):59-64.

D234

6. Comment obtenir le code source complet

Méthode 1 : Contactez le blogueur via WeChat ou QQ

Méthode 2 : Abonnez-vous au didacticiel MATLAB/FPGA, obtenez gratuitement le cas du didacticiel et 2 codes sources complets

Je suppose que tu aimes

Origine blog.csdn.net/ccsss22/article/details/124207560
conseillé
Classement