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