FPGA Design Methodology? - Page 1
Forum section: electronics / general

author: iry100fan
author_rank: Newbie
timestamp: April 12, 2018, 01:35:38 am
content: Hi Everyone,I am fairly new to FPGAs and CPLDs. I bought a couple of development boards to play with and have made a few simple projects. Since I have no formal schooling with programmable logic, I am curious on how professionals or talented individuals attack implementing a design.Up to now, I have been envisioning the functions that I want to implement as discrete logic, almost as if I was going to build it with 74XX series logic. While this has worked for me with small projects, it does seem to be like I am designing the project twice. Once on paper using logic and then again in VHDL. Is this bad practice? Is there a better methodology? Or, is this just basically how it gets done?(Hope my question make sense.)I appreciate the feedback.Thanks-Brian

author: james_s
author_rank: Super Contributor
timestamp: April 12, 2018, 02:49:23 am
content: There are different levels of abstraction you can look at the project through. Generally you'll only be designing very simple stuff at the gate level, for more complex things think about it in terms of overall behavior. You might look up behavioral modeling and register transfer level and see if that makes sense. You should also look at any existing code you can find and see how it's done. If you design it on paper first it will generally be a sort of high level block diagram.

author: rstofer
author_rank: Super Contributor
timestamp: April 12, 2018, 02:04:49 pm
content: Gate logic isn't all that interesting. It's not until we can create sequential circuits that we can move along to Finite State Machines (FSMs).These FSMs will be created using D-flops either explicitly or implicitly. If you search the Internet for 'lc3 state machine', you will find a project for a small CPU. No, there won't be any code but there will be a pictorial of the state machine transitions. You can see how each instruction the CPU understands is executed. You can see which registers are affected and you can see what will be gated on the single bus. See Figures C2 and C3.http://users.ece.utexas.edu/~patt/05f.360N/handouts/360n.appC.pdfThere's a lot more information on this project as many colleges and universities use it in their classes. There's also a book "Introduction To Computing Systems From Bits & Gates To C And Beyond" by Patt and Patel.I like to think of FSMs in terms of the kid's game 'Simon Says'. At each state 'Simon' says 'do this' or 'do that' and then 'move to somewhere else'. Rinse and repeat...As to methodology, there needs to be a system block diagram (Figure C3) that shows the overall system and, in most cases, there needs to be one or more state diagrams (Figure C2). We usually start at the top level (the actual inputs and outputs) and work down toward actual hardware descriptions.In the programming world, there is the idea of top-down design and bottom-up coding. That works pretty well for FPGAs as well. As you start dealing with the bottom-up coding, you may need more or less signals from the next level up. And so on... This allows testing of lower level components before they are integrated into a higher level block.

author: iMo
author_rank: Super Contributor
timestamp: April 12, 2018, 06:18:06 pm
content: Most FPGA dev tools allow to use a "schematic capture" input. You draw your schematics with standard gates and 74xxx-like parts (do not do it on the paper, do it with the schematic capture editor on the screen, there are large libraries with parts available). You may create your own modules/parts out of your schematics sheets. The schematics is then converted into verilog/vhdl automatically. The schematic capture is usually used when you want put some existing parts into a cpld/fpga, or, you copy an existing design made of discrete TTL/CMOS components.And yes, it is a normal way to start..After some time you may see the writing the code in verilog/vhdl directly is a much efficient way how to capture your design, however..

author: jmelson
author_rank: Super Contributor
timestamp: April 12, 2018, 08:43:18 pm
content: Quote from: imo on April 12, 2018, 06:18:06 pmYes, been there, DONE THAT! I started out doing very small interface bits of logic, and used either generic FPGA primitives (OR2, DFF, etc.) in schematic, or even their 74xx library components. I worked up to more complex modular functions, and things got seriously messy. I finally learned to code in real VHDL, and got readable VHDL files. If you do schematic entry, it produces structural VHDL instead of behavioral VHDL, and while the structural VHDL is a 1:1 correspondence to the schematic, it is not INTENDED to be human-readable, and sure ISN'T! Also, the libraries can CHANGE on you, and so a schematic-entry page may not provide the same logic in a different version of the tools! YIKES, I DON'T need that!Jon

