Do it the same way you'd do it in VHDL.
Remember, when writing VHDL, you're writing a description of RTL (register transfer level logic). If you ever forget this, and you write nonsense instead... well, yeah. The practical difference between VHDL and traditional procedural languages like C is more than just when a statement is relevant: it's that C is compiled to sequential software, whereas VHDL is synthesized to static logic. To do a very good job of C, you need to know what it compiles to; to do a very good job of VHDL, you need to know what it synthesizes to.
Anyway, last time I did that, it was:
Input debounce circuit. Majority voting method. Input is sampled at system clock frequency (which is several times the bitrate expected for this input; the input should also be analog filtered to a similar rate -- because after all, just because it's a 1-bit DAC doesn't mean sampling theory just goes out the window!), and sent through N shift registers. The bits are added up as unary. This looks something like, "q <= bit[0] + bit[1] + bit[2] + ... ;". Q needs LG(N) bits to account for carries, and you use a comparison of Q > N/2 to determine if it's up or down. (To enhance the input-debounce-iness of my circuit, I also added hysteresis, so that the output only gets set to '1' when Q > N/2 + E, or '0' when Q < N/2 - E, where E is some value less than N/2. Example: if N = 3 to 6, E = 0 to 2 is reasonable.)
The direct RTL implementation is a bunch of 1-bit adders chained together. The carries, in turn, get summed, and so on, until all LG(N) bits of Q are formed.
Whether this finally synthesizes to chained logic (as the above RTL description suggests -- implementing each 1-bit full adder as the traditional XOR + AND), or something more complex and compact (carry look-ahead, array logic, look-up tables?) depends on the required timing constraints and available logic structure. A CPLD would probably use a couple macrocells to do it in array logic, without much wiggle room on timing. An FPGA would use quite a few more LUTs to do much the same thing with varying amounts of chained or parallel activity, depending on timing.
Implementing it in SSI (small scale integration -- the three elementary logic gates and their complements), you'd have to run through the logic tables to see how many minterms and maxterms are needed. I don't know offhand.
You could even implement an even more compact solution with analog: each input connects through a resistor R to the summing junction (virtual ground) of an inverting amplifier. Thus, each input delivers a constant current, the total of which counts the number of inputs, independent of order. A comparator on the output then determines count against a reference. (To implement the debounce circuit I was talking about earlier, a pair of comparators at the respective thresholds, feeding an R-S flip-flop, would complete the logic.)
Tim