Creo que "descompilar el rtl original en el archivo" es la conversión de la codificación RTL al modelado a nivel de puerta. El estilo RTL tiene always
bloques y assign
, mientras que el modelado a nivel de puerta solo contiene llamadas a otros módulos y / o celdas estándar. Ambos son equivalentes funcionales (cuando están escritos correctamente). La gran diferencia es que RTL es un nivel de abstracción más alto y, por lo tanto, más fácil de codificar (especialmente los diseños complejos), mientras que el modelado a nivel de puerta está más cerca de lo que realmente será el diseño de silicio e incluso puede simular con temporización comentada.
El archivo de biblioteca contiene las definiciones de todas las celdas estándar disponibles para una tecnología en particular y se usa para la conversión de nivel RTL a puerta. En otras palabras, son las celdas que el sintetizador puede usar para la conversión. Por lo general, se mantienen las definiciones para nand, nor, xor, flop-flop, buffer, inversor, etc. y varios sabores de cada uno para admitir los requisitos de tiempo, carga y tamaño. Por lo general es proporcionado por un vendedor o fundición.
Si no tiene la biblioteca Verilog, pero sí tiene un esquema. A continuación, descubra cómo exportar la biblioteca como Verilog. De lo contrario, es posible crear una biblioteca falsa a mano (simplemente comprenda que no puede usarla con un proyecto real). Ejemplo: fake_udp.v
'celldefine
module FAKELIB_NAND2(output OUT, input IN0,IN1 );
assign OUT = ~(IN0 & IN1);
endmodule
module FAKELIB_NAND4(output OUT, input IN0,IN1,IN2,IN3 );
assign OUT = ~(IN0 & IN1 & IN2 & IN3);
endmodule
module FAKELIB_NOR2(output OUT, input IN0,IN1 );
assign OUT = ~(IN1 | IN0);
endmodule
module FAKELIB_INV(output OUT, input IN );
assign OUT = ~IN;
endmodule
module FAKELIB_BUF(output OUT, input IN );
assign OUT = IN;
endmodule
module FAKELIB_BUF_BIGLOAD(output OUT, input IN );
assign OUT = IN;
endmodule
module FAKELIB_DFF(output reg Q, input CLK, RST_N, SET_N, D );
FAKELIB_DFF_PRIMITIVE dff(Q, CLK, RST_N, SET_N, D);
endmodule
// ... more standard cells ...
'endcelldefine
primitive FAKELIB_DFF_PRIMITIVE(output reg Q, input CLK, RST_N, SET_N, D );
table
// CLK RST_N SET_N D : Q(state) : Q(next)
? 0 ? ? : ? : 0;
? 1 0 ? : ? : 1;
p 1 1 0 : ? : 0;
p 1 1 1 : ? : 1;
(?0) 1 1 ? : ? : -;
? 1 1 * : ? : -;
endtable
endprimitive
// ... more standard cells ...
Ahora suponga que tiene la siguiente RTL:
module my_module(input clk, rst_n, input [2:0] in, output reg [2:0] out);
always @(posedge clk, negedge rst_n) begin
if ( !rst_n ) begin
out <= 3'b0;
end
else begin
out[0] <= ~(in[0] & in[2]);
out[1] <= ∈
out[2] <= in[1] | in[2];
end
end
endmodule
Sintetizar con fake_udp.v ya que su biblioteca dará algo como esto: (Nota: el resultado depende de la herramienta y las opciones. También este ejemplo se hizo a mano)
module my_module(input clk, rst_n, input [2:0] in, output [2:0] out);
supply0 SUPVSS;
supply1 SUPVDD;
wire syn_0, syn_1, syn_2, syn_3, syn_4;
FAKELIB_NAND2 U0 (.OUT(syn_0), .IN0(in[0]), .IN1(in[2]));
FAKELIB_NAND4 U1 (.OUT(syn_1), .IN0(in[0]), .IN1(in[1]), .IN2(in[2]), .IN3(SUPVDD));
FAKELIB_NOR2 U2 (.OUT(syn_2), .IN0(in[1]), .IN1(in[2]));
FAKELIB_INV U3 (.OUT(syn_3), .IN(syn_1));
FAKELIB_INV U4 (.OUT(syn_4), .IN(syn_2));
FAKELIB_DFF out_0__reg (.Q(out[0]), .CLK(clk), .RST_N(rst_n), .SET_N(SUPVDD), .D(syn_0));
FAKELIB_DFF out_1__reg (.Q(out[1]), .CLK(clk), .RST_N(rst_n), .SET_N(SUPVDD), .D(syn_3));
FAKELIB_DFF out_2__reg (.Q(out[2]), .CLK(clk), .RST_N(rst_n), .SET_N(SUPVDD), .D(syn_4));
endmodule