author: james_s
author_rank: Super Contributor
timestamp: April 12, 2018, 09:38:02 pm
content: The schematic capture was an easy way to make the hardware do something when I was first starting out, but very soon it becomes a complete waste of time. It is very tedious to design circuits that way, it takes forever and it is a nightmare to debug and make changes to or port to other hardware. My advice is don't do it, go directly to writing VHDL or Verilog, it will pay off in the end.

author: nctnico
author_rank: Super Contributor
timestamp: April 12, 2018, 09:50:22 pm
content: This is hard to graps for some but don't think in logic but just use the HDL to describe the problem. Don't infer a memory but use an array. Don't use bit vectors but use numerical types like signed/unsigned for signals which are a number or index (that includes addresses on an address bus!). Suddenly accessing a piece of memory becomes using an index into an array and the number of lines to create a design reduces dramatically. FPGA vendors have guides on how HDL constructs are translated into hardware. Study these manuals. They will save a lot of time because they show how to do things the easy way without needing to get involved into the tedious details.

author: iry100fan
author_rank: Newbie
timestamp: April 14, 2018, 04:13:45 am
content: A big thanks to everyone that chimed in.I started looking up information on Behavioral/RTL coding and combing over other peoples projects. It seems as though I need to start thinking more block-diagram like and less discreet logic and let the "compiler" build the low-level details.I have tried the schematic editor but found it very tedious and annoying. VHDL seems much quicker to me. I think my problem is I have been writing my VHDL code to mimic the discreet logic when it should really describe a higher-level function.I look forward to reading about the LC3 machine. It will probably give me great insight into one of my upcoming projects.Thanks.-Brian

author: NorthGuy
author_rank: Super Contributor
timestamp: April 14, 2018, 04:41:35 am
content: Quote from: iry100fan on April 14, 2018, 04:13:45 amFPGAs do not have discrete logic similar to 74 series gates. The have LUTs which can be used to create different kinds of gates, but are much more powerful. There are other parts which facilitate common things such as adders, multipliers, memories etc. The tools select which parts to use. Unless you know what primitives are available and want to use them in a certain way (for example if you want something which runs very fast), there's no reason to worry about internals. The same thing may be accomplished in a variety of ways - say a shift register may be built from individual flip-flops or the tools may use built-in shift registers. It usually doesn't matter which way you're going to get, and often it is hard to predict. Thus, building your design from basic discrete components is most likely an illusion.

author: iMo
author_rank: Super Contributor
timestamp: April 14, 2018, 08:49:05 am
content: QuoteIt is not.There are libraries with "74xxx-like discrete components" you may build your design from. It works fine. You may build a PDP-11 on an FPGA without knowing verilog/vhdl.."Internally" the CPLDs/FPGAs do not use the "discrete components", but they map the "discrete components" into their internal structures (named LUTs, cells, slices, LEs, PLBs, etc.) such the "final logic" works identically as the "discrete components" would do.People who migrate from an "old school" design techniques (I did in past many designs with 74xxx-like components on Xilinx'es and Actel's) shall easily start with the schematic capture, as first they may this way get familiar with the new design tool-chain pretty fast (messing with the tool-chains per se is for the people from the older schools the largest barrier to overcome, imho). In parallel, with some tangible working results in hand, they may start to learn verilog/vhdl."Quick win" is an important motivation factor for people who start with new technologies and tools..Therefore all CPLD/FPGA vendors do include the schematic capture input into their tool-chains.PS: below a PWM from Xilinx'es schematics capture examples.

author: nctnico
author_rank: Super Contributor
timestamp: April 14, 2018, 10:06:21 am
content: Please don't advice to use schematic capture for CPLD/FPGA design. It doesn't scale at all and the schematic entry tools suck because they are no longer maintained. Down the road it causes major headaches (seen that).

