emacs verilog!

oh,my God ,emacs Verilog!

https://www.veripool.org/wiki/verilog-mode/Verilog-mode_veritedium

Verilog-Mode: Reducing the Veri-Tedium

Wilson Snyder

wsnyder AT wsnyder.org

SNUG San Jose 2001

Abstract

The Verilog Language has several design deficiencies which force usersto enter and maintain redundant information, such as argument lists,sensitivity lists, and cross-module wire statements. Supporting thisinformation leads to potential errors, lack of maintainability, andoverall code bloat.

The author extended the Emacs Verilog-Mode package to provide AUTOfeatures. These features look for /*AUTO*/ comments in the Verilogcode, and expand them into the appropriate text. The AUTO features areimplemented to be painless for even non-users; the code on disk is alwaysvalid Verilog code compatible with all existing tools. Though whilegreatly speeding coding for Emacs users, does not require Emacs to be usedfor later edits of the code.

Verilog-Mode allows the user to type:

module tedium (/*AUTOARG*/);
  input  in1,in2,in3,in4;
  input  out1,out2,out3,out4;

  /*AUTOREG*/
  /*AUTOWIRE*/

  always @ (/*AUTOSENSE*/) begin
    // complex logic here
  end

  sub sub1 (/*AUTOINST*/);
  sub sub2 (/*AUTOINST*/);
endmodule

And expand this with two keystrokes into a complete module.



1 Introduction

1.1 Is Verilog Tedious?

Verilog has a great deal of redundancy, which serves no useful purposein most modules. Let's look at a small Verilog module, and considerwhat information in the module is redundant.

module tedium (i1, i2, o1, o2);
  input  i1,i2;
  output o1,o2;
  reg    o1;

  wire   o2;
  wire   inter1;

  always @ (i1 or i2 or inter1)
    o1 = i1 | i2 | inter1;

  sub1 sub1 (.i1 (i1),
             .i2 (i2),
             .o2 (o2),
             .inter1 (inter1));

  sub2 sub2 (.i1 (i1),
             .inter1 (inter1));
endmodule

