always: statements inside in these blocks are executed sequentially ʳalways @(<sensitivity-list>): fire if any signal in sensitivity list changesalways @(*): means all input included- Executed repeatedly throughout the simulation
- Use
alwaysblock with care. Make sure that no twoalwaysblocks are in conflict. Otherwise unexpected behaviour can pop up.
repeat(n): replicate a blockntimes`timescale <time_unit>/<time_precision>`timescale 1ns/1ps: says 1 step is 1ns and I guess to report with precision upto 1ps- Specified for the benefit of simulator
- Units of time usable: s, ms, us, ns, ps or fs
- https://www.chipverify.com/verilog/verilog-timescale
- This is a compiler directive
- Modules, wires, registers
posedge <signal>,negedge <signal>: positive & negative edge of a signal respectively- eg:
always @(posedge clk or negedge rst) begin ... end - I guess
posedgeis likerising_edge(signal)in VHDL
- eg:
begin .. endis not needed if there's only one statementfunctionvstask: task can take up simulation time, unlike function- Tasks are generally non-synthesizable
logic: apparently same asreg>>>vs>>:>>>copies sign bit.>>fills in with0- Looks like there's no
<<<, which sounds meaningless anyway.
- Looks like there's no
$unsigned(v): type cast to unsignedcasexandcasez:casewith wildcards allowedunique,prioritymodifiers: ??64'sd1: a 64 bit signed decimal constant of value1
Signal strengths
- 4 driving strengths
- 3 capacitative strengths
- 1 high impedence
Table from here:
| Strength | Value | |
|---|---|---|
| supply | 7 | Su |
| strong | 6 | St |
| pull | 5 | Pu |
| large | 4 | La |
| weak | 3 | We |
| medium | 2 | Me |
| small | 1 | Sm |
| highz | 0 | HiZ |
- Strength of a net is the strength of its highest driving signal.
- High impedence is like when there is an open circuit ??
See:
- https://web.archive.org/web/20201022054201/https://verilog.renerta.com/source/vrg00047.htm
- https://www.hdlworks.com/hdl_corner/verilog_ref/items/Strengths.htm
- https://vlsiverify.com/verilog/strength-in-verilog/
—
Signal states ??
| ~Z~ | 'High impedence' / 'tristate' |
| ~X~ | Unknown state |
| ~?~ | Don't care |
In simulation, all values start with x by default.
| AND | 0 | 1 | x | z |
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 |
| 1 | 0 | 1 | x | x |
| x | 0 | x | x | x |
| z | 0 | x | x | x |
initial block
- Starts execution immediately
- Each statement in the block is executed one after the other, not concurrently
- The entire block runs only once
- Unlike
alwaysblock
- Unlike
- There can be multiple
initialblocks?? initialblocks are not synthesizable (generally)
Assignments
- Blocking:
= - non-blocking:
<=
General
- Comment: As in C
- Single line:
// - Multi-line:
/* ... */
- Single line:
- Values:
z: high impedencex: unknown/uninitialized0: logic 01: logic 1
localparam: similar toparameterbut cannot be modified by module instance argument or withdefparam
Literals
Format: n'bVAL:
n: number of bitsb: baseVAL: value
Default is base is decimal.
8'hFF: 8-bit hex number of valueFF(ie,0xFF)5'b101: 5-bit binary number (ie,0b00101)1: decimal number3'o5: 3-bit octal number (ie,0o5)
https://users.ece.utexas.edu/~patt/04s.382N/tutorial/verilog_manual.html
Compiler directives
- Starts with a backtick.
- Eg:
`define,`include,`ifdef .. else .. `endif, `include "file.v": include another verilog file`define: make text macros (à la C)
See:
Macros
- C-style macros
- Textual replacement
// word size
`define wsize 32
`define word [`wsize-1:0]
...
...
input `word a, b;Operators
- Conditional operator (ternary):
?:cond ? true : false
- Shifting:
<<and>> - Concatenation
- Possible for any sized value
- Syntax: comma seperated values inside curly braces
- Eg:
{1'b0, 1'b1, 1'b0}gives3'b010 - Provision for repetition available:
{2 {expr}}is same as{expr, expr}- Eg:
{2 {1'b0}, 1'b1}is3'b001 assign {c_out, sum} = a + b + c_in;(in full adder)
- Eg:
Bitwise operators
~ |
Unary negation |
& |
AND |
│ |
OR |
^ |
XOR |
~^a or ^~a |
XNOR |
Reduction operators
- These operators are unary.
- Kind of like a fold
- Eg: Reduction AND does AND of all bits in operand vector
&a |
Reduction AND |
│a |
Reduction OR |
~&a |
Reduction NAND |
~│a |
Reduction NOR |
^ |
Reduction XOR |
~^a or ^~a |
Reduction XNOR |
Indexing into vectors
Possible for sized values like vectors ??
Bit-select
'Indexing' into a vector/similar
Example:
wire [7:0] a;
// 0th bit of a
a[0]
// 4th bit of a
a[4]Part-select
'Slicing a vector/similar
Example:
wire [7:0] a;
// 2nd, 1st and 0th bits of a
a[2:0]
// 5th, 4th and 3rd bits of a
a[5:3]System tasks
$dumpfile("name.vcd"): dump wave info as vcd$dumpvars(number_of_levels, instance_name): dump wave info as vcd- levelcount = 0: dump all signals at all levels of the instance
- levelcount = 1: only dump signals at top level
- levelcount = n: dump signals n level hierarchically below named instance ??
$readmemb("filename", instance_name.mem, starting_addr): read from a binary file ??$readmemh("filename", instance_name.mem, starting_addr): read from a hex file ??$strobe: print messages on screen after end of current time slot (postpone region)- Like
printfin C - Eg:
$strobe()
- Like
$display: print messages (active region)$write: like$display, but no newline$time: returns current simulation time$finish: end simulation
See:
specify blocks
A relatively obscure part of verilog..
'Defines a delay across a module'
Delays are mentioned in picoseconds
A => B = 12: simple combinationational path from A to B with delay 12ps
See:
Misc
- bufif0, bufif1, notif0, buf
- trireg nets
- drive strength vs charge strength
iverilog
- Find directory of vpi modules:
iverilog-vpi --install-dirʳ
Tips
- Delay in synthetically verilog ??
- Count clock as per operating frequency
- How to find operating frequency of a design loaded onto fpga? Is that a constraint?
DBT
- Postpone region
- Active region
- Can this be made a one-liner?
temp[0] <= a^b;
temp[1] <= a&b;
- How to drive RGB output
- How to circularly shift a 1 in a vector
- Worst negative slack is 4.002ns, but total negative slack is 0.000ns ??
- what colour if 11 is written to an rgb led?
Splitting long lines
This works:
// Verilog
module full_adder (
input a, b, cin,
output s, cout
);
assign s = a ^ b ^ cin;
assign cout =
(a & b)
| (b & cin)
| (cin & a);
endmoduleLinks
- IEEE standard for SystemVerilog: https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8299595
SystemVerilog
- Function:
function <name> (args); <body> endfunction- Arguments can have default values
- Array
- Declaration:
<type> <name> [<size>]; - Size of array:
$size <name>
- Declaration:
forloop:for(int i=0; i<5; i++) begin ... end- Kinda like in C
.svh: like header files for SystemVerilog source
Stuff not in verilog:
===and!==++,--(incr/decr)+=,-=(assignment)always_ff,always_comb,always_latchpriorty,unique- Kind of like
parallel_caseandfull_casepragmas in verilog ??
- Kind of like
interface- https://www.doulos.com/knowhow/systemverilog/systemverilog-tutorials/systemverilog-rtl-tutorial/
enum type
typedef enum {red, green, blue} Colour;
typedef enum {red=10, green=20, blue=30} Colours;always stuff
always_comb: a combinatory block- sensitisation list can be inferred automatically if all used signals are there ??
always_ff: infer 'transparent flip flip'always_latch: infer 'transparent latch'
Verilog's always block was less expressive. Specialized
blocks convey the meaning more clearly.
Associative array
- Like python dictionaries
- Declaration syntax:
<val_type> <name> [<index_type>];
// Assoc array with string index and int values
int fruitprice[string];
fruitprice = '{"Apple": 190,
"Orange": 120};See: https://www.chipverify.com/systemverilog/systemverilog-associative-array
Classes
https://www.chipverify.com/systemverilog/systemverilog-class
- Syntax is kind of like JavaScript classes.
this: current object (or is it class??)function new (): constructor- Auto invoked on object creation
- Inheritance:
extends- Eg:
class subclass extends baseclass; - Invoke superclass attribute:
super.<attribute>
- Eg:
virtual class: abstract class- Can only be extended.
- Cannot be instantiated.
Command line arguments
Can be passed to simulation with a
+characterThese arguments are accessible with
plusargsfunctionshttps://www.chipverify.com/systemverilog/systemverilog-command-line-input
$test$plusargs (str): Check if the argumentstrexists ??$value$plusargs (str, var)- Like $test$plusargs but also gets value associated with argument
strtovar
- Like $test$plusargs but also gets value associated with argument
Constraints
- Kind of like refined types
- Useful during verification/testing
bit [7:0] addr;
constraint addr_limit { addr <= 8'hB; }https://www.chipverify.com/systemverilog/systemverilog-constraints
Coverage
coverpoint: variablescovergroupblock: groups cover points
https://www.chipverify.com/systemverilog/systemverilog-functional-coverage
iverilog
Apparently, iverilog doesn't consider input as systemverilog by
default. Got to use -g2005-sv.
$ iverilog -g mem.sv
Unknown/Unsupported Language generation mem.sv
Supported generations are:
1995 -- IEEE1364-1995
2001 -- IEEE1364-2001
2005 -- IEEE1364-2005
2005-sv -- IEEE1800-2005
2009 -- IEEE1800-2009
2012 -- IEEE1800-2012
Other generation flags:
assertions | supported-assertions | no-assertions
specify | no-specify
verilog-ams | no-verilog-ams
std-include | no-std-include
relative-include | no-relative-include
xtypes | no-xtypes
icarus-misc | no-icarus-misc
io-range-error | no-io-range-error
strict-ca-eval | no-strict-ca-eval
strict-expr-width | no-strict-expr-width
shared-loop-index | no-shared-loop-index
$ iverilog -g2005-sv mem.sv
Parenthesis in if condition
Looks like boolean expressions serving as conditions for
if always need to be enclosed within parenthesis.
This works:
if (en_wr)
but this doesn't
if en_wr
Clocking blocks
See: https://theoctetinstitute.com/content/sv/clocking-blocks/
A clocking block is a set of signals synchronised on a particular clock
Example:
clocking drv_cb @(posedge clk);
output a, b, cin;
endclockingMacros
Execute only if a macro is defined:
`ifdef MACRO_NAME
`endif
Linters
svlint
https://github.com/dalance/svlint
- Configuration file:
.svlint.toml - Get a template config file:
svlint --example > .svlint.toml - Newer svlint may change names of variables in config file. Can use:
svlint --update .svlint.toml > new.toml
Verible
https://github.com/chipsalliance/verible/tree/master/verible/verilog/tools/lint
For ignoring a linter error, use:
// verilog_lint: waive rule-name before that line.
$ verible-verilog-lint tb/*
tb/ifc.sv:18:1-2: Remove trailing spaces. [Style: trailing-spaces] [no-trailing-spaces]
tb/ifc.sv:33:31: Remove trailing spaces. [Style: trailing-spaces] [no-trailing-spaces]
tb/scoreboard.sv:26:87: Remove trailing spaces. [Style: trailing-spaces] [no-trailing-spaces]
tb/scoreboard.sv:30:101-119: Line length exceeds max: 100; is: 119 [Style: line-length] [line-length]
tb/scoreboard.sv:30:119: Remove trailing spaces. [Style: trailing-spaces] [no-trailing-spaces]
tb/top.sv:31:15: Remove trailing spaces. [Style: trailing-spaces] [no-trailing-spaces]
Autofix: verible linter can try to auto-fix errors:
--autofix_output_filepath for writing diff. Patch is written tostdoutif not givenEg:
--autofix=inplace-interactiveno No fix is is shown/applied. patch-interactive Interactive choice of fixes that are written as unified diff to –autofixoutputfile. inplace-interactive Interactive choice of fixes that are applied to the original file in place. (modifies input) patch All available fixes are written as unified diff. inplace All available fixes are applied to the original file in place. (modifies input) generate-waiver Generates a waiver rule for each violation, as a temporary fix.