07-08-00 TT CV2.100 User ManualThis manual describes the TT CV2.100 Simple Verilog Compiler. This is a tool which will compile a circuit description in the Verilog language into a gate-level, hierarchic, netlist. This netlist may then be fed into other tools for simulation or layout and fabrication. This manual also provides useful documentation for the VTOC tool, since many of the command line flags are the same and are explained in greater depth here. CV2.100 is only a basic RTL compiler and the current release does not contain high-quality logic minimisation. In the future, TT CV2.200 is intended to be a behavioural compiler, based on the same core algorithm as TT CTOV. CV2.100 has support for automatic generation of ROM, RAM, adder and multiplier instances taken from standard library blocks. CV2.100 compiles general RTL into a set of standard gates and flip-flops whose definitions are found in the file cv100gates.cv. Specific modules found only in certain technology libraries, such as IO pads, need to be manually instantiated. This software and manual are provided for use at your own risk. We accept no responsibility for any copyright or patent infringement or any other direct or consequential loss which may arise from using this software. The figure shows that the CV2.100 program accepts a number (not necessarily four) of source files and produces a single object file, as well as console messages in the case of any warnings or errors. All of the source files are in the Verilog language and normally have suffix `.cv'. One of the files contains a root module and the other files contain modules needed to synthesise the root module. These other files may be in the current directory or in libraries. The output file is a net list in Verilog (suffix `.vnl') or an ML parse tree. The tool should typically be used alongside a Verilog simulator which can simulate either the input or the output from CV2. Suitable simulators are CSIM (available within the University of Cambridge only) and Cadence Verilog-XL.
CV2.100 Verilog Language Subset and SyntaxThe CV2.100-V2 compiler accepts a subset of the full Verilog language for compilation into a gate-level netlist. This section describes that subset. The subset is the main structural and RTL (register transfer level) set of the language, but excludes Verilog's built-in transistors and gates, and signal strengths. CV2.100 is a basic RTL compiler and will not handle the following behavioural constructs: while , for , fork-join and more than one event control statement in the body of an always statement. The full Verilog language is described in the OVI (Open Verilog International) `Language Reference Manual' available for ftp from various places, including `ftp.chronologic.com/pub/ovi'. This section describes the language subset supported by the CV2.100 synthesiser. Other useful reference books include
Verilog is quite a rich language and supports four main levels of hardware specification of increasing abstraction using the various language constructs available. These levels can be freely mixed in one circuit. A taxonomy of four levels is handy for the current purposes, as follows:
The CV2.100 compiler (cv2) supports levels 1 through 3 an CV2.100 supports level 4 as well. Verilog LexicographyA Verilog source file contains modules, comments and macro definitions. All whitespace characters (outside of macro definition lines) are optional and ignored, except where adjacent identifiers would elide.
CommentsOne line comments are introduced with the revered double slash syntax and terminate at the end of line. Block comments are introduced with slash-star and terminate with star-slash. Block comments may not be nested. /* * This is a block comment. */ // And this is a single line comment.
IdentifiersIdentifier names consist of alphanumeric strings which can also contain underscores and must start with a letter. Case is significant. In this manual, uppercase identifiers are used by convention for module names, but this is not required by the language definition or CV2.100. CV2.100 maintains separate identifier spaces for modules, nets, macros and instances, allowing the same identifier to be used in more than one context. The net identifier space also includes other classes of identifier that could be used in expressions, such as parameters and integers. Many postprocessing tools do not maintain such separate namespaces, so it is possible to have clashes within these tools that were not a problem for CV2.100.
Module, Port and Net DefinitionsA module is the top-level syntactic item in a Verilog source file. Each module starts with the word module and ends with endmodule and between the two are `module declarative items'. // Here is a module definition, called FRED module FRED(q, a, b); input a, b; // These are the inputs output q; // Make sure your comments are helpful // ..... Guts of module go here ..... endmodule After the module name comes a list of formal parameters in parenthesis. These are also known as the `ports'. In the module body, semicolons are used to terminate atomic statements, but not composite statements. Hence there is never one after an endmodule (or an end or an endcase ). Valid module declarative items include the following statements parameter , input , output , inout , wire , reg , tri , pullup , pulldown , integer , event , time , assign , initial , always and gate and module structural instantiations. Initialisation with initial initial statements are ignored unless they start `initial while(1) ...' or `initial forever ...' in which case they are treated as always statements. Event definitions and activations are ignored. The order of the declarative items is unimportant semantically, except that nets need to be declared before they are referenced.
Input and Output definitionsEach of the ports of a module must be explained using the keywords
These declarations take a comma separated list of ports which share a similar direction. When a modules are instantiated, CV2.100 checks that no two outputs are connected to each other and that all nets of type wire are are driven by exactly one output.
Pullups and PulldownsA net may be defined to float to logic zero or one by the inclusion of a pulldown or pullup, respectively. These statements should be used for inputs which are liable to be disconnected or to tristate bus lines. wire a; tri b; pullup (a); pulldown (b);For synthesis, CV2.100 turns these Verilog language components into straightforward structural instances of a PULLUP or PULLDOWN. However, ignore the above, since with CV2, it is better to instantiate components called PULLUP and PULLDOWN instead of using the builtin pullup and pulldown declarators.
Bus definitionsA Verilog signal may either be a simple net or else a bus. When an identifier is introduced (using a declaration such as input or tri etc.), if it is given a range, then it is a bus, otherwise it is a simple net. When an identifier which denotes a bus is referred to without giving an index range, then the full range of the bus is implied. Most Verilog operators will operate on both busses and simple nets. Busses are defined by putting a range in square brackets after the keyword which declares then. For example // Here is a module definition with two input busses module FRED(q, d, e); input [4:0] d, e; // Ports d and e are each five bit busses output q; // q is still one bit wide endmodule Note that when a module port is actually a bus, the bus range specification is not given in the formal parameter list, just its identifier. However, some dialects of Verilog allow the range specifications in the formals. In Verilog, width specifications may be from high to low or low to high. With CV2.100 however, the most significant bit (highest index) must be specified first and the least significant bit index second. Users who define their busses the other way around will later find that certain built-in operators (such as addition) may not work as expected. The least significant index does not have to be zero, which is helpful sometimes. Before logical operations on busses, such as addition or comparison, the numeric values of the bus indecies are normalised by effectively subtracting the least significant index from all bus wires.
Local signal namesLocal signal names are introduced with the wire , reg and tri statements. There are slight variations in the way these types of nets can be used, as explained elsewhere in this manual, but the syntax of the three statements is the same. Here is an example using some wires: // Here are some local nets being defined module FRED(q, a); Verilog allows the words vectored and scalared to be put before range definitions, but they are ignored by the synthesiser. Structural SpecificationOne further statement type, beyond the wire and port declarations, is all we need for structural specification of a hierarchic or flat netlist. This is the component instance statment. The syntax of a submodule or component instance is: where the square brackets are meta-syntax to indicate optional repetition and the angle brackets indicate that an identifier is not a keyword. The syntax allows several instances of the same submodule to be specified in one instance statement, if desired. // Here is a module definition with submodule instances. module FRED(q, a, b);The submodule NOR2 must be defined somewhere, as a leaf module in a technology library, or in the same or another design-specific Verilog source file. Instance names, such as `mygate' in the example, are optional. CV2.100 will make up instance names for instances in its output netlists if they are not provided in the source Verilog. However, this is not recommended since these names are likely to change each time a circuit is compiled and this is often inconvenient if a simulator or placement tool has retained instance name state from one run to another. Note that explicit instantiation of this type at the low level of individual gates is not normally done by a human, unless this is an especially critical section of logic. Such gate-level Verilog is normally synthesised from the higher levels of Verilog source by CV2.100 or other tools.
Positional and Named port mappingThe component instance example above, for NOR2, uses positional port mapping. The writer of the Verilog had to know that in the definition of NOR2, the output net was put first. That is // Here is the signature of NOR2 module NOR2(y, x1, x2); input x1, x2; // These are the inputs output y; // Make sure your comments are always helpful endmodule However, Verilog also allows named port mapping in the instance statement. Using named port mapping, the writer does not have to remember the order of the ports in the module definition, he must remember their names instead. The chance of misconnection though giving the wrong order is eliminated and the compiler is able to generate more helpful error messages when the wrong number of arguments is supplied to an instance. // Here is a module definition with named port mapping. module FRED(q, a, b); input a, b; // These are the inputs output q; // Make sure your comments are helpful wire qbar; // Local, unported net NOR2 mygate(.x1(a), .y(q), .x2(qbar)), myothergate(.y(qbar), .x2(q), .x1(b)); endmoduleAs can be seen, the syntax of a named port association is .whereas for the positional syntax, we just have a list of signal expressions. I use the term `signal expression' since the actual parameters, for both syntaxes, do not have to be simply signal names, but for inputs to the submodule, can be any expression which results in a signal of the correct width. Signal expressions are explained shortly. It is often necessary to pass a single net of a bus, or a subgroup of a bus to or from a module instance. This can be done using the bus subranging operator denoted by square brackets.
Continuous Assignment and Signal ExpressionsThe level of Verilog specification which comes above netlists and structural instantiation is continuous assignment. The syntax of a continuous assignment within CV2.100 is assignFor example wire p; assign p = (q & r) | (~r & ~s);The stile denotes Boolean OR, the ampersand denotes Boolean AND and the tilde denotes inversion. The signals q, r and s must be defined already using one of the declarations input, output, inout, wire, tri or reg. A continuous assignment is synthesised into a set of gates which achieve the desired logic function. Logic minimisation is applied to the signal expression on the right-hand side, but CV2.100 does not eliminate explicitly declared nets or their interconnection pattern across continuous assignments. In Verilog, the `hash' form of event control may be used as part of an assignment statement to introduce a delay. For example assign #10 p = q;CV2.100 ignores delay specifications when they are present in assignment statements, but flags a warning at the end of compilation if the delays were in non-primitive modules. Verilog allows a shorthand that combines a wire declaration with an assignment. The above example can be written more concisely wire p = (q & r) | (~r & ~s);where the assignment to p is combined into the wire statement that introduced it. Multiple wires can be defined and initialised at once if they all have the same range. For example wire p = ~q, r = ~s; wire [3:0] bill = 15-ben, foo = 15-bar;
Constant numeric expressionsNumerical constants can be introduced in a number of bases using the syntax: where the base is a single letter:
For example wire [7:0] bus1, clipbus; assign clipbus = (bus1 > 8'd127) ? 8'd127 : bus1;where 8'd127 is the decimal number 127 expressed to a width of eight bits. If constants are given without a width, CV2.100 will attempt to provide an appropriate width to use. If the situation is ambiguous, an error is flagged. CV2.100 will also accept simple strings of digits and treat them as unsized decimal numbers. Underscores are allowed in numbers. These are ignored by the compiler but can make the language more readable. For instance wire [23:0] mybus = yourbus & 24'b11110000_11110000_00001111;
Bus subranging and concatenationTo have access to parts of a bus, indexing can be used with a bit field in square brackets. When the index is left out, which is the case in the examples until now, the default width of the bus is used.examples wire [31:0] dbus; wire bit7 = dbus[7]; wire [7:0] lowsevenbits = dbus[7:0]; wire [31:0] swapbus = dbus[0:31];It is possible to assign to part of a bus using a set of assignment statements provided that each net of the bus is assigned to exactly once (i.e.\ the ranges are disjoint). For example wire [11:0] boo; input [3:0] src; assign boo[11:8] = src; assign boo[7:4] = 4'b0; assign boo[3:0] = src + 4'd1; It is also possible to form anonymous busses using a concatenation of signals. Concatenations are introduced with curly braces and have width equal to the sum of their components. Hence, the previous example can be rewritten more briefly
assign boo = { src, 4'b0, src + 4'd1 }; Note that all items within a concatenation must have a clearly specified width. In particular, unsized numbers may not be used. Items in a concatenation may be prefixed with a repeat count if desired. The following two example lines are therefore identical in meaning. { bill, bill, ben, ben, ben, weed } { 2 { bill }, 3 { ben }, weed } Note that CV2.100 does not support assignment to concatenations, although many Verilog dialects do. Instead, multiple separate assignments are needed.
Verilog OperatorsThe table defines the set of combinatorial operators available for use in signal expressions in order of binding power. Parenthesis can be used to overcome binding power in the normal sort of way. All operators can be applied to simple nets or to busses. When a diadic operator (i.e., one that takes two arguments) is applied where one argument is a simple net and the other a bus, CV2.100 treats the simple net as the least significant bit of a bus with all other bits zero. This is also the case when busses of unequal size are combined. CV2.100 has no support for two's complement or sign extension built in it treats all numbers as unsigned. When signed operation is needed, the user must create such behaviour around the built-in operators. (Of course, addition and subtraction work both with unsigned and two's complement numbers anyway). Although Verilog defines integers to be signed, they are unsigned with CV2.100. TODO fix. There are both Boolean and logical versions of the AND and OR operators. These have different effects when applied to busses and also different precedence binding power. The Boolean operators `&' and or `|' produce bitwise ANDs and ORs of their two arguments. The logical operators `&&' and `||' first or-reduce their arguments and then combine them in a unit width AND or OR gate.
Unary ReductionIt is possible to reduce a bus to a wire under an operator: that is, to combine all of the wires of a bus using an associative Boolean diadic operator. This is called in Verilog `unary reduction' (in contrast to the mathematical use of a unary operator as a function that takes only one argument). The syntax of unary reduction required by CV2.100 insists on two sets of parenthesis. (the unary-operator must be one of the ones in next table. For example wire [9:0] mybus; wire ex = (& (mybus));constructs a ten-input AND gate such that ex will be a logical one if the bus contains all ones.
Logical Not and Bitwise NotThe logical not operator is `!' and has a different meaning from the bitwise not operator `~' when applied to a bus. The logical not operator will or-reduce the wires of the bus and then negate the result, giving a unit width output. The bitwise not operator simply gives a bus the same width as its input but with each wire negated.
Carry and borrow in addition and subtraction.In order to access the carry (borrow) bit which results when two busses of identical size are added (subtracted), it is necessary for the lhs expression to be one larger than the right hand side expression. wire [3:0] x0, x1; wire [4:0] sum_with_carry = x0 + x1; On the other hand, the following will not give access to the carry, and instead bit 4 of `sum_without_carry' will be always zeros and a width mismatch warning message will be given, since inside concatenations it is necessary to be strict about widths: wire [3:0] x0, x1; wire [4:0] sum_without_carry = { x0 + x1 };
Conditional ExpressionsThe conditional expression operator allows multiplexers to be made. It has the syntax (The value of the expression is the false-expression when the switch-expression is zero and the true-expression otherwise. If the switch-expression is a bus, then it is unary-reduced under the OR operator. CV2.100 does not insist on the parenthesis around the switch-expression, but they are recommended. The association of the conditional expression operator is defined to enable multiple cases to be tested without multiple parenthesis. Examples wire [7:0] p, q, r; wire s0, s1; wire [7:0] bus1 = (s0) ? p : q; wire [7:0] bus2 = (s0) ? p : (s1) ? q : r; The bus comparison predicates (==, !=, <, >, <=, and >=) take a pair of busses and return a unity width result signal. For example wire yes = p > r; The meta comparison operators (=== and !==) are the same as (== and !=) for synthesis.
Dynamic SubscriptionCV2.100 supports dynamic subscription (indexing) of a bus in a signal expression provided that the selected width from the bus is one bit wide. Dynamic subscription is not supported on the left hand side of any assignment. Here is an example of use module TEST(); wire [10:0] bus; wire [3:0] idx; ... wire bit = bus[idx]; ... endmodule
Behavioural SpecificationVerilog HDL contains a full set of behavioural programming constructs, allowing one to write procedural style programs, with ordered assignments (as opposed to continuous assignments). The CV2.100-V2 Verilog compiler supports a subset of the language's behavioural constructs for logic synthesis. These are described in this section. Behavioural statements must be included within an initial declaration or an always declaration. Initialisation with initial initial statements are ignored unless they start `initial while(1) ...' or `initial forever ...' in which case they are treated as always statements. CV2.100 ignores the contents of other initial statements which might simply assign to a variable: these may be present and are useful when simulating the source file with a Verilog simulator (e.g. Verilog-XL or CSIM). CV2.100 supports only the following main form of the Verilog always construct. It has the syntax always @(This statement causes execution of the behavioural statement each time an event in the sensitivity list occurs. The sensitivity list is described in a later section because we will first present the behavioural statements that are supported. CV2.100 will synthesise the following behavioural statements into hardware: begin-end , if-then-else , case repeat , forever , task invocation and both the blocking and non-blocking behavioural assignment. TODO for and while loop. begin-end Behavioural StatementThis statement is simply the sequencing construct required to extend the range of behavioural statements which include behavioural statements (such as if and always ) to cover multiple behavioural statements. The syntax is beginwhere multiple instances of the contents of the square brackets may be present. The order of statements inside a begin-end block is important when multiple blocking assignments are made to the same variable. Multiple non-blocking assignments to the same variable are not allowed unless they are in different branches of an if-then-else . The repeat Behavioural StatementThe repeat statement is supported by CV2.100 provided it has a compile-time constant argument and is simply textually expanded into that many copies of its argument statement (which of course can be a block). The syntax is repeat (
The if-then-else Behavioural StatementThe if statement enables selective execution of behavioural statements. The target behavioural statement (which can be any type of behavioural statement, including further if statements) is executed if the signal expression is non-zero. if (If the signal expression given for the condition is a bus it is or-reduced so that the target behavioural statement is executed if any of the wires in the bus are non-zero. When the optional else clause is present, the else clause is executed if the signal-expression condition is false.
The case Behavioural StatementThe case statement enables one of a number of behavioural statements to be executed depending on the value of an expression. The syntax of the statement is case (where the case-items are a list of items of the form and the list may include one default item of the form default :The semantic is that the top signal expression is compared against each of the tag signal expressions and the behavioural statement of the first matching tag is executed. If no tags match, the statement provided as the default is executed, if present. If the `parallel_case' flag is present in a comment immediately after the right hand parenthesis of the case top signal expression, then the semantic of the case statement is changed and all matching expressions are evaluated. This normally produces fewer gates than the sequential case semantic and is often helpful for one-hot state machines where the designer knows that only one state will actually match. It may be observed that there are a number of variations from the case statements found in other languages, such as C. These are: the tag values do not have to be constants, but can be any signal expression; for each group of tag expressions there must be exactly one target statement (`begin-end' must be used to overcome this) and there is no `fall-through' from one case section to the next (i.e.\ the `break' of C is implied.) The variant case statments casex and casez are supported and have the same syntax as the normal case statement. These can generate dont-care conditions which help in logic minimisation when `x', `z' or `?' are used in constant case tags. These are not explained in this tutoria.
Behavioural Assignment StatementsBehavioural assignment is used to change the values of nets which have type `reg'. These retain their value until the next assignment to them. CV2.100 supports two types of behavioural assignment (as well as the continuous assignment. Non-blocking or `delayed' assignment.Using the `<=' operator, an assignment is `non-blocking' (or is `delayed') in the sense that the value of the assigned variable does not change immediately and subsequent references to it in the same group of statements ( always block) will refer to its old value. This corresponds to the normal behaviour of synchronous logic, where each registered net corresponds to a D-type (or broadside register for a bus) clocked when events in the sensitivity list dictate. The syntax isThe left hand side signal must have type reg. For example, to swap two registers we may use x <= y; y <= x;Where a variable is updated by more than one delayed assignment per clock cycle, each new one simply cancels any previous one.
Blocking or `immediate' assignment.When assignment is made using the `=' operator, the assignment is `blocking' and occurs immediately meaning that the values found by the right-hand-sides of subsequent behavioural statements in the block will use the newly assigned value. The term `blocking' is not helpful in the current context, but is useful in general Verilog when the assignment also contains arbitrary event control statements. This is why I have introduced the two synonyms `delayed' and `immediate' for the two types of assignment. The syntax for blocking assignment is Again, the left hand side signal must have type reg. CV2.100 supports multiple such assignment to a variable to be made within one group of assignments. For example, two registers may be swapped using an intermediate register t as follows t = x; x = y; y = t;This will result in a flip-flop called t being present in the CV2.100 output, but in fact it will not drive anything, and so it will normally be deleted by subsequent CAE tools.
Sensitivity listsThe full syntax of a sensitivity list is where the edge qualifier is either null or one of posedge or negedge . There is also a hash delay form of senesitivity list, but this is ignored for synthesis.d The signal is the name of any net. If the net is a bus, subscripts are not allowed within the sensitivity list and the whole bus is implied. The square brackets indicate that any number of nets may be listed, separated with the keyword or . CV2.100-V2 supports several forms of sensitivity list, including
The first two variations make an always block represent a block of synchronous logic with a global clock of either polarity. The third form is the normal Verilog construct for introducing asynchronous presets or resets to the flip-flops within the block. The last form allows a complex combinatorial function to be expressed using behavioural constructs ( if and case etc.). All of the inputs to the function (known as the support ) must be listed in the sensitivity list. If a signal is missing from the support list, a transparent latch would be implied. Creation of these is normally not useful and CV2 instead reports an error.
Behavioural Example and StyleTo support registered outputs from a module, it is allowed for the same net name to appear both in a reg statement and an output statement. For example: module EXAMPLE(ck, ex); input ck; output ex; reg ex, ez; // ex is both a register and an output reg [2:0] q; always @(posedge ck) begin ex = 0; ez = ~ez; if (ez) begin q = q + 3'd1; if (q == 2) ex = 1; end end endmoduleThe example defines a divide by two flip-flop ez and a three bit counter with clock enabled by ez. The output ex is also a register. In addition ex is updated twice within the always block, but under different conditions. It is a matter of style whether to use many simple always declarations or fewer always declarations with large `begin-end' blocks, each containing a greater number of assignments. However, the interleaving of assignments in a simulation is not guaranteed across always blocks in the same module and can lead to random behaviour or different behaviour between simulation and synthesis. Therefore, it is usual practice to only use one always statement per clock in each module. For synthesis with cv2.100, a given net can only be updated in one always declaration.
$display and $strobe etc.The Verilog meta-statements $display , $write , and \$finish and some others may be embedded in the language accepted by CV2.100. They are in the syntactic category of behavioural statements and so must be inside an initial or always statement. Since these statements are only significant during simulation, CV2.100 completely ignores them.
Module Parameters and OverridesA Verilog parameter is an identifier which takes on a numerical value which is typically used to provide such things as variable bus widths or variable division ratio in a divider. In Verilog, parameters may be defined locally to a module with a constant value or passed in as a compile-time value from a structural instantiation of the module. Here is an example of parameter definition and use. module MOD1(..... ); parameter bussize = 10, fred = 3; parameter delta = 4; wire [bussize-1:0] mybus = yourbus + delta; .... endmodule These parameters can be overridden each time the module is instantiated using a list of expressions (here numbers are used) inside parenthesis and starting with a hash sign. The overrides are applied to the parameters in the textual order they are defined in the module, which in the example, is bussize, fred, delta. MOD1 #(11, 4, 5) the_mod1 (..... );Not all the parameters are overridden if the list of overrides is shorter than number of parameters.
TasksThe Verilog task system is supported for synthesis by CV2.100. Tasks must be non-recursive. Task definitions occur inside a module definition after the declaration of any free parameters, wires, regs, events and other identifiers which are referenced inside the task. The syntax of a task definitions is task < name> ; < declarative-items>* < behav-statement> endtaskwhere the declarative items are restricted to input, output, inout, net, reg, integer and parameter declarations. Owing to the vagueries of Verilog syntax, unlike a module, the task does not have a signature in parenthesis. Arguments must be passed to it in the order of the declaration statments in the task definition. There is no semicolon after an endtask . Here is an example module TEST(); reg a, freev; wire [2:0] b; task andingtask; output x; input [2:0] d; x = (&(d)) | freev; endtask always @(posedge clk) andingtask(a, b); endmoduleNote that the task has scope of the enclosing module and is able to make access to the local signals of the module, such as freev in the example, much like free variables in Pascal or Modula. Functions callsFunction calls are supported in CV2.100 but nor described in this version of the manual.
Asynchronous Resets and Clock EnablesThe D-type flip-flops generated by CV2.100 have the following signature and possible implementation. module DFF(q, d, c_enable, a_reset); input d, c_enable, a_reset; output q; reg q; always @(posedge clk or posedge a_reset) if (a_reset) q = 0; else if (c_enable) q = d; endmoduleContrarywise, synthesis of the above Verilog will result in one flip-flop, but whether the clock-enable input is actually used depends on compiler heuristics and surrounding context. Here is an example of behavioural Verilog which CV2.100 will compile into flip-flops with asynchronous resets (for z0 ) and presets (for z1 ). Asynchronous presets are actually achieved with the same DFF leaf flip-flop and with inversion applied to the d input and q output. reg [1:0] z0, z1; always @(posedge r or negedge clk) begin z0 = (r) ? 0 : d; z1 = 1; if (r == 0) z1 = d; end CV2.100 may not always spot that it can use an asynchronous reset to achieve a logic function and will stop with an error message. In these circumstances, simplify the logic that is assigned so that the division is easier for the compiler or else instantiate flip-flops structurally. Here is a 3 bit binary counter with asynchronous reset. // 3 bit binary counter with asynchronous reset module CTR3(q, ck, clear); input ck; output [2:0] q; reg [2:0] q; input clear; wire [2:0] e_d = q + 3'd1; DFF_AR ctr0(.q(q[0]), .d(e_d[0]), .ar(clear), .ck(ck)); DFF_AR ctr1(.q(q[1]), .d(e_d[1]), .ar(clear), .ck(ck)); DFF_AR ctr2(.q(q[2]), .d(e_d[2]), .ar(clear), .ck(ck)); endmodule And here is the source for the same using behavioural reset synthesis. module CTR3(q, ck, clear); input ck; output [2:0] q; reg [2:0] q; input clear; always @(posedge ck or posedge clear) q = (clear) ? 0 : q + 3'd1; endmodule
Primitive ModulesCV2.100 allows certain modules to be flagged as primitive. Primitive modules may be included by the user in his main source or in libraries. The purpose of a primitive module is to provided a prototype for a component or subcircuit which is to be later substituted for an alternative implementation. The alternative implementation may be an abstract simulation model that cannot be passed to CV2.100 (e.g. because it is written in C) or it might be a leaf module in the target technology library, such as a gate, pad or macrocell. The compiler does not examine the bodies of primitive modules, except for input , output or inout port specification statements, and it does not include primitive module definitions in the output netlist. There are three approved ways of marking that a module definition is a primitive prototype. The first is to use the keyword `primitive' instead of `module'. For example: primitive MYAND2(o, x, y); input x, y; output o; // The body is ignored and may be absent // in a primitive module endprimitive The second way is similar, but uses the preprocessor instead `celldefine module MYAND2(o, x, y); input x, y; output o; // The body is ignored and may be absent // in a primitive module endmodule `endcelldefine The third way it to place primitives in their own file and include this file on the command line (or contents of the -f file) after the -libs separator. Unflagged modules in such files will be treated as primitives. The -tech technology library is also treated in this way. CV2.100 also supports the non-standard methods of defining primitive modules used in the older CV2.18, which include `primitive everything' and `primitive module(...);'.
Verilog PreprocessorVerilog tools, such as CV2.100, include a preprocessor which is similar to the preprocessor defined for the C language. The following preprocessor commands are handled by CV2.100.
MacrosThe define macro allows replacement of text with other text, for instance `define red 1 `define amber 2 `define green (`red+`amber)introduces three identifiers whose scope is from their point of definition onwards, through all other subsequent files. The backquote must be given before the macro name at the point of macro expansion. The definition of `green' uses the fact that `red' and `amber' have been defined already. Macros may be defined from the command line with the -D or +define+ flags. The macro `SYNTHESIS' is defined by default in CV2.100.
Textual InclusionThe include preprocessor command takes as an argument a file name (which must be in one of the directories on the CVPATH) and textually inserts it in the source file. Includes may be nested. Example of use:`include mylibrary.cv
Conditional CompilationThe if , ifdef and ifndef macro commands turn on and off processing of the following text, up to an endif . There is also an else command. The if command takes an argument which must be `1' or `0' (after macro expansion) and processing continues if it is a 1. The other two look up the given argument in the list of defined macros and proceed with processing if or if not respectively the macro is defined. Ifs may be nested. `ifdef synthesis ... lines included if defined `else ... lines included if not defined `endif
Default nettypeThe directive default_nettype wire causes subsequent undefined net names to become automatically defined as type wire (or whatever else is specified) when encountered having not been declared. `default_nettype wire
Ignored MacrosThe timescale macro, used during simulation, may be present, but is ignored by CV2.100.CV2.100 Installation and InvocationThe CV2.100-V2 system consists of the executable binary file `cv3core' and several library files. The directory containing the binary file must be on the PATH. In unix systems, a soft link to cv3core called cv2.100 should also be on the PATH. The CVPATH is an environment variable which defines a search path for Verilog source files. It is a colon-separated list of directories. This list should normally include the current directory (dot), the CV2.100 library directory, and other technology and project specific libraries. The cv100gates.cv file should be on the CVPATH somewhere. The CVMETAPATH is an environment variable which defines a search path for system files needed by CV2.100. These include a license and a the .sml metalanguage files. No license is needed for CV2.100 for any user, whether commercial or academic. However, a license file called LICENSE.cv3 needs to be on the CVMETAPATH and the evaluation license will do for now. CV2.100 Command line argumentsCV2.100 is run with the following command cv2.100 [ options ] filename [ filename ... ] [ -libs filename [ filename ... ]]CV2.100 takes a list of one or more source files. Nothing is inferred from order of them, except for those that come before and after the -libs separator and the contents of all of the files are essentially concatenated during internal processing. The source files must either be in the current directory or in one of the directories given by the shell variable CVPATH. The CV2.100 program expects Verilog source files to have the suffix `.cv' and will try to append such a suffix, unless the user-supplied filename already has a dot in it. As well as the files that you specify, CV2.100 also reads a technology library specified using the -tech command line argument. This library defines the gates which the compiler will use in its synthesised logic and other leaf cells which are required for certain technologies, such as IO pads etc.. If the -tech command line argument is omitted, the standard library file `cvgates' will be used. This contains a set of unit delay `vanilla' gates. The library file must be on the CVPATH. The source files must contain a Verilog module whose name is supplied in the -root command line option and also all modules structurally instantiated by the root and its instantiated modules. Any other module not used but present in the source files are checked for correct syntax by the compiler, but not processed otherwise.
Root command line optionThe command line option-root < modname>must refer to the top level module that you wish synthesised. The arg string `modname' refers to the name of the module. All leaf modules required for this module must be found on the CVPATH and will be cross checked for contact rules. The -I command line optionThe -I option allows a string to be specified which overrides the (or any) CVPATH environment variable. The string may either be the next command line argument or else directly after the -I as part of the same textual argument.
Warn command line optionIf the -warn option is given, missing modules will cause only a warning, allowing partial checking to be done.
Libraries command line separatorThe token -libs may occur on the command line and it has the effect of making all of the contents of all of the Verilog source files listed after the -libs separator primitive. This is useful if the simulation models of library components are going to be used only for their signatures during compile.
Compile-only command line optionThe -c command line option disables most of the compiler and enables it to be used as quick source file syntax checker.
Macro define command line optionThe -Dname command line option causes `name' to defined as a macro, so that `ifdef name will succeed. The alternative form +define+name exists for users of Synopsys. Both forms can follow the name with an equals sign and a value to define the macro as. For example +define+myname=david . Delay specification command line optionsThe -mind and -maxd command line flags control selection of the speed variation fields in the Verilog souce code. For instance, a builtin AND gate or equivalent continuous assign can have its speed set using the following syntax: and #(12:15:19) (y0, a1, a2); assign #(12:15:19) y0 = a1 & a2; In the example, the default delay of 15 nanoseconds is overridden with the command line flags to either 12 or 19. Parameter overrides can be processed in the same form, where a single override expression is replaced with a set of three with colons between. Output format command line optionsThe -vnl command line causes the output from the compiler to be a Verilog netlist. A Verilog Netlist contains module definitions where the modules contain only wire definitions and instances of other more primitive modules. The -mlout command line causes the output from the compiler to be a ML parse tree. The -mlin command line causes the output from the compiler to be a ML parse tree, but the output is generated before any compilation is performed, so is semantically identical to the input source code.
Arg file command line optionsThe -f < filename> causes a file to be opened from which commands are read as though on the command line. The -files causes the file called "files" to be opened from which commands are read as though on the command line. The commands can be split over many lines, with all whitespace characters counting as delimiters. The file must lie in the current directory or a full path name given.
Verbose command line optionThe -verbose command line option causes the compiler to augment certain error messages with additional information. This is useful if an error is hard to understand.
Output file name optionThe -o < filename> option enables the output file name to be specified for synthesised netlists. The default is the standard output.
Listmods command line optionThe -listmods option causes the compiler to print a list of the modules that have been defined in the set of input files. Technology Libraries (and other filesCV2.100 takes a technology library using the -tech < techfn> command line flag. This has very little effect on the operation of CV2.100, but is a useful way to read in standard pads and other instantiatable modules. The currently available technology libraries are: xi4000, xi3000 and cv100gates. The CV2.100 compiler generates these gates: BUF MUX2 AND2 OR2 INV XOR2 DFF CVLATCH. These must be present in all technology libraries used with CV2.100. They must have the following signatures. CVMUX2(o, a, b, c); // Two input multiplexor DFF(q, d, ck, ce, ar, spare); // D-type edge tiggered FF CVLATCH(q, d, g, ar); // Transparent latch XOR2(o, i1,i2); // Binary xor gate AND2(o, i1,i2); // Binary an gate BUFIF1(out, in, enable); // Tristate buffer,active high enable OR2(o, i1,i2); // Binary or gate BUF(o, i); // Non-inverting buffer INV(o, i); // Invertor The compiler also generates multipliers, adders and subtractors and RAMs as described in the next section. CV2.100 can also output any other gate or module provided that it is structurally instantiated in the source file and a Verilog primitive prototype is provided in a library. Use of Macro Block GenerationCV2 will generate macro blocks instances under certain circumstances. The blocks generated are RAMs, ROMs, adders and multipliers. Array RAMsCV2.100 will map arrays larger than `minarraysize' to memories. The value of minarraysize is given on the commandline. Currently, CV2.100 will generate only simple, singled ported RAMs, but future versions of CV2.100 will generate more complex arbiters for the ports and instances of multi-port RAMs. A typical RAM needed by CV2.100 at the moment is: module SSRAM32768x8(y, clk, a, cen, d); input [7:0] d; output [7:0] y; input clk, cen; input [14:0] a; reg [7:0] mem [32767:0]; always @(posedge clk) if (cen) mem[a] = d; assign y = mem[a]; endmodule
Verilog Scalar outputScalar Verilog is the opposite to a net list. There are no component instances, only behavioural expressions. To use this, all leaf components must contain a Verilog behavioural model. CV2.100 has a pair of command line arguments which enable this form of output -scalar -dontbuild TODO define. A collection of examplesHere are some simple Verilog examples. The modules called SIMSYS are not designed for synthesis, but are test wrappers which can be used to simulate the Verilog example either before or after synthesis. First.cv - A 4 bit counter// first.cv // A divide by 16 counter with an exciting output. module CTR16(ck, o); input ck; output o; reg [3:0] count; always @(posedge ck) begin // Add a four bit decimal value of one to count count <= count + 4'd1; if (count == 14) count <= 1; end // Note ^ is exclusive or operator assign o = count[3] ^ count[1]; endmodule // Top level simulation model module SIMSYS(); wire ck; wire boo; CLK10MHz clock(ck); CTR16 counter(ck, boo); endmodule // end of first.cv SPDIF GeneratorHere is an example module which generates a digital SP-DIF bit stream equivalent to that found in many CD players and so on. // daudio.cv module CDSRC(sds, aclk, adata); input aclk; // audio clock output sds; // side select output adata;// audio data bit stream wire clk = aclk; reg [4:0] phase; reg [15:0] audio_data; reg sds, adata; always @(posedge clk) begin if (phase == 19) begin // This value may vary from one cd to another phase <= 0; end else phase <= phase + 1; if (phase == 15) begin // The `sound' is just a count sequence generated here audio_data <= audio_data + 16'h0201; sds <= ~sds; end end always @(posedge clk) if (phase < 16) adata <= audio_data[phase]; else adata <= 0; endmodule HDB3 coder and decoderHere is a decoder for the HDB3 line code used in European trunk PDH telehone systems. // cbg HDB3DEC module HDB3DEC(ck, rxpos, rxneg, dout); input ck; // Clock input input rxpos; // Positive pulse input input rxneg; // Negative pulse input output dout; // Decoded data out reg R_a, R_b, R_c, R_pol; wire ab = rxpos | rxneg; wire delta = rxpos ^ R_pol; wire mark = ab & delta; // This signal is not brought out, but could be to raise alarm. wire violation = ab & ~delta; always @(posedge ck) begin R_c <= mark; R_b <= R_c; R_a <= R_b; R_pol <= (~ab & R_pol) | (ab & rxpos); end assign dout = R_a & ~violation; endmodule // cbg HDB3DEC Here is the associated HDB3 encoder. module HDB3ENC (ck, din, txpos, txneg); input ck, din; // Input clock and data output txpos, txneg; // Output positive and negative pair reg R_a, R_b, R_c, R_d; reg [1:0] R_ct; reg R_apout, R_amout; reg R_pol, R_lastv; wire firstof4, viol_needed, mark; assign viol_needed = (R_ct == 2'b11) & ~R_a; always @(posedge ck) begin // Input data shifted into four bit register. R_a <= R_b; R_b <= R_c; R_c <= R_d; R_d <= din; // Counter of number of zeros, reset on ones. R_ct <= (R_a) ? 2'b00 : R_ct + 2'1; // Polarity reverses on bona-fida marks; R_pol <= R_pol ^ mark; // Save polarity of last violation R_lastv <= (viol_needed) ? ~R_pol : R_lastv; end // This is the magic rule defined in the spec. assign mark = R_a | (firstof4 & (R_lastv ^ R_pol)); // Detect first zero of a group of 4. assign firstof4 = ~R_a & ~R_b & ~R_c & ~R_d & (R_ct == 2'b00); // Generate the two outputs and register them. always @(posedge ck) begin R_apout <= ((mark & R_pol) | (viol_needed & ~R_pol)); R_amout <= ((mark & ~R_pol) | (viol_needed & R_pol)); end assign txpos = R_apout; assign txneg = R_amout; Traffic light controllerHere is an example traffic light controller which uses the case statement and some simple macros. // Traffic light controller `define red 1 `define amber 2 `define green 4 module TRAFFIC_LIGHTS(clk, lights); input clk; output [2:0] lights; reg [2:0] lights; reg [1:0] phase; always @(posedge clk) begin case (phase) 0 : lights = `red; 1 : lights = `red + `amber; 2 : lights = `green; 3 : lights = `amber; endcase phase = phase + 1; end endmodule /* TRAFFIC_LIGHTS */ module SIMSYS(); wire clk; wire [2:0] lights; CLK1MHz clk(clk); TRAFFIC_LIGHTS traffic_lights(clk, lights); endmodule Generation of Xilinx or other FPGAs from VerilogPlease see the separate document CV2 FOR FPGA .
CV2.100 Restrictions and ExtensionsMulti-symbol preprocessor macros are not supported by current CV2.100. The drive strength and delay qualifiers of a full Verilog continuous assignment are ignored by CV2.100. Disable, specify, named blocks and functions are not supported by CV2.100-V2.15. Procedure continuous assignment is not supported. Global events and trigger with `->' is not supported. User defined primitives with transition tables are not supported. |