Here the redundancies have been marked with light italics. Why is thisinformation redundant?

  1. The argument list is a duplication of the input/output statements.
  2. Reg statements are needed for signals already `declared' as outputs.
  3. Wires need to be declared for interconnecting submodule signals.
  4. Sensitivity lists are needed for obvious combinatorial logic.
  5. Finally, name based sub-module instantiations are a duplicate of thesub-module's input/output statements. (Presuming the wire name matchesthe port name it connects to.)

It is surprising how much extra baggage Verilog requires. (Thank god wearen't coding in VHDL or it would be worse!)

1.2 Why reduce the Tedium?

Why should we care if we need to just do a little extra typing?

First, and most obvious, reducing the number of lines of code simplymakes the code easier to comprehend. It's just easier to understand ifmeaningless information is removed.

Next, if a mistake is made in writing or maintaining that extra code, wehave more spins through our compiler or lint program. That takes time.

If we instantiate the same module multiple times, we are at great riskof cut-and-paste errors. It's also very difficult to understand how busbits are spread across multiple instantiations. (Does bit 0 always comefrom instantiation 0?)

Worse, sensitivity lists are just plain hard to get right in big blocks.If you omit a signal from the sensitivity list and didn't run a linttool it's likely to take hours to debug.

Finally, it's too hard to change, add, or delete a signal through thehierarchy. If the signal goes up two levels and back down two levels, youhave approximately 16 lines to edit.

1.3 Design goals

How can we reduce this tedium?

We could simplify the language itself. This is certainly cleanest;Verilog 2000 has many features that reduce tedium, including always @(*) for eliminating sensitivity lists. However, it faces the hurdle ofrequiring an all new tool suite; until all tools you are using supportit, it's effectively useless.

We could write a preprocessor. That seems ok, but it would be requiredto be run the preprocessor in front of all Verilog programs, and moreimportantly every user of the code would be required to have the tool.Because of this, if you are providing Intellectual Property to others, apreprocessor probably isn't an option.

What we would really like would be for legal Verilog to come into thetool, and legal Verilog to come out, so the file on the disk is alwayslegal. Only when the code is being edited should the code possibly notbe valid Verilog code. Thus someone not using our tool always has legaland complete source code.

1.4 The solution: Use comments

How do we have valid Verilog code come in and out, but still save all ofthat typing? We'll use comments to indicate that the text following thecomment should be automatically computed.

Take a simple Verilog program:

always @(/*AS*/) begin
   if (sel) z = a;
   else     z = b;
end

We'll make /*AS*/ a special comment the program can look for. When itfinds it, the program will scan the block after the comment and computethe sensitivity list.

Running the program we'll get back:

always @(/*AS*/a or b or sel) begin
   if (sel) z = a;
   else     z = b;
end

Where the sensitivity list was added. Then the user can edit this codeto make a RTL change:

always @(/*AS*/a or b or sel) begin
   if (sel) z = a;
   else     z = s2?c:d;
end

And rerun the program to get back the right sensitivity list:

always @(/*AS*/a or c or d
         or s2 or sel) begin
   if (sel) z = a;
   else     z = s2?c:d;
end

For readability, we'll also have a way to back out all computed informationto make the code easy to read again:

always @(/*AS*/) begin
   if (sel) z = a;
   else     z = s2?c:d;
end

1.4.1 How to implement this?

Expanding the comments, which we'll call the AUTOs from here out, isbest done in the editor. This lets the user expand and remove them atwill, and get instant feedback as to if the AUTOs are doing what isdesired. Most importantly, when the code is saved, it can be expandedon the way out, accomplishing our goal of the code on disk always beingvalid.

When editing, it's also nice to have automatic indentation andhighlighting of comments and such. Thus, we'd like a standard languagemode as the basis for the program.

Rather then start from scratch, the author started with the leadingVerilog language mode, Verilog-Mode by Michael McNamaramac@versity.com. Upon this base, parsing and expansion of theAUTOs were added.

2 General usage

I'll now discuss each feature of the AUTOs and how to use them.

Through this section, I'll refer to a couple of key sequences, as keysare easier to represent in a document, and quicker for power users.However, those that prefer the mouse can execute this command from underthe Verilog option in the menu bar. Likewise all commands anddocumentation can be found under the menu.

2.1 Batch invocation

For those that use vi, or have a script generating code, it isuseful to be able to expand the automatics from the shell. Batchinvocation is done with the shell command:

emacs --batch filename.v -f verilog-auto -f save-buffer

This invokes Emacs in batch mode (no window opened), reads the file,expands the automatics, then finally saves the file.

If you have a large site initialization file that is slow, you can bemore explicit (and faster) by loading Verilog-Mode directly with:

emacs --batch --no-site-file -l verilog-mode.el
      filename.v -f verilog-auto -f save-buffer

You'll find this very valuable when you are writing a perl script orsomething to generate Verilog code. Simply have your script print outthe AUTO comments and let Emacs worry about the sensitivity lists andsuch. It will make your script a lot simpler.

2.2 Expanding Autos

There are only three key sequences that implement all of the importantfeatures. The first two are for expanding the AUTOs, and the final fordeleting them.

Once you've added the AUTO comments for the first time, and/or wish toupdate them, the keys C-c C-a or M-x verilog-auto willexpand the automatics.

After trying this a couple of times, you'll probably get into the hangof expanding the automatics, then saving the file, then running yourlint program. Since this sequence is so common, C-c C-s orM-x verilog-auto-save-compile will do all three: expandautomatics, save the buffer, and run the compiler (which should be setupto be a linting tool.) This is easy to remember as being similar to thestandard save-buffer keys, C-x C-s.

2.3 Deleting Autos

If you wish to look at the smaller version of the file, or are planninga large number of edits and want to remove the extra baggage, all of theautomatics can be deleted with C-c C-d or M-xverilog-delete-auto. The same C-c C-a or M-x verilog-autodiscussed above will get the expanded results back.

2.4 Sensitivity Lists

The first AUTO comment addresses the biggest tedium in Verilog;sensitivity lists. Verilog-Mode will replace /*AUTOSENSE*/, or /*AS*/for short, with the sensitivity list for the block after that comment.For example:

always @ (/*AUTOSENSE*/) begin
   outin = ina | inb;
   out = outin;
end

Typing C-c C-a will make this into:

always @ (/*AUTOSENSE*/ina or inb) begin
   outin = ina | inb;
   out = outin;
end

Verilog-Mode understands that signals that are generated within the samealways block (outputs of that block) are not placed into thesensitivity list, so out and outin do not appear in the list. The Veriloglanguage doesn't understand memories (multidimensional arrays) insensitivity lists either, so AUTOSENSE will exclude them and add a/*memory or*/ comment as a reminder to you that memory changes won'tactivate the block.

In the example we used a begin/end pair after the always. This makessure Verilog-Mode recognizes where the block ends, and gets around a bugin early versions of Verilog-Mode. (The latest version hasn't beenfooled yet, but it's better to be safe with begin/end or case/endcasepairs in case older versions of Verilog-Mode are encountered).

2.4.1 Constant signals

AUTOSENSE probably won't do what you expect the first time you use aconstant inside your block:

always @ (/*AUTOSENSE*/ina or inb or `constant) begin
   out = ina | inb | `constant;
end

AUTOSENSE cannot always determine if the defined value for `constant isa numeric constant or a signal. There are a number of fixes for this:

  1. Use the AUTO_CONSTANT declaration anywhere in the module (theparenthesis are required):
    /* AUTO_CONSTANT ( `this_is_really_constant_dont_autosense_it ) */
    
  2. Use a parameter declared in the module rather then a define, this willautomatically be understood as a constant. (It has the added advantageof being local in scope, rather then polluting the global name space.)
  3. Use verilog-read-defines or verilog-read-includes asdescribed below in the Instantiation section.
  4. Set verilog-auto-sense-defines-constant, this will mark all definesas constants. This is best done at the bottom of the file:
    // Local Variables:
    // verilog-auto-sense-define-constant:t
    // End:
    
    You need to re-visit (type C-x C-v RET) the file after changing anysuch local variable block; Emacs only parses it when the file is read in.

