verilog ii cpsc 321 andreas klappenecker today’s menu verilog, verilog

50
Verilog II CPSC 321 Andreas Klappenecker

Post on 20-Dec-2015

307 views

Category:

Documents


3 download

TRANSCRIPT

Verilog IICPSC 321

Andreas Klappenecker

Today’s Menu

Verilog, Verilog, Verilog

Modules

module mod_name (parameters);input …output …reg ………endmodule

Full Adder

module fulladd(cin, x, y, s, cout) input cin, x, y; output s, cout; assign s = x ^ y ^ cin; assign cout = (x & y) | (cin & x) | (cin

& y); endmodule

Full Adder

module fulladd(cin, x,y,s, cout);input cin, x, y;output s, cout;assign { cout, s } = x + y + cin;endmodule

The assign statement assigns the MSB to cout and the LSB to s.

Hello World

module top;

initial

$display("Hello, world!");

endmodule

initial statements are executed once by the simulator

Vector wires

• Range [msb: lsb] wire [3:0] S;

S = 4’b0011 The result of this assignment is

S[3] = 0, S[2] = 0, S[1] = 1, S[0] = 1• wire [1:2] A;

A = S[2:1];

means A[1] = S[2], A[2] = S[1]

Variables

• Variables come in two flavors• reg• integers

• reg can model combinatorial or sequential parts of the circuits

reg does not necessarily denote a register!

• Integers often used as loop control variables

useful for describing the behavior of a module

Simple Example

module testgate;

reg b, c; // variables

wire a, d, e; // nets

and (d, b, c); // gates

or (e, d, c); //

nand(a, e, b); //

initial begin // simulated once

b=1; c=0; // blocking assignments

#10 $display("a = %b", a);

end

endmodule What value will be printed?

Operators

• 1’s complement ~A• 2’s complement -A• bitwise AND A&B• reduction &A produces AND of all bits in A

• Concatenate {a,b,c} • | {a,b,c} = a | b | c• Replication operators 2{A} = {A,A}

• {2{A},3{B}} = {A,A,B,B,B}

Continuous assignments

• Single bit assignments assign s = x ^ y ^ cin; assign cout = (x & y) | (cin & x) | (cin &y )

• Multibit assignments wire [1:3] a,b,c; … assign c = a & b;

Always Blocks

• An always block contains one or more procedural statements

• always @(sensitivity list) always @(x or y) begin

s = x ^ y;

c = x & y;

end

Mux: Structural Verilog

module mux(f, a,b,sel);

input a,b,sel;

output f;

wire f1, f2;

not(nsel, sel);

and(f1, a,nsel);

and(f2, b, sel);

or (f, f1, f2);

endmodule

ba

sel

f

Mux: Dataflow Model

module mux2(f, a,b,sel);

output f;

input a,b,sel;

assign f = (a & ~sel) | (b & sel);

endmodule

Mux: Behavioral Model

module mux2(f, a,b,sel);

output f;

input a,b,sel;

reg f;

always @(a or b or sel)

if (sel==1)

f = b;

else

f = a;

endmodule

Sign extension and addition

module adder_sign(x,y,s,ss);

input [3:0] x,y;

output [7:0] s, ss;

assign s = x + y,

