Soy nuevo en systemverilog. Recientemente estoy trabajando en un proyecto para decodificar un flujo de datos de un AVALON_ST. Utilizando systemverilog. Mi dispositivo de destino es Stratix V y el reloj es de 200Mz.
module decoder(
// clk and reset
input logic reset_n,
input logic clk,
// avalon st
input logic in_vld,
input logic in_sop,
input logic in_eop,
input logic[255:0] in_data,
input logic[4:0] in_eop_pos,
// output
output logic trigger
);
// local logics
shortint pos;
shortint limit;
shortint offset;
logic[511:0] buffer;
logic[255:0] remainning_data;
business_object obj; // systemverilog struct for the packed data
always_ff @(posedge clk or negedge reset_n) begin
// (0)
// handle reset_n
// (1)
// whenever in_vld, combine remainning_data (if any) and in_data
// to buffer
// (2)
// update pos, limit and offset based on in_eop_pos
// (3)
// decode the buffer and populate business_object field by field
// (4)
// if a completed obj is decoded, applied the business rule to output trigger
// (5)
// if there are remainning data bits (either after a full decoded obj
// or remainning bits that are not enough to pouplate business_object),
// store it in remainning_data
end
endmodule
Uso la asignación sin bloqueo para las partes # 0 y # 4 y la asignación de bloqueo para # 1, # 2, # 3 y # 5.
Uso ModelSim para simular el decodificador. Funciona. Sin embargo, no funciona en hardware.
Después de la investigación, descubrí que hay algo resaltado en rojo en el Analizador de tiempo de Quartus que dice que:
"El diseño contiene rutas de instalación con errores con una holgura de -9.561ns en el peor de los casos"
Hay un gran retraso lógico combinacional que excede un período de reloj.
Mis preguntas son:
1) ¿Importa el retraso lógico combinacional si hay varias asignaciones de bloqueo (# 1, # 2, # 3, # 5) dentro del bloque always_ff?
Sé que no es la mejor práctica tener una asignación de bloqueo dentro de always_ff pero aprendí de alguna parte que está bien tener una asignación de bloqueo para variable local o en el caso de que solo haya un bloque always_ff en el módulo.
Si es importante, ¿puedo reducir el retraso moviendo estas lógicas de asignación de bloqueo a always_comb?
2) La interfaz de Avalon tiene 256 bits de ancho y ya estoy usando la forma de línea de pines en mi diseño. ¿Algún otro consejo que pueda reducir el retraso lógico?
Update@20180806
Observo el esquema RTL junto con el analizador de tiempo y traté de entender por qué hay tantos niveles lógicos y señales de salida. Descubrí que lo siguiente consume suficiente demora en la ruta de datos:
a) if / else statement / switch-case en pos
, offset
etc
b) cálculo matemático (por ejemplo, adder
) en pos
, offset
Utilicé shortint
general como tipo de datos para pos
y limit
, que eran señales locales para representar el número de bits leídos / pendientes de lectura / bits restantes, etc.
El rango de datos de negocios de pos
es 12k bits (1500 bytes) y offset
256 bits (32 bytes), así que el original usé shortint
(16 bits). Fui demasiado generoso.
Ahora, cambié a bit[5:0]
para offset
y bit[9:0]
para que pos
represente el número de BYTES leídos / pendientes. Reduce el recuento de ALM del módulo de 3800 a 1900, reduce significativamente el retraso de los datos y ahora se cumple el requisito de tiempo.
Gracias a todos.