{"id":3682,"date":"2026-07-15T11:34:44","date_gmt":"2026-07-15T03:34:44","guid":{"rendered":"http:\/\/manufacturing.wiki\/?p=3682"},"modified":"2026-07-15T11:34:45","modified_gmt":"2026-07-15T03:34:45","slug":"standard-for-formatting-of-field-programmable-gate-array-codes","status":"publish","type":"post","link":"http:\/\/manufacturing.wiki\/index.php\/2026\/07\/15\/standard-for-formatting-of-field-programmable-gate-array-codes\/","title":{"rendered":"Standard for Formatting of Field-Programmable Gate Array Codes"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\">FPGA Code Formatting Standards: Write RTL That Other Engineers Can Actually Read<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Bad formatting does not cause synthesis errors. It does not break timing. It does not generate wrong bitstreams. So why does it matter so much? Because unreadable code creates bugs. Not logic bugs. Human bugs. The kind where someone misreads a signal name, connects the wrong port, or copies a block of code without noticing it does the opposite of what they think it does.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Formatting is not about aesthetics. It is about reducing cognitive load. Every engineer on your team should be able to read any file in the project within thirty seconds and understand what is happening. That only works if every file follows the same rules.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This guide covers the formatting standards that actually scale across large FPGA projects. These are not opinions pulled from thin air. They are patterns forged in real verification environments where sloppy formatting cost real money.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why Consistent Formatting Saves Money<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Think about the last time you opened someone else&#8217;s RTL file. The indentation was random. Some lines had four spaces, others had tabs, others had nothing. Signal names were camelCase in one module and snake_case in the next. Port lists wrapped at different column widths on every single file.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You spent ten minutes just figuring out where one block ended and another began. That is ten minutes of engineering time wasted on formatting instead of design. Multiply that by every file, every review, every debug session, and the number gets ugly fast.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Consistent formatting eliminates that friction. When every file looks the same, your eyes go straight to the logic. You stop thinking about structure and start thinking about function. That is the entire point.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Naming Conventions That Actually Work<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Naming is the first layer of formatting. If your names are inconsistent, no amount of indentation will save you.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Signal and Port Names<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Use snake_case for everything. Always. No exceptions.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>verilog1module uart_tx (\n2    input  wire        clk,\n3    input  wire        rst_n,\n4    input  wire &#91;7:0]  data_in,\n5    input  wire        data_valid,\n6    output reg         tx_out,\n7    output reg         tx_busy\n8);\n9<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Never mix styles in the same file.&nbsp;<code>dataValid<\/code>&nbsp;next to&nbsp;<code>tx_busy<\/code>&nbsp;is a red flag. It tells the reader that two different people wrote this code, or one person wrote it at two in the morning.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Clock and reset signals get short names.&nbsp;<code>clk<\/code>,&nbsp;<code>rst_n<\/code>,&nbsp;<code>clk_en<\/code>. Do not call them&nbsp;<code>system_clock_input<\/code>&nbsp;or&nbsp;<code>active_low_global_reset<\/code>. Everyone knows what&nbsp;<code>clk<\/code>&nbsp;and&nbsp;<code>rst_n<\/code>&nbsp;mean. Long names add noise.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Active-low signals should end with&nbsp;<code>_n<\/code>&nbsp;or&nbsp;<code>_b<\/code>. Not both. Pick one and stick with it across the entire project.&nbsp;<code>rst_n<\/code>&nbsp;or&nbsp;<code>rst_b<\/code>. Mixing them in the same file is confusing.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Module and Entity Names<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Module names use PascalCase.&nbsp;<code>UartTx<\/code>,&nbsp;<code>FifoSync<\/code>,&nbsp;<code>ClockDivider<\/code>. This makes them stand out from signals and ports immediately.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>verilog1module ClockDivider #(\n2    parameter DIV_RATIO = 10\n3) (\n4    input  wire clk,\n5    input  wire rst_n,\n6    output reg  clk_out\n7);\n8<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The parameter name&nbsp;<code>DIV_RATIO<\/code>&nbsp;uses snake_case because it is a parameter, not a module. Keep the convention consistent. Modules get PascalCase. Everything else gets snake_case.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Macro and Define Names<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Use ALL_CAPS with underscores. This is not optional. It is the universal convention in every HDL project ever written.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>verilog1`define DATA_WIDTH 16\n2`define ADDR_WIDTH 8\n3`define FIFO_DEPTH 256\n4<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">When you see&nbsp;<code>DATA_WIDTH<\/code>&nbsp;in the middle of a file, you know instantly that it is a constant, not a signal. That visual distinction saves your brain from having to scroll up and check the definition every time.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Indentation and Line Structure<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This is where most FPGA code goes wrong. The nesting in HDL is deep. Always blocks inside generate blocks inside module bodies. If your indentation is off by even one level, the entire structure becomes unreadable.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The Two-Space Rule<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Indent with two spaces. Not four. Not tabs. Two spaces.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Tabs cause problems because different editors display them with different widths. What looks aligned in your editor looks like a mess in mine. Two spaces look the same everywhere.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>verilog1<strong>always @<\/strong>(posedge clk) begin\n2  if (rst_n) begin\n3    counter &lt;= 0;\n4  end else begin\n5    if (enable) begin\n6      counter &lt;= counter + 1;\n7    end\n8  end\n9end\n10<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Every&nbsp;<code>begin<\/code>&nbsp;adds two spaces. Every&nbsp;<code>end<\/code>&nbsp;removes two spaces. The alignment is obvious. You can count the nesting depth by counting the indentation level. No guesswork.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">One Statement Per Line<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Never put two statements on the same line unless they are trivially short and obviously related.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Bad.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>verilog1assign sum = a + b; assign carry = (a &amp; b) | (a &amp; cin) | (b &amp; cin);\n2<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Good.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>verilog1assign sum   = a + b;\n2assign carry = (a &amp; b) | (a &amp; cin) | (b &amp; cin);\n3<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The good version lets you scan each assignment independently. The bad version forces you to parse two complete expressions on one line. Your eyes skip over it. You miss the typo. You introduce a bug.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Align Assignments in Declarations<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">When you declare multiple signals, align the bit widths and names.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>verilog1reg        &#91;7:0]  data_in;\n2reg        &#91;7:0]  data_out;\n3reg        &#91;15:0] counter;\n4reg               enable;\n5wire              full;\n6wire              empty;\n7<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The bit widths line up. The names line up. You can see at a glance which signals are wide and which are single-bit. This is especially useful in port lists.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>verilog1module fifo_sync #(\n2    parameter DATA_WIDTH = 8,\n3    parameter ADDR_WIDTH = 4\n4) (\n5    input  wire                    clk,\n6    input  wire                    rst_n,\n7    input  wire &#91;DATA_WIDTH-1:0]   data_in,\n8    input  wire                    wr_en,\n9    input  wire                    rd_en,\n10    output wire &#91;DATA_WIDTH-1:0]   data_out,\n11    output wire                    full,\n12    output wire                    empty\n13);\n14<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Every port is on its own line. Every type is aligned. When you add a new port, you add one line. When you remove a port, you delete one line. No cascading edits. No merge conflicts.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Commenting Without Cluttering<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Comments are good. Too many comments are worse than no comments. The rule is simple. Comment the why, not the what.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Block Comments for Intent<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Put a block comment above every always block that explains what the block does, not how it does it.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>verilog1\/\/ Free-running counter that wraps at DIV_RATIO\n2<strong>always @<\/strong>(posedge clk or negedge rst_n) begin\n3  if (!rst_n)\n4    counter &lt;= 0;\n5  else if (counter == DIV_RATIO - 1)\n6    counter &lt;= 0;\n7  else\n8    counter &lt;= counter + 1;\n9end\n10<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The comment tells you the intent. The code tells you the implementation. Together they are complete. Separately they are both useless.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Inline Comments for Non-Obvious Logic<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Use inline comments only when the code does something that is not immediately clear.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>verilog1\/\/ Gray code conversion prevents multi-bit metastability\n2assign gray_out = binary_in ^ (binary_in &gt;&gt; 1);\n3<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That comment is necessary. Without it, the next engineer might &#8220;simplify&#8221; this line and break the CDC logic.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Do not write comments like this.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>verilog1counter &lt;= counter + 1; \/\/ Increment counter by one\n2<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That is noise. The code says exactly what it does. The comment adds nothing. Delete it.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">TODO and FIXME Tags<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Use&nbsp;<code>\/\/ TODO:<\/code>&nbsp;and&nbsp;<code>\/\/ FIXME:<\/code>&nbsp;for things that need attention. These are searchable. When you run a grep for&nbsp;<code>TODO:<\/code>&nbsp;across the project, you get a clean list of everything that is incomplete.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>verilog1\/\/ TODO: Add overflow protection when DIV_RATIO &gt; 256\n2\/\/ FIXME: This assumes clk is 50 MHz. Parameterize it.\n3<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Make these visible in your editor. Most editors let you configure a TODO highlight pattern. Turn it on. It turns your comments into an actionable task list.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Vertical Spacing and Grouping<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">White space is free. Use it.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Separate Logical Blocks With Blank Lines<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Do not cram everything together. A blank line between logical sections tells the reader &#8220;this is a new thought.&#8221;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>verilog1\/\/ Reset logic\n2<strong>always @<\/strong>(posedge clk or negedge rst_n) begin\n3  if (!rst_n) begin\n4    state &lt;= IDLE;\n5    count &lt;= 0;\n6  end\n7end\n8\n9\/\/ State machine\n10<strong>always @<\/strong>(posedge clk) begin\n11  case (state)\n12    IDLE:  if (start) state &lt;= RUNNING;\n13    RUNNING: if (done) state &lt;= IDLE;\n14  endcase\n15end\n16\n17\/\/ Counter\n18<strong>always @<\/strong>(posedge clk) begin\n19  if (state == RUNNING)\n20    count &lt;= count + 1;\n21end\n22<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Three always blocks. Three logical functions. Blank lines between them. You can see the structure without reading a single line of code.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Group Related Parameters<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">If you have multiple parameters that serve the same purpose, group them together at the top of the module.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>verilog1module spi_master #(\n2    \/\/ Bus configuration\n3    parameter CLK_DIV   = 4,\n4    parameter CPOL      = 0,\n5    parameter CPHA      = 0,\n6    \/\/ Data configuration\n7    parameter DATA_WIDTH = 8,\n8    parameter FIFO_DEPTH = 16\n9) (\n10<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The comments separate the groups. The parameters within each group are sorted alphabetically. This makes it easy to find what you are looking for and easy to add new parameters in the right place.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">File-Level Structure<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Every RTL file should follow the same top-to-bottom structure. When an engineer opens any file, they should know exactly where to find each section.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The Standard File Order<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Copyright and license header at the top. Even if your project is internal, include a one-line header that says who owns the code and when it was created.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then the module declaration with parameters.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then the port list.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then internal signals and registers.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then instantiations.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then always blocks and assign statements.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then the endmodule at the bottom.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>verilog1\/\/=============================================================================\n2\/\/ File: uart_tx.v\n3\/\/ Description: UART transmitter with configurable baud rate\n4\/\/ Author: jdoe\n5\/\/ Created: 2024-03-15\n6\/\/=============================================================================\n7\n8module uart_tx #(\n9    parameter CLK_FREQ  = 50_000_000,\n10    parameter BAUD_RATE = 115200\n11) (\n12    input  wire       clk,\n13    input  wire       rst_n,\n14    input  wire &#91;7:0] data_in,\n15    input  wire       data_valid,\n16    output reg        tx_out,\n17    output reg        tx_busy\n18);\n19\n20    \/\/ Internal signals\n21    reg &#91;15:0] baud_counter;\n22    reg &#91;3:0]  bit_index;\n23    reg &#91;7:0]  tx_shift_reg;\n24\n25    \/\/ Baud rate generator\n26    <strong>always @<\/strong>(posedge clk or negedge rst_n) begin\n27        if (!rst_n)\n28            baud_counter &lt;= 0;\n29        else if (baud_counter == CLK_FREQ \/ BAUD_RATE - 1)\n30            baud_counter &lt;= 0;\n31        else\n32            baud_counter &lt;= baud_counter + 1;\n33    end\n34\n35    \/\/ Transmission logic\n36    <strong>always @<\/strong>(posedge clk or negedge rst_n) begin\n37        if (!rst_n) begin\n38            tx_out       &lt;= 1;\n39            tx_busy      &lt;= 0;\n40            bit_index    &lt;= 0;\n41            tx_shift_reg &lt;= 0;\n42        end else begin\n43            \/\/ ... transmission code ...\n44        end\n45    end\n46\n47endmodule\n48<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Every file looks like this. Every engineer knows where to look. No surprises. No hunting.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Common Formatting Mistakes That Create Real Bugs<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Trailing whitespace. It looks harmless. It causes diff noise. It confuses version control. Most editors can strip it on save. Turn that feature on.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Inconsistent use of parentheses.&nbsp;<code>if (a &amp; b)<\/code>&nbsp;versus&nbsp;<code>if a &amp; b<\/code>. Pick one. The parentheses make precedence explicit and prevent subtle bugs when someone adds a new condition later.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Mixing blocking and non-blocking assignments in the same always block. This is not a formatting issue strictly speaking, but it is a structural one. One always block should use one type of assignment. If you see&nbsp;<code>&lt;=<\/code>&nbsp;and&nbsp;<code>=<\/code>&nbsp;in the same block, something is wrong.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Long lines that wrap silently. If a line exceeds 120 characters, break it. Do not let the editor wrap it visually. A wrapped line hides the actual structure. Break the line at a logical boundary. Align the continuation with the opening parenthesis or assignment operator.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>verilog1assign next_state = (current_state == IDLE &amp;&amp; start_signal) ?\n2                    RUNNING :\n3                    (current_state == RUNNING &amp;&amp; done_signal) ?\n4                    IDLE :\n5                    current_state;\n6<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The ternary operator chain is broken at each&nbsp;<code>?<\/code>&nbsp;and&nbsp;<code>:<\/code>. The alignment shows the logic flow. You can read it top to bottom without scrolling horizontally.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Enforcing Standards Without Starting a War<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Nobody likes being told their formatting is wrong. The trick is to automate enforcement so no human has to be the bad guy.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Use a linter that runs on every save. Most editors support this. The linter flags violations automatically. The engineer fixes them before commit. No code review comments about indentation. No arguments about tabs versus spaces. The tool decides. The tool is always right.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Set up a pre-commit hook that runs the linter and refuses to commit if there are violations. This catches formatting drift before it reaches the repository. Once it is in version control, it is ten times harder to fix.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Share the configuration file. The&nbsp;<code>.editorconfig<\/code>&nbsp;or the linter config goes in the repo root. Every engineer gets the same rules automatically. No one has to remember anything. The environment enforces the standard.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Formatting is not about making code pretty. It is about making code predictable. When every file follows the same rules, your team spends less time reading and more time designing. That is the real return on investment.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">ChipApex is a global distributor of electronic components: ICs, semiconductors, passives &amp; interconnects. Source active &amp; obsolete parts with wholesale pricing, fast RFQ response, and worldwide delivery.Official website address:chipapex.com<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>FPGA Code Formatting Standards: Write RTL That Other En &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-3682","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"http:\/\/manufacturing.wiki\/index.php\/wp-json\/wp\/v2\/posts\/3682","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/manufacturing.wiki\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/manufacturing.wiki\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/manufacturing.wiki\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/manufacturing.wiki\/index.php\/wp-json\/wp\/v2\/comments?post=3682"}],"version-history":[{"count":1,"href":"http:\/\/manufacturing.wiki\/index.php\/wp-json\/wp\/v2\/posts\/3682\/revisions"}],"predecessor-version":[{"id":3683,"href":"http:\/\/manufacturing.wiki\/index.php\/wp-json\/wp\/v2\/posts\/3682\/revisions\/3683"}],"wp:attachment":[{"href":"http:\/\/manufacturing.wiki\/index.php\/wp-json\/wp\/v2\/media?parent=3682"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/manufacturing.wiki\/index.php\/wp-json\/wp\/v2\/categories?post=3682"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/manufacturing.wiki\/index.php\/wp-json\/wp\/v2\/tags?post=3682"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}