2.5 Argument Lists

Argument lists are created with /*AUTOARG*/. This parses theinput/output/inout statements and generates the argument list. Forexample:

module ex_arg (/*AUTOARG*/);
   input i;
   output o;
endmodule

Typing C-c C-a will make this into:

module ex_arg (/*AUTOARG*/
  // Outputs
  o,
  // Inputs
  i);

   input i;
   output o;
endmodule

Concatenation and outputting partial busses is not supported, nor are`ifdefs and such. You can work around that by placing ports between the( and /*AUTOARG*/. Verilog-Mode will presume these to be predeclaredand will not be redeclared by AUTOARG. Avoid doing this if you can, asit will just lead to more ifdefs if this module is then used in a/*AUTOINST*/.

module ex_arg (
`ifdef need_x_input
  x,
`endif
  /*AUTOARG*/
  // Outputs
  o,
  // Inputs
  i);

`ifdef need_x_input
  input x;   // This is an optional input, if `need_x_signal is defined
`endif

  ...

Since the generation of arguments is so foolproof, you'll probably neverneed to edit or think about a module's argument list again. AUTOARG isalso an excellent first thing to try on an existing module; it's prettyobvious what it does, and only a compile is needed to insure it teststhe same as the original.

2.6 Instantiations

Instantiations are the most frustrating part of Verilog, as each signalmust be listed three times; once as an input/output statement in thesubmodule, once in the instantiation's pin name, and once in theinstantiation's connected wire name.

AUTOINST understands how to find a submodule, and will make the namebased instantiation for you.

Assume that you have a submodule, stored in the file fanout.v:

module fanout (o,i)
   input i;
   output [31:0] o;
   wire [31:0] o = {32{i}};
endmodule

Now you want to use that submodule in an upper level module:

module ex_inst (o,i)
   input i;
   output [31:0] o;
   fanout fanout (/*AUTOINST*/);
endmodule

Typing C-c C-a will make the upper module into:

module ex_inst (o,i)
   output o;
   input i;
   fanout fanout (/*AUTOINST*/
                    // Outputs
                    .o (o[31:0]),
                    // Inputs
                    .i (i));
endmodule

Where the list of inputs and outputs came from reading fanout.v's inputand output statements.

2.6.1 Exceptions to direct connects

AUTOINST presumes a one-to-one port name to signal name mapping. Thisis the most common case.

Unless you are instantiating a module multiple times, or the module is ageneric part like an adder, do not change signal names across thehierarchy. It just makes for unmaintainable code. Generally, I renameeither the parent or child to be consistent. To do this, try my vrenamefrom http://veripool.com. Vrename makes it a 30 second job tofix up all of the name mismatches, and will give you lots of downstreambenefits.

When you need to violate this suggestion the simplest is to specify theport directly before the /*AUTOINST*/. Any ports defined before the/*AUTOINST*/ are not included in the list of automatics. You shouldalso put a // Input or // Output comment before the ports so thatAUTOWIRE, discussed below, will know in which direction the signal goes.

fanout fanout (
               // Inputs
               .i          (my_i_dont_mess_with_it),
               /*AUTOINST*/
               // Outputs
               .o          (o[31:0]));

2.6.2 Templates

If the same module is instantiated multiple times, you can use a/*AUTO_TEMPLATE*/ to specify the exceptions just once. Create acommented out template with AUTO_TEMPLATE as the instantiation name:

/* psm_mas AUTO_TEMPLATE (
        .PTL_MAPVALIDX          (PTL_MAPVALID[@]),
        .PTL_BUS                (PTL_BUSNEW[]),
        ); */

The module name in the template must be the same as the module name inthe instantiation. Only signals that must be different for eachinstantiation need to be listed.

It's important to have one port per line, ending in a comma or); just like AUTOINST produces. In fact, it's easiest to generatethe AUTO_TEMPLATE by making an AUTOINST, expanding the autos, thencutting out the lines Verilog-Mode inserted at the AUTOINST and pastingthem into the template.

Templates go above the instantiation(s). When an instantiationis expanded Verilog-Mode simply searches up for the closest template.Thus you can have multiple templates for the same submodule, justalternate between the template for an instantiation and the instantiationitself.

The above psm_mas template will convert:

psm_mas ms2 (/*AUTOINST*/);

Typing C-c C-a will make this into:

psm_mas ms2 (/*AUTOINST*/
    // Outputs
    .INSTDATAOUT     (INSTDATAOUT),
    .PTL_MAPVALIDX   (PTL_MAPVALID[2]),   // Templated
    .PTL_BUS         (PTL_BUSNEW[3:0]),   // Templated
    ....

The @ character is some very useful magic. The @ will be replaced bythe first digits in the instantiation's name. Note the @ character wasreplaced with the 2 from "ms2". Also, those ports not listed in the templateare assumed to be direct connections.

The AUTOs replace a [] in the template (a "null" bus subscript) by thebit range that the submodule needs, or nothing if it is a single bitport. Note how PTL_BUSNEW[] became PTL_BUSNEW[3:0] above. Generallyusing [] is better then putting the bits into the template, because ifthe submodule changes the bit-range in its input or output statement,it will propagate that change to the parent module automatically.(Which is the whole point of the AUTOs, hiding of information andautomating affects of changes.)

2.6.3 Lisp templates

Specifying a simple wire name in an AUTO_TEMPLATE isn't always enough,especially when spreading bits across multiple instantiations. ThusVerilog-Mode allows you to write a program to compute the name of a wireto connect to a given port:

/* psm_mas AUTO_TEMPLATE (
        .PTL_MAPVALIDP1X  (PTL_MAPVALID[@"(% (+ 1 @) 4)"]));
*/

submod i0 (/*AUTOINST*/);
submod i1 (/*AUTOINST*/);
submod i2 (/*AUTOINST*/);
submod i3 (/*AUTOINST*/);

When the syntax @"( ... )" is encountered, the expression in quoteswill be evaluated as an Emacs Lisp expression, with @ replaced by theinstantiation number. Lisp programming is fairly straight forward, justput the operator first (prefix notation). Any double-quotes inside theexpression itself will need to be quoted with a leading backslash\".

The MAPVALIDP1X example above would put [@+1 modulo 4] into thebrackets. Thus instantiation i0 gets PTL_MAPVALID[1], i1 getsPTL_MAPVALID[2], i2 gets PTL_MAPVALID[3], i3 gets PTL_MAPVALID[0]. (Thecoder picked the port name MAPVALIDP1X to mean MAPVALID plus 1instantiation number.) This type of thing is very useful for barrelshifters and the like.

Normal lisp variables can be used in the AUTO_TEMPLATE expressions. Inaddition some special variables are defined:

vl-name is the name portion of the input/output port (`PTL_MAPVALIDP1X').vl-bits is the bus bits portion of the input/output port (`[2:0]').

