You are on page 1of 56

(System)Verilog Tutorial

AleksandarMilenkovi
TheLaCASA Laboratory ElectricalandComputerEngineeringDepartment TheUniversityofAlabamainHuntsville Email:milenka@ece.uah.edu Web:http://www.ece.uah.edu/~milenka http://www.ece.uah.edu/~lacasa

Outline
Introduction CombinationalLogic SequentialLogic Memories Testbenches

Introduction
Verilog isaHardwareDescriptionLanguage(HDL) HDLs areusedforlogicsimulationandsynthesis
Simulation:inputsareappliedtoamoduleandtheoutputs arecheckedtoverifythatthemoduleoperatescorrectly Synthesis:thetextualdescriptionofamoduleis transformedintologicgates

Allowdescriptionofadigitalsystemat
BehavioralLevel describeshowtheoutputsarecomputed asfunctionsoftheinputs StructuralLevel describeshowamoduleiscomposedof simplermodulesofbasicprimitives(gatesortransistors)

Designstyles:TopDownvs.BottomUp
3

History
DevelopedbyPhilMoorby atGatewayDesignAutomation asaproprietarylanguageforlogicsimulationin1984 GatewayisacquiredbyCadencein1989 Madeanopenstandardin1990underthecontrolof OpenVerilog International BecameanIEEEstandardin1995and Updatedin2001[IEEE136401] In2005,itwasupdatedagainwithminorclarifications SystemVerilog [IEEE18002009]wasintroduced
StreamlinesmanyoftheannoyancesofVerilog and addshighlevelprogramminglanguagefeatures thathaveprovenusefulinverification
4

Modules
Ablockofhardwarewithinputs andoutputsiscalledamodule Amodulebeginswithalistingof theinputsandoutputs assign statementdescribes combinationallogic
~indicatesNOT,&indicatesAND, and|indicatesOR logicsignalssuchastheinputs andoutputsareBooleanvariables (0or1).Theymayalsohave floating(z)andundefinedvalues (x).

module sillyfunction(input logic a, b, c, output logic y); assign y = ~a & ~b & ~c | a & ~b & ~c | a & ~b & c; endmodule

Thelogictypewasintroducedin SystemVerilog
Itsupersedesthereg type,which wasaperennialsourceof confusioninVerilog shouldbeusedeverywhere exceptonnetswithmultiple drivers

CombinationalLogic
Operators:&,|,~,^ Operands:a,b,y1y5 Expressions:e.g.,(a&b) Statements:e.g.,y5=~(a|b); Assign statementimplies combinationallogic Assign indicatesa continuousassignment statement
Lefthandsideofexpressionis updatedanytimetheright handsidechanges(aorb)
module gates(input logic [3:0] a, b, output logic [3:0] y1, y2, y3, y4, y5); /* Five different two-input logic gates acting on 4 bit busses */ assign y1 = a & b; // AND assign y2 = a | b; // OR assign y3 = a ^ b; // XOR assign y4 = ~(a & b); // NAND assign y5 = ~(a | b); // NOR endmodule

Assign statementsare concurrent


6

CombinationalLogic(contd)
// full adder module fa (input logic a, b, cin, output logic s, cout); assign s = a ^ b ^ cin; assign cout = (a & b) | (cin & (a | b)); endmodule

Comments
Commentsbeginningwith/* continue,possiblyacrossmultiple lines,tothenext*/ Commentsbeginningwith//continue totheendoftheline

SystemVerilog iscasesensitive
y1andY1aredifferentsignals

Conditionalassignment
conditionaloperator?: chooses,based onafirstexpression,betweena secondandthirdexpression Thefirstexpressioniscalledthe condition.Iftheconditionis1,the operatorchoosesthesecond expression.Iftheconditionis0,the operatorchoosesthethirdexpression Equivalenttothisexpression: Ifs=1,theny=d1. Ifs=0,theny=d0.

/* 4-bit mux; selects one of two 4-bit inputs d0 or d1 */ module mux2_4 (input logic [3:0] d0, d1, input logic s, output logic [3:0] y); assign y = s ? d1 : d0; endmodule

