Verilog basic coding/naming conventions

Status
Not open for further replies.

pigtwo

Member level 4
Joined
Jul 16, 2015
Messages
70
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
2,771
Hello all,

I have a pretty quick question about basic Verilog naming and coding conventions. My goal is to try to make my code look professional so I'd like to make sure I'm not doing stuff that makes me look like I don't know what I'm doing.

The first question I have is about naming conventions is regards to types of registers/wires(or even parameters and other stuff). Currently I use this convention that I made up right when I first started but I don't know if it makes sense. I use all caps and underscores for the inputs/outputs of a module. I capitalize the first letter of each word in states. And finally I use no caps and underscores of registers and wires. I have an example lower down. What do you guys use? Is there a convention that is widely used professionally?

Next, when naming signals that have similar functions but are going to different places how do you name these? This is probably more easily described through example. Say you have a PROM and a SRAM both with data inputs. How would you name these data in signals? Would you do PROM_DATAIN, SRAM_DATAIN or DATAIN_PROM, DATAIN_SRAM ? Generically {function}_{destination} or {destination}_{function}?

Here's example of a RS232 TX module I recently wrote which shows how I currently do it. Any general criticism is also welcome.

Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
`timescale 1ns / 1ps
 
module RS232_SENDER(
 
    // Basic signals
    input wire CLOCK_50,
    input wire RESET,
    
    // Data and control signals
    input wire[7:0] DATA_IN,
    input wire EXECUTE,
    output reg READY,
    
    // RS232 signals
    output reg RS232_TX
    
    );
    
    
    // Internal registers
    reg start_counter;
    reg[7:0] counter;
    reg[9:0] data_send;
    
    // Define sequential logic
    always @(posedge CLOCK_50)  begin
        if(!RESET) begin
            RS232_TX <= 1;
            READY <= 0;
            data_send <= 8'b11111111;
            counter <= 0;
            start_counter <= 0;
            
        end else begin
        
            if(!READY && !start_counter)  // This should handle the start up/reset condition
                READY <= 1;
 
            if(READY && EXECUTE)    begin  // Detect execute signal(only when ready is high)
                READY <= 0;
                start_counter <= 1;
                data_send <= {1'b1, DATA_IN, 1'b0};  // Read data and include start and stop bits
            end else if(counter == 156) begin // All data sent, go back to ready
                READY <= 1;
                start_counter <= 0;
            end
            
            if(start_counter)
                counter <= counter + 1;  // Count when ready not high
            else
                counter <= 0;
            
            // Write out data at approrate times
            if( counter == 1 || counter == 24 || counter == 40 || counter == 56 || counter == 72 || counter == 88 || counter == 104 || counter == 120 || counter == 136 || counter == 155) begin
                RS232_TX <= data_send[0];
                data_send <= {1'b0, data_send[9:1]};
            end else if(counter == 0)
                RS232_TX <= 1'b1;
            else
                RS232_TX <= RS232_TX;
        end
        
    end
    
endmodule



Thank you!
 

Similar to all style conventions, everyone has their own preference. IMO, the most useful rule is to try to maintain whatever style a file already uses if the file already exists.

UPPER_CASE is normally used for `define and parameters. Some people also use them for ports. Some people use them for ports that are IO for the fpga. I generally associate UPPER_CASE ports to be something generated by code generators.
lower_case seems to be the preferred name for basically everything else.
UpperCamelCase can be used, but is less common. I've seen this used for port names in the past.
lowerCamelCase is also a thing, but I've never really seen it used in vhdl/verilog. Other than for kConstantName.

port ordering is mostly reset/clock followed by input interfaces followed by output interfaces. The goal is to give a top-to-bottom reading order. I have also seen this reversed -- it places reset last which avoids the annoying comma issues. Reversing also places the most important ports first -- the outputs of a module are why the module exists.

everyone also has an opinion on tabs vs spaces and tab width. I default to 2, but have seen 3, 4, and 8 used. I've given up on tabs although I find the concept to be useful.

directions in ports can be done with i_prefix, suffix_i, in_prefix, suffix_in, CamelSuffixIn, InCamelPrefix, iCamelPrefix, or omitted. The name should indicate the direction as seen by the module. Basically, always name ports as if the current module is the top level module in a design. In some case the SPI-style MOSI/MISO format is useful. This specifies the connection of the port in cases where the name might be confusing. Clock/reset generally don't have direction in the name unless the module generates the clock/reset.

In some cases, pipeline delay registers will be given names like pipe_ddd, pipe_d3, pipe_3d, pipe_rrr, etc... d3 vs the others is the only one that might have an issue. In the past, some tools would use a number suffix to indicate a bus. This might not be true of modern tools, but does explain why pipe_3d might be used. My preference is to use _r for sample-delays and _d for cycle-delays, but this is not that commonly done.

I've also seen names of clock, clk, ck, and c. Reset, clear, rst, clr, aclr, rstn, etc... In general, giving a clock a rate specifier is less desirable than a function specifier. This is because a module might get used with different clocks. That said, the practice is fairly common. clk_156m25 might be a 156.25MHz clock for example. There is also an issues when multiple similar rates are used -- eg 125MHz from a crystal and 125MHz from a networked device.

I find it weird to have the vhdl-ish "end else begin" mixed with single line if/else. Likewise, some devs like myself avoid the "goto fail" style if/else blocks. There are also devs that will place end on a different line, or place end/else/begin on their own line. It is weird to start a line with "end", but that is the choice Verilog made.