author: hans
author_rank: Super Contributor
timestamp: April 14, 2018, 10:47:28 am
content: Agreed. Click and mouse entry is slow, hard to maintain (refactor), etc.If you have trouble understanding what a certain VHDL statement is really doing, then open up the RTL viewer. You get a generated graphical representation of your design. If it's still unclear (i.e. "the generated RTL is not doing what I expected") you can dive ALOT deeper, but it's not for the faint hearted, as FPGA's are incredibly complex devices (i.e. from RTL there are many steps taken in order to synthesize an efficient design).Graphical representations are a nice way to understand, but not a way to start design entry. In college we started with VHDL day 1. There is no benefit in doing it graphically, unless you're really horrible with the VHDL syntax.And even then, some may argue that VHDL is too low-level, as it is very explicit in type conversions if you want to do any arithmetic computations. Nonetheless, it is way easier to use package ieee.numeric_std (don't bother with the other ones, those areNOTIEEE standards!) to instantiate an adder, than it is to roll your own. Also in FPGA's rolling your own adder will likely be a slower design, as the compiler may not always see you're building full-adders. Modern FPGA logic cells often have dedicated full-adder blocks with fast carry chain connections, rather than encoding it in the LUT, which may lead to a slower design.Sure, writing half adders, combining those blocks to full adders, then making a chain.. that's how we all started to appreciate structural complexity. But offloading some bits , and above all keeping VHDL toolchain independent, is the good thing to aim for.

author: james_s
author_rank: Super Contributor
timestamp: April 14, 2018, 04:57:16 pm
content: Yeah I started out with the schematic capture entry and while it was an easy way to make the hardware do something early on, it very quickly became a complete waste of time. If I were going to do it again, I'd have started out with VHDL in the first place, or switched over within a few days of starting out.

author: rstofer
author_rank: Super Contributor
timestamp: April 14, 2018, 08:20:06 pm
content: Quote from: hans on April 14, 2018, 10:47:28 amWhen you instantiate a vendor library component, like a full adder, one of the things you give up is toolchain independence. Xilinx has a huge library of components, all ready to drop into a design but you may pay a price in terms of time and effort when you go to port to another vendor.

author: nctnico
author_rank: Super Contributor
timestamp: April 14, 2018, 08:38:24 pm
content: Quote from: rstofer on April 14, 2018, 08:20:06 pmBesides that it is also more work (=more code to write) to use the library components.a =b*d+c is much easier to write and the synthesizer will come up with the best solution.Using library components in HDL is a remnant of schematic entry and should be avoided as well.

author: hamster_nz
author_rank: Super Contributor
timestamp: April 15, 2018, 02:06:56 am
content: Quote from: nctnico on April 14, 2018, 08:38:24 pmI think it is better to play at every level for a while, and see what each offers.Schematic entry sucks for describing fine details, but at a top level, where you connect three or four major blocks (e.g. at the Vivado IP level) it sort-of works better than huge HDL modules that just wire components together.CoreGen style IP blocks allow you to get complex things that work correctly with minimal effort - for example, If you want a dual-clock FIFO block I would suggest you use an IP block over inferring your own. This is where Intel/Altera have the edge on Xilinx with their MegaFunctions, which allow you to include common paramaterised IP in your design without the churn required to run IP wizards every time you want to change a single setting.I feel you are silly to use IP blocks for things that are almost primatives (e.g. MMCMs and PLLs) because using the HDL primitives is much less effort once you climb the learning curve of your first design.So back to inferring "a =b*d+c"... the problem I see with jumping straight to this is you don't see the constraints that are being pushed up from the FPGA architecture itself. What options do you have?How big should 'b', 'c' and 'd' be to get the best result? Is it better if b and d are 16, 17 or 18 bits? Does 'b' or 'd' being 'signed' or 'unsigned' make a difference? How many cycles of latency is best for optimal performance? How many cycles of latency is needed for minimal resource usage? How many bits is too big for 'a' or 'c' for efficient implementation?Likewise, for RAM, what sizes are good to use? Should you make 64kB asynchronous memory blocks, or should you have a cycle of latency? is a 10-bit x 1k entry clocked RAM block a good idea? how about a 10-bit x 2k entry RAM block?All of these have an (more or less) absolute answer, but if you stick to just using inference and trust the tools you will just get what you ask for, not what is best. Unless you have awareness/experience/understanding of the low level details you will usually end up with a sub-optimal result - and putting the effort in to implement a design in FPGA isn't about getting a sub-optimal result.However, once you know the limitations of the underlying architecture, you can write HDL that naturally maps onto the FPGA as if by magic. memories fit efficiently into RAM blocks with no waste, math fits into DSP blocks and runs fast, shift registers fits into a LUTs and doesn't eat huge numbers of flip-flops, and so on.If you target multiple FPGAs, you want to put a wrapper around anything that is sensitive to the FPGA architecture, isolating it from the rest of the design and allow you to replace it as needed - but that isn't a beginner's issue.

author: nctnico
author_rank: Super Contributor
timestamp: April 15, 2018, 10:21:56 am
content: Which is why I suggested this:Quote from: nctnico on April 12, 2018, 09:50:22 pm

author: NorthGuy
author_rank: Super Contributor
timestamp: April 16, 2018, 11:52:47 pm
content: Quote from: imo on April 14, 2018, 08:49:05 amExactly. The "discrete components" do not represent a "low level" which is used by HDL to build upon. The "discrete components" is simply a different abstraction which has nothing to do with HDL and is inferior to HDL. A proficiency with "discrete components" is not necessary and is not useful for HDL work.This is not the same situation as you would have with MCU (where studying assembler gives you better understanding on how you can program in C). If you want "low level" in FPGA, don't look at the "discrete components", but rather read vendor's documents which explain the internal composition of the FPGA.

author: asgard20032
author_rank: Regular Contributor
timestamp: April 17, 2018, 05:43:42 am
content: Quote from: NorthGuy on April 16, 2018, 11:52:47 pmExactly. You don't want to think in term of logical gate, but in term of LUT. And there are many other important aspect. Designing in term of discrete component will give inferior design by the fact that it will try to map non optimal design, because it give an extra layer of abstraction, one that is not good for the underlying. Vhdl and verilog also give a level of abstraction, but that abstraction can product the wanted result on the underlying hardware, if you follow the vendor document. On the other side, it is impossible to correctly predict what monstrosity will result from working with discrete component.The only AND only correct way to design on an FPGA is to get a general idea of what you want, understand how the translation/synthesis is done (read vendor documentation), verify the RTL to be sure it generated what you wanted, if so, debug in simulator, if not, verify and rewrite the fault part in your HDL. Also, by viewing the RTL you can also plan optimization.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: April 17, 2018, 06:32:42 am
content: Quote from: asgard20032 on April 17, 2018, 05:43:42 amSorry but that is simply wrong.There is no such thing as a "correct" way to do something, only more or less appropriate for a given set of circumstances.It is absolutely possible to write some HDL, compile it, download it to a part and have something working within a few minutes without looking at any details of what it's doing or doing any simulation.Obviously this is not true for all applications, but entirely appropriate for some.I have designed and shipped a few ( fairly simple) FPGA projects, and never touched a simulator.

author: nctnico
author_rank: Super Contributor
timestamp: April 17, 2018, 09:18:52 am
content: I agree there are several ways to debug an FPGA. In many of my designs I have a debug bus which can output various internal signals (through a settable mux) which I can then trace on a logic analyser. OTOH in designs which take long to route a simulator is very handy to design & test small units before implementing them. That increases the chance it is right the first time enormously.

author: NorthGuy
author_rank: Super Contributor
timestamp: April 17, 2018, 01:45:53 pm
content: I usually simulate small (leaf) modules which are not involved with outside world. I create a separate project with a test-bench to make sure the module is working. I may also do big (exhaustive) automated tests and such.For anything else I use ILA. Actually, once the design is mostly working and you only need to do small changes, there's often no need for debugging. It's just a matter of waiting for the tools to finish implementation.

author: rstofer
author_rank: Super Contributor
timestamp: April 17, 2018, 01:52:41 pm
content: Quote from: mikeselectricstuff on April 17, 2018, 06:32:42 amIt seems to me that there was a time when Xilinx ISE WebPack didn't include the simulator. Either that or I was too inexperienced to figure out how to use it...In any event, I have never used simulation. Not ever! I write the code and carry debug signals to some output pins and watch the show with a logic analyzer. I also arrange for a one-shot clock so I can step through the states of a FSM.Is it productive? Probably not! But for one reason or another, going back to debugging 8085s (late '70s), it is a familiar process and it works for me. Then again, it's just a hobby.I could see the advantage to simulation of individual blocks on a bottom-up methodology. Get the low level stuff running and work up toward the top. Vivado has a nice internal logic analyzer tool which is kind of a blend between simulation and an external logic analyzer. Of course there is also a nice simulator.The tools just keep getting better and better!