Furthermore, verilog-read-defines, described below, will make avh-{definename} variable for every define in the module. Even better,any comments of the form:

        /*AUTO_LISP(setq foo 1)*/

will evaluate any Lisp expression inside the parenthesis between thebeginning of the buffer and the point of the AUTOINST. This allowsvariables to be changed between each instantiation, and very complex templatesto be made, including string based substitutions.

2.6.4 Regexp templates

Sometimes fixed port names in AUTO_TEMPLATES aren't enough, it would beuseful to match many ports with one template line. The most common caseis when bit blasting or changing naming conventions across a largenumber of pins, such as at the top of a chip.

An AUTO_TEMPLATE entry of the form:

    .pci_req\([0-9]+\)_l   (pci_req_jtag_[\1]),

applies an Emacs style regular expression search. This example matchesany port beginning with "pci_req" followed by numbers and ending in"_l". That port is connected to the pci_req_jtag_[] wire, with the bussubscript coming from what matches inside the first set of \( \). Thuspci_req2_l connects to pci_req_jtag_[2].

Since matching \([0-9]+\) to port names is so common and ugly to read, a@ does the same thing. (Note this is different from the instantiationnumber, which is what @ does on the right side of the template.) Thusthe below template is equivalent to the above template:

    .pci_req@_l      (pci_req_jtag_[\1]),