You also have "input wire" but didn't specify `default_nettype none. That is another anti-feature in Verilog that should be disabled.

Some devs will columnize the port names. This allows editors that have b-editing to instantiate the module a little easier. Other devs don't like this as it adds additional edits any time the port map is updated.

Some devs will also include a line for RS232_TX <= RS232_TX, while others will omit this line as it is the default if RS232_TX hasn't been previously assigned.

Most devs will use the if (reset) else nomal-code. There is also a style that places the reset block at the end of the always block. This is more common in FPGA design where data busses often don't get a reset.

Some coding standards have a line limit. Likewise some code standards would prefer giving 1, 24, 40, 56, 72, 88, 104, 120, 136, and 155 names/calculations.

For your example, it looks fairly standard other than the port names being in upper case. That is usually reserved for defines or constants.


Overall, there are few style choices that are agree on.
 
Thank you very much, this is exactly what I needed!

You also have "input wire" but didn't specify `default_nettype none. That is another anti-feature in Verilog that should be disabled.
Thank you for mentioning this. I had to look this up. I didn't even know Verilog had default net types.

I haven't really decided how I want to do the 'end else begin'. I used to put them on separate lines but I saw a lot of code that put them together but I found this harder to read. So I've been trying it out lately to see if I learn to like it more.

I'm glad to hear my code is mostly normal. I don't work in an environment where I get to see professional Verilog so I get worried that I'm living in my own little world building bad habits. I'm definitely going to move to only constants being UPPER_CASE and using lower_case for everything else. I think my method was a little too complicated and not very consistent.

Thanks again!
 

Verilog has a lot of dangerous features. This is one reason I prefer VHDL. default nettype probably comes from the era of structural modeling and especially copying schematics into structural code. In modern times I don't think anyone intentionally uses this feature. However, it is dangerous because a typo can result in an unconnected wire that defaults to 0 in synthesis.

I prefer "end else begin" as it is fairly similar to VHDL and mostly removes the desire to have single statements in if/else -- the "goto fail" style as I've been calling it.

I think most coding styles also have a space after "if". spaces between operators is another topic that is inconsistent.


For the PROM/SRAM, there will normally be multiple data and control ports. I would give them a common prefix. This is because text editors support block editing and having an equal-length prefix makes this easier. If my module is driving these signals, I would append R/W to the port name. Eg "PromWDataOut" and "PromRdataIn". I'm not consistent with this though -- I'll use DataOut/ValidOut for ports that my module drives. I think the prom/sram case is a little different as I think of these as external components where the port names might be physical pin names.
 

Ah ok, that make sense. Originally I was very pro Verilog but the more I've used it I've noticed things that I don't like that it allows you to do/doesn't raise an error for. I've been considering at least becoming mildly capable with VHDL mainly just to keep job prospects open. But maybe I would find I like it more. I'm not sure how worthwhile this is though as I live on the west coast of the United States which I hear mostly uses Verilog. That is actually how I choose Verilog to begin with. I'm not sure how important it is to know both. Will an employer look at someone with a fair amount of Verilog experience and very little VHDL experience as unqualified for a job requiring VHDL?
 

I'm not 100% sure on this as I know both languages. Places I've worked focused more on if a candidate had any design experience more than the tools used. VHDL and Verilog are fairly similar at the core. The only tool that seems to be different is SystemVerilog for simulation -- all of the fancy high-level concepts that can be useful for sim. I try to stay away from verification engineering myself.

For a first job, understanding VHDL or Verilog is nice. Understanding static timing and implementation is likely enough to get you a first job. Having a little TCL experience doesn't hurt due to tool vendors believing that developers like using TCL. Some scripting/linux CLI experience is also a common "nice to have" for fpga devs.

For a first job, you should also know karnough maps. This is something you'll never actually use nor is it even applicable for FPGA design. It's just a common interview question.

For the US, defense jobs typically use VHDL and industry typically uses Verilog.
 
Reactions: pigtwo

    pigtwo

    Points: 2
    Helpful Answer Positive Rating
Most of the job interviews Ive been on arnt so bothered about your VHDL or Verilog skills - more about how good your design knowledge is for a particular domain. Learning a language is easy if you know the underlying architectures. If you can read/write one, then the other is easily read/learned.
If you ever want to get into verification, you will need Verilog as a start, as most verification jobs will require SystemVerilog and UVM. But while these are the defacto - dont write VHDL off for verification. You can do a lot more with it than most people know (and can require the same tedious debugging that verilog needs)

As a verilog engineer, you will probably hate VHDL and assume you'll get an RSI with all the typing required.
 
Reactions: pigtwo

    pigtwo

    Points: 2
    Helpful Answer Positive Rating
That's what I was hoping for. I was thinking that maybe the underlying principles would be the same for both languages so experience in one would at least somewhat translate to experience in the other(with practice in the syntax). Thank you for mentioning Karnough maps. I certainly would not have relearned those. They seemed sort of pointless with synthesizers and such but I can see how the could be an interview question. This is great because I am always looking for interview advice.

Unfortunately for me I'm not very familiar with some of those concepts but your post gives me a good idea of what to look more deeply into. So thank you!

And haha yes RSI is a concern of mine with VHDL. It seems very verbose but I don't really mind. It just justifies the cost of my mechanical keyboard more.
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…