Standard Compliance
Table of Contents
1 Summary of Unsupported IEEE Std 1364 Features
2.3.1.1 Simple Decimal Numbers
2.5.3 System Tasks and Functions
3.2 Nets, Variables, Named Events
3.2.2 Charge Strength - not supported
3.4.2 Specify Parameters – not supported
4.1.1 Arithmetic Left Shift Operator
4.2.1 Vector Bit/Part-Select Addressing
4.3 Minimum, typical, and maximum delay expressions – not supported
4.4 Controlling the sign of an expression
4.5 Evaluation Order of an Expression
5.5 Scheduling Implication of Assignments
5.5.1 Switch Processing – not supported
8 Switch Level Modeling – not supported
9 User-Defined Primitives (UDPs) - not supported
10.1 Conditional Statement (if-else)
10.4 Procedural Timing Controls
10.4.3 Named Events and Event or Operator
10.4.4 Level-Sensitive Event Control
10.4.5 Intra-Assignment Timing Controls
10.5.1 Parallel (fork-join) Blocks
11.4 Returning a Value from a Function
11.5 Use of Constant Functions
12 Disabling of Named Blocks and Tasks
13.1.3 Generated Instantiation
13.1.3.1 genvar - generate statement index variable
13.2 Overriding Module Parameter Values
13.2.2 Parameter Value Assignment by Ordered List
13.3.2 Port Specification/Binding
13.3.3 Connecting Module Instance Ports by Ordered List
13.3.4 Real Numbers in Port Connections
13.3.6 Connecting Dissimilar Data Types at Ports - not supported
13.3.7 Connecting Signed Values via Ports
14 Configuring the Contents of a Design – not supported
15 Specify Blocks – not supported
16 Timing Checks – not supported
17 Backannotation Using SDF – not supported
18.2 File Input-Output System Tasks and Functions
18.4 Simulation Control System Tasks
18.5 PLA Modeling System Tasks – not supported
18.6 Stochastic Analysis Tasks
18.7 Simulation Time System Functions
18.9 Probabilistic Distribution Functions
The IEEE Std 1364-2001 (the standard) is the latest Verilog standard CvSDL supports. The list below summarizes all the standard features that are not supported by the CvSDL simulator and/or the Verilog to CvSDL translator.
Switch level features such as charge strength, trireg, CMOS switches, etc. are not supported.
The vectored and scalared keywords and their associated features are not supported.
Wired-logic nets are not supported as array elements.
Delays are parsed and reduced to single delay quantities by averaging constituent delay numbers.
Ambiguous signal strength and the strength range notation in the format string for the display system tasks are not supported.
User-defined primitives (UDPs) are not supported.
Procedural continuous assignments are not supported.
Design configuration features are not supported.
Specify blocks, specify timing check and SDF features are not supported.
PLA modeling system tasks are not supported.
Extended VCD format is not supported.
The following compiler directives are ignored: `celldefine, `endcelldefine, `default_nettype, `resetall, `line, `unconnected_drive and `nounconnected_drive.
PLI (TF/ACC/VPI) is not supported.
Note that there are some features that are supported but not working in the current version of CvSDL, and that some in the above list may be supported in the future. Also that a Verilog feature is not natively supported by CvSDL does not necessarily mean that the feature is not supported. For example, CvSDL does not support declaration-assignments except for parameters, but the translator splits such a declaration-assignment as two separate CvSDL statements.
The sections that follow detail the syntactical differences between the standard and CvSDL.
Verilog white spaces are blank spaces, tabs, new lines and formfeeds. CvSDL uses isspace() to detect white spaces.
One-line comments (//) and block comments ( /* ... */) are supported. Note that Verilog does not allow block comments to be nested.
A simple Verilog decimal number is an unsigned number with zero or more underscore characters '_' inserted anywhere except at the beginning and optionally preceded by a + or – operator. The simple decimal numbers are treated as signed integers.
To use them in CvSDL, enclose them in double quotes, “”. You can also use C++ integer, int, without double quotes. C++ unsigned integer types are not supported.
|
Example: Simple decimal numbers |
|
|---|---|
|
Verilog |
CvSDL |
|
-55 |
“-55” |
CvSDL uses a 32-bit vector to represent a simple decimal number. If a constant does not fit in a 32-bit vector, the contents of the vector would be unknown.
CvSDL supports Verilog sized constants fully but they must be enclosed by double quotes. If the most significant bit of an unsized unsigned constant is x or z, the value is extended to the size of the expression that contains the constant (a Verilog-2001, not Verilog-95, rule).
|
Example: No size given |
|
|---|---|
|
Verilog |
CvSDL |
|
'hx_456_ |
“'hx_456_” |
|
Example: Size given |
|
|---|---|
|
Verilog |
CvSDL |
|
1_024 'h x_ffff |
“1_024 'h x_ffff” |
Verilog real constants are fully supported but they must be enclosed in double quotes; if you do not need to use the underscore characters '_', you can also use C++ double constants without double quotes.
|
Example: Real constants |
|
|---|---|
|
Verilog |
CvSDL |
|
-7_34.555_876_e-9 |
“-7_34.555_876_e-9” |
Note that there are a few syntactical differences between Verilog and C++ double constants. For example, .12 is illegal in Verilog but it is legal in C++. You can use any legal C++ double constants with or with double quotes. Assigning a real to an integer variable will round the real to the nearest integer.
Verilog string constants are not 0-terminated strings, but C++ 0-terminated strings can in general be used where string constants are desired. When you need to embed '\0' in a string, you need to use a sized string constant format (not a Verilog construct) that specifies the exact number of bits, which should be a multiple of 8, followed by 'sa, 'sA, 'Sa or 'SA, and finally by the desired array of characters. Strings are treated as unsigned integer. Special characters allowed in strings are \n, \t, \\, \", and the octal escape sequence \ddd. Do not use other special characters allowed in C++ to be compatible with Verilog. If the string you desire looks like a sized constant number, precede it with 'a or 'A.
|
Example: String constants |
|
|---|---|
|
Verilog |
CvSDL |
|
“Hello world!” |
“Hello world!” |
CvSDL requires variables to be declared as module (class/struct) members and then to be specified in terms of variable types and other attributes in the module constructor. When you specify a variable you also need to give the instance name (a 0-terminated C++ string) for the variable. The instance names, not the variable names, correspond to the Verilog variable names.
|
Example: Variable declaration and specification |
|
|---|---|
|
Verilog |
CvSDL |
|
my_module(...); |
struct my_module : TCvModule |
Escaped identifiers require two backslash characters (\\) in CvSDL and they are not considered to be part of the identifiers. For example, “\\net$123” and “net$123” are considered the same name as in Verilog.
|
Example: Identifiers |
|
|---|---|
|
Verilog |
CvSDL |
|
r_data |
“r_data” |
Generated identifiers are also supported, but you have to manually specify how to generate the names in generate loops to match Verilog generated identifiers.
Note that, though the Verilog identifiers can be as long as 1024 characters and C++ does not impose any length limit, other tools such as assemblers and linkers may impose shorter limitations. CvSDL does not check the length of instance names.
The table below summarizes all the Verilog-2001 keywords and corresponding CvSDL keywords/others. The entry '-' means there is no corresponding keyword. All the CvSDL keywords are explained in subsequent sections.
Note that the C++ keywords are also reserve.
|
Verilog |
CvSDL |
Verilog |
CvSDL |
|---|---|---|---|
|
always |
always |
and |
CV_GATE_AND |
|
assign |
- |
automatic |
- |
|
begin |
{ |
buf |
CV_GATE_BUF |
|
bufif0 |
CV_GATE_BUFIF0 |
bufif1 |
CV_GATE_BUFIF1 |
|
case |
casev |
- |
case_item |
|
casex |
casex |
casez |
casez |
|
cell |
|
cmos |
- |
|
config |
- |
- |
- |
|
deassign |
- |
default |
case_default |
|
defparam |
|
design |
- |
|
disable |
break |
- |
- |
|
edge |
- |
else |
else |
|
end |
} |
endcase |
endcase |
|
endconfig |
- |
endfunction |
} |
|
endgenerate |
} |
endmodule |
} |
|
endprimitive |
- |
endspecify |
- |
|
endtable |
- |
endtask |
} |
|
event |
event |
- |
- |
|
for |
for |
force |
- |
|
forever |
while (1) |
fork |
- |
|
function |
- |
- |
- |
|
generate |
- |
genvar |
- |
|
highz0 |
CV_STR_HIGHZ |
highz1 |
CV_STR_HIGHZ |
|
if |
if |
ifnone |
- |
|
incdir |
- |
include |
- |
|
initial |
initial |
inout |
inout |
|
input |
input |
instance |
instance* |
|
integer |
integer |
- |
- |
|
join |
- |
- |
- |
|
large |
- |
liblist |
- |
|
library |
- |
localparam |
localparam |
|
macromodule |
struct (class) |
medium |
- |
|
module |
struct (class) |
- |
- |
|
nand |
CV_GATE_NAND |
negedge |
negedge |
|
nmos |
- |
nor |
CV_GATE_NOR |
|
noshowcancelled |
- |
not |
CV_GATE_NOT |
|
notif0 |
CV_GATE_NOTIF0 |
notif1 |
CV_GATE_NOTIF1 |
|
or |
, |
output |
output |
|
parameter |
parameter |
pmos |
- |
|
posedge |
posedge |
primitive |
- |
|
pull0 |
|
pull1 |
|
|
pulldown |
CV_GATE_PULLDOWN |
pullup |
CV_GATE_PULLUP |
|
pulsestyle_onevent |
- |
pulsestyle_ondetect |
- |
|
rcmos |
- |
real |
real |
|
realtime |
realtime |
reg |
reg |
|
release |
- |
repeat |
for(;;) |
|
rnmos |
- |
rpmos |
- |
|
rtran |
- |
rtranif0 |
- |
|
rtranif1 |
- |
- |
- |
|
scalared |
- |
showcancelled |
- |
|
signed |
|
small |
|
|
specify |
- |
specparam |
- |
|
strong0 |
|
strong1 |
|
|
supply0 |
supply0 |
supply1 |
supply1 |
|
supply0 |
CV_STR_SUPPLY0 |
supply1 |
CV_STR_SUPPLY1 |
|
table |
- |
task |
- |
|
time |
time |
tran |
- |
|
tranif0 |
- |
tranif1 |
- |
|
tri |
tri |
tri0 |
- |
|
tri1 |
- |
triand |
wand |
|
trior |
wor |
trireg |
- |
|
unsigned |
|
use |
- |
|
vectored |
- |
- |
- |
|
wait |
wait |
wand |
wand |
|
weak0 |
|
weak1 |
|
|
while |
while |
wire |
wire |
|
wor |
wor |
- |
- |
|
xnor |
CV_GATE_XNOR |
xor |
CV_GATE_XOR |
The dollar sign ($) that starts a Verilog system task/function name is replaced by the three character sequence, cv_. For example $display() becomes cv_display().
Many of Verilog compiler directives have equivalent directives in C++.
|
Verilog |
CvSDL |
|---|---|
|
‘celldefine |
- |
|
‘endcelldefine |
- |
|
‘default_nettype |
- |
|
‘define |
#define |
|
‘undef |
#undef |
|
‘ifdef |
#ifdef |
|
‘else |
#else |
|
‘elsif |
#elif |
|
‘endif |
#endif |
|
‘ifndef |
#ifndef |
|
‘include |
#include |
|
‘resetall |
- |
|
‘line |
|
|
‘timescale |
cv_timescale() |
|
‘unconnected_drive |
- |
|
‘nounconnected_drive |
- |
Verilog attributes should be embedded in block comments (/**/).
For example, /*(* full_case=1, parallel_case=1 *)*/.
CvSDL does not make use of them; however, they are recognized during CvSDL-to-Verilog translation.
The two Verilog data types are both supported; 4-value logic (0,1,x,z) and real. When a real number is converted to a logic number, the real number is rounded, not truncated, to the nearest whole number per Verilog. When a logic value is converted to a real number, any x or z bits are treated as 0. No overflow check is done.
TCvVar variables that are declared in module definitions must be specified in their constructors in CvSDL. Verilog net types (wire, tri, wand, and wor), variable types (reg, integer, real, time, and realtime), and named events are supported. The Verilog types, tri1, tri0 and trireg types are not supported.
The table below summarizes the Verilog net and variable types and CvSDL TCvVar member functions you call to specify types in CvSDL with examples.
|
Verilog |
CvSDL |
Initial Value |
||
|---|---|---|---|---|
|
Type |
Example |
Specification |
Example |
|
|
wire |
wire [31:0] d; |
.wire() |
d.wire(“d”, 31,0); |
z |
|
wire signed |
wire signed [0:7] sq; |
.wire_signed() |
sq.wire_signed(“sq”,0,7); |
z |
|
tri |
tri [31:0] a; |
.tri() |
a.tri(“a”, 31,0); |
z |
|
tri signed |
tri signed sa; |
.tri_signed() |
sa.tri_signed(“sa”); |
z |
|
wand |
wand [31:0] wa0; |
.wand() |
wa0.wand(“wa0”,31,0); |
z |
|
wand signed |
wand signed swa1; |
.wand_signed() |
swa1.wand_signed(“swa1”); |
z |
|
wor |
wor [3:0] d_wor; |
.wor() |
d_wor.wor(“d_wor”,3,0); |
z |
|
wor signed |
wor signed sc_wor; |
.wor_signed() |
sc_wor.wor_signed(“sc_or”); |
z |
|
supply0 |
supply0 [3:0] g0; |
.supply0() |
g0.supply0(“g”,3,0); |
z |
|
supply0 signed |
supply0 signed sg0; |
.supply0_signed() |
sg0.supply0_signed(“sg0”); |
z |
|
supply1 |
supply1 v0; |
.supply1() |
v0.supply1(“v0”); |
z |
|
supply1 signed |
supply1 signed sv0; |
.supply1_signed() |
sv0.supply1_signed(“sv0”); |
z |
|
tri1 |
- |
- |
- |
- |
|
tri0 |
- |
- |
- |
- |
|
trireg |
- |
- |
- |
- |
|
reg |
reg a; |
.reg() |
a.reg(“a”); |
x |
|
reg signed |
reg signed [15:0] sd; |
.reg_signed() |
sd.reg_signed(“sd”, 15, 0); |
x |
|
integer |
integer fp; |
.integer() |
fp.integer(“fp”); |
x |
|
real |
real ex; |
.real() |
ex.real(“ex”); |
0.0 |
|
time |
time t0; |
.time() |
t0.time(“t0”); |
x |
|
realtime |
realtime tr1; |
.realtime() |
tr1.realtime(“tr1”); |
0.0 |
|
event |
event e1; |
.event() |
e1.event(“e1”); |
- |
Note that in Verilog the pairs, wire and tri, wand and triand, wor and trior, and real and realtime, are synonymous to each other.
The following Verilog features are not supported:
implicit declarations
vectored/scalared keywords
net declaration assignments
The maximum vector length is 65535 bits in CvSDL.
The drive strengths are fixed at strong levels for assignments and variable specifications. Multiple drive strengths are supported for primitive gates and pulls.
Each TCvVar variable declared in a module definition needs to be specified in terms of its actual (Verilog-compatible) type in the constructor by calling one of the type-specifying member functions:
|
Synopsis |
Example |
|---|---|
|
va-spec: identifier .
spec-func ( instance-name
) ; spec-func: one of wire_signed tri_signed wand_signed wor_signed supply0_signed supply1_signed reg_signed integer time real realtime range: |
a.wire(“a”); addr.tri(“addr”, 63,
8); d1.real(“d1”); t3.time(“t3”);
// in Verilog they would be wire a; // scalar net tri [63:8] addr; reg [31:0] data; // signed reg integer n; real d1; time t3; |
Both the msb and lsb must be constant expressions that resolve to integer quantities. They can be negative. If msb>lsb then the variable is little-endian; otherwise it is big-endian. The range applies only to the net (wire, tri, wand, and wor) and reg types.
The time variables are implemented as 64-bit unsigned vectors in the little-endian format with the lsb set to 0.
There are two ways to create array variables in CvSDL.
You can create arrays using the C++ array creation mechanism:
|
Declaring Array Variables |
Example |
|---|---|
|
// in module definition |
// in constructor {
my_array.reg(cv_sprintf(“my_array_%d”,i),7,0); |
Note the arrays created this way are translated into individual variables in Verilog.
The other way is to declare a TCvVar variable and specify it to be an array:
|
Synopsis |
Example |
|---|---|
|
array-specification: range: |
cv_array<1>(bus.wire(“bus”,3,0), 15,0); cv_array<1>(M.reg(“M”,7,0), 0, 255); cv_array<2>(d_int.integer(“d_int”), 0,63,0,63); cv_array(d_int.integer(“d_int”),(TCvVar( 0),TCvVar(63),TCvVar(0),TCvVar(63)); // in Verilog they would be wire [3:0] bus [15:0]; reg [7:0] M [0:255]; integer d_int [0:63][0:63]; |
The specification uses a function template. The template requires the array dimension, dim, that can be up to 15. The range values, lhv and rhv, must be integer constants and can be negative. There must be as many ranges as the array dimension.
The following data types are currently not supported as array element types, tri, wand, wor, tri0, tri1, and trireg.
A TCvVar variable declared in a module definition can be specified as a parameter or local parameter by calling one of the (local) parameter specification functions in the constructor. These functions are TCvVar member functions.
|
Synopsis |
Example |
|---|---|
|
parameter-specification: param-type (
name,
const-expr ) ; local-parameter-specification: lparm-type
( name, expr ) ; |
WIDTH.param(“WIDTH”,16);
// in Verilog they would be parameter WIDTH = 16; parameter signed [7:0] OP=WIDTH>>2; parameter TYPE=”ADD”; |
CvSDL is C++ and therefore C++ name spaces apply to all of CvSDL names. In addition the instance names given to CvSDL design objects are subject to the Verilog name spaces if the design should be translated to Verilog. Verilog name spaces are:
definition name space – module, macromodule and primitive names (global)
text macro name space – compiler directive defines (global)
block name space – names within each of named blocks, functions, and tasks
module name space – names within each of modules, macromodules, and primitives
port name space – port names per each of modules, macromodules, primitives, functions and tasks (overlapping the module/block name spaces)
specify block name space – not supported
attribute name space – names within attributes
|
Operators |
Description |
for real/realtime |
CvSDL |
|---|---|---|---|
|
unary +, - |
Unary operators |
supported |
+e1 |
|
{} {{}} |
Concatenation replication |
- |
( e1 , e2 , ... ) |
|
+ - * / ** |
Arithmetic |
supported |
e1 + e2 |
|
% |
Modulus |
- |
e1 % e2 |
|
> >= < <= |
Relational |
supported |
e1 > e2 |
|
! |
Logical negation |
supported |
! e1 |
|
&& |
Logical and |
supported |
e1 && e2 |
|
|| |
Logical or |
supported |
e1 || e2 |
|
== |
Logical equality |
supported |
e1 == e2 |
|
!= |
Logical inequality |
supported |
e1 != e2 |
|
=== |
Case equality |
- |
case_equ(e1, e2) |
|
!== |
Case inequality |
- |
case_neq(e1, e2) |
|
~ |
Bit-wise negation |
- |
~e1 |
|
& |
Bit-wise and |
- |
e1 & e2 |
|
| |
Bit-wise inclusive or |
- |
e1 | e2 |
|
^ |
Bit-wise exclusive or |
- |
e1^ e2 |
|
^~ or ~^ |
Bit-wise equivalence |
- |
bw_xnor(e1, e2) |
|
& |
Reduction and |
- |
operand.r_and() |
|
~& |
Reduction nand |
- |
operand.r_nand() |
|
| |
Reduction or |
- |
operand.r_or() |
|
~| |
Reduction nor |
- |
operand.r_nor() |
|
^ |
Reduction xor |
- |
operand.r_xor() |
|
~^ or ^~ |
Reduction xnor |
- |
operand.r_xnor() |
|
<< |
Logical left shift |
- |
e1<<e2 |
|
>> |
Logical right shift |
- |
e1>>e2 |
|
<<< |
Arithmetic left shift |
- |
e1<<e2 |
|
>>> |
Arithmetic right shift |
- |
asr(e1, e2) |
|
? : |
Conditional |
supported |
cv_cond(e1,e2, e3) |
|
or , |
Event or |
supported |
( e1,e2, ... ) |
The arithmetic left shift operator in CvSDL is the same as logical left shift operator.
The Verilog conditional operator evaluates differently from the C++ conditional operator when the first expression e1 results in x or z and/or the sizes of e2 and e3 are different. The CvSDL function, cv_cond(), supports the Verilog conditional.
|
Verilog |
CvSDL |
|---|---|
|
conditional-expression: e1 ? e2 : e3 |
cv_cond ( e1 , e2 , e3 ) |
A valid CvSDL (and Verilog) operand is one of the following:
Number
Variable (a module or temporary variable excluding events)
Bit-select or part-select of a logic variable
Array element
Function call that returns any of the above
A concatenation of above operands is also treated as an operand.
There are one bit selection and three part selection mechanisms in Verilog-2001:
|
Verilog |
CvSDL |
|---|---|
|
vector [ expr ] vector [ const-msb : const-lsb ] vector [ base-expr +: const-width ] vector [ base-expr -: const-width ] |
vector [ expr ] vector ( const-msb , const-lsb ) vector ( base-expr , true , const-width ) vector ( base-expr , false , const-width ) |
Array elements are addressed in the same way in Verilog and CvSDL.
|
Verilog |
CvSDL |
|---|---|
|
my_array1_[10] my_array2[128][-1] my_array3[-10][0][0] |
my_array1_[10] my_array2[128][-1] my_array3[-10][0][0] |
C++ null string (“”) can be used just as in Verilog. It is equivalent to “\0”. Note that Verilog strings are not the same as C++ 0-terminated strings and may contain '\0'. See the section on String Constants on how to embed 0s in CvSDL strings.
|
Verilog |
CvSDL |
|---|---|
|
$signed ( expr ) $unsigned ( expr ) |
cv_signed ( expr ) cv_unsigned ( expr ) |
Verilog basically requires the following steps:
determine the expression type (implicit type conversion towards larger or real type)
if the type is bit-vector/logic, determine the expression bit size
force all operands (except for self-determined) to the type and, if the type is logic, do x, z or sign extension as needed for each operand
evaluate
The CvSDL Simulator is based on the Verilog simulation reference model described in the IEEE Std 1364-2001 documentation.
A simulation cycle at time T consists of the the following steps:
Activate all inactive events (initials at time 0, delayed and callback processes) at T.
If there is an evaluation event (scheduled process), evaluate the process and schedule update events (updates of nets and variables with their values changed).
If there are update events, update all modified variables, schedule sensitive processes and go back to Step 2.
If there are (new) inactive events, go back to Step 1.
If there are nonblocking assign update events, activate all nonblocking assignments and go back to Step 3.
If there are monitor events, execute all monitor events.
If there is no more event scheduled in the future, DONE.
Advance the simulation time to the nearest future time T with a valid event.
Note that an explicit zero delay (#0 in Verilog, cv_delay(0) in CvSDL) causes the calling process to be suspended and linked to the inactive event queue.
A delta cycle may start at Step 1 or at the transition from Step 5 to Step 3 and it may end at Step 5 (that leads to Step 3) or Step 7.
Sequential execution of statements in procedural process – fully supported
Multiple nonblocking assignments in a
procedural block – supported.
If there is more than one
nonblocking assignment to a variable in a procedural process, CvSDL
schedules only the last assignment. Verilog requires that all of the
assignments be queued and executed one by one in the order that the
assignments are encountered. The consequence is that the potential
glitches for a variable that can be created in Verilog cannot be
seen in CvSDL.
Nondeterminism exists in CvSDL as in Verilog due to the unpredictable order of executing evaluation and update events. Another source of nondeterminism in Verilog, due to possible preemptive interruptions while executing behavioral statements, does not exist in CvSDL.
Race conditions are possible if you try to use the contents of a variable in one process that is being updated in another process at the same simulation time.
Verilog task and function arguments are passed by value using blocking assignments. CvSDL task and function arguments are passed by reference and therefore no blocking assignments take place unless temporary variables to receive arguments.
Net declaration assignments are not supported. Variable declaration assignments are not supported. Procedural continuous assignments are not supported.
Delays are supported for continuous assignments and procedural blocking and nonblocking assignments.
|
Assignment |
lvalue |
Assignment Operator |
|---|---|---|
|
Continuous Assignment |
Net Constant bit-select of a vector net Constant part-select of a vector net Constant indexed part select of a vector net Concatenation of any of the above |
Continuous assignment only: Use '=' in Verilog and cv_assign() in CvSDL |
|
Procedural blocking and nonblocking assignments |
Variable Bit select of a vector variable Constant part select of a vector variable Indexed part select of a vector variable Array element Concatenation of any of the above |
Blocking assignment: Use '=' in Verilog and CvSDL
Non-blocking assignment: Use '<=' in Verilog Use '<<=' in CvSDL |
|
Procedural Continuous Assignment |
- |
- |
|
Example: Assignments |
|
|---|---|
|
Verilog |
CvSDL |
|
// continuous assign en=status[3]; assign #10 cas_n=cas_r; // procedural d0 =#1 next_d0 d1 <= next_d1; |
// in constructor cv_assign(en, status[3]); cv_assign(10, cas_n, cas_r); // in processes d0 = cv_delay(1, next_d0); d1 <<= next_d1; |
All Verilog primitive gates are supported in the following syntax:
cv_gate(gate_type,
output, input);
cv_gate(gate_type,
strength_a,
strength_b, output,
input);
as summarized in the table below:
|
Verilog |
CvSDL |
Verilog |
CvSDL |
Verilog |
CvSDL |
Verilog |
CvSDL |
|---|---|---|---|---|---|---|---|
|
and |
and_gate |
xor |
xor_gate |
bufif0 |
bufif0 |
pulldown |
pulldown |
|
nand |
nand_gate |
xnor |
xnor_gate |
bufif1 |
bufif1 |
pullup |
pullup |
|
or |
or_gate |
buf |
buf_gate |
notif0 |
notif0 |
|
|
|
nor |
nor_gate |
not |
not_gate |
notif1 |
notif1 |
|
|
Arrays of primitive gates using ranges are not supported. Generate facility should be used to generate arrays of primitive gates and modules instead. Propagation delays are not supported.
Drive strengths for the enabled gates (bufif0, bufif1, notif0 and notif1) and pulldown and pullup gates are fully supported. Drive strengths for other gate types are set to the strong 0 and strong 1.
Individual gates can be instantiated as summarized below:
|
Synopsis |
Example |
|---|---|
|
gate-instantiation: |
// in constructor bufif0(“bufif0_3”, o1, in1, en); // strong 0, strong 1
// notif1(“notif1_5”, o2, in2, CV_STR_WEAK0, CV_STR_WEAK1); |
|
enable-gate: one of n-input-gate: one of xor_gate xnor_gate n-output-gate: one of |
|
|
str0: CV_STR_HIGHZ0
CV_STR_WEAK0 CV_STR_PULL0 |
|
The default drive strengths for pull gates are the weak0 and weak1. The default drive strengths for other gates are the strong 0 and strong 1.
|
Verilog |
CvSDL |
|---|---|
|
if ... else ... |
if ... else ... |
The syntactical differences for case statements between Verilog and CvSDL are:
|
Verilog |
CvSDL |
|---|---|
|
case-statement: case-type ( expr ) item { item } endcase case-type: one of item: |
case-statement: case-type ( expr ) item { item } endcase case-type: one of item: |
The keywords, casev, casez, casex, case_item and case_default, are implemented as macros.
The case_default statement is optional and, if used, must appear only once as the last item in a case statement. Note the Verilog keyword 'case' is replaced by 'casev' in CvSDL. The argument to the case expression can be a constant.
Multiple expressions for a case item allowed in Verilog are not supported by the case macros. However they can be supported by modifying the case_item macro to include multiple expressions.
|
Example: casev |
|
|---|---|
|
Verilog |
CvSDL |
|
case ( en[1:0] ) 2'b00: next_q = q; 2'b01: next_q = ~q; 2'b0x, 2'b0z: next_q = 'bx; default next_q =d; endcase |
casev ( en(1,0) ) case_item(“2'b00”) next_q = q; case_item(“2'b01”) next_q = ~q; case_item((TCvVar(“2'b0x”),TCvVar(“2'b0z”))) cv_display(“en contains x or z”); next_q = 'bx; default next_q =d; endcase |
|
Example: casez |
|
|---|---|
|
Verilog |
CvSDL |
|
casez ( sel[3:0] ) 4'b???1: data = data_a; 4'b??10: data = data_b; 4'b?100: data = data_c; default data = 32'h0; endcase |
casez (sel(3,0)) case_item(“4'b???1”) data = data_a; case_item(“4'b??10”) data = data_b; case_item(“4'b?100”) data = data_c; case_default data = 32'h0; endcase |
The syntactical differences for loops statements between Verilog and CvSDL are:
|
Verilog |
CvSDL |
|---|---|
|
forever repeat ( expr ) while for |
while (1) for (int i=0; i< expr; ++i) while for |
The delay control in CvSDL is a statement.
|
Verilog |
CvSDL |
|---|---|
|
delay-control: # delay-value # ( mintypmax_expr ) |
delay-control: cv_delay ( delay-value ) ; // statement - |
|
Example |
|
|---|---|
|
Verilog |
CvSDL |
|
#10 we=1; |
cv_delay(10); we=1; |
The event control in CvSDL is a statement. Verilog @* and @(*) are not supported. Verilog-2001 allows use of ',' in place of event 'or'.
|
Verilog |
CvSDL |
|---|---|
|
event-control: @ event-identifier @ ( event_expression ) @ * @ (*) event-expression: expression hier-identifier posedge expression negedge expression event-expression or event-expression event-expression , event-expression event-trigger: -> hier-event-identifier |
event-control: cv_at ( event-identifier ) ; cv_at ( event-expression ) ; - - event-expression: expression identifier posedge ( expression ) negedge ( expression ) event-expression , event-expression
event-trigger: trigger ( event_identifier ) |
|
Example |
|
|---|---|
|
Verilog |
CvSDL |
|
@ evnt0 count=count+1; @ (negedge clk) state=3; |
cv_at(event0); count=count+1; cv_at(negedge(clk)); state=3; |
Named events are TCvVar variables that are specified as events. Use the comma instead of the 'event or' in CvSDL.
|
Example |
|
|---|---|
|
Verilog |
CvSDL |
|
@(my_event or halt==1) ctrl=7; always @(my_event or halt==1) |
cv_at(my_event or halt==1); ctrl=7; always(process_a, (my_event, halt==1) ) ; |
The level-sensitive event control in CvSDL is a statement by itself.
|
Verilog |
CvSDL |
|---|---|
|
wait-statement: wait ( expression ) statement-or -null |
wait-statement: wait ( expression ) ; statement-or-null |
Verilog '@*' and '@(*)' are not supported in CvSDL. Only single-value delays are supported (no min:typ:max delay values).
|
Verilog |
CvSDL |
|---|---|
|
blocking-assignment: var-lvalue = delay_event? expression nonblocking-assignment: var-lvalue <= delay_event? expression delay-event: delay-control event-control repeat ( expression ) event-control |
blocking-assignment: var-lvalue = cv_delay ( delay, expression ) ; var-lvalue = cv_at ( events, expression ) ; var-lvalue = cv_rep_at ( cnt, events, expression ) ; nonblocking-assignment: var-lvalue <<= cv_delay ( delay, expression ) ; var-lvalue <<= cv_at ( events, expression ) ; var-lvalue <<= cv_rep_at ( cnt, events, expression ) ; |
|
delay-control: # delay-value # ( mintypmax-expr ) |
delay: cnt: constant-expression |
|
event-control: @ event-identifier @ ( event_expression ) @ * @ (*) |
events: event-expression ( event_expression { , event_expression } )
|
|
event-expression: expression hier-identifier posedge expression negedge expression event-expression or event-expression event-expression , event-expression |
event-expression: expression hier-identifier posedge ( expression ) negedge ( expression ) |
|
Example |
|
|---|---|
|
Verilog |
CvSDL |
|
q0 = next_q0; q1 = #1 next_q1; q2 <= next_q2; q3 <= @(e1 or posedge clk) next_q3; |
q0 = next_q0; q1 = cv_delay(1, next_q1); q2 <<= next_q2; q3 <<= cv_at( ( e1, posedge(clk) ), next_q3); |
The identifiers for Verilog named blocks are not supported except for named processes in CvSDL.
A module member function of the type
void func-name(void);
can be used as the argument to the macro initial to create a thread process that is equivalent to the Verilog initial block. The default stack size (in bytes) is specified by the constant, CV_DEFAULT_STACK_SIZE, defined in cv_types.h. If you need to change the stack size, use the macro, initial-s, instead that takes a new stack size as the second argument.
|
Verilog |
CvSDL |
|---|---|
|
initial-construct: initial statement initial block : inst_name statement end |
initial-construct: initial ( func-name ) ; initial_named ( inst-name, func-name ) ; initial_s ( func-name , stack-size ) ; |
A module member function of the type
void func-name(void);
can be used as the argument to the macro always to create a nonthread process that is equivalent to a Verilog always block of the form:
always @( event-expression )
The macro takes two arguments; the first one is the process function name and the second one is the sensitivity list.
If you need to use an indexed always process (in generate loops) you can use another macro, always_i1, that takes one integer index as an argument. The process function for the macro takes the index as the argument:
void f(int)
|
Verilog |
CvSDL |
|---|---|
|
always-construct: always statement |
always-construct: always ( func-name , sensitivity -list ) ; always_i1 ( func-name , index , sensitivity-list ); always_t ( func-name ); |
CvSDL tasks and functions are simply module member functions. They follow the same distinctions made by Verilog:
a function returns a value, but a task does not,
a function cannot contain delay controls and event expressions, but a task can,
a function must return a value (TCvVar), but a task must not,
a function can call functions but cannot call tasks; a task can call functions and tasks,
a function must have at least one input port and no outputs/inouts; a task can have zero or more ports of any type.
CvSDL tasks and functions cannot be given instance names and are always of the automatic (reentrant) type as defined in Verilog-2001. Note that synthesizable tasks and functions must be of the automatic type, per IEEE Std 1364.1-2002 and that automatic task items are accessible as defined in Verilog-2001.
Note that Verilog does not allow use of nonblocking assignments with or without a delay control or event expression and use of system tasks such as cv_monitor(), cv_dumpvars(), etc.
Formal arguments to tasks and functions must be the reference type, TCvVar&. Any expression can be used as actual arguments. Only the lvalues for procedural assignments can be connected to output arguments.
The use of the C++ keyword static for local variables to create a static task is not recommended, since they are not equivalent to Verilog static variables that are not global.
If you want to make sure the type of an input port is what you expect, you can use a temporary variable with the type and assign the input port value to the temporary..
|
Example |
|
|---|---|
|
Verilog |
CvSDL |
|
task my_task; inout [3:0] out; input [3:0] i0, i1; begin out=i0+i1; end endtask |
void my_task(TCvVar& Out, TCvVar& i0, TCvVar& I1) { // assume i0 type and size are always correct TCvVar i1(“i1”, 3,0, I1); // force type/size on I1 // result type/size automatically adjusted to Out Out = i0+i1; } |
CvSDL reserves the name, cv_rval, for the function return value. Language translators will recognize its type as the function return type. You need to declare it as a temporary variable of the type and bit size, if applicable, for the function. You need to assign a value before the function is exited with the statement:
return cv_rval;
|
Example |
|
|---|---|
|
Verilog |
CvSDL |
|
function [3:0] f1; input [3:0] i0, i1; begin f1=i0+i1; end endfunction |
TCvVar f1(TCvVar& Out, TCvVar& i0, TCvVar& i1) { // assume i0 and i1 always have correct type and size TCvVar cv_rval(“f1”, CV_DATA_REG, 3,0); cv_rval = i0+i1; return cv_rval; } |
Constant function calls are used during elaboration time in Verilog and module construction time in CvSDL.
In order for CvSDL constant functions to be translatable to the equivalent functions in Verilog, you need to follow all the Verilog rules on them. Basically a constant function is static and not generated in generate blocks, takes only constant expressions as the arguments, ignores any system tasks, does not allow any system function calls, has all references defined locally beforehand within the current module (except for parameters, but defparams are not allowed to affect them) and does not call other constant functions.
The table below summarizes the valid ways of disabling named blocks and tasks in CvSDL. Other ways not in the table, but allowed in Verilog are not supported. Note that the synthesizable Verilog only allows disabling a named block from within.
You can disable initials and threaded always that are blocked and waiting for some events or delays. When you disable an initial, the process will be disabled for the rest of the simulation. When you disable a threaded always, its stack is reinitialized and the process is queued as an inactive event.
|
Use |
Verilog |
CvSDL |
|---|---|---|
|
disabling a block from within the block |
begin : my_block ... if (en==0) disable my_block ... end |
{ ... if (en==0) goto SKIP_X; ... SKIP_X: } |
|
disabling a task from within the task |
task my_task; begin ... if (en==0) disable my_task; ... end endtask |
void my_task() { ... if (en==0) return; ... } |
|
Loop flow control |
begin: my_break for (i=0;i<n;i=i+1) begin: my_next ... if (en==0) disable my_break; ... if (cnt<10) disable my_next; ... end end |
for (i=0; i<n;i=i+1) { ... if (en==0) break; ... if (cnt<10) continue; .. } |
|
disabling initials |
disable my_initial; |
cv_disable(“my_initial”); |
|
disabling threaded always |
always begin : my_always #100 ... end
... begin ... disable my_always; ... end |
void my_always() { cv_delay(100); ... } // in constructor, specify threaded always always_t(“my_always”,my_always, ...); void another_proc() { cv_disable(“my_always”); } |
In Verilog, top-level modules do not need to be instantiated, but in CvSDL they must be instantiated and registered through TCvSdl::RegisterComponent(). They are then maintained as sub-modules of the internal (not user-defined) top level module called “CvSDL”.
Arrays of instances (using the range specification) are not supported. If you want to generate module arrays, use the generate facility instead.
Blank port connections are not supported except for default parameter ports at the end of a port list. Port connections by name are not supported.
To instantiate a module in CvSDL, use the instance macro, the only argument to which is the module constructor with actual arguments.
|
Example |
|
|---|---|
|
Verilog |
CvSDL |
|
my_module my_mod1(a, b, c); |
instance( my_module(“my_mod1”, a, b, c) ); |
The generate facility is supported in module constructors. You can specify variables or generate multiple instances of one or more of the following objects in loops using the for-loop statement or conditionally using the if-else statement or the case statements:
modules
primitive gates
continuous assignments
initial processes
always processes
UDPs are not supported.
In Verilog, tasks and functions can be generated conditionally but not in loops. In CvSDL, tasks and functions cannot be generated in generate blocks; instead of generating tasks and functions in generate blocks, you can simply include conditionals inside tasks and functions. You could, though considered not translatable currently, use a function pointer to conditionally point to a desired function.
No variables can be declared inside generate blocks; they must be declared as module variables beforehand. But they can be specified in generate blocks. Specified variables and generated instances can be uniquely named and referenced hierarchically.
Unlike defparam statements in generate blocks in Verilog, defparam statements in CvSDL are not limited to the generate blocks that include them. That is, there is no scope limitation in CvSDL as there is in Verilog.
Any integer variables defined in the module constructor and used in generate blocks are considered genvars.
|
Example: Continuous assignment |
|
|---|---|
|
Verilog |
CvSDL |
|
genvar i; generate for (i=0; i<WIDTH; i=i+1) begin:data assign d[i]=^gray[WIDTH-1:i]; end endgenerate |
// module constructor
for (int i=0; i<WIDTH; ++i) // i=genvar d[i]=gray(WIDTH-1,i).xor(); |
|
Example: Always process |
|
|---|---|
|
Verilog |
CvSDL |
|
genvar i; generate for (i=0; i<WIDTH; i=i+1) begin:data always @(gray(WIDTH-1:i]) d[i]=^gray[WIDTH-1:i]; end endgenerate |
my_module::my_module(...) { // constructor for (int i=0; i<WIDTH; ++i) // i=genvar always_i1(gray_scale, i, gray(WIDTH-1,i)); } // parameterized always process function void my_module::gray_scale(int i) { d[i]=^gray[WIDTH-1:i]; } |
|
Example: Primitive gates |
|
|---|---|
|
Verilog |
CvSDL |
|
wire [WIDTH-1:0] in0, in1; wire [WIDTH-1:0] out [1:0];
genvar i; generate for (i=0; i<WIDTH; i=i+1) begin:ar and g0(out[0][i], in0[i], in1[i]); or g1(out[1][i], in0[i], in1[i]); end endgenerate |
my_module::my_module(...) { // constructor in0.wire(“in0”, WIDTH-1,0); in1.wire(“in1”, WIDTH-1,0); array<1>(out.wire(“out”, WIDTH-1,0), 1,0);
for (int i=0; i<WIDTH; ++i) // i=genvar { and_gate(cv_sprintf(“ar[%d].g0”, i), out[0][i], in0[i], in1[i]); or_gate(“cv_sprintf(“ar[%d].g1”, i), out[1][i], in0[i], in1[i]); } } |
|
Example: Primitive gates with variable declarations |
|
|---|---|
|
Verilog |
CvSDL |
|
wire [WIDTH-1:0] in0, in1;
genvar i; generate for (i=0; i<WIDTH; i=i+1) begin:ar wire out0, out1; and g0(out0, in0[i], in1[i]); or g1(out1, in0[i], in1[i]); end endgenerate |
my_module::my_module(...) { // constructor in0.wire(“in0”, WIDTH-1,0); in1.wire(“in1”, WIDTH-1,0);
// TCvVar out0[WIDTH], out1[WIDTH]; for (int i=0; i<WIDTH; ++i) // i=genvar { out0[i].wire(cv_sprintf(“ar[%d].out0”, i)); out1[i].wire(cv_sprintf(“ar[%d].out1”, i));
and_gate(cv_sprintf(“ar[%d].g0”, i), out0[i], in0[i], in1[i]); or_gate(“cv_sprintf(“ar[%d].g1”, i), out1[i], in0[i], in1[i]); } } |
|
Example: Primitive gates |
|
|---|---|
|
Verilog |
CvSDL |
|
generate if (WIDTH <= 8) modA #(WIDTH) m0(o0, in0, in1); else modB #(WIDTH) m0(o0, in0, in1); endgenerate |
// module constructor if (WIDTH <= 8) instance(modA(”m0”,o0, in0, in1, WIDTH) ); else instance(modB(”m0”,o0, in0, in1, WIDTH) );
|
|
Example: Modules |
|
|---|---|
|
Verilog |
CvSDL |
|
generate case (WIDTH) 8'h4, 8'h8 : modA #(WIDTH) m0(o0, in0, in1); default: modB #(WIDTH) m0(o0, in0, in1); endcase endgenerate |
// module constructor
casev (WIDTH) case_item( (TCvVar(“8'h4”),TCvVar(“8'h8”))) instance(modA(”m0”,o0, in0, in1, WIDTH) ); case_default instance(modB(”m0”,o0, in0, in1, WIDTH) ); endcase |
There are three ways to override default parameter values:
defparam statement – supported
module instance parameter value assignment by ordered list – supported
module instance parameter value assignment by name – not supported
The defparam statement overriding a parameter must appear before the module that contains the parameter during compilation. If there is more than one defparam statement for a parameter, a warning is generated and the last statement encountered, before the parameter is elaborated, is used to override the default value of the parameter.
|
Verilog |
CvSDL |
|---|---|
|
module configs; defparam modA.modB.WIDTH=32, modA.modB.TESTNO=”test3”; endmodule |
struct configs : TCvModule { configs() { // constructor defparam(“modA.modB.WIDTH”, 32); defparam(“modA.modB.TESTNO”, “test3”); } }; |
The Verilog parameter value assignment by ordered list uses the C++ function arguments with default initialization values.
|
Verilog |
CvSDL |
|---|---|
|
my_module #(32, “test1”) modA(a, b); |
// in constructor instance( modA(“modA”, a, b, 32, “test1”) ); |
Overridden values for parameters are propagated to others that are dependent on the parameters.
The following features are not directly supported:
List of ports declarations in Verilog-2001 - not supported
Connecting module instance ports by name - not supported
The list of ports or the module ports are the formal arguments to the constructor of a module that are declared as TCvVar references, TCvVar&.
Note that ports must be specified one variable at a time.
port-specification:
port-type ( inst-name,
local-var, port-var
) ;
port-type (
inst-name, local-var,
range, port-var
) ;
port-type:
one of
input output
inout
|
Example : Port binding |
|
|---|---|
|
Verilog |
CvSDL |
|
module split_ports(a[7:4],a[3:0]); input [7:0] a; |
TCvVar a; split_ports(.., TCvVar& AH, TCvVar& AL) { // constructor input(“a”, a, 7, 0, (AH, AL)); } |
|
module concat( {a, b} ); input [7:0] a, b; |
TCvVar a,b; concat(.., TCvVar& AB) { // constructor input(“a”, a, 7, 0, AB(15, 8) ); input(“b”, b, 7, 0, AB(7, 0) ); } |
|
module same_port( .a(w), .b(w) ); inout [7:0] w; // tri?, wand?, wor?
|
TCvVar w; some_port(.., TCvVar& A, TCvVar& B) { // constructor inout(“w”, w, 7, 0, A ); inout(“w”, w, 7, 0, B ); // connect A & B } |
|
module same_input( a, a ); input [7:0] a; // two ports are (bit-wise?) ored.
|
TCvVar a; same_input(.., TCvVar& A0, TCvVar& A1) { // constructor input(“a”, a, 7, 0, A0|A1 ); } |
Any valid expression can be connected to each port of a module.
Use cv_realtobits() and cv_bitstoreal() to pass reals as bits across module ports.
Each port connection behaves as a continuous assignment to the lvalue.
An input or inout port must be a valid lvalue for continuous assignments.
Input ports that are assigned values internally (used as outputs) are considered fatal errors in CvSDL; they generate warning messages in Verilog.
The synthesizable subset of Verilog ignores the net types resulting from connecting dissimilar data types at ports that are defined in Verilog-2001, potentially causing simulation mismatches between RTL and gate level models. CvSDL allows the connections of truly compatible data types only.
The table below summarizes the compatible internal and external data types at ports. The entries with '-' indicate the combinations of the corresponding data types are not allowed and error messages will be generated.
|
Internal |
External |
||||||
|---|---|---|---|---|---|---|---|
|
port type |
data type |
wire |
tri |
wand |
wor |
supply1 |
supply0 |
|
input |
wire |
wire |
wire/tri |
wire/wand |
wire/wor |
wire/supply1 |
wire/supply0 |
|
tri |
- |
tri |
- |
- |
- |
- |
|
|
wand |
- |
- |
wand |
- |
- |
- |
|
|
wor |
- |
- |
- |
wor |
- |
- |
|
|
supply1 |
supply1/wire |
- |
- |
- |
supply1 |
- |
|
|
supply0 |
supply0/wire |
- |
- |
- |
- |
supply0 |
|
|
output |
wire |
wire |
- |
- |
- |
wire/supply1 |
wire/supply0 |
|
tri |
tri/wire |
tri |
- |
- |
- |
- |
|
|
wand |
wand/wire |
- |
wand |
- |
- |
- |
|
|
wor |
wor/wire |
- |
- |
wor |
- |
- |
|
|
supply1 |
supply1/wire |
- |
- |
- |
supply1 |
- |
|
|
supply0 |
supply0/wire |
- |
- |
- |
- |
supply0 |
|
|
reg |
reg/wire |
- |
- |
- |
- |
- |
|
|
inout |
wire |
wire |
- |
- |
- |
supply1 |
supply0 |
|
tri |
tri/wire |
tri |
- |
- |
- |
- |
|
|
wand |
wand/wire |
- |
wand |
- |
- |
- |
|
|
wor |
wor/wire |
- |
- |
wor |
- |
- |
|
|
supply1 |
supply1/wire |
- |
- |
- |
supply1 |
- |
|
|
supply0 |
supply0/wire |
- |
- |
- |
- |
supply0 |
|
In CvSDL, sub-module ports assume the signs of the expressions connected to the ports. The use of signed types across ports should be avoided unless the signs are used consistently across ports (no sign conversions).
The hierarchical path names in CvSDL are formed in the same manner as in Verilog but enclosed in double quotes (“”).
Searching for a hierarchical name starts with
a module identifier (module-identifier.item-name), or
a module instance name (module-instance-name.item-name)
The search algorithm is specified by Verilog. Note that module-instance-name is searched first before module-identifier at the current level.
A valid item-name is the name of a net, a variable, a parameter or named block. Functions and tasks are automatic and their internal objects are not accessible.
Use the following two functions, cv_variable() and cv_block(), to get references to named objects:
hierarchical-variable-reference:
cv_variable ( “
hierarchical-variable-path-name
“ )
hierarchical-block-reference:
cv_block ( “
hierarchical-block-path-name
“ )
cv_variable() returns the reference to a variable. If the variable does not exist, the reference is to a dummy variable and a warning message is generated.
cv_block() returns the reference to a block such as a process or module. If the block does not exist, it return the reference to the “CvSDL” module and a warning message is generated.
|
Verilog |
CvSDL |
|---|---|
|
modA.modB.enable=3; |
cv_variable(“modA.modB.enable”)=3; |
CvSDL uses the C++ scope rules that are basically the same as the Verilog scope rules. However when an object is given a string name, the string name (not the object name recognized by C++) actually corresponds to the equivalent Verilog name. Therefore you need to make sure string names do not collide within the same scope.
If a task or function is referenced directly in a module, it must be a module member task or function in CvSDL, whereas Verilog allows the use of a task or function defined in a higher-level module.
All Verilog system tasks and functions, except for PLA modeling tasks, are supported. The dollar sign ($) in front of a name is replaced by “cv_”. For example, $display() becomes cv_display(). Arguments to some tasks and functions are slightly different from Verilog. The differences are noted below.
You can use C++ file I/O functions for some of Verilog file I/O functions such as ftell().
The item not supported is the format specification, %l and %L, for displaying library binding information. Also note that CvSDL does not support charge strengths.
|
Verilog |
CvSDL |
|---|---|
|
display-task: display-task-name ( list_of_arguments ) ; display-task-name: one of $display $displayb $displayo $displayh $write $writeb $writeo $writeh |
display-task: display-task-name ( list_of_arguments ) ; display-task-name: one of cv_display cv_displayb cv_displayo cv_displayh cv_write cv_writeb cv_writeo cv_writeh |
|
strobe-task: strobe-task-name ( list_of_arguments ) ; strobe-task-name: one of $strobe $strobeb $strobeo $strobeh |
strobe-task: strobe-task-name ( list_of_arguments ) ; strobe-task-name: one of cv_strobe cv_strobeb cv_strobeo cv_strobeh |
|
monitor-task: monitor-task-name ( list_of_arguments ) ; monitor-task-name: one of $monitor $monitorb $monitoro $monitorh |
monitor-task: monitor-task-name ( list_of_arguments ) ; monitor-task-name: one of cv_monitor cv_monitorb cv_monitoro cv_monitorh |
|
$monitoron ; |
cv_monitoron() ; |
|
$monitoroff; |
cv_monitoroff() ; |
|
Verilog |
CvSDL |
|---|---|
|
integer mcd=$fopen ( “filename“ ); integer fd=$fopen( “filename”, type); |
int mcd=cv_fopen( “filename“ ); FILE *fp=cv_fopen( “filename” , type); |
|
$fclose(mcd); $fclose(fd); |
cv_fclose(mcd); cv_fclose(fp); |
|
string-output-tasks: str-out-task ( str_reg, list_of_args ); str-out-task: one of $swrite $swriteb $swriteo $swriteh |
string-output-tasks: str-out-task ( str_reg, list_of_args ); str-out-task: one of cv_swrite cv_swriteb cv_swriteo cv_swriteh |
|
sformat-task: $sformat( str_reg, format_str, list_of_args ); |
sformat-task: cv_sformat( str_reg, format_str, list_of_args ); |
|
integer code=$fgets ( str, fd ) ) ; |
int code = cv_fgets ( str, fd ) ) ; |
|
integer code=$fscanf (fd, format, args ); |
int code=cv_fscanf (fd, format, args ); |
|
integer code=$sscanf (fd, format, args ); |
int code=cv_sscanf (fd, format, args ); |
|
integer code=$fread( reg, fd); integer code=$fread( mem, fd); integer code=$fread( mem, fd, start); integer code=$fread( mem, fd, start, count ); integer code=$fread( mem, fd, , count ); |
int code=cv_fread( reg, fd); int code=cv_fread( mem, fd); int code=cv_fread( mem, fd, start); int code=cv_fread( mem, fd, start, count ); int code=cv_fread2( mem, fd, count ); |
|
$fgetc, $ungetc, $ftell, $fseek, $rewind, $ferror |
Use equivalents in C++: fgetc, ungetc, ftell, fseek, rewind, ferror |
|
load-mem-task: lm-type(“filename”,mem); lm-type(“filename”,mem, start); lm-type(“filename”,mem, start, finish); lm-type: one of $readmemb $readmemh |
load-mem-task: lm-type(“filename”,mem); lm-type(“filename”,mem, start); lm-type(“filename”,mem, start, finish); lm-type: one of cv_readmemb cv_readmemh |
|
$sdf_annotate |
- |
|
Verilog |
CvSDL |
|---|---|
|
$printtimescale; $printtimescale( hier-identifier ); |
cv_printtimescale(); cv_printtimescale( hier-identifier ); |
|
$timeformat; $timeformat( unit, prec, suffix, minwidth ); |
cv_timeformat; cv_timeformat( unit, prec, suffix, minwidth ); |
|
Verilog |
CvSDL |
|---|---|
|
$finish; $finish( level ); |
cv_finish(); cv_finish( level ); |
|
$stop; $stop( level ); |
cv_stop(); cv_stop( level ); |
|
$log; $log( filename ); |
cv_log(); cv_log( filename ); |
|
$nolog; |
cv_nolog(); |
|
$reset; $reset( stop-value ); $reset( stop-value, reset-value ); $reset( stop-value, reset-value, diag-value ); |
cv_reset(); cv_reset( stop-value ); cv_reset( stop-value, reset-value ); cv_reset( stop-value, reset-value, diag-value ); |
|
$reset_count; |
cv_reset_count(); |
|
$reset_value; |
cv_reset_value(); |
|
Verilog |
CvSDL |
|---|---|
|
$q_initialize(q-id,q-type max-length,status); |
cv_q_initialize(q-id,q-type max-length,status); |
|
$q_add(q-id,job-id,inform-id,status); |
cv_q_add(q-id,job-id,inform-id,status); |
|
$q_remove(q-id,job-id,inform-id,status) ; |
cv_q_remove(q-id,job-id,inform-id,status) ; |
|
$q_full(q-id,status) ; |
cv_q_full(q-id,status) ; |
|
$q_exam(q-id,q-stat-code,q-stat-value,status); |
cv_q_exam(q-id,q-stat-code,q-stat-value,status); |
|
Verilog |
CvSDL |
|---|---|
|
$time |
cv_time() |
|
$stime |
cv_stime() |
|
$realtime |
cv_realtime() |
|
Verilog |
CvSDL |
|---|---|
|
$rtoi( real-val ) |
cv_rtoi( real-val ) |
|
$itor( int-val ) |
cv_itor( int-val ) |
|
$realtobits( real-val ) |
cv_realtobits( real-val ) |
|
$bitstoreal( bit-val ) |
cv_bitstoreal( bit-val ) |
|
Verilog |
CvSDL |
|---|---|
|
$random; $random( seed ); |
cv_random(); cv_random( seed ); |
|
$dist_uniform( seed, start, end ); |
cv_dist_uniform ( seed, start, end ); |
|
$dist_normal(seed, mean, standard-deviation ); |
cv_dist_normal(seed,mean,standard-deviation); |
|
$dist_exponential( seed, mean ); |
cv_dist_exponential( seed, mean ); |
|
$dist_poisson( seed , mean ); |
cv_dist_poisson( seed , mean ); |
|
$dist_chi_square (seed, degree-of-freedom ); |
cv_dist_chi_square (seed, degree-of-freedom ); |
|
$dist_t ( seed, degree-of-freedom ); |
cv_dist_t ( seed, degree-of-freedom ); |
|
$dist_erland ( seed , k-stage , mean ); |
cv_dist_erland ( seed , k-stage , mean ); |
|
Verilog |
CvSDL |
|---|---|
|
command-line |
void TCvSdl::CommandLine(int argc, char**); |
|
$test$plusargs ( string ) |
cv_test_plusargs ( string ) |
|
$value$plusargs ( string , variable ) |
cv_value_plusargs ( string , variable ) cv_value_plusargs ( string-variable , variable ) |
|
Verilog |
CvSDL |
|---|---|
|
$dumpfile ( filename ) ; |
cv_dump ( filename ); // filename optional |
|
$dumpvars; $dumpvars( levels ); $dumpvars( levels , list-of-mods-or-vars ); |
cv_dumpvars(); cv_dumpvars( levels ); cv_dumpvars(
levels, module
) ; |
|
$dumpoff |
cv_dumpoff() ; |
|
$dumpon |
cv_dumpon(); |
|
$dumpall; |
cv_dumpall(); |
|
$dumplimit( filesize ); |
cv_dumplimit( filesize ); |
|
$dumpflush; |
cv_dumpflush(); |
The dumpvars() argument list, list-of-mods-or-vars, are translated to an appropriate cv_dumpvars() statement for each item in the list.
Trademarks
and registered trademarks are property of the respective
owners.
CvSDL is a trademark of Tenko Technologies Inc.
Copyright
© 2005 Tenko
Technologies Inc. All rights reserved. Last modified on