CombinationalLogic(contd)
module and8 (input logic [7:0] a, output logic y); assign y = & a; // &a is much easier to write than // assign y = a[7] & a[6] & a[5] & a[4] // & a[3] & a[2] & a[1] & a[0]; endmodule

Reductionoperatorsimplya multipleinputgateactingona singlebus


|,^,~&,and~|reduction operatorsareavailableforOR, XOR,NAND,andNOR
/* an array of inverters */ module invA4 (input logic [3:0] a, output logic [3:0] y); assign y = ~a; endmodule

CombinationalLogic(contd)
/* 32-bit adder */ module adder (a, b, y); input logic [31:0] a; input logic [31:0] b; output logic [31:0] y; assign y = a + b; endmodule

/* */ module whatami(input logic [3:0] d0, d1, d2, d3, input logic [1:0] s, output logic [3:0] y); assign y = s[1] ? (s[0] ? d3 : d2) : (s[0] ? d1 : d0); endmodule

CombinationalLogic(contd)
module fulladder(input logic a, b, cin, output logic s, cout); logic p, g; assign assign assign assign endmodule p = a ^ b; g = a & b; s = p ^ cin; cout = g | (p & cin);

Internalvariables
Neitherinputsoroutputs

Concurrency
Orderofassignstatements doesnotmatter

10

Verilog OperatorsandOperatorPrecedence
Similartoprecedenceinother languages
assigncout =g|p&cin;

Subtractioninvolvesatwos complementandaddition Multipliersandshiftersuse substantiallymorearea(unless theyinvolveeasyconstants) Divisionandmodulusinhardware issocostlythatitmaynotbe synthesizable Equalitycomparisons(==)implyN 2inputXORs todetermine equalityofeachbitandanNinput ANDtocombineallofthebits Relativecomparisoninvolvesa subtraction

11

Verilog Numbers
SystemVerilog numberscanspecifytheir baseandsize(thenumberofbitsusedto representthem) TheformatfordeclaringconstantsisN'Bvalue
Nisthesizeinbits Bisthebase,and Valuegivesthevalue 9'h25indicatesa9bithexnumber(37 decimalor000100101inbinary)

Base:'bforbinary(base2),'oforoctal(base 8),'dfordecimal(base10),and'hfor hexadecimal(base16).


Ifthebaseisomitted,thebasedefaultsto decimal

Size:Ifthesizeisnotgiven,thenumberis assumedtohaveasmanybitsasthe expressioninwhichitisbeingused.


Zerosareautomaticallypaddedonthe frontofthenumbertobringituptofull size E.g.,ifwisa6bitbus,assignw='b11gives wthevalue000011.Itisbetterpracticeto explicitlygivethesize.Anexceptionisthat '0and'1areSystemVerilog shorthands for fillingabuswithall0sandall1s.

12

ZsandXs
Zindicatesafloatingvalue
Usefulfordescribingatristate buffer; itsoutputfloatswhentheenableis0 Abuscanbedrivenbyseveraltristate buffers,exactlyoneofwhichshould beenabled

module tristate(input logic [3:0] a, input logic en, output tri [3:0] y); assign y = en ? a : 4'bz; endmodule

yisdeclaredastri ratherthan logic


Logicsignalscanonlyhaveasingle driver Tristatebussescanhavemultiple drivers,sotheyshouldbedeclaredas anet

Twotypesofnets:tri andtrireg
Onedriverisactiveatatime,andthe nettakesthatvalue; Ifnodriversareenabled,thetrinet floats(z),whilethetrireg netretains thepreviousvalue

Ifnotypeisspecifiedforaninputor output,triisassumed
13

ZsandXs(contd)
SystemVerilog ANDgatetruthtable

SystemVerilog signalvaluesare 0,1,z,andx xindicatesaninvalidlogiclevel


E.g.,ifabusissimultaneously drivento0and1bytwo enabledtristate buffers(or othergates),theresultisx, indicatingcontention Atthestartofsimulation, statenodessuchasflipflop outputsareinitializedtoan unknownstate(x)

Constantsstartingwithzorx arepaddedwithleadingzs or xs (insteadof0s)toreachtheir fulllengthwhennecessary


14