Here's another example to remove the _l, perhaps because the namingconventions specify _ alone to mean active low. Note the use of [] todetermine the bus subscript automatically:

    .\(.*\)_l        (\1_[]),

Here's a final template that is very useful:

/* submod AUTO_TEMPLATE (
      .\(.*[^0-9]\)@  (\1[\2]),
      );*/

It says to take a port of the form lettersDIGITS and convert it toletters[DIGITS], conveniently vectorizing the signal. The [^0-9] isneeded because otherwise .* could match trailing digits.

2.7 Interconnection Wires

When interconnecting modules, wire statements are required for bussedoutputs of submodules. /*AUTOWIRE*/ will declare wires for the outputsof all submodules. This is especially nice for signals that crossbetween two submodules and are not used in the top module itself.

AUTOWIRE assumes that either /*AUTOINST*/ was used, or you manuallyadded // Output comments to the instantiations. For example:

module top (o,i)
   output o;
   input i;

   /*AUTOWIRE*/

   inst inst   (/*AUTOINST*/);
   other other (/*AUTOINST*/);
endmodule

Typing C-c C-a will make this into:

module ex_wire (o,i)
   output o;
   input i;

   /*AUTOWIRE*/
   // Beginning of automatic wires
   wire [31:0]  ins2oth;    // From inst of inst.v
   wire [31:0]  oth2ins;    // From other of other.v
   // End of automatics

   inst inst   (/*AUTOINST*/
                // Outputs
                .ins2oth  (ins2oth[31:0]),
                .o        (o),
                // Inputs
                .oth2ins  (oth2ins[31:0]),
                .i        (i));

   other other (/*AUTOINST*/
                // Outputs
                .oth2ins  (oth2ins[31:0]),
                // Inputs
                .ins2oth  (ins2oth[31:0]),
                .i        (i));

endmodule

Cross and oth2ins are declared because they are outputs of submodules.It also adds a nice comment that makes it easy to understand where thewires are coming from. Even if bus bits come from multiple submodules,or the wires were manually declared, AUTOWIRE will do the right thing.

2.8 Registered Outputs

If a module output comes from a register, the signal needs to bedeclared as both a register and as an output. AUTOREG will read theoutput declarations and make the register declaration for you. As wouldbe expected, if the output comes from a submodule or wire, the regstatement isn't added. For example:

module ex_reg (o,i)
   output o;
   input i;

   /*AUTOREG*/

   always o = i;
endmodule

Typing C-c C-a will make this into:

module ex_reg (o,i)
   output o;
   input i;

   /*AUTOREG*/
   // Beginning of automatic regs
   reg    o;
   // End of automatics

   always o = i;
endmodule

Where o needs to be both an output and a register.

2.9 Shell Modules

Often one module needs an identical port list as another module. This isneeded to produce a shell around the original module, or to create anull module. /*AUTOINOUTMODULE(module)*/ copies theinput/output/inout statements from the specified module and inserts itinto the current module. Any I/O which were already defined in thecurrent module will not be redefined.

For example:

