Para la lógica combinacional, if
/ else
se implementa como un multiplexor 2: 1. En el álgebra de Boole, esto sería:
Q = (A * S) + (B * S')
donde:
-
S
es la entrada suministrada por la condición if
,
-
A
es la entrada que alimenta la subexpresión then
,
-
B
es la entrada que alimenta la subexpresión else
, y
-
Q
es el resultado de la expresión.
Teóricamente, podría generalizar esto para incluir un borde de reloj single , pero se vuelve mucho más complejo y se parecería a una celda FPGA cuando termine. Básicamente, si se incluyera un margen de reloj, no podría tener una cláusula else
(porque está implícitamente "no cambiar la salida"), y cualquier parte que no sea de borde de la condición if
simplemente se convertiría en el reloj habilitado expresión. Una vez que el polvo se haya asentado, quedará con una versión menos clara de la declaración always_ff
, que debería usar en su lugar de todos modos.
Las condiciones con dos o más bordes de reloj no se pueden sintetizar.
EDITAR: Primero, no estoy seguro de que if(posedge(...))
sea sintetizable. En general, utiliza la cláusula posedge(...)
en la línea always_ff @(...)
y no necesita el posedge()
dentro del bloque.
En SystemVerilog, la forma genérica de un multiplexor 2: 1 es una declaración if
. Por ejemplo:
always_comb begin
if(S)
Q = A;
else
Q = B;
end
Sin embargo, si hay un margen de reloj, necesitas usar un flip-flop:
always_ff @(posedge CLK) begin
if(CLK_ENA)
Q <= D;
end
Agregar un reinicio asíncrono se ve así:
always_ff @(posedge RESET, posedge CLK) begin
if(RESET)
Q <= '0;
else if(CLK_ENA)
Q <= D;
end
En este caso, RESET está activo-alto. Tenga en cuenta que solo necesita decir que RESET es sensible al borde en la parte @()
. En el resto del bloque, RESET tendrá el nivel después del borde. También tenga en cuenta que las sensibilidades de borde son una lista; No puedes decir "y". (En Verilog original, se separaron las sensibilidades de borde con "o", engañando a la gente para que piense "y" podría funcionar también.)