Bitswizzling
assign y = {c[2:1], {3{d[0]}}, c[0], 3'b101};

c[2:1] subset,2bitvector Concatenateoperator:{}


{3{d[0]}}indicatesthreecopies ofd[0] 3'b101isa3bitbinary constant yisa9bitvector Ifywerewiderthan9bits, zeroswouldbeplacedinthe mostsignificantbitpositions

module mul(input logic [7:0] a, b, output logic [7:0] upper, lower); assign {upper, lower} = a*b; endmodule

module signextend(input logic [15:0] a, output logic [31:0] y); assign y = {{16{a[15]}}, a[15:0]}; endmodule

15

Delays
`timescale 1ns/1ps module example(input logic a, b, c, output logic y); logic ab, bb, cb, n1, n2, n3; assign assign assign assign assign endmodule #1 #2 #2 #2 #4 {ab, bb, cb} = ~{a, b, c}; n1 = ab & bb & cb; n2 = a & bb & cb; n3 = a & bb & c; y = n1 | n2 | n3;

Statementsmaybeassociatedwith delaysspecifiedinarbitraryunits Helpfulduringsimulation


Predicthowfastacircuitwillwork(if youspecifymeaningfuldelays) Debugthecauseandeffect

Delaysareignoredduringsynthesis
Delayofagateproducedbythe synthesizerdependsonitstpd andtcd specifications

Timescaledirective
`timescaleunit/step

#symbolisusedtoindicatethe numberofunitsofdelay
Itcanbeplacedinassignstatements, aswellasnonblocking (<=)and blocking(=)assignments

16

StructuralModel
Describeamoduleintermsofhow itiscomposedofsimplermodules Mux4outofMux2s TryDec4to16usingDec2to4s?
module mux2_4 (input logic [3:0] d0, d1, input logic s, output logic [3:0] y); assign y = s ? d1 : d0; endmodule

module mux4_4 (input logic [3:0] d0, d1, d2, d3, input logic [1:0] s, output logic [3:0] y); logic [3:0] mol, moh; mux2_4 lowmux(d0, d1, s[0], mol); mux2_4 highmux(d2, d3, s[0], moh); mux2_4 finalmux(mol, moh, s[1], y); endmodule

17

StructuralModeling
module tristate_4 (input logic [3:0] a, input logic en, output tri [3:0] y); assign y = en ? a : 4bz; endmodule // demonstrate selection of ranges on a bus module mux2_8 (input logic [7:0] d0, d1, input logic s, output logic [7:0] y); mux2_4 lsbmux(d0[3:0], d1[3:0], s, y[3:0]); mux2_4 msbmux(d0[7:4], d1[7:4], s, y[7:4]); // mux2 using tristate module mux2_4 (input logic [3:0] d0, d1, input logic s, output tri [3:0] y); tristate(d0, ~s, y); tristate(d1, s, y); endmodule endmodule

18

SequentialLogic
HDLsynthesizersrecognizecertainidiomsandturnthem intospecificsequentialcircuits Othercodingstylesmaysimulatecorrectly,butsynthesize intocircuitswithblatantorsubtleerrors Note:Usetheproperidiomstodescriberegistersand latchesdescribedhere

19

Registers
4bitregister
module flop(input logic clk, input logic [3:0] d, output logic [3:0] q); always_ff @(posedge clk) q <= d; endmodule

alwaysstatementform:
always@(sensitivitylist)statement;

Thestatementisexecutedonlywhen theeventspecifiedinthesensitivity listoccurs


q<=d(pronouncedqgetsd)only onthepositiveedgeoftheclockand otherwiserememberstheoldstateof q

<=iscalledanonblocking assignment
Agroupofnonblocking assignmentsis evaluatedconcurrently alloftheexpressionsontheright handsidesareevaluatedbeforeany ofthelefthandsidesareupdated

20

Flipflops
DFFwith PositiveClock
module flop (C, D, Q); input C, D; output Q; reg Q;

DFFwithNegativeedgeClock andAsync.Clear
module flop (C, D, CLR, Q); input C, D, CLR; output Q; reg Q;

always @(posedge C) begin Q = D; end endmodule

always @(negedge C or posedge CLR) begin if (CLR) Q = 1'b0; else Q = D; end endmodule

21

Flipflops
DFFwithPositiveEdgeClockand SynchronousSet
module flop (C, D, S, Q); input C, D, S; output Q; reg Q; always @(posedge C) begin if (S) Q = 1'b1; else Q = D; end endmodule

DFFwithPositiveEdgeClockand ClockEnable
module flop (C, D, CE, Q); input C, D, CE; output Q; reg Q;

always @(posedge C) begin if (CE) Q = D; end endmodule

22

ResettableRegisters
module flopr_s(input logic clk, input logic reset, input logic [3:0] d, output logic [3:0] q); // synchronous reset always_ff @(posedge clk) if (reset) q <= 4'b0; else q <= d; endmodule module flopr_a(input logic clk, input logic reset, input logic [3:0] d, output logic [3:0] q); // asynchronous reset always_ff @(posedge clk, posedge reset) if (reset) q <= 4'b0; else q <= d; endmodule

Whensimulationbeginsorpoweris firstappliedtoacircuit,theoutputof theflopisunknown(xinVerilog) =>Useresettableregisterssothaton powerupyoucanputyoursystemin aknownstate Synchronousorasynchronousreset


Synchronous:occursontheactive edgeoftheclock Asynchronous:occursimmediately

Note:
Synchronousresettakesfewer transistorsandreducestheriskof timingproblemsonthetrailingedge ofreset However,ifclockgatingisused,care mustbetakenthatallflipflops reset properlyatstartup

23

EnabledResettableRegisters
module flopenr(input logic clk, input logic reset, input logic en, input logic [3:0] d, output logic [3:0] q); // synchronous reset always_ff @(posedge clk) if (reset) q <= 4'b0; else if (en) q <= d; endmodule

24

SynchronizerCircuit
module sync(input logic clk, input logic d, output logic q); logic n1;

Multiplestatementsinalways blocksaremarkedbyabegin endpair Nonblocking assignments

always_ff @(posedge clk) begin n1 <= d; q <= n1; end endmodule

25

Latches
LatchwithPositiveGate
module latch (G, D, Q); input G, D; output Q; reg Q;

LatchwithPositiveGateand AsynchronousClear
module latch (G, D, CLR, Q); input G, D, CLR; output Q; reg Q;

always @(G or D) begin if (G) Q = D; end endmodule

always @(G or D or CLR) begin if (CLR) Q = 1'b0; else if (G) Q = D; end endmodule

26

4bitLatch
4bitLatchwithInvertedGateand AsynchronousPreset
module latch (G, D, PRE, Q); input G, PRE; input [3:0] D; output [3:0] Q; reg [3:0] Q;

always @(G or D or PRE) begin if (PRE) Q = 4'b1111; else if (~G) Q = D; end endmodule

27

4bitLatch
always_latch
module latch(input logic clk, input logic [3:0] d, output logic [3:0] q); always_latch if (clk) q <= d; endmodule

Newconstructin SystemVerilog Equivalenttoalways@(clk,d)

28

Counters
module counter(input logic clk, input logic reset, output logic [3:0] q); always_ff @(posedge clk) if (reset) q <= 4'b0; else q <= q+1; endmodule module counter(input logic clk, input logic reset, output logic [3:0] q); logic [3:0] nextq; flopr qflop(clk, reset, nextq, q); adder inc(q, 4'b0001, nextq); endmodule

