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 the if
condition,
A
is the input fed by the then
subexpression,
B
is the input fed by the else
subexpression, and
Q
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.)
Serial/parallel-load shift registers and bit rotations are going to work most naturally with a D flip flop, since they just send data straight through; binary counters are going to work most naturally with a T flip flop, since each counter bit Ck = Ck,previous XOR carryk, where carry is the carry bit from the previous stage.
If you look at JK flip-flops, however, they are the "universal" flip-flop that can act as a D- or T- flip-flop depending on the input signals.
To get a D from a T, or vice versa, you need an XOR gate. To get a T from a JK, you just tie the JK inputs together. To get a D from a JK, you need an inverter, as the J/K inputs need to be opposites.
In your application, you've got enough complexity, that I suspect the gate counts are going to be very close, and it's probably not worth worrying about -- unless you have to optimize, in which case you'll just have to try it for each case.
IMHO, the D flip-flop is conceptually the simplest to use, and it works naturally with most of your operations, so I'd start with that.
Best Answer
D, JK or T flip flops can all be configured such that they divide by 2. SR flip-flops, by themselves, can not be wired to toggle that way. So they are not applicable.
There are really only two types of counters you can build; a ripple counter, which divides by 2\$^N\$ using N flip-flops, and a ring counter, which divides by N using N flip-flops. The ripple counter's output can be short-circuited to divided by a number less than 2\$^N\$, for example a decade counter using four flip-flops. So we just need ripple counters, the ring counter will always use more flip-flops and can be discarded.
So to minimize the number of flip-flops, you need to break the counter value into prime factors, e.g. 21 breaks up into 3 x 7, and 30 breaks up into 2 x 3 x 5.
In the first case (21), since it doesn't divide by two you can't use a single flip-flop to divide the input by half. But you can cascade two ripple counters, one counting to 3 and the other counting to 7 (the output of the first fed into the input of the second). The total number of flip-flops needed would be 2 + 3 = 5.
In the second case (30), you can divide the input by two using a single flip-flop, and once again cascade two ripple counte3rs, one counting to 3 and the other counting to 5. The total number of flip-flops needed would be 1 + 2 + 3 = 6. (Or, you could use one ripple counter counting to 5, and another counting to 6, using the same number of flip-flops.)