Quartus II ignorando el atributo de síntesis noprune

2

Hay un registro en mi diseño que estoy usando para propósitos de depuración con cero fan-out. Ya que no está impulsando ninguna lógica, el sintetizador lo optimiza. Sin embargo, según mi conocimiento, el uso del atributo noprune dirigirá el sintetizador para mantener el registro.

Desafortunadamente, incluso con este atributo de síntesis, el registro se elimina del diseño en Quartus II. Se me sugirió que, dado que el módulo tiene una lógica mínima, puede causar un problema. Sin embargo, esto no me parece del todo correcto.

He probado otros atributos similares, como preservar, pero esto tampoco funcionó.

¿Es esta una peculiaridad de Quartus? ¿Sería mejor intentar sintetizar el diseño en algo como Synopsys Synplify y luego transferir ese diseño a Quartus para que se ajuste?

¿Alguna idea de cuál podría ser el problema?

Gracias de antemano!

Aquí está el código para el módulo:

VERSIÓN 1

module connector_test(button, txd)

input button;
output reg txd;
reg [2999:0] data /* synthesis noprune */;

always @(button) begin
if(button==1'b0) begin
    txd <= 1'b0;
    data <= {3000 {1'b1}};
end
else begin
    txd <= 1'b1;
    data <= 3000'b0;
end

end

endmodule

... y el resumen de la síntesis:

+------------------------------------------------------------------------------------+
; Analysis & Synthesis Summary                                                       ;
+------------------------------------+-----------------------------------------------+
; Analysis & Synthesis Status        ; Successful - Tue Sep 18 18:20:36 2012         ;
; Quartus II 32-bit Version          ; 12.0 Build 232 07/05/2012 SP 1 SJ Web Edition ;
; Revision Name                      ; connector_test                                ;
; Top-level Entity Name              ; connector_test                                ;
; Family                             ; Cyclone III                                   ;
; Total logic elements               ; 0                                             ;
;     Total combinational functions  ; 0                                             ;
;     Dedicated logic registers      ; 0                                             ;
; Total registers                    ; 0                                             ;
; Total pins                         ; 2                                             ;
; Total virtual pins                 ; 0                                             ;
; Total memory bits                  ; 0                                             ;
; Embedded Multiplier 9-bit elements ; 0                                             ;
; Total PLLs                         ; 0                                             ;
+------------------------------------+-----------------------------------------------+

VERSIÓN 2:

module trigger_test(trigger, reset, clk);

input clk;
input reset;
output reg trigger;
reg [2999:0] data = 3000'b0 /* synthesis noprune */;
reg [15:0] counter = 16'h32; //Trigger will be set every 1000ns (1us).

always @(posedge clk) begin

if(~reset) begin
    trigger <= 1'b0;
    data <= 3000'b0;
    counter <= 16'h32;
end 
else begin
    if(!counter) begin
        trigger <= 1'b1;    //Trigger and data will stay at these values for 20ns because they're synced with the clk.
        data <= {3000 {1'b1}};
        counter <= 16'h32;
    end
    else begin
        trigger <= 1'b0;
        data <= 3000'b0;
        counter <= counter - 1;
    end
end

end
endmodule

VERSIÓN 3:

module toplevel(clk, reset, trigger, out);

input clk;
input reset;
output reg trigger;
output wire out;

reg d = 1'b1;
reg q;

shift shifter( .clk(clk),
       .si(q),
       .so(out));

toggle tff_inst ( .d(d),
          .clk(clk),
          .rst(reset),
          .q(q));

endmodule

TOGGLE:

module toggle(d, clk, rst, q);

input clk;
input d;
input rst;
output reg q;

always @(posedge clk or negedge rst) begin
if(~rst)
    q <= 1'b0;
else if (d) 
    q <= !q;
end

endmodule

La tercera versión tampoco sintetiza ningún registro, y creo que esto se debe a que estoy recibiendo una advertencia de que la señal de salida (la salida del registro de desplazamiento) está atascada en la GND. Esto puede deberse a que no estoy inicializando el registro de alternancia que da entrada al registro de desplazamiento, pero no estoy seguro de cómo inicializar esto fuera de los propósitos de simulación. ¿Alguna sugerencia?

    
pregunta kbarber

1 respuesta

4

A pesar de la declaración "reg" en el código fuente, de hecho no ha creado ningún registro. El comportamiento de su bus de "datos" de 3000 bits es simplemente que su valor es una función del valor actual de la entrada del "botón"; no depende de la historia pasada de esa o cualquier otra señal, por lo que no se especifica un comportamiento real de la memoria y, por lo tanto, no hay flip-flops sintetizables.

La única lógica aquí es un inversor simple, cuya salida se replica 3000 veces. Como no hay nada conectado al bus de "datos" (y ni siquiera se especifica como un puerto de salida del módulo), no hay necesidad de implementar lógica para soportar el fanout, y de hecho, no hay necesidad de implementar el inversor en todos. ¿Qué es lo que realmente estás tratando de depurar? ¿Por qué mecanismo esperaba observar el bus de datos?

Supongo que Xilinx tomó un enfoque ultraconservador e implementó 3000 inversores. No tengo idea de por qué haría eso. La respuesta puede tener algo que ver con los mecanismos de depuración reales que cada fabricante incorpora en sus chips.

Si está tratando de medir cosas como el consumo de energía para varios niveles de utilización de FPGA, la técnica habitual para esto es crear un registro de turno largo. El registro está sincronizado por una señal de reloj común (generalmente un reloj global) y la entrada del primer bit y la salida del último bit se llevan a los pines (este último es para que el software de síntesis no "elimine" el sonido). cadena entera).

Usted controla la cantidad de utilización de recursos variando la longitud del registro de desplazamiento, y controla la cantidad de actividad de conmutación por el patrón que cambia. Un patrón de todos los ceros o de todos finalmente tiene la actividad mínima, mientras que un patrón de alternar unos y ceros eventualmente aumenta hasta el nivel máximo de actividad.

module shift (clk, si, so);
  parameter SHIFT_LENGTH = 3000;
  input     clk, si;
  output    so;
  reg    [SHIFT_LENGTH-1:0] data;
  always @(posedge clk) begin
    data <= {data[SHIFT_LENGTH-2:0], si};
  end
  assign so = data[SHIFT_LENGTH-1];
endmodule
    
respondido por el Dave Tweed

Lea otras preguntas en las etiquetas