29

Shifters
module shiftreg(input logic clk, input logic reset, load, input logic sin, input logic [3:0] d, output logic [3:0] q, output logic sout); always_ff @(posedge clk) if (reset) q <= 0; else if (load) q <= d; else q <= {q[2:0], sin}; assign sout = q[3]; endmodule

30

CombinationalLogicwithAlwaysBlocks
always_comb
module inv(input logic [3:0] a, output logic [3:0] y); always_comb y = ~a; endmodule

module fulladder(input logic a, b, cin, output logic s, cout); logic p, g; always_comb begin p = a ^ b; // blocking g = a & b; // blocking s = p ^ cin; cout = g | (p & cin); end endmodule

Modelcombinationallogic Reevaluatesthestatements insidethealwaysblockanytime anyofthesignalsontheright handsideof<=or=insidethe alwaysstatementchange Preferredwayofdescribing combinationallogicin SystemVerilog Equivalenttoalways@(*)

=inthealwaysstatementiscalled ablockingassignment
Preferredforcombinationallogic inSystemVerilog

Agroupofblockingassignments areevaluatedintheorderthey appearinthecode

31

TriState
module three_st (T, I, O); input T, I; output O; reg O; module three_st (T, I, O); input T, I; output O;

always @(T or I) begin if (~T) O = I; else O = 1'bZ; end endmodule