module ex_shell (/*AUTOARG*/)
   /*AUTOINOUTMODULE("ex_main")*/
endmodule

module ex_main (i,o,io)
  input i;
  output o;
  inout io;
endmodule

Typing C-c C-a will make this into:

module ex_shell (/*AUTOARG*/i,o,io)

   /*AUTOINOUTMODULE("ex_main")*/
   // Beginning of automatic in/out/inouts
   input i;
   output o;
   inout io;
   // End of automatics

endmodule

2.10 State Machines

When you are debugging a state machine in waves, it's very nice to havea signal you can see with the names of the states in it. Likewise, ifusing a $display statement, you'd like to have a string with the statename. /*AUTOASCIIENUM(in,out,prefix)*/ takes a set ofparameters and makes a block to decode the state vector. For example:

//== State enumeration
parameter [2:0] // synopsys enum state_info
                SM_IDLE =  3'b000,
                SM_SEND =  3'b001,
                SM_WAIT1 = 3'b010;

//== State variables
reg [2:0]       /* synopsys enum state_info */
                state_r;  /* synopsys state_vector state_r */
reg [2:0]       /* synopsys enum state_info */
                state_e1;

//== ASCII state decoding
/*AUTOASCIIENUM("state_r", "_stateascii_r", "sm_")*/

Typing C-c C-a will make this into:

... same front matter ...

//== ASCII state decoding
/*AUTOASCIIENUM("state_r", "_stateascii_r", "sm_")*/
// Beginning of automatic ASCII enum decoding
reg [39:0]           _stateascii_r;          // Decode of state_r
always @(state_r) begin
   casex ({state_r}) // synopsys full_case parallel_case
     SM_IDLE:  _stateascii_r = "idle ";
     SM_SEND:  _stateascii_r = "send ";
     SM_WAIT1: _stateascii_r = "wait1";
     default:  _stateascii_r = "%Erro";
   endcase
end
// End of automatics

Here's how to use it:

  1. Declare state parameters as an enumeration using the synopsys enumcomment. The comment must be between the keyword and the symbol.(Annoying, but that's what Synopsys's dc_shell FSM reader requires.)
  2. Tag registers to which that enum applies with the same enum. Synopsysalso suggests labeling state vectors, but Verilog-Mode doesn't care.
  3. Add the /*AUTOASCIIENUM(in,out,prefix)*/ comment.
    in
    The first parameter is the name of the signal to be decoded.
    out
    The second parameter is the signal name to store the ASCII code into.For the signal foo, I suggest the name _foo__ascii, where the leading _indicates a signal that is just for simulation, and the magic characters_ascii tell waveform viewers like my Dinotrace to display inASCII format.
    prefix
    The final optional parameter is a string which will be removed from thestate names. This simply reduces the width of the ascii decoding, so it'smore likely to fit on the screen in a waveform viewer.

After expanding, you'll get the block and the decoded signal you need.Note that the vector _stateascii_r is declared to the exact width neededto fit the ascii for the largest state.

3 General Tips

This section covers a couple of general tips for using the AUTOs.

3.1 Finding Modules

If you've read through the instantiation section, you might be wonderinghow Verilog-Mode knows where to find a given module declaration.

Verilog-Mode looks first in the current file, that's in case you havemultiple modules defined there. Then it looks for the module name witheach extension in verilog-library-extensions appended, normally a`.v'. Finally it searches in each directory defined inverilog-library-directories.

Thus if you have a top level module that needs to find submodules insubdirectories, you need to tell Verilog-Mode to look in thesubdirectories. The best way to do this is to define the libraryvariables at the end of each Verilog file that needs them:

// Local Variables:
// verilog-library-directories:("." "subdir" "subdir2")
// verilog-library-files:("/some/path/technology.v" "/some/path/tech2.v")
// verilog-library-extensions:(".v" ".h")
// End:

Emacs automatically parses this section and sets the appropriatevariables. Since Emacs doesn't notice edits to them until the file isre-read, remember to C-x C-v RET if changing localvariables!

These three variables have the following effects:

verilog-library-directories
The variable verilog-library-directories contains a list of directoriesin which to look for the module. Having at least the current directory(the default) is a good idea.
verilog-library-extensions
The variable verilog-library-extensions contains a list of filenameextensions to try to append to module names to generate filenames. Normally just ".v".
verilog-library-files
The variable verilog-library-files contains a list of files that will besearched in entirety for modules. This is usually a complete path to atechnology file with many standard cells defined in it.

