El registro FPGA práctico (un conjunto de flip-flops D) solo tiene un pin de reloj por lo que sirve exactamente un dominio de reloj. Tenga en cuenta este hardware de bajo nivel al escribir el código HDL.
Cuando una señal cruza de un dominio de reloj a otro, es común usar una tubería de tres registros, con la primera etapa en el dominio de reloj de origen y el segundo y tercer registros en el dominio de reloj de destino. Esto causa una latencia predecible, pero evita las condiciones de carrera y el comportamiento indefinido.
// From Xilinx ISE 14.1 Language Templates
// Verilog | Synthesis Constructs | Coding Examples | Misc | Asynchronous Input Synchronization
module async_input_sync(
input clk,
(* TIG="TRUE", IOB="FALSE" *) input async_in,
output reg sync_out
);
(* ASYNC_REG="TRUE", SHREG_EXTRACT="NO", HBLKNM="sync_reg" *) reg [1:0] sreg;
always @(posedge clk) begin
sync_out <= sreg[1];
sreg <= {sreg[0], async_in};
end
endmodule
Sincronice pci_data, pci_wr y pci_addr en el dominio de reloj mcclk. Por ejemplo:
wire [xxx] pci_mc_data; // pci_ signal in pciclk clock domain, source mc_data
wire pci_mc_wr; // pci_ signal in pciclk clock domain, source mc_data
wire [xxx] pci_mc_addr; // pci_ signal in pciclk clock domain, source mc_data
async_input_sync(pciclk, mc_data[xxx], pci_mc_data[xx]);
async_input_sync(pciclk, mc_wr, pci_mc_wr);
async_input_sync(pciclk, mc_addr[xxx], pci_mc_addr[xx]);
Sincronice mc_data, mc_wr y mc_addr en el dominio de reloj pciclk. Por ejemplo:
wire [xxx] mc_pci_data; // mc_ signal in mcclk clock domain, source pci_data
async_input_sync(mcclk, pci_data[xxx], mc_pci_data[xx]);
Tendrá un registro en el dominio del reloj pciclk, y otro registro en el dominio del reloj mcclk. Ambos registros tienen los mismos datos después de que la señal se propaga a través del dominio del reloj. Por ejemplo, el registro en el lado pci podría verse así:
// All of these signals are in the pciclk clock domain
always @(posedge pciclk) begin
if (pci_wr & pci_addr == 0) begin
pci_cntl_reg <= pci_data;
end
if (pci_mc_wr & pci_mc_addr == 0) begin
pci_cntl_reg <= pci_mc_data;
end
end
También tenga en cuenta el uso de la asignación no bloqueante < = para ayudar a la herramienta de síntesis a reconocer que está solicitando un conjunto de D flip flops. La palabra clave verilog register
es solo un tipo de datos, no siempre resulta en la síntesis de un flip-flop D.