0% found this document useful (0 votes)
20 views92 pages

Systemverilog Progressive Example Approach

The document outlines the design requirements and system descriptions for IC design, focusing on various hardware description languages (HDLs) such as VHDL and Verilog. It includes examples of structural and behavioral code for components like full adders, multiplexers, and arithmetic logic units (ALUs), as well as test benches and sequential circuits. Additionally, it covers combinational circuits, registers, counters, and memory modules, providing a comprehensive overview of digital design principles.

Uploaded by

qamar4503117
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
20 views92 pages

Systemverilog Progressive Example Approach

The document outlines the design requirements and system descriptions for IC design, focusing on various hardware description languages (HDLs) such as VHDL and Verilog. It includes examples of structural and behavioral code for components like full adders, multiplexers, and arithmetic logic units (ALUs), as well as test benches and sequential circuits. Additionally, it covers combinational circuits, registers, counters, and memory modules, providing a comprehensive overview of digital design principles.

Uploaded by

qamar4503117
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 92

Summer School IC Design

Dr. Muhammad Fahim Ul Haque


Design Requirement
• Mandatory Requirement
– Functionality
• Cost
– Power consumption
– Size
– Speed
• Design should fulfill mandatory requirement.
System Description
• Behavioral (RTL)
- Input and output behaviour
• Functional (Data flow)
- Boolean expression
• Structural (Gate level Description)
- Gate level schematic
• Physical
- Detail Layout
Hardware Description Language
• HDLs are popular mode of design entry.
• Popular HDLs are
- VHDL
-Verilog HDL
-System Verilog
• Both HDLs can describe digital systems at
several different levels –behavioral, data flow,
and structural.
Full Adder (Structural Code)
module FullAdder (s,cout,a,b,cin);
output s, cout;
input a,b,cin;
wire w1, w2, w3;
//Sum Circuit
xor(s,a,b,cin);
//Cout Circuit
and(w1,a,b);
and(w2,a,cin);
and(w3,b,cin);
or(cout,w1,w2,w3);
endmodule
Full Adder (Functional)
module fulladder (s,cout,a,b,cin);
output s, cout;
input a,b,cin;
assign s = a^b^cin;
assign cout = (a & b) | (a & cin)|(b & cin);
endmodule
Four bit Adder (Structural)
module adder4(sum,cout,a,b,cin);
output[3:0] sum;
output cout;
input[3:0] a,b;
input cin;
wire[2:0] c;
fulladder fa0 (.s(sum[0]) , .cout(c[0]) , .a(a[0]) , .b(b[0]) , .cin(cin));
fulladder fa1 (.s(sum[1]) , .cout(c[1]) , .a(a[1]) , .b(b[1]) , .cin(c[0]));
fulladder fa2 (.s(sum[2]) , .cout(c[2]) , .a(a[2]) , .b(b[2]) , .cin(c[1]));
fulladder fa3 (.s(sum[3]) , .cout(cout) , .a(a[3]) , .b(b[3]) , .cin(c[2]));
endmodule
Four bit Adder (Structural)

module adder4(sum,cout,a,b,cin);
output[3:0] sum;
output cout;
input[3:0] a,b;
input cin;
wire[2:0] c;
fulladder fa0 (.s(sum[0]) , .cout(c[0]) , .a(a[0]) , .b(b[0]) , .cin(cin));
fulladder fa1 (.s(sum[1]) , .cout(c[1]) , .a(a[1]) , .b(b[1]) , .cin(c[0]));
fulladder fa2 (.s(sum[2]) , .cout(c[2]) , .a(a[2]) , .b(b[2]) , .cin(c[1]));
fulladder fa3 (.s(sum[3]) , .cout(cout) , .a(a[3]) , .b(b[3]) , .cin(c[2]));
endmodule
Four bit Adder (Behavioral)
module adder_behave #(parameter width = 8)(sum,cout,a,b,cin);
output [width-1:0] sum;
output cout;
input [width-1:0] a,b;
input cin;
assign {cout,sum} = a + b + cin;
endmodule
MUX (Behavioral)
module mux2to1#(parameter width = 8)(f,I0,I1,sel);
output [width-1:0] f;
input [width-1:0] I0,I1;
input sel;
assign f = sel? I1:I0;
endmodule
4to1 MUX
module mux4to1 #(parameter width= 8)(f,i3,i2,i1,i0,sel);
output [width-1:0] f;
input [width-1:0] i3,i2,i1,i0;
input [1:0] sel;
assign f = sel[1] ? (sel[0]? i3 : i2): (sel[0]? i1 : i0);
endmodule
ALU (Behavioral)
module ALU#(parameter width = 4)(result,cout,a,b,cont);
output [width-1:0] result;
output cout;
input [width-1:0] a, b;
input [1:0]cont;
wire [width-1:0] b_bar, mux2to1_out, sum, and_N_out, or_N_out;
assign and_N_out = a & b;
assign or_N_out = a | b;
assign b_bar = ~b;
mux2to1#(width)mux1(mux2to1_out,b,b_bar,cont[0]);
adder#(width) add1(sum,cout,a,mux2to1_out,cont[0]);
mux4to1 #(width)mux2(result,or_N_out,and_N_out,sum,sum,cont);
endmodule
Process
• Initial Process
initial
begin
sequential statements
end