ss = {{4{x[3]}},x}+{{4{y[3]},y}

endmodulex = 0011, y = 1101s = 0011 + 1101 = 00010000ss = 0011 + 1101 = 00000011 + 11111101= 00000000

Demux Example

2-to-4 demultiplexer with active low

enable a b z[3] z[2] z[1] z[0]

0 x x 1 1 1 1

1 0 0 1 1 1 0

1 1 0 1 1 0 1

1 0 1 1 0 1 1

1 1 1 0 1 1 1

Demux: Structural Model

// 2-to-4 demultiplexer

module demux1(z,a,b,enable);

input a,b,enable;

output [3:0] z;

wire abar,bbar;

not v0(abar,a), v1(bbar,b);

nand (z[0],enable,abar,bbar);

nand (z[1],enable,a,bbar);

nand (z[2],enable,abar,b);

nand (z[3],enable,a,b);

endmodule

enable a b z[3] z[2] z[1] z[0]

0 x x 1 1 1 1

1 0 0 1 1 1 0

1 1 0 1 1 0 1

1 0 1 1 0 1 1

1 1 1 0 1 1 1

Demux: Dataflow model

// 2-to-4 demux

// dataflow model module

demux2(z,a,b,enable);

input a,b,enable;

output [3:0] z;

assign z[0] = | {~enable,a,b};

assign z[1] = ~(enable & a & ~b);

assign z[2] = ~(enable & ~a & b);

assign z[3] = enable ? ~(a & b) : 1'b1;

endmodule

enable a b z[3] z[2] z[1] z[0]

0 x x 1 1 1 1

1 0 0 1 1 1 0

1 1 0 1 1 0 1

1 0 1 1 0 1 1

1 1 1 0 1 1 1

Demux: Behavioral Model

// 2-to-4 demultiplexer with active-low outputs

module demux3(z,a,b,enable);

input a,b,enable;

output [3:0] z;

reg z; // not really a register!

always @(a or b or enable)

case ({enable,a,b})

default: z = 4'b1111;

3'b100: z = 4'b1110;

3'b110: z = 4'b1101;

3'b101: z = 4'b1011;

3'b111: z = 4'b0111;

endcase

endmodule

enable a b z[3] z[2] z[1] z[0]

0 x x 1 1 1 1

1 0 0 1 1 1 0

1 1 0 1 1 0 1

1 0 1 1 0 1 1

1 1 1 0 1 1 1

Always Blocks

• The sensitivity list @( … ) contains the events triggering an evaluation of the block

• @(a or b or c)• @(posedge a)• @(negedge b)

• A Verilog compiler evaluates the statements in the always block in the order in which they are written

Assignments

• If a variable is assigned a value in a blocking assignment

a = b & c; then subsequent references to a

contain the new value of a•Non-blocking assignments <= assigns the value that the variables

had while entering the always block

D Flip-flop

module D_FF(Q,D,clock);

output Q;

input D, clock;

reg Q;

always @(negedge clock)

Q <= D;

endmodule

QQ

_Q

Q

_Q

Dlatch

D

C

Dlatch

DD

C

C

D

C

Q

Clock

• A sequential circuit will need a clock• supplied by the testbed

• Clock code fragment reg clock;

parameter period = 100;

initial clock 0;

always @(period/2)

clock = ~clock;

D-Flipflop with Synchronous Reset

module flipflop(D, Clock, Resetn, Q);

input D, Clock, Resetn;

output Q;

reg Q;

always @(posedge Clock)

if (!Resetn)

Q <= 0;

else

Q <= D;

endmodule // 7.46 in [BV]

module latch(D, clk, Q)

input D, clk;

output Q;

reg Q;

always @(D or clk)

if (clk)

Q <= D;

endmoduleMissing else clause => a latch will be synthesized to keep value of Q when clk=0

Gated D-Latch

Q

C

D

_Q

D

C

Q

module example(D,Clock, Q1, Q2)

input D, Clock;

output Q1, Q2;

reg Q1, Q2;

always @(posedge Clock)

begin

end

endmodule

Shift Register: What is wrong here?

Q1 = D;

Q2 = Q1;

Q1 = D;

Q2 = Q1; // D=Q1=Q2

Shift register: Correct Version

module example(D,Clock, Q1, Q2)

input D, Clock;

output Q1, Q2;

reg Q1, Q2;

always @(posedge Clock)

begin

Q1 <= D;

Q2 <= Q1;

end

endmodule

Rule of Thumb

• Blocking assignments are used to describe combinatorial circuits

• Non-blocking assignments are used in sequential circuits

n-bit Ripple Carry Adder

module ripple(cin, X, Y,

S, cout);

parameter n = 4;

input cin;

input [n-1:0] X, Y;

output [n-1:0] S;

output cout;

reg [n-1:0] S;

reg [n:0] C;

reg cout;

integer k;

always @(X or Y or cin)

begin

C[0] = cin;

for(k = 0; k <= n-1; k=k+1)

begin

S[k] = X[k]^Y[k]^C[k];

C[k+1] = (X[k] & Y[k])

|(C[k]&X[k])|(C[k]&Y[k]);

end

cout = C[n];

end

endmodule

Loops and Integers

• The for loop is used to instantiate hardware modules

• The integer k simply keeps track of instantiated hardware

• Do not confuse integers with reg variables

Bit-Counter

• Count the number of bits having value 1 in register X

• Again an example for parameters• Another example of a for loop

Bit Counter

module bit_cnt(X,Count);

parameter n = 4;

parameter logn = 2;

input [n-1:0] X;

output [logn:0] Count;

reg [logn:0] Count;

integer k;

always @(X)

begin

Count = 0;

for(k=0;k<n;k= k+1)

Count=Count+X[k];

end

endmodule

Blocks of Procedural Code

• initial • executed once at the beginning of simulation• initial $display(“Hello World”);

• always• repeatedly executed

• begin-end• sequential execution of block statements• delays add up

• fork-join blocks• concurrent execution of statements

Concurrency Example

module concurrency_example;

initial begin

#1 $display(“Block 1 stmt 1");

$display(“Block 1 stmt 2");

#2 $display(“Block 1 stmt 3");

end

initial begin

$display("Block 2 stmt 1");

#2 $display("Block 2 stmt 2");

#2 $display("Block 2 stmt 3");

end

endmodule

Block 2 stmt 1

Block 1 stmt 1

Block 1 stmt 2

Block 2 stmt 2

Block 1 stmt 3

Block 2 stmt 3

Concurrency Example

module concurrency_example;

initial begin

#1 $display(“Block 1 stmt 1");

$display(“Block 1 stmt 2");

#2 $display(“Block 1 stmt 3");

end

initial begin

$display("Block 2 stmt 1");

#2 $display("Block 2 stmt 2");

#2 $display("Block 2 stmt 3");

end

endmodule

Block 2 stmt 1

Block 1 stmt 1

Block 1 stmt 2

Block 2 stmt 2

Block 1 stmt 3

Block 2 stmt 3

Concurrency: fork and join

module concurrency_example;

initial fork

#1 $display(“Block 1 stmt 1");

$display(“Block 1 stmt 2");

#2 $display(“Block 1 stmt 3");

join

initial fork

$display("Block 2 stmt 1");

#2 $display("Block 2 stmt 2");

#2 $display("Block 2 stmt 3");

join

endmodule

Block 1 stmt 2

Block 2 stmt 1

Block 1 stmt 1

Block 1 stmt 3

Block 2 stmt 2

Block 2 stmt 3

Displaying Results

a = 4’b0011

$display(“The value of a is %b”, a);

The value of a is 0011

$display(“The value of a is %0b”, a);

The value of a is 11

If you you $display to print a value that is changingduring this time step, then you might get the new orthe old value; use $strobe to get the new value

Displaying Results

• Standard displaying functions• $display, $write, $strobe, $monitor

• Writing to a file instead of stdout• $fdisplay, $fwrite, $fstrobe, $fmonitor

• Format specifiers• %b, %0b, %d, %0d, %h, %0h, %c, %s,…

Display Example

module f1;

integer f;

initial begin

f = $fopen("myFile");

$fdisplay(f, "Hello, bla bla");

end

endmodule

Moore Machines

The output of a Moore machine dependsonly on the current state. Output logic andnext state logic are sometimes merged.

next

state

logic

present

state

register

output

logic

input

Coding Moore Machines

• The logic in the Moore machine can be described by two case statements

(one case statement if logic blocks are merged)

• Enumerate all possible states of input and current state, and generate the output and next state

• Give states meaningful names using define or parameters

Moore Machine Example

Automatic food cooker• Has a supply of food• Can load food into the heater when

requested• Cooker unloads the food when cooking

done

Automated Cooker

Outputs from the machine• load = signal that sends food into the

cooker• heat = signal that turns on the heater• unload = signal that removes food from

cooker• beep = signal that alerts that food is done

Automated Cooker

Inputs• clock • start = start the load, cook, unload

cycle• temp_ok = temperature sensor

detecting when preheating is done• done = signal from timer when done• quiet = Should cooker beep?

Cooker

module cooker(

clock, start, temp_ok, done, quiet, load, heat, unload, beep

);

input clock, start, temp_ok, done, quiet;

output load, heat, unload, beep;

reg load, heat, unload, beep;

reg [2:0] state, next_state;

Defining States

`define IDLE 3'b000

`define PREHEAT 3'b001

`define LOAD 3'b010

`define COOK 3'b011

`define EMPTY 3'b100

You can refer to these states as ‘IDLE, ‘PREHEAT, etc.

State Register Block

`define REG_DELAY 1

always @(posedge clock)

state <= #(`REG_DELAY) next_state;

Next State Logic

always @(state or start or temp_ok or done)

// whenever there is a change in input

begin

case (state)

`IDLE: if (start) next_state=`PREHEAT;

`PREHEAT: if (temp_ok) next_state = `LOAD;

`LOAD: next_state = `COOK;

`COOK: if (done) next_state=`EMPTY;

`EMPTY: next_state = `IDLE;

default: next_state = `IDLE;

endcase

end

Output Logic

always @(state)

begin

if(state == `LOAD) load = 1; else load = 0;

if(state == `EMPTY) unload =1; else unload = 0;

if(state == `EMPTY && quiet == 0) beep =1;

else beep = 0;

if(state == `PREHEAT ||

state == `LOAD ||

state == `COOK) heat = 1;

else heat =0;

end