assign O = (~T) ? I: 1'bZ; endmodule

32

Muxes
module mux2( input d0, d1, s, output y); module mux2( input d0, d1, s, output y); reg y;

reg y;

always @(s or d0 or d1) begin : MUX case(s) 1'b0 : y = d0; 1'b1 : y = d1; endcase end endmodule

always @(*) begin : MUX case(s) 1'b0 : y = d0; 1'b1 : y = d1; endcase end endmodule

Warning:Allthesignalsontheleftsideofassignmentsinalwaysblocks mustbedeclaredasreg.However,declaringasignalasreg doesnotmean thesignalisactuallyaregister.

33

CaseStatements
module sevenseg(input logic [3:0] data, output logic [6:0] segments); always_comb case (data) // abc_defg 0: segments = 7'b111_1110; 1: segments = 7'b011_0000; 2: segments = 7'b110_1101; 3: segments = 7'b111_1001; 4: segments = 7'b011_0011; 5: segments = 7'b101_1011; 6: segments = 7'b101_1111; 7: segments = 7'b111_0000; 8: segments = 7'b111_1111; 9: segments = 7'b111_1011; default: segments = 7'b000_0000; endcase endmodule module decoder3_8(input logic [2:0] a, output logic [7:0] y); always_comb case (a) 3'b000: y 3'b001: y 3'b010: y 3'b011: y 3'b100: y 3'b101: y 3'b110: y 3'b111: y endcase endmodule

= = = = = = = =

8'b00000001; 8'b00000010; 8'b00000100; 8'b00001000; 8'b00010000; 8'b00100000; 8'b01000000; 8'b10000000;

34

Ifelse,Casez
module priorityckt(input logic [3:0] a, output logic [3:0] y); always_comb if (a[3]) y = 4'b1000; else if (a[2]) y = 4'b0100; else if (a[1]) y = 4'b0010; else if (a[0]) y = 4'b0001; else y = 4'b0000; endmodule module priority_casez(input logic [3:0] a, output logic [3:0] y); always_comb casez(a) 4'b1???: 4'b01??: 4'b001?: 4'b0001: default: endcase endmodule

y y y y y

= = = = =

4'b1000; 4'b0100; 4'b0010; 4'b0001; 4'b0000;

35

BlockingandNonblockingAssignments
Blockingassignments(use=)
Agroupofblockingassignments insideabeginendblockisevaluatedsequentially

Nonblockingassignments(use<=)
Agroupofnonblockingassignmentsareevaluatedin parallel;allofthestatementsareevaluatedbeforeanyof theleftsidesareupdated.

36

Blockingvs.Nonblocking
1.Usealways_ff @(posedge clk) andnonblocking assignmentsto modelsynchronoussequential logic 2.Usecontinuousassignmentsto modelsimplecombinationallogic Usealways_comb andblocking assignmentstomodelmore complicatedcombinationallogic wherethealwaysstatementis helpful 4.Donotmakeassignmentsto thesamesignalinmorethanone alwaysstatementorcontinuous assignmentstatement.Exception: tristate busses.
always_ff @(posedge clk) begin n1 <= d; // nonblocking q <= n1; // nonblocking end

assign y = s ? d1 : d0;

always_comb begin p = a ^ b; // blocking g = a & b; // blocking s = p ^ cin; cout = g | (p & cin); end

37