author: james_s
author_rank: Super Contributor
timestamp: April 18, 2018, 02:14:28 am
content: For very simple stuff it's not really worth mucking with thesynthesizersimulator. What I generally recommend is have a go with it early on to get a taste, then focus instead on learning HDL well. Then revisit the simulator again when you need it. In large complex designs simulating can save a lot of time but for most hobbyist size projects the savings are questionable in many cases.

author: hamster_nz
author_rank: Super Contributor
timestamp: April 18, 2018, 03:34:26 am
content: Quote from: james_s on April 18, 2018, 02:14:28 amDid you mean 'synthesizer' or 'simulator'?I find that if I need the simulator or not depends on a few things, with no hard/fast rules:- Visibility - how much internal state can you infer from the outputs? If most of it can be inferred from observation, then debug in hardware can work as well as simulation. Sometimes bringing additional debug signals to the outside world helps aid visibility. Simulation allows you to watch everything in your design, not just the bits you have debug probes attached to, which is important if you are not sure how your design isn't working.- Time scale of debugging. With simulation even tracing for a few milliseconds is hard work. Better to reach for a virtual logic analyzer which can probe deep in the design over many seconds and trigger on special conditions.- Timing accuracy - if I need per-cycle accuracy (e.g. for driving ADCs, DACs, sensors and so on) then simulation is a must. Making fencepost errors is so easy in HDL.- Interaction with the outside world. No amount of simulation will help if things on the outside world don't work as you expect them to. Writing an invalid test bench doesn't help.- Complexity of design. Some things would be really really time consuming or impossible to debug in hardware the real world. It either works, or could be broken in a million different ways. In these cases simulation is the only viable debug technique.- Repeatability. If you want to be able to run exactly the same test twice and compare results, then simulation will let you do so. Important for regression testing, to check if you haven't "fixed something real good".- My understanding. If I am familiar with what I am doing simulation is not really that useful. But when working with new features (e.g. maybe resetting of transceivers on startup or PLL reprogramming) I need simulation to show that things are working as I expect they should (usually after trying and failing in H/W first). This is why simulation is so helpful for beginners, even on simple projects.Virtual Logical analyzers (ChipScope and so on) are much like the FPGA equivalent of in-circuit debuggers, but simulation is a level of debug that isn't common in the hobby programming world. The closest thing to simulation in the professional S/W world are unit tests.

