Estoy implementando una CPU simple de estilo Harvard usando Xilinx ISE versión 14.1. Estoy usando configuraciones compatibles con una placa Digilent Nexys3, pero por el momento todo el proyecto se realiza solo en simulación.
Tengo la siguiente entrada en mi archivo UCF que especifica la ubicación (pin) del reloj en la placa Nexys3, junto con una restricción de período de 100 MHz. Esto significa un período de 10ns.
Net "clk" LOC=V10 | IOSTANDARD=LVCMOS33;
Net "clk" TNM_NET = sys_clk_pin;
TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 100000 kHz;
Estoy cronometrando toda la lógica síncrona usando el borde positivo de este reloj.
El análisis de tiempo estático posterior a Place-and-Route sugiere que todo está bien:
Timing constraint: TS_sys_clk_pin = PERIOD TIMEGRP "sys_clk_pin" 100 MHz HIGH
50%;
For more information, see Period Analysis in the Timing Closure User Guide (UG612).
12987 paths analyzed, 961 endpoints analyzed, 0 failing endpoints
0 timing errors detected. (0 setup errors, 0 hold errors, 0 component switching limit errors)
Minimum period is 4.003ns.
El período mínimo está dentro del objetivo de 10 ns. No hay rutas sin restricciones en el informe.
El informe luego menciona este camino primero. Dado que el tiempo coincide, asumo que es el camino más lento en el diseño (el camino con la menor holgura). Es la ruta desde el registro de instrucciones hasta el bit más alto del puntero de la pila. La ruta (a través de la ALU y el bus 3) parece sana para mi diseño cuando el registro se carga con un valor inmediato. La ruta push/pop toma una ruta diferente.
Slack (setup path): 5.997ns (requirement - (data path - clock path skew + uncertainty))
Source: CONTROL/IR_15_2 (FF)
Destination: SP/VALUE_31 (FF)
Requirement: 10.000ns
Data Path Delay: 3.951ns (Levels of Logic = 9)
Clock Path Skew: -0.017ns (0.252 - 0.269)
Source Clock: clk_BUFGP rising at 0.000ns
Destination Clock: clk_BUFGP rising at 10.000ns
Clock Uncertainty: 0.035ns
Clock Uncertainty: 0.035ns ((TSJ^2 + TIJ^2)^1/2 + DJ) / 2 + PE
Total System Jitter (TSJ): 0.070ns
Total Input Jitter (TIJ): 0.000ns
Discrete Jitter (DJ): 0.000ns
Phase Error (PE): 0.000ns
Maximum Data Path at Slow Process Corner: CONTROL/IR_15_2 to SP/VALUE_31
Location Delay type Delay(ns) Physical Resource
Logical Resource(s)
------------------------------------------------- -------------------
SLICE_X13Y30.BQ Tcko 0.391 CONTROL/IR_15_3
CONTROL/IR_15_2
SLICE_X5Y31.D3 net (fanout=12) 0.847 CONTROL/IR_15_2
SLICE_X5Y31.D Tilo 0.259 RAM/read_address<1>
ALU1/Mmux_RR11241
SLICE_X14Y24.B3 net (fanout=4) 1.283 bus3_1_OBUF
SLICE_X14Y24.COUT Topcyb 0.380 SP/VALUE<3>
SP/Mcount_VALUE_lut<1>
SP/Mcount_VALUE_cy<3>
SLICE_X14Y25.CIN net (fanout=1) 0.003 SP/Mcount_VALUE_cy<3>
SLICE_X14Y25.COUT Tbyp 0.076 SP/VALUE<7>
SP/Mcount_VALUE_cy<7>
SLICE_X14Y26.CIN net (fanout=1) 0.003 SP/Mcount_VALUE_cy<7>
SLICE_X14Y26.COUT Tbyp 0.076 SP/VALUE<11>
SP/Mcount_VALUE_cy<11>
SLICE_X14Y27.CIN net (fanout=1) 0.003 SP/Mcount_VALUE_cy<11>
SLICE_X14Y27.COUT Tbyp 0.076 SP/VALUE<15>
SP/Mcount_VALUE_cy<15>
SLICE_X14Y28.CIN net (fanout=1) 0.003 SP/Mcount_VALUE_cy<15>
SLICE_X14Y28.COUT Tbyp 0.076 SP/VALUE<19>
SP/Mcount_VALUE_cy<19>
SLICE_X14Y29.CIN net (fanout=1) 0.003 SP/Mcount_VALUE_cy<19>
SLICE_X14Y29.COUT Tbyp 0.076 SP/VALUE<23>
SP/Mcount_VALUE_cy<23>
SLICE_X14Y30.CIN net (fanout=1) 0.003 SP/Mcount_VALUE_cy<23>
SLICE_X14Y30.COUT Tbyp 0.076 SP/VALUE<27>
SP/Mcount_VALUE_cy<27>
SLICE_X14Y31.CIN net (fanout=1) 0.003 SP/Mcount_VALUE_cy<27>
SLICE_X14Y31.CLK Tcinck 0.314 SP/VALUE<31>
SP/Mcount_VALUE_xor<31>
SP/VALUE_31
------------------------------------------------- ---------------------------
Total 3.951ns (1.800ns logic, 2.151ns route)
(45.6% logic, 54.4% route)
Armado con este conocimiento, ejecuto una simulación posterior a Place-and-Route con un período de reloj de 10 ns pensando que todo estará bien. Sin embargo, no lo es. Las señales no se asientan a tiempo para el siguiente borde del reloj y todo es un desastre. Relajar el reloj a 50 ns (20 Mhz) permite mucho tiempo para que todo se asiente.
A los 425ns obtenemos el pulso de reloj que señala el inicio del ciclo en el que ejecutaremos la instrucción SP <- 0xFFFFFFFF
. IR_15_2
es la señal del informe de tiempo. SP_value
es un registro, por lo que solo asume el valor que se le presenta en el siguiente flanco ascendente. SP se carga desde bus3, así que lo usamos como proxy.
En el gráfico vemos que se necesitan aproximadamente 3 ns para IR_15_2
que se afirme. Luego, toma más de 10 ns más para que el bus1 tome el control de la señal. A los 451 ns, 26 ns más tarde, la señal está disponible en el bus 3 y podemos empezar a pensar en cargar SP con ella.
El tiempo estático me dice que la ruta más larga de registro a registro en el diseño debería tomar alrededor de 4 ns, mientras que la simulación muestra que las señales tardan alrededor de 26 ns en establecerse. ¿Que esta pasando aqui? ¿El análisis de tiempo estático no encuentra todas las rutas relevantes? ¿Usé/configuré mal el simulador? ¿Leí mal el análisis de tiempo estático?
Estoy bien ejecutando el diseño a 20Mhz, esto no es una competencia de velocidad. Solo tengo la sensación de que me falta algo importante.
El proyecto completo (archivos VHDL, proyecto XISE) está disponible en bitbucket .
Mirando a través de su informe de tiempo, no hay nada que indique un problema potencial. Dado que tiene un problema, esto significa que los escenarios que está comprobando el análisis de tiempo estático (STA) no cubren el uso real de su circuito.
Sin una configuración seria de STA, algunas suposiciones comunes son que todas las entradas son válidas en el momento en que sube el reloj y que se conocen todos los estados (es decir, una lógica 1
o 0
). Inmediatamente, el UUUUUUUU
encendido bus3
parece muy sospechoso y es un posible problema con la inicialización. En simulaciones lógicas, U
implica que la línea es a 1
o 0
, pero un registro que la controla no se inicializó correctamente. Esto podría hacer que el simulador dé respuestas extrañas hasta que todos los registros se carguen o se restablezcan. Sin embargo, este problema se manifiesta en ciclos posteriores después de inicializar todos los registros.
El otro problema potencial es que se bus1
inicia en un estado de alta impedancia ( ZZZZZZZZ
). Teniendo en cuenta que los tres estados generalmente no se asumen en el análisis de tiempo, esta es la fuente más probable de la discrepancia de tiempo. Las condiciones tri-estatales deben codificarse cuidadosamente en su herramienta STA para que puedan ser consideradas. Esta puede ser una tarea muy difícil y es propensa a errores (programación incorrecta, casos perdidos, etc.). Creo que la programación en retrasos de tres estados probablemente le daría un resultado STA preciso que debería coincidir con su simulación.
Sin embargo, tri-state suele ser una mala elección para la comunicación en chip tanto para ASIC como para FPGA. Esta ambigüedad de la confiabilidad de STA, el potencial de contención del bus y la incertidumbre de los requisitos de potencia de la unidad hacen que sea más probable que los sistemas tri-state causen problemas en lugar de solucionarlos. El método más seguro es usar un multiplexor para seleccionar qué fuente "habla" con el bus, o dividir el diseño de manera diferente. Solo usaría tri-state cuando sé que resolverá más problemas de los que puede causar.
drxzcl
W5VO
UUUUUUUU
? ¿Es esta la primera instrucción que ejecuta, o hay algo más que haceU
que se propague? No estoy seguro de cómo maneja STAU
, y eso puede ser parte de su problema.drxzcl
drxzcl
W5VO
Z
oU
?W5VO
drxzcl
W5VO
Z
deben tratarse como un martillo, útil en casos específicos, pero no una solución milagrosa o incluso una solución preferida.drxzcl