Forum Discussion
By higher-level, Brad is talking about Verilog or VHDL, where you would describe the functionality of the design in a specific syntax, somewhat like C for SW code. You said you chose schematic over HDL... Instead of creating a schematic that includes all the components, FPGA designers typically use these Hardware Description Languages to describe the functionality. So your function would contain things like a input signal A, input signal B, and a signal that = a XOR B. Then you have an if statment, saying something like "if xcounter is 0 or 1 or 2 then result =A", and so on. The software will create the look-up tables to implement the function you described. You'd also have an input clock and an output for the registered result. Then you define that at the rising edge of a clock event, result = reg_result, and the software will take care of creating the register for that function. Then output_pin = reg_result. Obviously I'm not giving you the syntax, but I think it wouldn't be too many lines of HDL code...
The idea is that the synthesis tool, Quartus II in this case, can determine how to map the code into the target device. And you don't have to worry about exactly how many LEs/LUTs/registers etc are required or how many levels of logic. Also you can change device easily. For example, you were creating 4-input LUTs. But the Stratix II and III devices, for high-performance and much larger designs, use 6-input LUTs. So your 4-LUT would not be the most efficient for those devices. By creating general code that is not architecture dependent, it makes your design much more portable. There are things you can do to make your design architecture-friendly, and it's great that you are thinking about the target device when you create your design, but the tools don't expect people to go down to your level of detail. I can understand wanting to have total control over it, it's kind of a natural instinct for us techie types. It works OK for a small design but if you had a huge logic function implementing say, an embedded microprocessor with a memory controller and some DSP processing and who knows what else, it would be far too difficult to implement at the very low architecture level. When you describe the functionality instead of instantiating the components, you can then focus on a higher level to ensure that the register-to-register paths occur in a delay that allows your clock to run at the right frequency. That's what the timing assignments do. You will have to "trust" the tool to a certain extent to create the right logic from your code. But the tools are pretty good these days! Sure, from time to time you may encounter something that you think you could have done better by hand, as Brad suggested. The tools do provide ways to optimize designs, and make low-level changes to the netlist, but that's getting pretty advanced for your first FPGA design. For some examples of VHDL and Verilog code that describe functions like memory, multipliers, multiplexers, and state machines, see the Recommended HDL Coding Styles at http://www.altera.com/literature/hb/qts/qts_qii51007.pdf. If you're going to give it a try, a basic Verilog text book would probably be a good start. There are some Templates in the Quartus II text editor if you right-click within a text file in the GUI. Now, all that being said, since you have already done the work to split this design into look-up-table functions, there are some Altera primitives provided to help you specify LUT inputs within HDL code. I'm not sure if they will do everything that you want to do, but maybe you can take a look at the docs to see. Designing With Low-Level Primitives User Guide at http://www.altera.com/literature/ug/ug_low_level.pdf. There is some info about instantiating registers (which is not too hard, and you should have found DFF primitives in the schematic libraries already). Then check out the Look-Up Table Buffer Primitives on page 13 for specifying LUT functions. The idea is that you could use HDL to connect up the LUT buffers and registers that you need, if you want to create a very specific function at a low level. Not sure if that helps... Hope it at least makes you feel less like you're in the twilight zone!