Verilog in Emacs
- Details
- Last Updated: Wednesday, 01 March 2023 08:15
- Published: Wednesday, 01 March 2023 08:06
- Hits: 402
Before we start with real Verilog coding, we should use an editor which recognizes Verilog mode and formats it appropriately.
We have "verilog mode" in emacs that not only allows formatting, but allows us to write succinct code which can be expanded to real Verilog code. We'll talk about this feature below.
Verilog mode for Emacs:
Verilog-mode.el is the extremely popular free Verilog mode for Emacs. It can be downloaded from link over here (It's not included by default in standard emacs download). https://www.veripool.org/wiki/verilog-mode
Once downloaded and installed, emacs will start showing verilog specific highlighting, indenting, etc. To verify if verilog mode is there in your emacs, open emacs. You would see tabs on top for File, Edit, Options, etc. If verilog mode is installed, there should be a tab for "Verilog". If you click on "verilog" tab, you should see a pull down showing various action tabs as compile, Recompute AUTOs, etc. You can do more customization by reading help section.
Verilog has a lot of redundant typing built into the syntax. Verilog mode for emacs provides "AUTO" keyword that we can put in verilog code within comments. Putting these keywords within comments /* */ guarantees that this code will work seamlessly with any other tool, which has no knowledge of these "AUTO" keywords as they are in comments.Only verilog mode in emacs looks for these special keywords to expand your verilog code. We can always manually edit the code further or make changes that we didn't like that were introduced by AUTO.
Info about AUTO keywords here: https://www.veripool.org/wiki/verilog-mode/verilog-mode_veritedium
To make changes after inserting AUTO* keywords in verilog code, we can use shortcut "Ctrl+c , Ctrl+a", or goto Verilog tab on emacs and click on "Recompute AUTOs". This expands AUTO keywords (still keeps the commented AUTO keyword so that we know ehere the changes happened).
For older designs which don't have AUTO keywords in them, we can use emacs to inject AUTO in them, so that next time if there are more changes, we can just do "Recompute AUTOs". For Inject AUTOs, we can use shortcut "Ctrl+c , Ctrl+z". All of these AUTO keywords would be injected within comments, so they won't affect if used with other tools.
verilog mode also allows us to expand system verilog .* port connections, so it's easy to check and debug in source code.
Few AUTO cmds:
NOTE: there should be no space between /* and AUTO keyword, i.e /*AUTOARG*/ will work, but /* AUTOARG */ may not work due to spaces)
1. AUTOARG: This is to add argument list for any module. It looks at i/p and o/p ports and adds those in port list of module.
ex: module (/* AUTOARG */); input a; output b; ... => gets transformed into =>
module (/* AUTOARG */
//outputs
out_1, out_2, ..., out_n,
//inputs
in_1, in_2, ..., in_n);
input a; output b; ...
NOTE: Even if we declare no input/output ports. AUTOARG expand will look for undriven input signals and floating output signals, and assign them as input/output ports. This is useful to detect ports automatically.
ex: module (/* AUTOARG */); //This will automatically infer all I/O ports and put them here after expansion
NOTE: To distinguish ports inserted manually by the user, vs ports inferred from AUTOARG expansion, verilog adds comments in auto inserted ports. i.e //From mod_1 of mod_1.v or //To mod_1 of mod_1.v
2. AUTOINPUT, AUTOOUTPUT: This looks for undriven input signals and floating output signals, and assign them as input/output ports. This is useful to detect ports automatically.
ex: module (/* AUTOARG */); /* AUTOINPUT */ /* AUTOOUTPUT */ //This will automatically infer all I/O ports and put them here after expansion (along with AUTOARG expansion)
3. AUTOINST: This automatically adds port connections for a submodule by reading module defn. It creates net connections with same names as port names for module defn. NOTE: AUTOARG is for adding ports to module, while AUTOINST is to add port connections to sub-module.
ex: submod I_submod (/* AUTOINST */); => gets transformed into => submod I_submod ( .out(out), .in(in) ...);
However, sometimes we may want connecting wires to be named differently than port name. In that case we can define exceptions by coding those connections ourselves. AUTO won't overwrite those.
ex: submod I_submod ( .a(a_1), /* AUTOINST */); => gets transformed into => submod I_submod ( .a(a_1), .out(out), .in(in) ...); => NOTE: port "a" remain connected to "a_1"
NOTE: To distinguish ports connected manually by the user, vs port connections inferred from AUTOINST expansion, you can put your own comments for manually connected ports (while auto port connections will show no comments)
4. AUTO_TEMPLATE: NOTE: this has a underscore in it. We use this keyword for same situation as AUTOINST, but when there are multiple instantiations of a module. In such a case, writing exceptions for port connections for each submodule become cumbersome, so we use other reserved special char (as @, $, etc) to make complicated renaming possible.
ex: /* submod AUTO_TEMPLATE (.z(out[@]), .a(invec@ [])); */ => NOTE: here whole thing is in comments as opposed to just the keyword AUTO_TEMPLATE. @ in template takes the leading digits from instantiating module's name. empty [] takes the bit range for the bus from module defn. More complicated lisp expressions possible. Regular expressions also supported. @ suffices for most of the cases. AUTO_TEMPLATE is used in conjunction with AUTOINST. AUTO_TEMPLATE does all complicated connections with renaming, and anything left over is taken care of by AUTOINST. However, AUTOINST always overrides AUTO_TEMPLATE connections in case of conflict, so hardcode connections in instantiation of module if you are unsure what the AUTO_TEMPLATE or AUTOINST is going to do (generally it's used where we want to tie port connections to constants, so we hard code those connections in actual inst of module, as you see in ex of AUTOINST above).
ex: submod I_0 (.z1(out_z), .i2(), .. /* AUTOINST */); => This is regular instantiation of submod. Here AUTOINST is used in regular way. However, since AUTO_TEMPLATE is also defined for this module "submod", emacs will attempt to make connections for port "z" and port "a" (port z connected to out[0] and port a connected to invec0[31:0], since @ takes leading digits from I_0 which is 0. If there are more instances like I_BL_1, then connections will be named out[1], invec1[31:0], etc))
ex: /* submod AUTO_TEMPLATE (.sense_\(.*\) (sense@_\1), ..) */ => \( \) is emacs basic regular expression (see in linux regexp section). Anything inside it is put in var \1. So, here for inst I_0, sense_in4 would be connected to sense0_in4, for inst I_1, it would be sense1_in4 and so on.
NOTE: To distinguish ports connected by AUTO_TEMPLATE, verilog adds comments in auto inserted ports. i.e //Templated. Any user comments put in AUTO_TEMPLATE section are not shown in expanded connections.
5. AUTOWIRE, AUTOREG, AUTOLOGIC => AUTOWIRE takes o/p of submodules and declares wires for them. AUTOREG saves having to duplicate reg stmt for nets declared as outputs. AUTOLOGIC declares logic instead of wire or reg.
ex: module ... output y; /* AUTOWIRE */ /*AUTOREG */ wire a; ... => gets transformed into => ... output y; /* AUTOWIRE */ /*AUTOREG */ wire b; reg y; wire a; ...
6. AUTOSENSE (or shortcut AS) => replaces everything with sensitivity list. System Verilog supports @* for sensitivity list, so AS is not needed any more.
ex: always @ (/* AS */) begin ... end => gets transformed into => always @ (/* AS */ a or b or sel) begin ... end
Running emacs in batch mode:
Instead of opening emacs and doing it on gui, we can run emacs in batch mode (i.e as cmd line w/o invoking editor) as follows:
emacs -batch my_design.v -f verilog-auto -f save-buffer => same as doing "compute AUTOs" and saving in same file