[1] IEEE Standard for SystemVerilog--Unified Hardware Design, Specification, and Verification Language - Redline https://ieeexplore.ieee.org/document/5985443
[2] http://www.sunburst-design.com/papers/CummingsSNUG2003SJ_SystemVerilogFSM.pdf
To use SystemVerilog, when adding a new file to a project select SystemVerilog instead of Verilog the file extension will be .sv instead of .v
Example System Verilog State Machine:
module statemachine_sv(out,finished, skip_to_finish, ,clk,rst); input clk; enum logic [1:0] {S_INIT=2'd0, S_WAIT=2'd1, S_FINISH=2'd2} CS,NS; logic [7:0] x,_x; output logic finished; logic _finished; input skip_to_finish; input rst; output logic out; logic _out; logic rst_n; not myinv(rst_n,rst);
always_ff @ (posedge clk,negedge rst_n) begin if (rst_n==0) begin CS<=S_INIT; end else begin CS<=NS; end end always_ff @ (posedge clk,negedge rst_n) begin if (rst_n==0) begin //no resets required end else begin finished <= _finished; out <= _out; x <= _x; end end
//Next State Logic always_comb begin NS = CS; case(CS) S_INIT: NS = S_WAIT; S_WAIT: if (skip_to_finish) NS=S_FINISH; else if (x==0) NS=S_FINISH; else NS=CS; S_FINISH: NS = S_INIT; endcase end //Extended State Registers Combinatorial Logic always_comb begin _x = 'x; case(CS) S_INIT: _x = 4; S_WAIT: _x = x-1; endcase end
//Registered Output Logic Based on CS,NS always_comb begin _finished = 0; _out = 0; case (NS) S_INIT: begin _out = 0; if (CS == S_FINISH) begin _finished=1; end else begin _finished=0; end end S_WAIT: begin _out = 0; _finished = 0; end S_FINISH: begin _finished=0; if (skip_to_finish) begin _out=0; end else begin _out=1; end end endcase // case (CS) end // always @ endmodule // test
keyword enum
enum logic [1:0] {S_INIT=2'd0, S_WAIT=2'd1, S_FINISH=2'd2} CS,NS;
enum logic [1:0] {S_INIT,S_WAIT,S_FINISH} CS,NS;
Useful for State Variables
will display in waveform viewers, statemachine viewers
can print with %s and .name()
$display( "%s : %d\n", CS.name, CS );
See Reference [2] 10.1 Enumerated types
use keyword always_comb in combinatorial blocks were always @ (*) typically used
infers sensitivity list
enforces memoryless logic, tools should check that only combinatorial logic is inferred
Example Use and Error from Quartus
module top(output logic [3:0] x, input [3:0] a,input [3:0] b); //logic [3:0] _x; always_comb begin //x = 'x; //would be a don't care if not commented if (a>b) begin x=a; end end endmodule
Info (12127): Elaborating entity "top" for the top level hierarchy
Warning (10240): Verilog HDL Always Construct warning at top.sv(59): inferring latch(es) for variable "x", which holds its previous value in one or more paths through the always construct
Error (10166): SystemVerilog RTL Coding error at top.sv(59): always_comb construct does not infer purely combinational logic.
Info (10041): Inferred latch for "x[0]" at top.sv(59)
Info (10041): Inferred latch for "x[1]" at top.sv(59)
Info (10041): Inferred latch for "x[2]" at top.sv(59)
Info (10041): Inferred latch for "x[3]" at top.sv(59)
Error (12153): Can't elaborate top-level user hierarchy
Error: Quartus Prime Analysis & Synthesis was unsuccessful. 2 errors, 2 warnings
Error: Peak virtual memory: 409 megabytes
Error: Processing ended: Mon Sep 27 14:30:20 2021
Error: Elapsed time: 00:00:09
Error: Total CPU time (on all processors): 00:00:18
Error (293001): Quartus Prime Full Compilation was unsuccessful. 4 errors, 2 warnings
Example Errors from Quartus
Warning (10230): Verilog HDL assignment warning at xx.sv(49): truncated value with size 32 to match size of target (8)
Warning (10240): Verilog HDL Always Construct warning at xx.sv(32): inferring latch(es) for variable "_x", which holds its previous value in one or more paths through the always construct
Warning (10240): Verilog HDL Always Construct warning at xx.sv(32): inferring latch(es) for variable "_finished", which holds its previous value in one or more paths through the always construct
Warning (10240): Verilog HDL Always Construct warning at xx.sv(32): inferring latch(es) for variable "_out", which holds its previous value in one or more paths through the always construct
Error (10166): SystemVerilog RTL Coding error at xx.sv(32): always_comb construct does not infer purely combinational logic.
Example Use
always_comb begin _x = 'x; case(CS) S_INIT: _x = 4; S_WAIT: _x = x-1; endcase end
prevents writing to output variables from other processes
in simulation called once at time zero after initial and always procedures
[2] 10.2 @* and always_comb
no blocking timing controls allowed
always_ff @(posedge clk or negedge rst_n)
), no blocking timing controls allowedfinal
procedure keyword
final begin $display("Simulation Ended"); end
New shorthand for Implicit port connections
use .* in instantiation to connect ports of module to variables names in the same scope
useful for testbenches, since it is common to create several signals with the same name as the ports of the
can shorthand to connect individual matching port and nets by leaving out the ()
e.g. ,.clk ,
connects clk to port clk.
examples:
stamachine DUT(.*);
stamachine DUT(.rst(~rst_n),.*);
stamachine DUT(.rst(~rst_n),.clk,.a,.b,.q);
stamachine DUT(.rst(~rst_n),.*);
See reference [2] 11.0 Implicit port connections
dest<='x;
dest='z;
extern module statemachine(out, finished, skip_to_finish, clk,rst);
good reference:
https://www.verilogpro.com/systemverilog-unique-priority/
unique
keyword
if
(if else, else), case
, casez
, casex
unique0
keyword in SystemVerilog 12 only checks for multiple matches but not unmatched
priority
keyword