3.2 Defines

When using AUTOINST or AUTOSENSE, it's sometimes important forVerilog-Mode to know what defines are defined in the current file. Thisallows Verilog-Mode to properly resolve modules and know which definesrepresent constants.

If macros are defined earlier in the same file and you want theirvalues, you can read them automatically:

// Local Variables:
// eval:(verilog-read-defines)
// eval:(verilog-read-defines "group_standard_includes.v")
// End:

The first eval will read all of the `defines in the current file. Thesecond eval will read the defines in a specific file, such as if thereis a standard include file that does not have a specific `include in themodule itself.

Defines must be simple text substitutions, one on a line, starting atthe beginning of the line. Any ifdefs or multiline comments around thedefine are ignored.

3.3 Include files

For speed reasons, Verilog-Mode doesn't automatically read includefiles. This means that constants defined in an include file won't beknown as constants for AUTOSENSE. This can be fixed by telling Emacs toread the includes when the file is read:

// Local Variables:
// eval:(verilog-read-includes)
// End:

This will parse the file just read in, and read any `includes that itfinds in that file. Remember the C-x C-v RET after changinglocal variables!

It is good to get in the habit of including all needed files in each .vfile that needs it, rather then waiting for compile time. This will aidVerilog-Mode, Verilint, and readability. To prevent defining the samevariable over and over when many modules are compiled together, put atest around the entire contents of each include file:

        // include if not already included
        `ifdef _FOO_V `else
         `define _FOO_V
         ... contents of file
        `endif // _FOO_V

This is standard procedure for C header files, and should becomestandard practice in Verilog for the same reasons.

4 Getting Verilog-Mode

The best way to explore Verilog-Mode is to get it, and try a couple ofsimple features like AUTOARG and AUTOSENSE. You'll find more and moreAUTOs creeping into your code, and you'll soon join the thousands ofengineers that would never work without them.

Verilog-Mode comes with VCS, but that version is fairly old, and unlessyou've recently downloaded the latest (version 3.50 at thiswriting), you should might as well download the latest before gettingstarted.To download, follow the link off the author's site:http://veripool.com.

Please report bugs to the Verilog-Mode GNATS server,verilog-mode-bugs@surefirev.com.

To contact the author directly, email .


emacs verilog-mode对IC顶层集成的帮助

原创 2017年07月09日 09:55:17

背景介绍

emacs默认自带verilog-mode插件,不仅仅支持语法高亮、代码段自动补全等功能,核心应用还有/*AUTOXXX*/
IC顶层集成,最常见的工作就是实例化和端口线网的连接。可以利用/*AUTOINST*//*AUTOWIRE*/节省很多工作量,减少出错可能性。

AUTOINST和AUTOWIRE的应用

下面是示例。用到的技巧包括:
1. ctrl+c ctrl+a是把/*AUTOINST*/等关键词展开;得到实例化等代码段。连续操作,可以更新。
2. ctrl+c ctrl+k是把/*AUTOINST*/等关键词收起;
3. AUTOWIRE,是把output变量进行wire类型声明;如果input也想声明wire类型,可以临时改为output。
4. AUTOINST,默认的线网连接名称与端口名称相同;如对此有要求,可以利用AUTO_TEMPLATE。
5. 虽然实例化代码和设计代码可以不放在一个文件里,只需要在一个目录里。但个人还是推荐,把module声明和实例化放在一个临时文件里,进行生成,这样代码干净思路清晰一些。

下面有两段代码,第一段代码,按键ctrl+c ctrl+a之后,会自动生成第二段代码。
==================================
module noc(
           output        z1,
           output        z2,
           output [31:0] z3,
           input         a1,
           input         a2,
           input [31:0]  a3
           );
endmodule
module noc1(
            output        z1,
            output        z2,
            output [31:0] z3,
            output        a1,
            output        a2,
            output [31:0] a3
            );
endmodule
module a;
   /*AUTOWIRE*/
   noc u_noc(/*AUTOINST*/);
endmodule
module a;
   /*AUTOWIRE*/
   noc1 u_noc1(/*AUTOINST*/);
endmodule
module a;
   /*AUTOWIRE*/
   /* noc AUTO_TEMPLATE(
    .z1 (output1),
    .z2 (output2),
    .z3 (output3),
    .a3 (input3),
    );
    */
   noc u_noc(/*AUTOINST*/);
endmodule


===========================================================
module noc(
           output        z1,
           output        z2,
           output [31:0] z3,
           input         a1,
           input         a2,
           input [31:0]  a3
           );
endmodule
module noc1(
            output        z1,
            output        z2,
            output [31:0] z3,
            output        a1,
            output        a2,
            output [31:0] a3
            );
endmodule
module a;
   /*AUTOWIRE*/
   // Beginning of automatic wires (for undeclared instantiated-module outputs)
   wire                 output1;                // From u_noc of noc.v
   wire                 output2;                // From u_noc of noc.v
   wire                 output3;                // From u_noc of noc.v
   // End of automatics
   noc u_noc(/*AUTOINST*/
             // Outputs
             .z1                        (output1),               // Templated
             .z2                        (output2),               // Templated
             .z3                        (output3),               // Templated
             // Inputs
             .a1                        (a1),
             .a2                        (a2),
             .a3                        (input3));                // Templated
endmodule
module a;
   /*AUTOWIRE*/
   // Beginning of automatic wires (for undeclared instantiated-module outputs)
   wire                 a1;                     // From u_noc1 of noc1.v
   wire                 a2;                     // From u_noc1 of noc1.v
   wire [31:0]          a3;                     // From u_noc1 of noc1.v
   wire                 z1;                     // From u_noc1 of noc1.v
   wire                 z2;                     // From u_noc1 of noc1.v
   wire [31:0]          z3;                     // From u_noc1 of noc1.v
   // End of automatics
   noc1 u_noc1(/*AUTOINST*/
               // Outputs
               .z1                      (z1),
               .z2                      (z2),
               .z3                      (z3[31:0]),
               .a1                      (a1),
               .a2                      (a2),
               .a3                      (a3[31:0]));
endmodule
module a;
   /*AUTOWIRE*/
   // Beginning of automatic wires (for undeclared instantiated-module outputs)
   wire                 output1;                // From u_noc of noc.v
   wire                 output2;                // From u_noc of noc.v
   wire                 output3;                // From u_noc of noc.v
   // End of automatics
   /* noc AUTO_TEMPLATE(
    .z1 (output1),
    .z2 (output2),
    .z3 (output3),
    .a3 (input3),
    );
    */
   noc u_noc(/*AUTOINST*/
             // Outputs
             .z1                        (output1),               // Templated
             .z2                        (output2),               // Templated
             .z3                        (output3),               // Templated
             // Inputs
             .a1                        (a1),
             .a2                        (a2),
             .a3                        (input3));                // Templated
endmodule


  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Emacs Verilog Mode是一种用于在Emacs编辑器中编辑Verilog HDL(Hardware Description Language)的模式。它提供了丰富的功能和快捷键,使Verilog代码的编写和调试更加方便和高效。 Emacs Verilog Mode具有以下主要特点: 1. 语法高亮显示:Verilog代码的不同部分会使用不同的颜色进行区分,以便更容易地阅读和理解代码。 2. 自动缩进:在编写代码时,程序会自动进行缩进,以便更清晰地展示代码的层次结构。 3. 代码折叠:Emacs Verilog Mode允许代码的折叠和展开,以隐藏或显示特定的代码块。这样可以更好地组织和查看大型的Verilog项目。 4. 代码模板:模板功能使得可以快速插入常用的Verilog代码片段,例如模块定义、寄存器定义等,提高代码的编写速度和一致性。 5. 代码跳转:通过快捷键可以方便地在模块之间进行跳转,快速浏览和编辑代码。 6. 语法检查和自动补全:Emacs Verilog Mode可以检查代码中的语法错误,并提供自动补全功能,减少拼写错误和编程失误。 7. 特定的功能块标记:针对Verilog HDL特有的结构和语法,Emacs Verilog Mode提供了特定的功能块标记,如module、always、if-else语句等,以便更好地识别和编辑这些代码块。 总之,Emacs Verilog Mode是一个强大而实用的工具,它简化了Verilog代码的编辑过程,提高了工作效率和代码质量。无论是进行硬件设计还是进行FPGA编程,使用Emacs Verilog Mode都能够帮助开发人员更好地完成任务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值