Blockingvs.Nonblocking (contd)
// nonblocking assignments (not recommended) module fulladder(input logic a, b, cin, output logic s, cout); logic p, g; always_comb begin p <= a ^ b; // nonblocking g <= a & b; // nonblocking s <= p ^ cin; cout <= g | (p & cin); end endmodule a=b=cin=0; // initial conditions p=g=0; a=1; // a changes => trigger always block -------/* all nonblocking assignments are concurently executed; all assume a=1, b=0, cin=0 */ p<=1; // sch. change for next delta (1) g<=0; // no changes s<=0; // no changes cout<=0; // no changes --------------/* move time; p has changed, re-evaluate always block again) (a=1, p=1)*/ .... module fulladder(input logic a, b, cin, output logic s, cout); logic p, g; always_comb begin p = a ^ b; // blocking g = a & b; // blocking s = p ^ cin; cout = g | (p & cin); end a=b=cin=0; // initial conditions a=1; // a changes => trigger always block /* Note that p and g get their new value before s and cout are computed because of the blocking assignments. This is important because we want to compute s and cout using the new values of p and g.*/ ----------------p=1; // immediate assignment g=0; s=1; cout=0;

38

Blockingvs.Nonblocking (contd)
module sync(input logic clk, input logic d, output logic q); logic n1; logic n1; always_ff @(posedge clk) begin n1 <= d; q <= n1; end endmodule always_ff @(posedge clk) begin n1 = d; // blocking q = n1; // blocking end endmodule // Bad implementation using blocking assignments module syncbad(input logic clk, input logic d, output logic q);

39

Blockingvs.Nonblocking (contd)
module shiftreg (input clk, input sin, output reg [3:0] q); always @(posedge clk) begin q[0] <= sin; q[1] <= q[0]; q[2] <= q[1]; q[3] <= q[2]; // could be replaced by // q <= {q[2:0], sin} end endmodule end endmodule // this is incorrect shift register module shiftreg (input clk, input sin, output reg [3:0] q); always @(posedge clk) begin q[0] = sin; q[1] = q[0]; q[2] = q[1]; q[3] = q[2];

40

FiniteStateMachines

41

MooreMachine
module divideby3FSM(input logic clk, input logic reset, output logic y); logic [1:0] state, nextstate; // State Register always_ff @(posedge clk) if (reset) state <= 2'b00; else state <= nextstate; // Next State Logic always_comb case (state) 2'b00: nextstate = 2'b01: nextstate = 2'b10: nextstate = default: nextstate endcase

2'b01; 2'b10; 2'b00; = 2'b00;

// Output Logic assign y = (state == 2'b00); endmodule

42

MooreMachine
module divideby3FSM(input logic clk, input logic reset, output logic y); typedef enum logic [1:0] {S0, S1, S2} statetype; statetype state, nextstate; // State Register always_ff @(posedge clk) if (reset) state <= S0; else state <= nextstate; // Next State Logic always_comb case (state) S0: nextstate = S1; S1: nextstate = S2; S2: nextstate = S0; default: nextstate = S0; endcase // Output Logic assign y = (state == S0); endmodule