• Sequential process
always @ (sensitivity-list)
begin
sequential statements
end
Process
Assignments
• Type of Assignments
– Continuous Assignments
• Explicit Assignment
• Implicit Assignment
– Procedural Assignments
• Blocking Assignment
• Non-blocking Assignment
Procedural Assignments
Delay
• Inertial Delay

• Transport Delay
`timescale 1ns/1ps
module delay (z1, z2, z3, a);
output z1,z2,z3;
output z4;
input a;
reg z1,z2;
// Inertial Delay
a
assign #10 z3 = a;
always@(*)
z1 Begin
// Inertial Delay in process
#10 z2 <= a;
z2/z3 end
// Transport Delay
always@(a)
begin
z1 <= #10 (a);
end
endmodule
Test Benches
module FA_TB();
module FA(s,cout,a,b,cin);
reg a,b,cin;
input a,b,cin;
wire s,cout;
output s,cout;
// Applying test signal from test bench
assign s = a^b^cin;
initial
assign cout =
begin
(a&b)|(a&cin)|(b&cin);
a = 0; b = 0; cin = 0; #10;
endmodule
a = 0; b = 0; cin = 1; #10;
a = 0; b = 1; cin = 0; #10;
a = 0; b = 1; cin = 1; #10;
a = 1; b = 0; cin = 0; #10;
a = 1; b = 0; cin = 1; #10;
a = 1; b = 1; cin = 0; #10;
a = 1; b = 1; cin = 1;#10;
end
//Instantiating Fulladder module
FA dut(s,cout,a,b,cin);
endmodule
Test Benches
module FA_TB();
reg a,b,cin;
wire s,cout;
// Applying test signal from test bench
initial
begin
a = 0; b = 0; cin = 0; #10;
a = 0; b = 0; cin = 1; #10;
a = 0; b = 1; cin = 0; #10;
a = 0; b = 1; cin = 1; #10;
a = 1; b = 0; cin = 0; #10;
a = 1; b = 0; cin = 1; #10;
a = 1; b = 1; cin = 0; #10;
a = 1; b = 1; cin = 1;#10;
end
//Instantiating Fulladder module
FA dut(s,cout,a,b,cin);
endmodule
module FA_TB_complete();
reg a,b,cin; wire s, cout;
initial
begin
a = 0; b = 0; cin = 0; #5;
assert ((s===0)&&(cout===0)) else $error("000 failed");
Test Benches
#10; a = 0; b = 0; cin = 1; #5;
assert ((s===1)&&(cout===0)) else $error("001 failed");
#10; a = 0; b = 1; cin = 0; #5;
assert ((s===1)&&(cout===0)) else $error("010 failed");
#10; a = 0; b = 1; cin = 1; #5;
assert ((s===0)&&(cout===1)) else $error("011 failed");
#10; a = 1; b = 0; cin = 0; #5;
assert ((s===1)&&(cout===0)) else $error("100 failed");
#10; a = 1; b = 0; cin = 1; #5;
assert ((s===0)&&(cout===1)) else $error("101 failed");
#10; a = 1; b = 1; cin = 0; #5;
assert ((s===0)&&(cout===1)) else $error("110 failed");
#10; a = 1; b = 1; cin = 1; #5;
assert ((s===1)&&(cout===1)) else $error("111 failed"); #10;
end
FA dut(s,cout,a,b,cin);
endmodule
Test Benches
Sequential Circuits (D Flip Flop)
module DFF(q,d,clk);
output q;
input d, clk;
reg q;
always @(posedge clk)
begin
q <= d;
end
endmodule
Sequential Circuits (D Flip Flop TB)
`timescale 1ns/1ps initial
module TB_DFF(); begin
logic clk, d, q; #5; assert(q === 0) else $error("1 cycle failed");
initial #10; assert(q === 1) else $error("2 cycle failed");
begin #10; assert(q === 1) else $error("3 cycle failed");
d = 0; #5; #10; assert(q === 0) else $error("4 cycle failed"); #5;
d = 1; #10; $stop;
d = 0; #2; end
d = 1; #10; DFF ff1(q,d,clk);
d = 0; endmodule
end
always
begin
clk =1; #5;
clk =0; #5;
end
Sequential Circuits (D Latch)
module Dlatch(q,d,clk);
output q;
input d,clk;
reg q;
always @(clk,d)
begin
if (clk)
q <= d;
end
endmodule
Combinational Ckt through process
module transmission_gate(y,x,en);
output y;
input x,en;
reg y;
always @(x,en)
begin
if (en)
y = x;
else
y = 1'bz;
end
endmodule
Combinational Ckt (Decoder/Encoder)
module bin_decoder(a,z);
input [2:0] a;
output [7:0] z;
reg [7:0] z;
always @(*)
begin
case(a)
3'b000: z = 8'b00000001;
3'b001: z = 8'b00000010;
3'b010: z = 8'b00000100;
3'b011: z = 8'b00001000;
3'b100: z = 8'b00010000;
3'b101: z = 8'b00100000;
3'b110: z = 8'b01000000;
3'b111: z = 8'b10000000;
endcase
end
endmodule
Combinational Ckt (Decoder TB)
module tb_bin_decoder(); always@(posedge clk)
logic clk, reset; begin
logic [2:0] a; {a,z_expected} = testvector[iter];
logic [7:0] z; end
logic [7:0] z_expected; // checking result on falling edge of clock
logic [2:0] iter, error; always @(negedge clk)
logic [11:0] testvector[7:0]; begin
bin_decoder decode1(a,z); if (~reset)
always begin
begin if (z !== z_expected)
clk = 1; #5; begin
clk = 0; #5; $display("Error: input =%b", a);
end $display("Error: output = %b(%b expected)",z,z_expected);
initial error = error + 1;
begin end
$readmemb("test_vector.txt",testvector); if (iter === 3'b111)
iter = 0; begin
error = 0; $display("%d total error",error);
reset = 1; #22; $stop;
reset = 0; end
end iter = iter + 1;
end
end
endmodule
Sequential Circuits (Register)
module register #(parameter width = 4)(q,d,clr,ld,clk);
output reg [width-1:0] q;
input [width-1:0] d;
input clr,ld,clk;
always @(posedge clk)
begin
if (clr)
q <= {width{1'b0}};
else if (ld)
q <= d;
end
endmodule
Sequential Circuits (Shift Register)
module shift_register
#(parameter width = 4)
(q,d,clr,ls,ld,rin,clk) ;
output reg [width-1:0] q;
input [width-1:0] d;
input clr, ls, ld, rin, clk;
always @(posedge clk, posedge clr)
if(clr)
q <= {width{1'b0}};
else if(ld)
q <= d;
else if(ls)
q <= {q[width-2:0],rin};
endmodule
Sequential Circuits (Counter)
module c74163(LdN, ClrN, P, T, Clk, D, Cout, Qout);
input LdN;
input ClrN;
input P;
input T;
input Clk;
input [3:0] D;
output Cout;
output [3:0] Qout;
reg [3:0] Q;
assign Qout = Q;
assign Cout = Q[3] & Q[2] & Q[1] & Q[0] & T;
always @(posedge Clk)
begin
if (~ClrN) Q <= 4'b0000;
else if (~LdN) Q <= D;
else if (P & T) Q <= Q + 1;
end
endmodule
module clk_divider(clk, clk_50);
input clk_50;
output reg clk;
reg [31:0] count;
initial
count = 32'h00000000;
//reg count;
always@(posedge (clk_50))
begin
Clock Divider
if (count >= 32'd50000000)
count <= 32'h00000000;
else
begin
if (count<=32'd25000000)
clk <= 1;
else
clk <= 0;
count <= count + 1;
end
end
endmodule
RAM
module ram #(parameter N =6, M=32)(clk, we, adr, din, dout);
input logic clk, 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)
begin
if(we)
mem[adr] <= din;
end
assign dout = mem[adr];

endmodule
ROM/Combinational Ckt through ROM
module parity_gen(X, Y);
input [3:0] X;
output [4:0] Y;
wire ParityBit;
parameter [0:15] OT = {1'b1, 1'b0, 1'b0, 1'b1, 1'b0, 1'b1, 1'b1, 1'b0, 1'b0, 1'b1, 1'b1,
1'b0, 1'b1, 1'b0, 1'b0, 1'b1};
assign ParityBit = OT[X];
assign Y = {X, ParityBit};
endmodule
ROM/Combinational Ckt through ROM
module parity_gen(X,Y);
input [2:0] X;
output [3:0] Y;
parameter [3:0] OT[7:0] =
{5'b1000,
5'b0001,
5'b0010,
5'b1011,
5'b0100,
5'b1101,
5'b1110,
5'b0111};
assign Y = OT[X];
endmodule
State Machines

Dr. Muhammad Fahim Ul Haque


Moore and Mealy Machine
Single Way Traffic Signal Design
Single Way Traffic Signal Design
module trafficSignal (clk_50, r, y, g); always @(state)
output reg r,y,g; begin
input clk_50; case(state)
3'b000: {r,y,g} = 3'b100;
wire clk; 3'b001: {r,y,g} = 3'b100;
reg [2:0] state, nextstate; 3'b010: {r,y,g} = 3'b100;
initial 3'b011: {r,y,g} = 3'b110;
begin 3'b100: {r,y,g} = 3'b001;
state = 3'b000; nextstate = 3'b000; {r,y,g} = 3'b000; 3'b101: {r,y,g} = 3'b001;
3'b110: {r,y,g} = 3'b001;
end 3'b111: {r,y,g} = 3'b010;
always @(state) endcase
begin end
case(state) always @(posedge clk)
3'b000: nextstate = 3'b001; begin
state <= nextstate;
3'b001: nextstate = 3'b010; end
3'b010: nextstate = 3'b011; clk_divider divider1 (.clk(clk),.clk_50(clk_50));
3'b011: nextstate = 3'b100; endmodule
3'b100: nextstate = 3'b101;
3'b101: nextstate = 3'b110;
3'b110: nextstate = 3'b111; Traffic Signal State
3'b111: nextstate = 3'b000;
endcase Verilog Code 1
end
module clk_divider(clk, clk_50);
input clk_50;
output reg clk;
reg [31:0] count;
initial
count = 32'h00000000;
//reg count;
always@(posedge (clk_50))
begin
if (count >= 32'd50000000)
count <= 32'h00000000;
else
Clock Divider Verilog
begin Code
if (count<=32'd25000000)
clk <= 1;
else
clk <= 0;
count <= count + 1;
end
end
endmodule
module traffic_signal_struct(r,y,g,clk_50);
output logic r,y,g;
input clk_50;
logic clk;
logic [2:0] cs;
logic [2:0] ns;
clk_divider divider1 (.clk(clk),.clk_50(clk_50));
// Combinational circuit for output generation
assign r = (~cs[2]&~cs[1]&~cs[0]) | (~cs[2]&~cs[1]&cs[0]) | (~cs[2]&cs[1]&~cs[0]) | (~cs[2]&cs[1]&cs[0]);
assign y =(~cs[2]&cs[1]&cs[0]) | (cs[2]&cs[1]&cs[0]);
assign g =(cs[2]&~cs[1]&~cs[0]) | (cs[2]&~cs[1]&cs[0]) | (cs[2]&cs[1]&~cs[0]);
// Combinational circuit for next state
assign ns[2] = (~cs[2]&cs[1]&cs[0]) | (cs[2]&~cs[1]&~cs[0]) | (cs[2]&~cs[1]&cs[0]) | (cs[2]&cs[1]&~cs[0]);
assign ns[1] = (~cs[2]&~cs[1]&cs[0]) | (~cs[2]&cs[1]&~cs[0]) | (cs[2]&~cs[1]&cs[0]) | (cs[2]&cs[1]&~cs[0]);
assign ns[0] = (~cs[2]&~cs[1]&~cs[0]) | (~cs[2]&cs[1]&~cs[0]) | (cs[2]&~cs[1]&~cs[0]) |
(cs[2]&cs[1]&~cs[0]);
// State Register
dflipflop dff0(cs[0],ns[0],clk);
dflipflop dff1(cs[1],ns[1],clk); Traffic Signal State
dflipflop dff2(cs[2],ns[2],clk);
endmodule Verilog Code 2
Manchester Encoder
Manchester Encoder State Diagram
module manchester_moore(z,w,clk); 2'b01:begin always @(posedge clk)
output z; nextstate = 2'b10; begin
input w, clk; z = 0; state <= nextstate;
reg z; end end
reg [1:0] state, nextstate; 2'b10:begin endmodule
initial if (w===0)
begin nextstate = 2'b11;
state = 2'b00; nextstate = 2'b00;
else if (w === 1)
nextstate = 2'b01;
end
else
always @(state,w)
nextstate = 2'b00;
begin
z = 1;
case(state) end
2'b00:begin 2'b11:begin
if (w===0) nextstate = 2'b00;
nextstate = 2'b11; z = 1;
else if(w === 1) end Manchester
nextstate = 2'b01; default:
else begin
Encoder Verilog
nextstate = 2'b00; state = 2'b00; Code
z = 0; nextstate = 2'b00;
end end
endcase
end
Sequence Detector
Sequence Detector
module seq_detector(z,w,clk); //State 1 //state register
output reg z; input w,clk; 2'b01:begin always@(posedge clk)
reg [1:0] state, nextstate; if(w === 1) begin
begin state <= nextstate;
initial nextstate = 2'b10; end
begin z = 0;
state = 2'b00; nextstate = 2'b00; end endmodule
end else
always @(state,w) begin
begin
nextstate = 2'b00;
z = 0;
Sequence Detector
case(state)
//state 0
end
end
Verilog Code 1
2'b00:begin //state 2
if(w === 1) 2'b10:begin
if(w === 1)
begin begin
nextstate = 2'b01; z = 0; nextstate = 2'b10; z = 1;
end end
else else
begin begin
nextstate = 2'b00;
nextstate = 2'b00; z = 0;
z = 0; end
end end
end endcase
end
Sequence Detector Verilog Code 2

module seq_det_struct(z,w,clk); module dflipflop(q,d,clk);


output z; output reg q;
input w,clk; input d,clk;
initial
reg [1:0] c; begin
reg [1:0] n; q = 0;
assign z = (c[1]&~c[0]&w); end
assign n[1] = (~c[1]&c[0]&w) | (c[1]&~c[0]&w); always@(posedge clk)
assign n[0] = ~c[1]&~c[0]&w; begin
q <= d;
dflipflop d0(c[0],n[0],clk); end
dflipflop d1(c[1],n[1],clk); endmodule
endmodule
Multiplication
Multiplication (Edge Detector)
//Edge Detector 2'b01:begin always @(posedge(clk_in))
module edge_detector(x,y,clk_in); y = 1; begin
input x, clk_in; if (x == 1) cs <= ns;
output reg y; ns = 2'b10; end
reg [1:0] cs, ns; else
initial ns = 2'b00; endmodule
end
begin
2'b10:begin
cs = 2'b00; ns = 2'b00; y = 0; y = 0;
end if (x == 1)
always @(*) ns = 2'b10;
begin else
case(cs) ns = 2'b00;
2'b00:begin end
y = 0; default:
if (x == 1) begin
ns = 2'b01; ns = 2'b00;
y = 0;
else
end
ns = 2'b00; endcase
end end
//Parameterized Register //Shift Register
module
module register
shift_register(q,din0,din1,reset,load_l,shift,add,clk);
#(parameter width=9) output reg [8:0] q; input [3:0] din0; input [4:0] din1;
(q,d,done,clk); input reset, load_l, shift, add, clk;
output reg [width-1:0] q; always @(posedge clk)
input[width-1:0] d; begin
if(reset) Data Path
input done,clk;
q <= 9'h0; Component
always@(posedge clk) else if(load_l)
begin q[3:0] <= din0;
if(done) else if(add)
q <= d; q[8:4] <= din1;
else if(shift)
end
q <= {1'b0,q[8:1]};
endmodule end
endmodule

module adder_behave #(parameter width = 8)(sum,cout,a,b,cin);


output [width-1:0] sum; output cout;
input [width-1:0] a,b;
input cin;
assign {cout,sum} = a + b + cin;
endmodule
Multiplication (Data Path)
module data_path(qout,m,mplier,mplicand,done,reset,load_l,shift,add,clk);
output [8:0] qout; output m; input [3:0] mplier, mplicand;
input done, reset, load_l, shift, add, clk;
wire [3:0] q0;
wire [8:0] q1;
wire [4:0] sum;
//mplicand Register
register #(4)mplicand_reg(.q(q0),.d(mplicand),.done(load_l),.clk(clk));
//Accumalator Register
shift_register SR(.q(q1),.din0(mplier),.din1(sum),.reset(reset)
,.load_l(load_l),.shift(shift),.add(add),.clk(clk));
assign m = q1[0];
//Output register
register #(9) out_reg(.q(qout),.d(q1),.done(done),.clk(clk));
//Adder Circuit
adder_behave #(4)
adder0(.sum(sum[3:0]),.cout(sum[4]),.a(q0),.b(q1[7:4]),.cin(1'b0));
endmodule
Multiplication (Controller – State Machine- State Diagram)
Multiplication (Controller – State Machine- Verilog Code-Style1)
module controller
(done,reset,load_l,shift,add,st,m,clk);
output reg done, reset, load_l, shift, add;
input st,m,clk; reg [3:0] cs,ns;
initial
begin
done = 0; reset = 0; load_l = 0; shift = 0; add = 0;
end
always @(cs,st,m)
begin
case(cs)
4'd0:begin
if(st === 1) begin
done = 0; reset = 1; load_l = 0; shift = 0; add = 0;ns = 4'd1;
end
else begin
done = 0; reset = 0; load_l = 0; shift = 0; add = 0; ns = 4'd0;
end
end
4'd1:begin 4'd4:begin else
done = 0; reset = 0; load_l = 1; if (m === 1) begin
shift = 0; add = 0; ns = 4'd2; begin done = 0; reset = 0; load_l = 0;
done = 0; reset = 0; load_l = 0; shift = 1; add = 0; ns = 4'd8;
end shift = 0; add = 1; ns = 4'd5; end
4'd2:begin end end
if (m === 1) else 4'd7:begin
begin begin done = 0; reset = 0; load_l = 0;
done = 0; reset = 0; load_l = 0; done = 0; reset = 0; load_l = 0; shift = 1; add = 0; ns = 4'd8;
shift = 1; add = 0; ns = 4'd6; end
shift = 0; add = 1; ns = 4'd3; end 4'd8:begin
end end if (m === 1)
else 4'd5:begin begin
begin done = 0; reset = 0; load_l = 0; done = 0; reset = 0; load_l = 0;
done = 0; reset = 0; load_l = 0; shift = 1; add = 0; ns = 4'd6; shift = 0; add = 1; ns = 4'd9;
end end
shift = 1; add = 0; ns = 4'd4; 4'd6:begin else
end if (m === 1) begin
end begin done = 0; reset = 0; load_l = 0;
4'd3:begin done = 0; reset = 0; load_l = 0; shift = 1; add = 0; ns = 4'd10;
done = 0; reset = 0; load_l = 0; shift = 0; add = 1; ns = 4'd7; end
end end
shift = 1; add = 0; ns = 4'd4;
end
Multiplication (Controller – State Machine- Verilog Code-Style1)

4'd9:begin
done = 0; reset = 0; load_l = 0;
shift = 1; add = 0; ns = 4'd10;
end
4'd10:begin
done = 1; reset = 0; load_l = 0;
shift = 0; add = 0; ns = 4'd0;
end
default:begin
done = 0; reset = 0; load_l = 0;
shift = 0; add = 0; ns = 4'd0;
end
endcase
always @(posedge clk)
begin
cs <= ns;
end
endmodule
Multiplication (Controller – State Machine- Verilog Code- style2)
module 4'd1:begin
controller(done,reset,load_l,shift,add,st,m,clk); done = 0; reset = 0; load_l = 1;
output reg done, reset, load_l, shift, add; shift = 0; add = 0; ns = 4'd2;
input st,m,clk; reg [3:0] cs,ns; end
initial 4'd2,4'd4,4'd6,4'd8:begin
begin if (m === 1) begin
done = 0;reset = 0;load_l = 0;shift = 0;add = 0; done = 0; reset = 0; load_l = 0;
end shift = 0; add = 1; ns = cs+4'd1;
always @(cs,st,m) end
begin else begin
case(cs) done = 0; reset = 0; load_l = 0;
4'd0:begin shift = 1; add = 0; ns = cs+4'd2;
if(st === 1) begin end
done = 0; reset = 1; load_l = 0; end
shift = 0; add = 0; ns = 4'd1; 4'd3,4'd5,4'd7,4'd9:begin
end done = 0; reset = 0; load_l = 0;
else begin shift = 1; add = 0; ns = cs+4'd1;
done = 0; reset = 0; load_l = 0; end
shift = 0; add = 0; ns = 4'd0;
end
end
Multiplication (Controller – State Machine- Verilog Code- style2)
4'd10:begin
done = 1; reset = 0; load_l = 0;
shift = 0; add = 0; ns = 4'd0;
end
default:begin
done = 0; reset = 0; load_l = 0;
shift = 0; add = 0; ns = 4'd0;
end
endcase
end
always @(posedge clk)
begin
cs <= ns;
end
Test bench Result for Controller
Multiplication(Top Entity)
module top(qout,st,clk,mplier,mpcand);
output[8:0] qout;
input[3:0] mplier, mpcand;
input st, clk;
wire m,done,reset,load_l,shift,add,st_edge;
edge_detector ed0(st,st_edge,clk);
data_path d0(qout,m,mplier,mpcand,done,reset,load_l,shift,add,clk);
controller c0(done,reset,load_l,shift,add,st_edge,m,clk);
endmodule
Micro-Program
Controller_MicroProgram
Controller_MicroProgram
Controller_MicroProgram
State CS Test NSF NST Reset Load_l Shift Add Done
SO 0000 0 0000 0001 0 0 0 0 0
S1 0001 0 0010 0010 1 0 0 0 0
S2 0010 0 0011 0011 0 1 0 0 0
S3 0011 1 0101 0100 0 0 0 0 0
S4 0100 1 0101 0101 0 0 0 1 0
S5 0101 1 0110 0110 0 0 1 0 0
S6 0110 1 1000 0111 0 0 0 0 0
S7 0111 1 1000 1000 0 0 0 1 0
S8 1000 1 1001 1001 0 0 1 0 0
S9 1001 1 1011 1010 0 0 0 0 0
S10 1010 1 1011 1011 0 0 0 1 0
S11 1011 1 1100 1100 0 0 1 0 0
S12 1100 1 1110 1101 0 0 0 0 0
S13 1101 1 1110 1110 0 0 0 1 0
S14 1110 1 1111 1111 0 0 1 0 0
S15 1111 1 0000 0000 0 0 0 0 1
Controller_MicroProgram_Components
module mux module u_rom(data_out,add);
#(parameter width = 4)(z,sel,in0,in1); output logic[13:0] data_out; input logic[3:0] add;
output [width-1:0] z; always @(*) begin
case(add)
input [width-1:0] in0,in1;
4'b0000: data_out = 14'b0_0000_0001_00000;
input sel;
4'b0001: data_out = 14'b0_0010_0010_10000;
assign z = sel?in1:in0; 4'b0010: data_out = 14'b0_0011_0011_01000;
endmodule 4'b0011: data_out = 14'b0_0101_0100_00000;
module register 4'b0100: data_out = 14'b1_0101_0101_00010;
#(parameter width=9)(q,d,done,clk); 4'b0101: data_out = 14'b1_0110_0110_00100;
output reg [width-1:0] q; 4'b0110: data_out = 14'b1_1000_0000_00000;
input[width-1:0] d; 4'b0111: data_out = 14'b1_1000_1000_00010;
input done,clk; 4'b1000: data_out = 14'b1_1001_1001_00100;
always@(posedge clk) 4'b1001: data_out = 14'b1_1011_1010_00000;
4'b1010: data_out = 14'b1_1011_1011_00010;
begin
4'b1011: data_out = 14'b1_1100_1100_00100;
if(done)
4’b1100: data_out = 14'b1_1110_1101_00000;
q <= d; 4’b1101: data_out = 14'b1_1110_1110_00010;
end 4’b1110: data_out = 14'b1_1111_1111_00100;
endmodule 4’b1110: data_out = 14'b1_0000_0000_00001;
endcase
end
endmodule
Controller_MicroProgram
module Controller_uprog(done,reset,load_l,shift,add,st,m,clk);
output reg done, reset, load_l, shift, add;
input st,m,clk;
logic [3:0] state;
logic [13:0] data_out;
logic z0;
logic [3:0] z1;
initial
begin
state = 4'b0000;
z0 = 0;
z1 = 4'b0000;
end
u_rom rom0(data_out,state);
mux #(1)mux0(z0,data_out[13],st,m);
mux #(4)mux1(z1,z0,data_out[12:9],data_out[8:5]);
register #(4)reg0(state,z1,1'b1,clk);
assign {reset,load_l,shift,add,done} = data_out[4:0];
endmodule
Constant
Constant
• Number of way to declare constant,
Define
Parameter
Localparm
const
Constant data types
`define FETCH 3'h0 always @(State)
`define WRITE 3'h1 begin
`define ADD 3'h2 case(State)
`define SUB 3'h3 WAIT: NextState = LOAD;
`define MULT 3'h4 LOAD: NextState = STORE;
`define DIV 3'h5 STORE: NextState = WAIT;
`define SHIFT 3'h6 endcase
`define NOP 3'h7 end
module controller(output reg read, write, always @(State, instruction)
input wire[3:0] begin
instruction, input wire clock, resetN); read = 0; write = 0;
parameter WAIT = 0, LOAD =1, STORE = 2; if (State == LOAD && instruction == `FETCH)
reg [1:0] State, NextState; read = 1;
else if (State == STORE && instruction ==
always @(posedge clock, negedge resetN) `WRITE)
begin write = 1;
if(!resetN) State <= WAIT; end
else State <= NextState; endmodule
end
User-Defined and Enumerated Data
Type
• User defined and Enumerated data type are
feature specific to system Verilog.
• Can be use for both digital circuit synthesis
and verification.
• Help to make code self documented and
easier to read.
• May reduce code to fewer lines.
User-Defined Data Type
• Local User-Defined Type
module alu (….);
typedef bit [3:0] nibble;
nibble opA, opB; //Variables of the nibble data type
nibble [7:0] data; // a 32-bit vector made from 8 nibble types
…..
…..
endmodule
User-Defined Data Type
• External User-Defined Type

`ifdef TWO_STATE
typedef bit dtype_t; //external typedef
`else
typedef logic dtype_t;
`endif

module counter (output dtype_t [15:0]count, input dtype_t clock, resetN);


always @(posedge clock, negedge resetN)
if (!resetN)
count <= 0;
else
count <= count + 1;
endmodule
Loops
Loops
Forever Loops (Infinite Loop) • This equivalent statement block can not be
• Use with process, function, tasks and used in system Verilog classes
classes. ______________________________________
• Non-synthesizable. Example (Clock Generation for Test bench)
• Use for verification and modeling. initial
____________________________________ begin
forever clk = 1’b0;
//Single statement forever
____________________________________ begin
forever #10;
begin clk = ~clk;
//Multiple… end
//Statement ______________________________________
end Equivalent Code
____________________________________ always
• Equivalent to following statement begin
always #10 KEY <= ~KEY;
begin end
//Multiple statement ______________________________________
end
_____________________________________
Loops
For Loops (finite Loop) module adder4_loop(cout,sum,a,b,cin);
• Can be synthesizable output logic [3:0] sum;
output logic cout;
for (initial_statement; expression; increament) input [3:0] a,b;
begin input cin;
//Sequential statement logic c_in;
end
______________________________________ always@(*)
begin
integer i;
c_in = cin;
for (i=0; i<4; i=i+1)
begin
cout = (a[i] && b[i])||(a[i] && c_in) || (b[i] &&
c_in);
sum[i] = a[i] ^ b[i] ^ c_in;
c_in = cout;
end
end
endmodule
Loops
While Loops (Infinite Loop)
• Can be synthesizable
_____________________________________
while (condition)
begin
//sequential statements;
end
_____________________________________
‘define Max 100
module count;
initial begin
count = 0;
while (count < `Max) begin
count = count +1;
end
$display (“number = %d”, count);
end
endmodule
Functions and Tasks
Function in Verilog
• At least one input arguments, but no output • Examples
or inout arguments.
• Return a single value by assigning the value //Defination of function
to the function name. function [4:0] parity;
• Cannot embedded delays, wait statement input [3:0] A;
or time-controlled statement. reg temp_parity;
• Executes in zero time. begin
• Cannot contain non-blocking assignment or temp_parity = A[0] ^ A[2] ^ A[3];
procedural continuous assignments. parity = {A, temp_parity};
end
Definition of Function
function <range or type> function_name; //Calling of function
input [declaration] module (parity_out, dat);
<declartations> //reg, parameter, inger, etc. input [4:0] dat;
begin output[4:0] parity_out;
sequential statements always(*)
end begin
Endfunction parity_out = parity(data);
end
Calling of Function endmodule
function_name(input-argument-list)
function [4:0] add4; Function in Verilog
input [3:0] A, B; input cin; module test_squares (clk);
reg [4:0] sum; reg cout; input clk;
begin reg [3:0] FN;
integer i; reg [7:0] answer;
for (i=0; i<3; i=i+1)
begin function [7:0] squares;
cout = (A[i] & B[i]) | (A[i] & cin) | (B[i] & cin); input [3:0] Number;
Sum[i] = A[i] ^ B[i] ^ cin; begin
end squares = Number * Number;
sum[4] = cout; end
add4 = sum; endfunction
end
endfunction initial
______________________________________ begin
module add4_function(cout, sum, a, b, cin); FN=4’b0011;
output [3:0] sum; output count; End
input [3:0] a,b; input cin; always @(posedge clk)
always(*) begin
begin answer = squares(FN);
{cout,sum} =add4(a,b,cin); end
end endmodule
endmodule
Task in Verilog
• Can contain time-controlling statement task Addvec;
and operation complete at some other input [3:0] add1;
time. input [3:0] add2;
• Can call other task and functions input Cin;
• Can have zero or more input output [3:0] sum;
arguments. output cout;
• Cannot return a value, but can achieve reg c;
the same effect using output begin
arguments. c = cin;
• Can have multiple output arguments. integer i;
for (i=0; i<= 4; i = i+1)
Declaration of Task: begin
sum[i] = add1[i]^add2[i]^C;
task taskname c = (add1[i] & add2[i]) | (add1[i] & c) | (add2[i]|c);
input [declarations] end
output [declarations] cout = c;
<declaration> //reg, parameters, integer, end
etc. endtask
begin
//Sequential Statement Calling of Task:
endtask
Addvec(A,B,Cin,Sum,Cout);
Task in Verilog
module tb; module tb;
initial display(); initial display();
initial display(); initial display();
initial display(); initial display();
initial display(); initial display();
// This is a static task // Note that the task is now automatic
task display(); task automatic display();
integer i = 0; integer i = 0;
i = i + 1; i = i + 1;
$display("i=%0d", i); $display("i=%0d", i);
endtask endtask
endmodule endmodule

Simulation Results: Simulation Results:


i=1 i=1
i=2 i=1
i=3 i=1
i=4 i=1
Task in Verilog
task display();
$display("Hello World !"); module tb;
endtask reg signal;

module des; initial wait_for_1(signal);


initial begin
display(); function wait_for_1(reg signal);
end #10;
endmodule endfunction
endmodule
module tb;
reg signal;

initial wait_for_1(signal);

task wait_for_1(reg signal);


#10;
$display(“Hello World!”);
endtask
endmodule
Generate
Generate
module Adder4 (A, B, Ci, S, Co);
input[3:0] A; //inputs
input[3:0] B;
input Ci;
output[3:0] S; //outputs
output Co;
wire[4:0] C;
assign C[0] = Ci ;
genvar i;
generate
for (i=0; i<4; i=i+1)
begin: gen_loop
FullAdder FA (A[i], B[i], C[i], C[i], S[i]);
end
endgenerate
assign Co = C[4];
endmodule
Structure
Structure
Structure Declaration
• Anonymous Structure always @(posedge clock, negedge resetN)
struct { if (!resetN)begin
int a,b; IW.a = 100;
byte opcode; IW.b = 5;
bit [23:0] address; IW.opcode = 8’hFF;
} Intruction_word; IW.address = 0;
end
• OR typed structure else begin
….
typedef struct { end
int a,b; OR
byte opcod; always @(posedge clock, negedge resetN)
bit[23:0] address; If (!resetN) IW = {100, 5, 8’hFF, 0};
} instruction_word_t; //structure definition else begin
….
instruction_word_t IW; //Structure allocation end

• Structure can be define external to module, IW = {address:0, opcode:8’hFF, a:100, b:5};


inside module, and in the interfaces.
Structure
Default values in Structure Packed Structure:
typedef struct { struct packed {
real x,y; bit valid;
int a,b; byte tag;
byte opcode; bit [31:0] data;
bit [23:0] address; } data_word;
} instruction_word_t;
data_word.tag = 8’hf0;
instruction_word_t IW; data_word[39:32] = 8’hf0;
• All members of packed structure must be
IW = {default:0}; integral value i.e. byte, int, bit or logic types
• Packed structure does contain real or
• Data type specific default shortreal variables, unpacked structures,
IW = {real:1.0, default:0}; unpacked union and unpacked arrays.
• Packed structure are seen as vector.
• Default value precedence Therefore all vector operation are
IW = {real:1.0, default:0, x=3.142}; performed on packed structures.
Enumerated and User defined
Types
Enumerated data types
typedef enum {FETCH, WRITE, ADD, SUB, always @(State, instruction)
MULT, DIV, SHIFT, NOP} instr_t; begin
read = 0; write = 0;
module controller(output reg read, write, if (State == LOAD && instruction == FETCH)
input wire[3:0] instruction, read = 1;
input wire clock, resetN); else if (State == STORE && instruction ==
WRITE)
enum {WAIT, LOAD, STORE} State, NextState; write = 1;
else
always @(posedge clock, negedge resetN) read = 0; write = 0;
begin end
if(!resetN) State <= WAIT; endmodule
else State <= NextState;
end
always @(State)
begin
case(State)
WAIT: NextState = LOAD;
LOAD: NextState = STORE;
STORE: NextState = WAIT;
endcase
end
Enumerated data types
Shorthand Notation always @(posedge clock)
enum { reset, s[5], W[6:9]} state; begin: fsm2
reset enum{WAIT, GO, DONE} fsm2_state;
s0,s1,s2,s3,s4, and s5 …..
W6,W7,W8, and W9 end
…..
Enumerated type scope: endmodule
module FSM(…);
enum{GO,STOP} fsm1_state; Enumerated type value
enum {WAIT,G0,DONE} fsm2_state;//error enum{ONE = 1, FIVE =5, TEN = 10} state;
…. enum{A=1, B, X=24, Y, Z} list1;
…. Enum{A=1, B, C, D=3} list2; //Error
endmodule
---------------Alternate Correct Solution------------ Data Type of Enumerated type value
module FSM(…); enum bit [1:0]{WAIT, LOAD, READY} state;
……. enum bit[2:0] {WAIT =3’b001, LOAD=3’b010,
always @(posedge clock) READY = 3’b100}state;
begin: fsm1 enum{WAIT = 3’b001, LOAD = 3’b010,
enum {STOP, GO} fsm1_state; READY =3’b100} state;//Error
….. enum bit {A=1’b0, B, C} list;//Error
end
Enumerated data types
Strong type of Enumerated type Type Casting for enumerated types
An enumerated variable can only be assigned: typedef enum {WAIT, LOAD, READY} states_t;
• A named value from it enumerated type states_t state, next_state;
list. next_state = states_t’(state++); //legal
• Another enumerated type variable of the $cast(next_state, state+1); //legal
same type (that is declared with the same Special system task and methods for
enumerated type list) enumerated types
• A value cast to type of enumerated variable. <enum_variable_name>.first
<eunm_variable_name>.last
typedef enum {WAIT,LOAD,READY} states_t; <eunm_variable_name>.next(N)
States_t state, next_state; <eunm_variable_name>.prev(N)
Int foo; <eunm_variable_name>.num
<eunm_variable_name>.name
state = next_state;//legal operation
foo = state + 1; //legal operation
state = foo + 1; //Error: illegal assignment
state = state + 1; //illegal operation
state++ ; illegal operation
next_state +=state //illegal operation

You might also like