Habiendo encontrado información múltiple, a veces contradictoria o incompleta en Internet y en algunas clases de capacitación sobre cómo crear restricciones de tiempo en formato SDC correctamente, me gustaría pedir ayuda a la comunidad de EE con algunas estructuras generales de generación de relojes que he encontrado.
Sé que hay diferencias sobre cómo se implementaría una determinada funcionalidad en un ASIC o FPGA (he trabajado con ambos), pero creo que debería haber una forma general y correcta de restringir el tiempo de una estructura determinada , independientemente de la tecnología subyacente; avíseme si me equivoco.
También hay algunas diferencias entre las diferentes herramientas para la implementación y el análisis de tiempo de diferentes proveedores (a pesar de que Synopsys ofrece un código fuente del analizador SDC), pero espero que sean principalmente un problema de sintaxis que se puede consultar en la documentación.
Consulte también la pregunta relacionada Restricciones de tiempo ASIC a través de SDC: ¿Cómo especificar correctamente un reloj multiplexado?
Se trata del siguiente divisor de reloj de ondulación, que es parte del módulo clkgen , que es parte de un diseño más grande que utiliza los relojes generadores:
La generación de clk0
parece ser relativamente sencilla:
create_clock [get_pins clkgen/clk0] -name baseclk -period 500
Aunque no estoy tan seguro acerca de los comandos SDC para los relojes generados, divididos clk2
y clk4
: clk8
¿Cómo se deben especificar las opciones de origen y destino ? Mi pensamiento inicial fue que el objetivo es el pin de salida en la celda generadora de reloj, la fuente está lo más cerca posible del objetivo:
create_generated_clock -name div2clk -source [get_pins clkgen/divA/clk] -divide_by 2 [get_pins clkgen/divA/q]
La fuente también podría ser el pin de entrada del reloj del módulo:
create_generated_clock -name div2clk -source [get_pins clkgen/clk0] -divide_by 2 [get_pins clkgen/divA/q]
O el reloj fuente previamente definido , como se sugiere aquí :
create_generated_clock -name div2clk -source [get_clocks baseclk] -divide_by 2 [get_pins clkgen/divA/q]
...lo que también plantea la cuestión de si las opciones de origen o de destino deben ser distintas de get_pins
, como get_nets
, get_registers
o get_ports
.
clk2
Para mantener el ejemplo lo más general posible , supongamos que los relojes generados clk4
podrían clk8
estar impulsando otros registros potencialmente interactivos (cruce de dominio de reloj) (que no se muestran en el esquema).
Creo que las restricciones para clk4
y clk8
deberían ser obvias una vez que sepamos cómo clk2
se escribe la restricción.
La instancia X1 (un búfer simple) en el esquema es solo un marcador de posición para resaltar el problema de en qué parte de la red de propagación del reloj se debe configurar la opción de fuentecreate_generated_clock
, ya que las herramientas automáticas de lugar y ruta generalmente son libres de colocar búferes en cualquier lugar (como como entre los pines divA1/q
y ).divB1/clk
Diría que la regla general es: configure el puerto de entrada del módulo superior o el pin Q de un flip-flop interno como la fuente del reloj generado.
Ejemplo de código Verilog:
module top (
input clk,
input rst,
...
);
...
always @(posedge clk or negedge rst)
begin
if (rst == 1'b0)
div_2_clk = 1'b0;
else
div_2_clk = ~div_2_clk;
end
...
endmodule
Ejemplo de código SDC:
create_clock -name clk -period 5 [get_port clk]
...
create_generated_clock -name slow_clk -source [get_port clk] -divide_by 2 [get_pins div_2_clk_reg/Q]
No probé la sintaxis anterior. También tenga en cuenta la extensión _reg
agregada al nombre RTL de la señal: esta es la extensión agregada por la herramienta de síntesis cuando detecta que la señal debe estar representada por un flip-flop. Esta extensión puede variar entre herramientas (no lo sé con certeza).
Si usa cualquier envoltorio RTL alrededor de flip-flops, configure la fuente de los relojes generados para que sea el pin Q interno del flip-flop, no el pin de salida del envoltorio.
Si sigue estas reglas simples, no necesita preocuparse por los búfer agregados por las herramientas de síntesis o P&R.
AmigoFX
create_clock [get_ports clk0]
(suponiendoclk0
que sea el puerto de nivel superior)? Si pudiera incorporar eso en su respuesta y también incluir al menos un ejemplo completo de lacreate_generated_clock
declaración, ¡me encantaría aceptarlo!vasiliy
AmigoFX
create_*clock
comandos, ¿eso significa que el analizador de tiempo agregará los retrasos de la ruta (y el posible búfer insertado) a la latencia de los relojes (generados)?vasiliy
AmigoFX
source
untarget
reloj generado incluirá cualquier búfer que la herramienta P&R pueda insertar entre estos nodos.vasiliy
AmigoFX
-source
opción debe referirse al pin de reloj más cercano del objetivo especificado ". Esto solo puede ser relevante cuando se usan varios relojes en el mismo puerto y para ese caso, la-master_clock
opción se puede utilizar de todos modos. Solo quiero asegurarme de que no estoy impidiendo que el analizador de tiempo tome en cuenta todos los retrasos correctamente.AmigoFX
clk0
yclk4
en mi ejemplo, cualquier demora en la red de relojes entreclk0
yclk4
debe tenerse en cuenta por el tiempo analizador de estos caminos, ¿verdad?vasiliy
clk0
yclk4
, la definirá como ruta falsa (si los relojes son mutuamente excluyentes, si usa sincronizadores, ...) o como una ruta de varios ciclos. En el primer caso, la herramienta no debe realizar ningún análisis de tiempo y depende de usted asegurarse de que no se produzca ningún fallo lógico. En el último caso, todas las demoras relevantes fueron tomadas en cuenta por otras herramientas que vi.AmigoFX
vasiliy
AmigoFX
create_generated_clock
comando SDC. Acepté tu respuesta. Tal vez-source
en algún momento comience una pregunta separada sobre los detalles de la opción. ¡Gracias por tus esfuerzos!