typedef definesstatetype to beatwobitlogicvaluewith oneofthreepossibilities:S0, S1,orS2 stateandnextstate are statetype signals Enumeratedencodingsdefault tonumericalorder:S0=00,S1 =01,andS2=10 Theencodingscanbeexplicitly setbytheuser
Thefollowingsnippet encodesthestatesas3bit onehotvalues: typedef enum logic[2:0]{S0= 3'b001,S1=3'b010,S2= 3'b100}statetype;
43

MealyMachine
Identify3portions
Stateregister Nextstatelogic Outputlogic

Stateregister
Resetsasynchronouslytothe initialstate Otherwiseadvancestothenext state

Nextlogic
Computesthenextstateasa functionofthecurrentstateand inputs

Outputlogic
Computestheoutputasa functionofthecurrentstateand theinputs
44

MealyMachine(contd)
module historyFSM(input logic clk, input logic reset, input logic a, output logic x, y); typedef enum logic [2:0] {S0, S1, S2, S3, S4} statetype; statetype state, nextstate; always_ff @(posedge clk) if (reset) state <= S0; else state <= nextstate; always_comb case (state) S0: if (a) nextstate else nextstate = S1: if (a) nextstate else nextstate = S2: if (a) nextstate else nextstate = S3: if (a) nextstate else nextstate = S4: if (a) nextstate else nextstate = default: nextstate = endcase 45 //output logic assign x = (state[1] & ~a) | (state[2] & a); assign y = (state[1] & state[0] & ~a) | (state[2] & state[0] & a);

endmodule

= S3; S1; = S3; S2; = S3; S2; = S4; S1; = S4; S1; S0;

TypeIdiosyncracies
StandardVerilog primarilyuses twotypes:reg andwire
reg signalmightormightnotbe associatedwitharegister Wasagreatsourceofconfusion forthoselearningthelanguage
module flop(input clk, input [3:0] d, output reg [3:0] q); always @(posedge clk) q <= d; endmodule

InstandardVerilog
ifasignalappearsontheleft handsideof<=or=inanalways block,itmustbedeclaredasreg Otherwise,itshouldbedeclared aswire Inputandoutputportsdefaultto thewiretypeunlesstheirtypeis explicitlyspecifiedasreg

qissetinalwaysblock=> declaredasreg type

46

TypeIdiosyncracies (contd)
SystemVerilog introducedthelogictype
logicisasynonymforreg

Logiccanbeusedoutsidealwaysblocks whereawiretraditionallywouldberequired
NearlyallSystemVerilog signalscanbe logic

Theexceptionaresignalswithmultiple drivers(e.g.,atristate bus)


Mustbedeclaredasanet AllowsSystemVerilog togenerateanerror messageratherthananxvaluewhena logicsignalisaccidentallyconnectedto multipledrivers

Themostcommontypeofnetiscalledawire ortri
Synonymous,butwireisconventionally usedwhenasingledriverispresentandtri isusedwhenmultipledriversarepresent wireisobsoleteinSystemVerilog =>use logic

Typesandnetresolution(seetable)

47

ParameterizedModules
2waymux,defaultwidth8
module mux2 #(parameter width = 8) (input logic [width-1:0] d0, d1, input logic s, output logic [width-1:0] y); assign y = s ? d1 : d0; endmodule // use default widths module mux4_8(input logic [7:0] d0, d1, d2, d3, input logic [1:0] s, output logic [7:0] y); logic [7:0] low, hi; mux2 lowmux(d0, d1, s[0], low); mux2 himux(d2, d3, s[0], hi); mux2 outmux(low, hi, s[1], y); endmodule

// 12-bit mux; override default using #() module mux4_12(input logic [11:0] d0, d1, d2, d3, input logic [1:0] s, output logic [11:0] y); logic [11:0] low, hi; mux2 #(12) lowmux(d0, d1, s[0], low); mux2 #(12) himux(d2, d3, s[0], hi); mux2 #(12) outmux(low, hi, s[1], y); endmodule

48

ParameterizedModules
module decoder #(parameter N = 3) (input logic [N-1:0] a, output logic [2**N-1:0] y); always_comb begin y = 0; y[a] = 1; end endmodule

49

GenerateStatement
module andN #(parameter width = 8) (input logic [width-1:0] a, output logic y); genvar i; logic [width-1:1] x; generate for (i=1; i<width; i=i+1) begin:forloop if (i == 1) assign x[1] = a[0] & a[1]; else assign x[i] = a[i] & x[i-1]; end endgenerate assign y = x[width-1]; endmodule

Generatestatementsproduce avariableamountofhardware dependingonthevalueofa parameter Generatesupportsforloops andifstatementstodetermine howmanyofwhattypesof hardwaretoproduce Example:NinputANDfunction fromacascadeof2inputANDs

50

Memories
// separate read and write busses module ram #(parameter N = 6, M = 32) (input logic clk, input logic we, input logic [N-1:0] adr, input logic [M-1:0] din, output logic [M-1:0] dout); logic [M-1:0] mem[2**N-1:0]; always @(posedge clk) if (we) mem[adr] <= din; assign dout = mem[adr]; endmodulev // bidirectional bus module ram #(parameter N = 6, M = 32) (input logic clk, input logic we, input logic [N-1:0] adr, inout tri [M-1:0] data); logic [M-1:0] mem[2**N-1:0]; always @(posedge clk) if (we) mem[adr] <= data; assign data = we ? 'z : mem[adr]; endmodule

51

MultiportedRegisterFiles,ROMs
module ram3port #(parameter N = 6, M = 32) (input logic clk, input logic we3, input logic [N-1:0] a1, a2, a3, output logic [M-1:0] d1, d2, input logic [M-1:0] d3); logic [M-1:0] mem[2**N-1:0]; always @(posedge clk) if (we3) mem[a3] <= d3; assign d1 = mem[a1]; assign d2 = mem[a2]; endmodule module rom(input logic [1:0] adr, output logic [2:0] dout); always_comb case(adr) 2'b00: dout 2'b01: dout 2'b10: dout 2'b11: dout endcase endmodule

= = = =

3'b011; 3'b110; 3'b100; 3'b010;

52

Testbench
Testbench isanHDLmoduleused totestanothermodule,calledthe deviceundertest(DUT) Containsstatementstoapply inputstotheDUTand,ideally,to checkthatthecorrectoutputsare produced
Inputanddesiredoutputpatterns arecalledtestvectors.
module testbench1(); logic a, b, c; logic y; // instantiate device under test sillyfunction dut(a, b, c, y); // apply inputs one at a time initial begin a = 0; b = 0; c = 0; #10; c = 1; #10; b = 1; c = 0; #10; c = 1; #10; a = 1; b = 0; c = 0; #10; c = 1; #10; b = 1; c = 0; #10; c = 1; #10; end endmodule

Initialstatementexecutesthe statementsinitsbodyatthestart ofsimulation Initialstatementsshouldonlybe usedintestbenches for simulation,notinmodules intendedtobesynthesizedinto actualhardware

53

SelfCheckingTestbench
Checkingforcorrectoutputsby handistediousanderrorprone Determiningthecorrectoutputsis mucheasierwhenthedesignis freshinyourmind =>Amuchbetterapproachisto writeaselfcheckingtestbench SystemVerilog assertstatement checksifaspecifiedconditionis true
Ifitisnot,itexecutestheelse statement. $errorsystemtaskintheelse statementprintsanerror messagedescribingthe assertionfailure
module testbench2(); logic a, b, c; logic y; // instantiate device under test sillyfunction dut(a, b, c, y); // apply inputs one at a time // checking results initial begin a = 0; b = 0; c = 0; #10; assert (y === 1) else $error("000 c = 1; #10; assert (y === 0) else $error("001 b = 1; c = 0; #10; assert (y === 0) else $error("010 c = 1; #10; assert (y === 0) else $error("011 a = 1; b = 0; c = 0; #10; assert (y === 1) else $error("100 c = 1; #10; assert (y === 1) else $error("101 b = 1; c = 0; #10; assert (y === 0) else $error("110 c = 1; #10; assert (y === 0) else $error("111 end endmodule

failed."); failed."); failed."); failed."); failed."); failed."); failed."); failed.");

