Date post: | 20-Dec-2015 |
Category: |
Documents |
View: | 307 times |
Download: | 3 times |
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
_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.
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