Categorías
Otros

Estudio de diseño ic digital señala _ problema de sincronización de dominio de reloj cruzado 2

Notas del estudio de diseño de IC digital

Problema de sincronización de dominios a través del reloj

2 Multi-bit signal cross-clock domain problem_asynchronous FIFO

2 FIFO asincrónico

  • Diagrama esquemático


El diseño de FIFO asincrónico consta principalmente de 5 partes:

  1. Memoria FIFORAM de puerto 😀 ual para almacenar datos
  2. sync_r2w: Sincronizador, sincroniza el puntero de datos leídos con el dominio de reloj de escritura
  3. sync_w2r: Sincronizador, sincroniza el puntero de datos de escritura para leer el dominio de reloj
  4. wptr_full: Lógica para manejar el puntero de escritura y la señal completa
  5. rptr_empt: Lógica para procesar punteros de lectura y señales nulas
  • Código Verilog
//----TOP module-------------------------------
module asyncfifo_r1#(
	parameter	ADDRSIZE	=	4,
	parameter	DATASIZE	=	8
)
(	
//----write signal ----------------------------
	input wclk,
	input wrst,
	input [DATASIZE-1:0] wdata,
	input winc,
	
	output wfull,
//----resd signal ----------------------------
   input rclk,
	input rrst,
	input rinc,
	
	output empty,
	output [DATASIZE-1:0] rdata
    );
 wire [ADDRSIZE-1:0] waddr;
 wire [ADDRSIZE-1:0] raddr;
 wire [ADDRSIZE:0] wptr, rptr, wq2_rptr, rq2_wptr;
 
 FIFOMEM_R0 U1 (
	.wclk (wclk),
	.wdata(wdata),
	.rdata(rdata),
	.waddr (waddr),
	.raddr(raddr),
	.wclken(winc),
	.wfull (wfull)
 );
 
 syn_r2w U2 (
	.wclk(wclk),
	.rst_n(wrst),
	.wq2_rptr(wq2_rptr),
	.rptr(rptr)
 );
 
  sync_w2r_r1 U3 (
	.rclk(rclk),
	.rst_n(rrst),
	.rq2_wptr(rq2_wptr),
	.wptr(wptr)
 );
 
  wptr_full_r1 U4(
  	.wclk(wclk),
	.wrst_n(wrst),
	.winc(winc),
	.wq2_rptr(wq2_rptr),
	.wfull(wfull),
	.waddr(waddr),
	.wptr(wptr)
  );
  
  rptr_empty U5(
  	.rclk(rclk),
	.rst_n(rrst),
	.rinc(rinc),
	.rq2_wptr(rq2_wptr),
	.rempty(empty),
	.raddr(raddr),
	.rptr(rptr)
  ); 
  
  
endmodule

1. Memoria FIFO

  • En FPGA, podemos usar carnero de bloque o carnero distribuido.
  • Código Verilog
module FIFOMEM_R0#(
	parameter DATASIZE = 8, // memory data word width
	parameter ADDRSIZE = 4	// memory address bits
)
(	
	input 					wclk,
	input	[DATASIZE-1:0]	wdata,
	input	[ADDRSIZE-1:0]	waddr,
	input	[ADDRSIZE-1:0]	raddr,
	input						wclken,
	input						wfull,
	
	output	[DATASIZE-1:0]	rdata
    );
	 localparam DEPTH = 1<< ADDRSIZE;
	 
	 reg [DATASIZE-1:0] mem [0:DEPTH-1];
//read----------------------------------	 
	 assign rdata = mem[raddr];
//write---------------------------------	 
	 [email protected](posedge wclk)begin
	 if(wclken && !wfull) //Write is valid and not full
		mem[waddr] <= wdata;
	 end
endmodule
  • Simulación de Modelsim

    Nota: La dirección de memoria es una dirección binaria; la dirección para determinar si está lleno o vacío es una dirección de código gris.
  [2021] Reparar el sistema Ubuntu16.04

2. sync_r2w

  • Código Verilog
module syn_r2w#(
	parameter ADDRSIZE = 4
)
(
	input 					wclk,
	input						rst_n,
	input [ADDRSIZE:0] rptr,
	
	output reg [ADDRSIZE:0] wq2_rptr 
    );
	reg	[ADDRSIZE:0]	wq1_rptr;
	
	[email protected](posedge wclk or negedge rst_n)begin
		if(!rst_n)begin
			wq1_rptr <= 0;
			wq2_rptr <= 0;
			end else begin
			wq1_rptr <= rptr;
			wq2_rptr <= wq1_rptr;
			end
		end
endmodule
  • Simulación de Modelsim


3. sync_w2r

  • Código Verilog
module sync_w2r_r1#(
	parameter ADDRSIZE = 4
)
(
	input rclk,
	input rst_n,
	input [ADDRSIZE:0] wptr,
	
	output reg [ADDRSIZE:0] rq2_wptr
    );
	 reg [ADDRSIZE:0] rq1_wptr;
	 
	 [email protected](posedge rclk or negedge rst_n)begin
		if(!rst_n)begin
			rq1_wptr <= 0;
			rq2_wptr <= 0;
		end else begin
				rq1_wptr <= wptr;
				rq2_wptr <= rq1_wptr;
		end
	 end