InSystemVerilog,comparison using==or!=spuriouslyindicates equalityifoneoftheoperandsisx orz. The===and!==operatorsmust beusedinsteadfortestbenches becausetheyworkcorrectlywithx andz

54

Testbench withTestVectorFile
module testbench3(); logic clk, reset; logic a, b, c, yexpected; logic y; logic [31:0] vectornum, errors; logic [3:0] testvectors[10000:0]; // instantiate device under test sillyfunction dut(a, b, c, y); // generate clock always begin clk = 1; #5; clk = 0; #5; end // at start of test, load vectors // and pulse reset initial begin $readmemb("example.tv", testvectors); vectornum = 0; errors = 0; reset = 1; #27; reset = 0; end

example.tv
000_1 001_0 010_0 011_0 100_1 101_1 110_0 111_0

55

Testbench withTestVectorFile(contd)
// apply test vectors on rising edge of clk always @(posedge clk) begin // wait for 1 time unit before assignment #1; {a, b, c, yexpected} = testvectors[vectornum]; end // check results on falling edge of clk always @(negedge clk) if (~reset) begin // skip during reset if (y !== yexpected) begin $display("Error: inputs = %b", {a, b, c}); $display(" outputs = %b (%b expected)", y, yexpected); errors = errors + 1; end vectornum = vectornum + 1; if (testvectors[vectornum] === 'bx) begin $display("%d tests completed with %d errors", vectornum, errors); $finish; end end endmodule

$readmemb readsafileof binarynumbersintoanarray $readmemh readsafileof hexadecimalnumbersintoan array #1;waitsonetimeunitafter therisingedgeoftheclock(to avoidanyconfusionofclock anddatachanging simultaneously) $displayisasystemtaskto printinthesimulatorwindow $finishterminatesthe simulation Notehowweterminate simulationafter8testvectors
56