author: james_s
author_rank: Super Contributor
timestamp: April 18, 2018, 05:57:55 am
content: Oops, yes, stupid brain. I definitely meant simulator, it would be pretty hard to get much done with an FPGA without using the synthesizer.

author: Berni
author_rank: Super Contributor
timestamp: April 18, 2018, 06:54:43 am
content: My decision between simulating or running on real hardware also depends on the design.Simple designs that don't involve really wide buses can be easily debugged in hardware by preparing 16 spare IO pins and connecting them to a logic analyzer or use the built in logic analyzer inside the FPGA. Both Altera and Xilinix provide a nice one that you just tell what signals you want and it stuffs the entire softcore logic analyzer into the FPGA behind your back.But if you are developing something more complex like maybe a memory mapped CAN bus controller or your own softcore CPU or something then simulation is well worth it. The extra time taken to set it up and write a testbench can save you a TON of time later in the form of much faster compile times and ability to look at any signal you want. It also depends how easy it is to make a test bench.For example if you are making that CAN bus controller you might need the testbench to emulate another CAN device on the bus that your controller can talk to. That's obviously a lot of work, but you can do a trick and simply instantiate two or more of your CAN controllers that you are developing and connect them to the same bus to have them talk to each other.Most HDL simulation tools also don't have protocol decoding in the waveform viewer. But what you can do is implement a simple protocol decode inside the testbench and have it output the decoded data as a bus that you then add to your waveform view, or alternatively you can print the data to the console. This part can then be reused to have the testbench run an automated test to check if correct data came trough and say PASS if it did.