endmodule
  • Simulación de Modelsim


4. wptr_full

  • La lógica de generación de señal completa se coloca en el dominio de reloj de escritura. Dado que los bits N-1 inferiores del código gris de N-bit son simétricos, al comparar punteros de lectura y escritura, no basta con juzgar que el bit Nth no es igual y los bits N-1 inferiores son iguales al comparar punteros de lectura y escritura, y se generará una señal completa falsa. Para generar la señal completa correcta, tenemos que juzgar las siguientes tres condiciones al mismo tiempo:
    El bit N-1 no es igual
    N-2th bits no son iguales
    Los bits bajos de N-3 son todos iguales

    Al igual que la señal nula, para la salida de registro de la señal completa, podemos utilizar wgraynext en lugar de wptr para el puntero de escritura (wptr es un latido más tarde que wgraynext).

  • Código Verilog

module wptr_full_r1#(
	parameter ADDRSIZE = 4
)
(
	input wclk,
	input	wrst_n,
	input	winc,
	input	[ADDRSIZE:0] wq2_rptr,
	
	output reg                wfull,
	output     [ADDRSIZE-1:0] waddr,
	output reg [ADDRSIZE:0]    wptr
    );
	 
	wire 					wfull_val;
	wire [ADDRSIZE:0]	wbinnext;
	wire [ADDRSIZE:0] wgraynext;
	reg [ADDRSIZE:0] 	wbin;
	
//----write address---------------//
	assign waddr = wbin[ADDRSIZE-1:0];

//----bin2gray--------------------//
	assign wbinnext = wbin + (winc & ~wfull);

	assign wgraynext = (wbinnext>>1)^ wbinnext;	
//----gray pointer----------------//
	[email protected](posedge wclk or negedge wrst_n)begin
		if(!wrst_n)begin
			wptr <= 0;
			wbin <= 0;
		end else
		begin
			wptr <= wgraynext;//gray
			wbin <= wbinnext;
			end		
	end

//----write full------------------//
	assign wfull_val = ((wgraynext[ADDRSIZE]     != wq2_rptr[ADDRSIZE]) &&
	                    (wgraynext[ADDRSIZE-1]   != wq2_rptr[ADDRSIZE-1]) &&
							  (wgraynext[ADDRSIZE-2:0] == wq2_rptr[ADDRSIZE-2:0]));
	[email protected](posedge wclk or negedge wrst_n)begin
		if(!wrst_n)
		wfull <= 0;
		else
		wfull <= wfull_val;
	end
endmodule
  • Simulación de Modelsim

    5. rptr_empty
  • La lógica de generación de la señal nula se coloca en el dominio de reloj de lectura. Compare directamente si los punteros de lectura y escritura son iguales (el puntero de lectura se pone al día con el puntero de escritura). Tenga en cuenta que el puntero de escritura aquí es el puntero de escritura sincronizado con el dominio de reloj de lectura. Para la salida de registro de la señal vacía, podemos utilizar el puntero de lectura al comparar
    rgraynext en lugar de rptr (rptr es un ritmo más tarde que rgraynext).
  • Código Verilog
module rptr_empty#(
	parameter ADDRSIZE = 4
)
(
	input 							rclk,
	input								rst_n,
	input 							rinc,
	input	[ADDRSIZE:0] 		rq2_wptr,
	
	output	reg					rempty,
	output	[ADDRSIZE-1:0] 	raddr,
	output	reg [ADDRSIZE:0]	rptr //gray
    );
	 
	reg 			[ADDRSIZE:0] rbin;
	wire        [ADDRSIZE:0] rgraynext;
	wire        [ADDRSIZE:0] rbinnext;
	wire							rempty_val;
	
//----gray pointer---------------------------------------//
	[email protected](posedge rclk or negedge rst_n)begin
		if(!rst_n)begin
			rbin <= 0;
			rptr <= 0;
		end else
		begin 
			rbin <= rbinnext;
			rptr <= rgraynext;
			end			
	end
	
//----memory address-------------------------------------//
	assign raddr = rbin[ADDRSIZE-1:0];
//----bin2gray-------------------------------------------//
	assign rbinnext = rbin + (rinc & ~rempty);
	assign rgraynext = (rbinnext>>1)^rbinnext; 
	 
//----FIFO empty when rptr == ayncronized wptr-----------//
	assign rempty_val = (rgraynext == rq2_wptr);
	
	[email protected](posedge rclk or negedge rst_n)begin
		if(!rst_n)begin
			rempty <= 0;
			end else
				rempty <= rempty_val;
	end
endmodule
  • Simulación de Modelsim
  La sintaxis de programación Java _Java sintaxis básica básica de programación

[Note]: Notas de estudio personales, si hay algún error, por favor siéntase libre de iluminarme. Esto es educado ~~~


.

Por Programación.Click

Más de 20 años programando en diferentes lenguajes de programación. Apasionado del code clean y el terminar lo que se empieza. ¿Programamos de verdad?

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *