Re: 8-bit Serial Adder Verilog Code Formatterl

0 views
Skip to first unread message
Message has been deleted

Velasco Thibault

unread,
Jul 15, 2024, 4:14:39 AM7/15/24
to trusverlaseas

I'm a software engineer. As a programmer, I have an understanding of what my compiler does for me because I've manually written a close textual representation of what it outputs (e.g. assembly). For precise details of what's output I can look at the ELF/COFF/MachO specifications (e.g. the file type that it translates my code into, results may vary by language). To figure out what the encodings of instructions are I can look at look my processor's instruction manual. That gives me enough information to understand the kind of data the compiler is outputting. It also gives me the vocabulary to ask questions like "How do I inspect details of an ELF file" and that question is relatively well-formed. I could also ask "How do I look at the assembly generated by my compiler" and that question would be well-formed. Eventually the bytes specified by the ELF file get put into memory, and the processor runs each instruction in order and I understand the semantics of each instruction.

8-bit Serial Adder Verilog Code Formatterl


Download File https://mciun.com/2yLWT4



The equivalent steps/questions are entirely unclear to me for an FPGA. I don't know what Verilog or VHDL get translated to. I don't know what the underlying primitives the FPGA operates with are. I don't know how to ask questions like the two well-formed questions above because I just lack the words to ask. It might be the case that equivalent questions make no sense in this context but I have no way to know that at this moment. All I know is that I can write some Verilog and then it winds up being run on a simulator or on an FPGA.

I write some Verilog which is then synthesized to...something? What is that something? Is it a file that I can inspect? Is there a standard format used that I can look up? For instance if I wanted to write a simulator myself, what format would my simulator consume?

After that, the synthesized output is programmed onto an FPGA. What primitives does that FPGA use? If this was an embedded device then generally bytes would be written raw to flash or some kind of storage. Is there an equivalent for FPGAs? Maybe a more abstract and more answerable question would be "what bytes go over the write when an FPGA is being programmed?"

Just like a procedural programming language goes through several steps (compile, assemble, link) to produce an executable, HDLs must pass through several processes before a usable configuration file for the FPGA is generated. These include

Place and route --- select which of the actual resources on the device will be used for each of the required elements in the mapper output, and choose which routing resources will be used to interconnect them.

So if, when you ask what is the output of synthesis, you mean what's the output of the first step of this process, then it's an intermediate file used as input to the mapper. If you mean what is the output of the whole process, it's a bitfile that the FPGA can use to configure all of its logic and routing resources.

Register Transfer Logic (RTL) is the result of the first translation phase, before it is mapped to the vendor-specific resources, which are not portable between vendors or even between different FPGA from the same vendor. Essentially RTL shows both the combinational logic and the synchronous registers (D flip flops), so state machines are recognizable. RTL is pretty consistent between Altera and Xilinx, and is probably the most interesting and useful phase to inspect. Synthesis problems first become visible at the RTL phase, and the design is still recognizable. Once it goes to vendor-specific mapping it gets chopped up and scrambled. Trying to decode a chip-specific bitstream is high-cost, low-benefit, and will be useless when you move to a different vendor or even a different size FPGA in the same family. You can see what you need to see at the RTL level.

It's always good practice to test your newly developed Verilog or VHDL code by instantiating it inside a test bench or a simple toplevel module, and inspecting the RTL code. Xilinx ISE is very nice for inspecting RTL as a schematic (though it sometimes misses things.) The most common issues are:

I too came from embedded systems programming first and verilog second, and the biggest hazard for people like us when learning HDL coding is that it looks like a procedural programming language, and it feels like a procedural programming language (during simulation), but then everything blows up when you try to synthesize working code. You really have to think about what the hardware has to look like, and make sure the RTL code includes all the hardware you expect.

Other than the fact that Verilog/VHDL involve typing some source code into a computer file, there's not really much resemblance to traditional C/C++/etc. Very little of your programming experience will transfer. Focus on dividing big problems into little problems, documenting everything in great detail, and writing test benches. Also invest in a good digital sampling oscilloscope if you don't already have one. Take a look at some of the example code published on opencores.org, as with C/C++ you can learn a lot of technique (both good and bad) from reading other people's code.

One thing that drives me nuts about FPGA development is that source control is not something that the toolchain vendors seem to think is an important feature. Xilinx Vivado is particularly bad in this regard, their advice seems to be to re-generate the project files from scratch when doing a new checkout. Trying to do a project handoff with 100Mb+ zip files is daunting.

The other thing that drives me nuts about FPGA development is that Quartus/ISE/Vivado tools don't really have a satisfying way to quell the flood of warning messages. When I write C/C++ programs, I expect to be able to address every warning message individually and either fix it or sanction it, so that I can eventually get a clean compile with zero warnings. Never really seen anyone achieve that in FPGA development; other FPGA developers (who are smarter than me) seem to just accept that a normal project has lots of diagnostic messages, which they often simply ignore, leaving it down to doing labwork and verifying on real hardware.

If you ever develop your own FPGA board (which I don't recommend), be sure to bring out any unused I/O pins to a header somewhere -- as many as you can manage -- because that's going to be your lifeline when you have to debug the FPGA code, or implement some eleventh-hour patch.

You mentioned programming in assembly language as a way to exercise precise control over what the computer is doing, and it is possible to exercise similarly precise control over FPGA code by using non-portable, vendor-specific primitives. This will be different for each vendor and each FPGA, just as assembly language is different for different CPUs. For Xilinx you would write a constraints file (different for ISE toolchain or Vivado toolchain). The constraints file would call out specific instances or specific nets, and specify timing requirements. Typically the low-level CLBs/LUTs/whateverUnits are arranged in a grid, so you can pin down a specific low-level primitive to live at a specific X,Y grid location. Look up the old Xilinx "FPGA Editor" for the Spartan 3 series, they used to encourage people to use it that way. I think the newer series 7 and Zynq chips it's not supported. Like assembly, it's very specific to the technology, and is thus kind of a volatile skill set.

Similar to assembly, for anything other than a trivial 'homework' exercise, you really want to minimize how much assembly you write; use C/C++ for 98%-99% and only write assembly for the 1% that is performance-sensitive. If for example you have an FPGA design that requires some sub-process to run at 200MHz, it's worth diving into the low-level mapping to see what the tools are doing. Best payoff for optimization is if you can eliminate unnecessary work stages. Only after you're pared the hot elements down to the bare minimum, only then is it worthwhile to start manually routing which IOBs belong at which grid locations. Let the machine do the bulk of the work, so you can focus your efforts.

Most FPGAs do not have on-board non-volatile configuration memory. Instead, the configuration bitstream is stored on an external configuration FLASH ROM and on power-up the FPGA loads that bitstream from external non-volatile memory into its internal configuration SRAM which is directly connected to and controls the CLBs.

It is a file such as a *.bit. There is no standard format. I am not sure why you would want to write a simulator yourself when FPGA development tools come with a simulator. Much effort is put into this and they know their devices better than anyone else because unlike software, each primitive that is specified in the bitstream must be physically located somewhere on the FPGA die and the floor plan can make or break some designs.

This is less answerable generally, because it is 100% manufacturer-specific and device-specific. Some manufacturers publish datasheets for this; other manufacturers consider this a "trade secret" and you would need to sign an NDA to find out.

With a C (or any other language) compiler anyway, the raw bytes are not the most basic part. The most basic part is the series of processor instructions which implement your program, and the raw bytes are simply how you tell the processor what those instructions are. These instructions cause the processor to carry out operations using its various hardware facilities such as adders, multipliers and the like, and store or retrieve data in registers and memories.

This is very similar in an FPGA, except that you're starting at a lower level. Instead of having a list of instructions to run, what you have is a list of how every gate in the FPGA should be interconnected. Most FPGAs also contain specialised sections for RAM and other features, and your program will also include how these are hooked up.

What you end up with then is a netlist, the same as if you were designing a PCB with a million logic chips. This is conceptually the most basic output from your FPGA compiler to tell you what it's doing, in the same way as an assembler listing is conceptually the most basic output from your C compiler to tell you what the processor is doing.

7fc3f7cf58
Reply all
Reply to author
Forward
0 new messages