1 Getting Started
1.1 Getting Started
module top_module( output one );
// Insert your code here
assign one = 1'b1;
endmodule
1.2 Output Zero
module top_module(
output zero
);// Module body starts after semicolon
assign zero = 1'b0;
endmodule
2 Verilog Language
2.1 Basic
2.1.1 Simple wire
module top_module( input in, output out );
assign out = in;
endmodule
2.1.2 Four wires
module top_module(
input a,b,c,
output w,x,y,z );
assign w = a;
assign x = b;
assign y = b;
assign z = c;
endmodule
2.1.3 Inverter
module top_module( input in, output out );
assign out = ~in;
endmodule
2.1.4 AND gate
module top_module(
input a,
input b,
output out );
assign out = a & b;
endmodule
2.1.5 NOR gate
module top_module(
input a,
input b,
output out );
assign out = ~(a | b);
endmodule
2.1.6 XNOR gate
module top_module(
input a,
input b,
output out );
assign out = ~(a ^ b);
endmodule
2.1.7 Declaring wire
module top_module(
input a,
input b,
input c,
input d,
output out,
output out_n );
wire w1,w2;
assign w1 = a & b;
assign w2 = c & d;
assign out = w1 | w2;
assign out_n = ~(w1 | w2);
endmodule
2.1.8 7458 chip
module top_module (
input p1a, p1b, p1c, p1d, p1e, p1f,
output p1y,
input p2a, p2b, p2c, p2d,
output p2y );
wire w1,w2,w3,w4;
assign w1 = p2a & p2b;
assign w2 = p2c & p2d;
assign w3 = p1a & p1b & p1c;
assign w4 = p1d & p1e & p1f;
assign p2y = w1 | w2;
assign p1y = w3 | w4;
endmodule
2.2 Vectors
2.2.1 Vector0
module top_module (
input wire [2:0] vec,
output wire [2:0] outv,
output wire o2,
output wire o1,
output wire o0 ); // Module body starts after module declaration
assign outv = vec;
assign o2 = vec[2];
assign o1 = vec[1];
assign o0 = vec[0];
endmodule
2.2.2 Vectors in more detail
module top_module(
input wire [15:0] in,
output wire [7:0] out_hi,
output wire [7:0] out_lo );
assign out_hi = in[15:8];
assign out_lo = in[7:0];
endmodule
2.2.3 Vector part select
module top_module(
input [31:0] in,
output [31:0] out );
assign out[31:24] = in[7:0];
assign out[23:16] = in[15:8];
assign out[15:8] = in[23:16];
assign out[7:0] = in[31:24];
endmodule
2.2.4 Bitwise Operators
module top_module(
input [2:0] a,
input [2:0] b,
output [2:0] out_or_bitwise,
output out_or_logical,
output [5:0] out_not
);
assign out_or_bitwise = a | b; //bitwise or |
assign out_or_logical = a || b; //logical or ||
assign out_not = {~b , ~a};
endmodule
2.2.5 Four-input gates
module top_module(
input [3:0] in,
output out_and,
output out_or,
output out_xor
);
assign out_and = & in;
assign out_or = | in;
assign out_xor = ^ in;
endmodule
2.2.6 Vector concatenation operator
module top_module (
input [4:0] a, b, c, d, e, f,
output [7:0] w, x, y, z );//
assign { w, x, y, z } = { a, b, c, d, e, f, 2'b11 };
endmodule
2.2.7 Vector reversal 1
module top_module(
input [7:0] in,
output [7:0] out
);
integer i;
always@(*)begin
for(i = 0; i <= 7; i = i + 1)begin
out[i] = in[7-i];
end
end
endmodule
2.2.8 Replication operation
module top_module (
input [7:0] in,
output [31:0] out );
assign out = {{24{in[7]}}, in };
endmodule
2.2.9 More replication
module top_module (
input a, b, c, d, e,
output [24:0] out );//
assign out = {{5{a}},{5{b}},{5{c}},{5{d}},{5{e}}} ~^ {5{a, b, c ,d, e}};
endmodule
2.3 Module: Hierarchy
2.3.1 Modules
module top_module ( input a, input b, output out );
//mod_a instance1(a,b,out);
mod_a instance1(
.out (out ),
.in1 (a ),
.in2 (b )
);
endmodule
2.3.2 Connecting ports by position
module top_module (
input a,
input b,
input c,
input d,
output out1,
output out2
);
mod_a instance1(out1, out2, a, b, c, d);
endmodule
2.3.3 Connecting ports by name
module top_module (
input a,
input b,
input c,
input d,
output out1,
output out2
);
mod_a instance1(
.out1 (out1 ),
.out2 (out2 ),
.in1 (a ),
.in2 (b ),
.in3 (c ),
.in4 (d )
);
endmodule
2.3.4 Three modules
module top_module ( input clk, input d, output q );
wire w1,w2;
my_dff my_dff1(
.clk (clk ),
.d (d ),
.q (w1 )
);
my_dff my_dff2(
.clk (clk ),
.d (w1 ),
.q (w2 )
);
my_dff my_dff3(
.clk (clk ),
.d (w2 ),
.q (q )
);
endmodule
2.3.5 Modules and vectors
module top_module (
input clk,
input [7:0] d,
input [1:0] sel,
output [7:0] q
);
wire [7:0] w1;
wire [7:0] w2;
wire [7:0] w3;
my_dff8 my_dff8_1(
.clk (clk ),
.d (d ),
.q (w1 )
);
my_dff8 my_dff8_2(
.clk (clk ),
.d (w1 ),
.q (w2 )
);
my_dff8 my_dff8_3(
.clk (clk ),
.d (w2 ),
.q (w3 )
);
always@(*)begin
case(sel)
2'b00: q = d;
2'b01: q = w1;
2'b10: q = w2;
2'b11: q = w3;
endcase
end
endmodule
2.3.6 Adder 1
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire cout;
add16 add16_low(
.a (a[15:0] ),
.b (b[15:0] ),
.cin (1'b0 ),
.sum (sum[15:0] ),
.cout (cout )
);
add16 add16_high(
.a (a[31:16] ),
.b (b[31:16] ),
.cin (cout ),
.sum (sum[31:16] ),
.cout ( )
);
endmodule
2.3.7 Adder 2
module top_module (
input [31:0] a,
input [31:0] b,
output [31:0] sum
);//
wire cout;
add16 add16_low(
.a (a[15:0] ),
.b (b[15:0] ),
.cin (1'b0 ),
.sum (sum[15:0] ),
.cout (cout )
);
add16 add16_high(
.a (a[31:16] ),
.b (b[31:16] ),
.cin (cout ),
.sum (sum[31:16] ),
.cout ( )
);
endmodule
module add1 ( input a, input b, input cin, output sum, output cout );
assign {cout, sum} = a + b + cin;
endmodule
2.3.8 Carry-select adder
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire cout;
wire [15:0] sum1;
wire [15:0] sum2;
wire [15:0] sum3;
add16 add16_u1(
.a (a[15:0] ),
.b (b[15:0] ),
.cin (1'b0 ),
.sum (sum1 ),
.cout (cout )
);
add16 add16_u2(
.a (a[31:16] ),
.b (b[31:16] ),
.cin (1'b0 ),
.sum (sum2 ),
.cout ( )
);
add16 add16_u3(
.a (a[31:16] ),
.b (b[31:16] ),
.cin (1'b1 ),
.sum (sum3 ),
.cout ( )
);
assign sum = cout ? {sum3, sum1} : {sum2, sum1}; //三元操作符
endmodule
2.3.9 Adder-subtractor
module top_module(
input [31:0] a,
input [31:0] b,
input sub,
output [31:0] sum
);
wire [31:0] w1;
wire cout;
assign w1 = {32{sub}} ^ b;
add16 add16_u1(
.a (a[15:0] ),
.b (w1[15:0] ),
.cin (sub ),
.sum (sum[15:0] ),
.cout (cout )
);
add16 add16_u2(
.a (a[31:16] ),
.b (w1[31:16] ),
.cin (cout ),
.sum (sum[31:16] ),
.cout ( )
);
endmodule
2.4 Procedure
2.4.1 Always blocks (combination)
module top_module(
input a,
input b,
output wire out_assign,
output reg out_alwaysblock
);
assign out_assign = a & b;
always@(*)begin
out_alwaysblock = a & b;
end
endmodule
2.4.2 Always blocks(clocked)
module top_module(
input clk,
input a,
input b,
output wire out_assign,
output reg out_always_comb,
output reg out_always_ff );
assign out_assign = a ^ b;
always@(*)begin
out_always_comb = a ^ b;
end
always@(posedge clk)begin
out_always_ff <= a ^ b;
end
endmodule
2.4.3 If statement
// synthesis verilog_input_version verilog_2001
module top_module(
input a,
input b,
input sel_b1,
input sel_b2,
output wire out_assign,
output reg out_always );
assign out_assign = (sel_b1&sel_b2) ? b : a;
always@(*)begin
if (sel_b1&sel_b2) begin
out_always = b;
end
else begin
out_always = a;
end
end
endmodule
2.4.4 If statement latches
module top_module (
input cpu_overheated,
output reg shut_off_computer,
input arrived,
input gas_tank_empty,
output reg keep_driving ); //
always @(*) begin
if (cpu_overheated)
shut_off_computer = 1;
else shut_off_computer = 0;
end
always @(*) begin
if (~arrived)
keep_driving = ~gas_tank_empty;
else keep_driving = 0;
end
endmodule
2.4.5 Case statement
module top_module (
input [2:0] sel,
input [3:0] data0,
input [3:0] data1,
input [3:0] data2,
input [3:0] data3,
input [3:0] data4,
input [3:0] data5,
output reg [3:0] out );//
always@(*) begin // This is a combinational circuit
case(sel)
3'd0:begin
out = data0;
end
3'd1:begin
out = data1;
end
3'd2:begin
out = data2;
end
3'd3:begin
out = data3;
end
3'd4:begin
out = data4;
end
3'd5:begin
out = data5;
end
default: out = 1'b0;
endcase
end
endmodule
2.4.6 Priority encoder
module top_module (
input [3:0] in,
output reg [1:0] pos );
always@(*)begin
casez(in)
4'bzzz1:begin
pos = 2'd0;
end
4'bzz10:begin
pos = 2'd1;
end
4'bz100:begin
pos = 2'd2;
end
4'b1000:begin
pos = 2'd3;
end
default:pos =2'd0;
endcase
end
endmodule
2.4.7 Priority encoder with casez
module top_module (
input [7:0] in,
output reg [2:0] pos );
always @(*) begin
casez (in[7:0])
8'bzzzzzzz1: begin
pos = 3'd0;
end
8'bzzzzzz10: begin
pos = 3'd1;
end
8'bzzzzz100: begin
pos = 3'd2;
end
8'bzzzz1000: begin
pos = 3'd3;
end
8'bzzz10000: begin
pos = 3'd4;
end
8'bzz100000: begin
pos = 3'd5;
end
8'bz1000000: begin
pos = 3'd6;
end
8'b10000000: begin
pos = 3'd7;
end
default: begin
pos = 3'd0;
end
endcase
end
endmodule
2.4.8 Avoiding latches
module top_module (
input [15:0] scancode,
output reg left,
output reg down,
output reg right,
output reg up );
always @(*) begin
up = 1'b0; down = 1'b0; left = 1'b0; right = 1'b0;
case (scancode)
16'he075:begin
up = 1'b1;
end
16'he072:begin
down = 1'b1;
end
16'he06b:begin
left = 1'b1;
end
16'he074:begin
right = 1'b1;
end
endcase
end
endmodule
2.5 More Verilog Features
2.5.1 Conditional ternary operator
module top_module (
input [7:0] a, b, c, d,
output [7:0] min);//
wire [7:0] min1,min2;
assign min1 = (a > b) ? b : a;
assign min2 = (c > d) ? d : c;
assign min = (min1 > min2) ? min2 : min1;
endmodule
2.5.2 Reduction operators
module top_module (
input [7:0] in,
output parity);
assign parity = ^ in;
endmodule
2.5.3 Reduction: Even wider gates
module top_module(
input [99:0] in,
output out_and,
output out_or,
output out_xor
);
assign out_and = & in;
assign out_or = | in;
assign out_xor = ^ in;
endmodule
2.5.4 Combinational for-loop: Vector reversal 2
module top_module(
input [99:0] in,
output [99:0] out
);
integer i;
always@(*)begin
for(i = 0; i <= 99; i = i + 1)begin
out[i] = in[99 - i];
end
end
endmodule
2.5.5 Combinational for-loop: 255-bit population count
module top_module(
input [254:0] in,
output [7:0] out );
integer i;
always@(*)begin
out = 8'd0;
for(i = 0; i <= 254; i = i + 1)begin
out = out + in[i];
end
end
endmodule
2.5.6 Generate for-loop: 100-bit binary adder 2
module top_module(
input [99:0] a, b,
input cin,
output [99:0] cout,
output [99:0] sum );
generate
genvar i;
for(i=0;i<100;i=i+1)begin:adder
if(i == 0) begin
assign {cout[0], sum[0]}= a[0] + b[0] + cin;
end
else begin
assign {cout[i], sum[i]}= a[i] + b[i] + cout[i-1];
end
end
endgenerate
endmodule
2.5.7 Generate for-loop: 100-bit digit BCD adder
module top_module(
input [399:0] a, b,
input cin,
output cout,
output [399:0] sum );
wire [99:0] cout_1;
generate
genvar i;
for(i = 0; i <= 99; i = i + 1)begin:adder //每四位分别例化一个BCD加法器
if(i == 0)begin
bcd_fadd u0_bcd_fadd(
.a (a[3:0] ),
.b (b[3:0] ),
.cin (cin ),
.sum (sum[3:0] ),
.cout (cout_1[0] )
);
end
else begin
bcd_fadd ui_bcd_fadd(
.a (a[4 * i + 3: 4 * i] ),
.b (b[4 * i + 3: 4 * i] ),
.cin (cout_1[i - 1] ),
.sum (sum[4 * i + 3: 4 * i] ),
.cout (cout_1[i] )
);
end
end
assign cout = cout_1[99];
endgenerate
endmodule