For combinational logic, if
/else
is implemented as a 2:1 multiplexer. In Boolean algebra, this would be:
Q = (A * S) + (B * S')
where:
S
is the input fed by theif
condition,A
is the input fed by thethen
subexpression,B
is the input fed by theelse
subexpression, andQ
is the output of the expression.
You could theoretically generalize this to include a single clock edge, but it gets a lot more complex and would resemble an FPGA cell when you're done. Basically, if a clock edge were included, you could not have an else
clause (because it is implicitly "do not change the output"), and any non-edge parts of the if
condition would simply become the clock enable expression. Once the dust settled, you'd be left with a less-clear version of the always_ff
statement, which you should use instead anyway.
Conditions with two or more clock edges are not synthesizable.
EDIT: First, I'm not sure if(posedge(...))
is synthesizable. In general, you use the posedge(...)
clause in the always_ff @(...)
line and don't need the posedge()
inside the block.
In SystemVerilog, the generic form of a 2:1 multiplexer is an if
statement. For example:
always_comb begin
if(S)
Q = A;
else
Q = B;
end
If there's a clock edge, though, you need to use a flip-flop:
always_ff @(posedge CLK) begin
if(CLK_ENA)
Q <= D;
end
Adding an asynchronous reset looks like this:
always_ff @(posedge RESET, posedge CLK) begin
if(RESET)
Q <= '0;
else if(CLK_ENA)
Q <= D;
end
In this case, RESET is active-high. Note that you only need to say RESET is edge sensitive in the @()
part. In the rest of the block, RESET will have the level after the edge. Also note that the edge-sensitivities are a list; you can't say "and". (In original Verilog, you separated edge sensitivities with "or", misleading people into thinking "and" could work as well.)