加载中...
HDLBits
发表于:2023-04-02 | 分类: Verilog

1 Getting Started

1.1 Getting Started (Output one)

1
2
3
module top_module( output one );
assign one = 1'b1;
endmodule

1.2 Output zero

1
2
3
module top_module( output zero);
assign zero = 1'b0;
endmodule

2 Verilog Language

2.1 Basic

2.1.1 Simple wire

1
2
3
module top_module( input in, output out );
assign out = in;
endmodule

2.1.2 Four wires

1
2
3
4
5
6
7
8
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

1
2
3
module top_module( input in, output out );
assign out = ~in;
endmodule

2.1.4 AND gate

1
2
3
4
5
6
module top_module( 
input a,
input b,
output out );
assign out = a & b;
endmodule

2.1.5 NOR gate

1
2
3
4
5
6
module top_module( 
input a,
input b,
output out );
assign out = ~(a|b);
endmodule

2.1.6 XNOR gate
1
2
3
4
5
6
module top_module( 
input a,
input b,
output out );
assign out = (a & b) + (!a & !b);
endmodule

2.1.7 Declaring wires
1
2
3
4
5
6
7
8
9
10
11
12
13
14
`default_nettype none
module top_module(
input a,
input b,
input c,
input d,
output out,
output out_n );
wire one,two;
assign one = a & b;
assign two = c & d;
assign out = one | two;
assign out_n = ~out;
endmodule

2.1.8 7458 chip
1
2
3
4
5
6
7
8
module top_module ( 
input p1a, p1b, p1c, p1d, p1e, p1f,
output p1y,
input p2a, p2b, p2c, p2d,
output p2y );
assign p1y = (p1a & p1b & p1c) | (p1d & p1e & p1f);
assign p2y = (p2a & p2b ) | (p2c & p2d);
endmodule

2.2 Vectors

2.2.1 Vectors

1
2
3
4
5
6
7
8
9
module top_module ( 
input wire [2:0] vec,
output wire [2:0] outv,
output wire o2,
output wire o1,
output wire o0 );
assign outv = vec;
assign {o2,o1,o0} = vec;
endmodule

2.2.2 Vectors in more detail
1
2
3
4
5
6
7
8
`default_nettype none     // Disable implicit nets. Reduces some types of bugs.
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

1
2
3
4
5
6
7
8
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

1
2
3
4
5
6
7
8
9
10
11
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_no );
assign out_or_bitwise = a | b;
assign out_or_logical = a || b;
assign out_not[5:3] = ~b;
assign out_not[2:0] = ~a;
endmodule

2.2.5 Four-input gates

1
2
3
4
5
6
7
8
9
module top_module( 
input [3:0] in,
output out_and,
output out_or,
output out_xor );
assign out_and = in[3] & in[2] & in[1] & in[0];
assign out_or = in[3] | in[2] | in[1] | in[0];
assign out_xor = in[3] ^ in[2] ^ in[1] ^ in[0];
endmodule

2.2.6 Vector concatenation operator

1
2
3
4
5
6
7
8
module top_module (
input [4:0] a, b, c, d, e, f,
output [7:0] w, x, y, z );
assign w = {a, b[4:2] };
assign x = {b[1:0], c, d[4] };
assign y = {d[3:0], e[4:1] };
assign z = {e[0], f, 2'b11};
endmodule

2.2.7 Vector reversal 1
1
2
3
4
5
module top_module( 
input [7:0] in,
output [7:0] out);
assign {out[7], out[6], out[5], out[4], out[3], out[2], out[1], out[0] } = {in[0], in[1], in[2], in[3], in[4], in[5], in[6], in[7]};
endmodule

2.2.8 Replication operator
1
2
3
4
5
module top_module (
input [7:0] in,
output [31:0] out );
assign out = { {24{in[7]}} , in };
endmodule

2.2.9 More replication
1
2
3
4
5
6
7
module top_module (
input a, b, c, d, e,
output [24:0] out );
// The output is XNOR of two vectors created by
// concatenating and replicating the five inputs.
assign out = ~{ {5{a}}, {5{b}}, {5{c}}, {5{d}} ,{5{e}} } ^ { 5{a, b, c, d, e} };
endmodule

2.3 Modules: Hierarchy

2.3.1 Modules

1
2
3
module top_module ( input a, input b, output out );
mod_a test (.in1(a), .in2(b), .out(out));
endmodule

2.3.2 connecting ports by position
1
2
3
4
5
6
7
8
9
module top_module ( 
input a,
input b,
input c,
input d,
output out1,
output out2);
mod_a test(out1, out2, a, b, c, d);
endmodule

2.3.3 connecting ports by name
1
2
3
4
5
6
7
8
9
module top_module ( 
input a,
input b,
input c,
input d,
output out1,
output out2);
mod_a test (.in1(a), .in2(b), .in3(c), .in4(d), .out1(out1), .out2(out2));
endmodule

2.3.4 three modules
1
2
3
4
5
6
module top_module ( input clk, input d, output q );
wire q_1, q_2;
my_dff my_dff_1(.clk(clk), .d(d), .q(q_1));
my_dff my_dff_2(.clk(clk), .d(q_1), .q(q_2));
my_dff my_dff_3(.clk(clk), .d(q_2), .q(q) );
endmodule

2.3.5 modules and vectors
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
module top_module ( 
input clk,
input [7:0] d,
input [1:0] sel,
output [7:0] q );
wire [7:0] q_1, q_2, q_3;
reg [7:0] q_out_reg;
my_dff8 my_dff8_1(.clk(clk), .d(d), .q(q_1));
my_dff8 my_dff8_2(.clk(clk), .d(q_1), .q(q_2));
my_dff8 my_dff8_3(.clk(clk), .d(q_2), .q(q_3));
always @(*) begin
case (sel)
2'd0: q_out_reg = d;
2'd1: q_out_reg = q_1;
2'd2: q_out_reg = q_2;
2'd3: q_out_reg = q_3;
endcase
end
assign q = q_out_reg;
endmodule

2.3.6 adder1
1
2
3
4
5
6
7
8
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum);
wire cout;
add16 add16_1(.a(a[15:0]), .b(b[15:0]), .cin(1'b0), .sum(sum[15:0]), .cout(cout));
add16 add16_2(.a(a[31:16]), .b(b[31:16]), .cin(cout), .sum(sum[31:16]), .cout());
endmodule

2.3.7 adder2
1
2
3
4
5
6
7
8
9
10
11
12
module top_module (
input [31:0] a,
input [31:0] b,
output [31:0] sum);
wire cout_1;
add16 add16_1(.a(a[15:0]), .b(b[15:0]), .cin(1'b0), .sum(sum[15:0]), .cout(cout_1));
add16 add16_2(.a(a[31:16]), .b(b[31:16]), .cin(cout_1), .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
1
2
3
4
5
6
7
8
9
10
11
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum);
wire cout;
wire [15:0] sum_1,sum_2;
add16 add16_1(.a(a[15:0]), .b(b[15:0]), .cin(1'b0), .sum(sum[15:0]), .cout(cout));
add16 add16_2(.a(a[31:16]), .b(b[31:16]), .cin(1'b0), .sum(sum_1), .cout());
add16 add16_3(.a(a[31:16]), .b(b[31:16]), .cin(1'b1), .sum(sum_2), .cout());
assign sum[31:16] = cout ? sum_2 : sum_1;
endmodule

2.3.9 adder-subtractor
1
2
3
4
5
6
7
8
9
10
11
module top_module(
input [31:0] a,
input [31:0] b,
input sub,
output [31:0] sum);
wire cout;
wire [31:0] b_1;
assign b_1 = b ^ {32{sub}};
add16 add16_1(.a(a[15:0]), .b(b_1[15:0]), .cin(sub), .sum(sum[15:0]), .cout(cout));
add16 add16_2(.a(a[31:16]), .b(b_1[31:16]), .cin(cout), .sum(sum[31:16]), .cout());
endmodule

2.4 Procedures

2.4.1 always blocks 1

1
2
3
4
5
6
7
8
9
10
11
// synthesis verilog_input_version verilog_2001
module top_module(
input a,
input b,
output wire out_assign,
output reg out_alwaysbloc);
assign out_assign = a & b;
always @(*) begin
out_alwaysblock = a & b;
end
endmodule

2.4.2 always blocks 2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// synthesis verilog_input_version verilog_2001
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 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)
out_always = b;
else
out_always = a;
end
endmodule

2.4.3 if statement latches
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// synthesis verilog_input_version verilog_2001
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 = ~arrived;
end
endmodule

2.4.4 case statement
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// synthesis verilog_input_version verilog_2001
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: out = data0;
3'd1: out = data1;
3'd2: out = data2;
3'd3: out = data3;
3'd4: out = data4;
3'd5: out = data5;
default: out = 4'd0;
endcase
end
endmodule

2.4.5 priority encoder
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// synthesis verilog_input_version verilog_2001
module top_module (
input [3:0] in,
output reg [1:0] pos );
always @(*) begin
case (in)
4'b0000: pos = 2'd0;
4'b0001, 4'b0011, 4'b0101, 4'b0111, 4'b1001, 4'b1011, 4'b1101, 4'b1111: pos = 2'd0;
4'b0010, 4'b0110, 4'b1010, 4'b1110: pos = 2'd1;
4'b0100, 4'b1100: pos = 2'd2;
4'b1000: pos = 2'd3;
default: pos = 2'd0;
endcase
end
endmodule

2.4.6 priority encoder with casez

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// synthesis verilog_input_version verilog_2001
module top_module (
input [7:0] in,
output reg [2:0] pos );
always @(*)begin
casez (in[7:0])
8'bzzzzzzz1: pos = 3'd0;
8'bzzzzzz1z: pos = 3'd1;
8'bzzzzz1zz: pos = 3'd2;
8'bzzzz1zzz: pos = 3'd3;
8'bzzz1zzzz: pos = 3'd4;
8'bzz1zzzzz: pos = 3'd5;
8'bz1zzzzzz: pos = 3'd6;
8'b1zzzzzzz: pos = 3'd7;
default: pos = 3'd0;
endcase
end
endmodule

2.4.7 avoiding latches

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// synthesis verilog_input_version verilog_2001
module top_module (
input [15:0] scancode,
output reg left,
output reg down,
output reg right,
output reg up );
always @(*) begin
case (scancode)
16'he06b: begin left = 1; down = 0; right = 0; up = 0; end
16'he072: begin left = 0; down = 1; right = 0; up = 0; end
16'he074: begin left = 0; down = 0; right = 1; up = 0; end
16'he075: begin left = 0; down = 0; right = 0; up = 1; end
default: begin left = 0; down = 0; right = 0; up = 0; end
endcase
end
endmodule

2.5 More Verilog Features

2.5.1 conditional ternary operator

1
2
3
4
5
6
7
8
module top_module (
input [7:0] a, b, c, d,
output [7:0] min);
wire [7:0] min_1, min_2;
assign min_1 = (a < b) ? a : b;
assign min_2 = (c < d) ? c : d;
assign min = (min_1 < min_2) ? min_1 : min_2;
endmodule

2.5.2 reduction operators
1
2
3
4
5
module top_module (
input [7:0] in,
output parity);
assign parity = ^in;
endmodule

2.5.3 reduction : even wider gates
1
2
3
4
5
6
7
8
9
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

1
2
3
4
5
6
7
8
9
10
module top_module( 
input [99:0] in,
output [99:0] out);
reg [6:0] i = 0;
always @(*) begin
for (i = 0; i < 100; i = i + 1)begin
out[i] = in[99 - i];
end
end
endmodule

2.5.5 combinational for-loop: 255-bit population count

1
2
3
4
5
6
7
8
9
10
11
12
13
module top_module( 
input [254:0] in,
output [7:0] out );
reg [7:0] i;
always @(*)begin
out = 8'd0;
for(i = 0; i < 255; i = i + 1)
if (in[i])
out = out + 1'b1;
else
out = out;
end
endmodule

2.5.6 generate for-loop: 100-bit binary adder 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
module top_module( 
input [99:0] a, b,
input cin,
output [99:0] cout,
output [99:0] sum );
assign cout[0] = a[0] & b[0] | a[0] & cin | b[0] & cin;
assign sum[0] = a[0] ^ b[0] ^ cin;
genvar i;
generate
for (i=1; i<100; i++) begin : adder_loop
assign cout[i] = a[i] & b[i] | a[i] & cout[i-1] | b[i] & cout[i-1];
assign sum[i] = a[i] ^ b[i] ^ cout[i-1];
end
endgenerate
endmodule

2.5.7 generate for-loop: 100-bit digit BCD adder 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
module top_module( 
input [399:0] a, b,
input cin,
output cout,
output [399:0] sum );
wire [399:0] cout_temp;
bcd_fadd u1(.a(a[3:0]), .b(b[3:0]), .cin(cin), .cout(cout_temp[0]), .sum(sum[3:0]));
assign cout = cout_temp[396];
genvar i;
generate
for(i = 4; i < 400; i = i + 4) begin : adder_loop
bcd_fadd u1(.a(a[i+3:i]), .b(b[i+3:i]), .cin(cout_temp[i-4]), .cout(cout_temp[i]), .sum(sum[i+3:i]));
end
endgenerate
endmodule

3 Circuits

3.1 Combinational Logic

3.1.1 Basic Gates

1 wire

1
2
3
4
5
module top_module (
input in,
output out);
assign out = in;
endmodule

2 GND

1
2
3
4
module top_module (
output out);
assign out = 1'b0;
endmodule

3 NOR
1
2
3
4
5
6
module top_module (
input in1,
input in2,
output out);
assign out = ~(in1 | in2);
endmodule

4 another gate

1
2
3
4
5
6
module top_module (
input in1,
input in2,
output out);
assign out = in1 & (~in2);
endmodule

5 two gate

1
2
3
4
5
6
7
module top_module (
input in1,
input in2,
input in3,
output out);
assign out = (in1 ^~ in2) ^ in3;
endmodule

6 more logic gates

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
module top_module( 
input a, b,
output out_and,
output out_or,
output out_xor,
output out_nand,
output out_nor,
output out_xnor,
output out_anotb );

assign out_and = a & b;
assign out_or = a | b;
assign out_xor = a ^ b;
assign out_nand = ~(a & b);
assign out_nor = ~(a | b);
assign out_xnor = a ^~ b;
assign out_anotb = a & (~b);

endmodule

7 7420 chip
1
2
3
4
5
6
7
8
9
module top_module ( 
input p1a, p1b, p1c, p1d,
output p1y,
input p2a, p2b, p2c, p2d,
output p2y );
assign p1y = ~(p1a & p1b & p1c & p1d);
assign p2y = ~(p2a & p2b & p2c & p2d);

endmodule

8 truth table
1
2
3
4
5
6
7
module top_module( 
input x3,
input x2,
input x1,
output f );
assign f = ((~x3) & x2 & (~x1)) | ((~x3) & x2 & x1) | (x3 & (~x2) & x1) | (x3 & x2 & x1);
endmodule

9 two-bits equality

1
2
3
module top_module ( input [1:0] A, input [1:0] B, output z ); 
assign z = (A == B) ? 1 : 0;
endmodule

10 sample circuits A

1
2
3
module top_module (input x, input y, output z);
assign z= (x ^ y) & x;
endmodule

11 sample circuits B
1
2
3
module top_module ( input x, input y, output z );
assign z = x ^~ y;
endmodule

12 combine circuits A and B
1
2
3
4
5
6
module top_module (input x, input y, output z);
wire z1,z2;
assign z1= (x ^ y) & x;
assign z2 = x ^~ y;
assign z = (z1 | z2) ^ (z1 & z2);
endmodule

13 ring or vibrate
1
2
3
4
5
6
7
module top_module (
input ring,
input vibrate_mode,
output ringer,
output motor );
assign {ringer, motor} = ring ? (vibrate_mode ? 2'b01 : 2'b10) : 2'b00;
endmodule

14 thermostat
1
2
3
4
5
6
7
8
9
10
11
12
module top_module (
input too_cold,
input too_hot,
input mode,
input fan_on,
output heater,
output aircon,
output fan );
assign heater = mode ? (too_cold ? 1'b1 : 1'b0) : 1'b0;
assign aircon = ~mode ? (too_hot ? 1'b1 : 1'b0) : 1'b0;
assign fan = heater | aircon | fan_on;
endmodule

15 3-bit population count
1
2
3
4
5
6
7
8
9
10
11
12
13
14
module top_module( 
input [2:0] in,
output [1:0] out );
reg [1:0] i;

always @(*) begin
out = 2'd0;
for(i = 0; i < 3; i = i + 1'b1)
if (in[i] == 1)
out = out + 1'b1;
else
out = out;
end
endmodule

16 gates and vectors
1
2
3
4
5
6
7
8
9
module top_module( 
input [3:0] in,
output [2:0] out_both,
output [3:1] out_any,
output [3:0] out_different );
assign {out_both[2], out_both[1], out_both[0]} = {in[3] & in[2], in[2] & in[1], in[1] & in[0]};
assign {out_any[3], out_any[2], out_any[1]} = {in[3] | in[2], in[2] | in[1], in[1] | in[0]};
assign {out_different[3], out_different[2], out_different[1], out_different[0]} = {in[0] ^ in[3], in[3] ^ in[2], in[2] ^ in[1], in[1] ^ in[0]};
endmodule

17 Even longer vectors

1
2
3
4
5
6
7
8
9
module top_module( 
input [99:0] in,
output [98:0] out_both,
output [99:1] out_any,
output [99:0] out_different );
assign out_both = in[99:1] & in[98:0];
assign out_any = in[99:1] | in[98:0];
assign out_different = in[99:0] ^ {in[0], in[99:1]};
endmodule

3.1.2 Multiplexers

1 2 to 1 multiplexers

1
2
3
4
5
module top_module( 
input a, b, sel,
output out );
assign out = sel ? b : a;
endmodule

2 2 to 1 bus multiplexers
1
2
3
4
5
6
module top_module( 
input [99:0] a, b,
input sel,
output [99:0] out );
assign out = sel ? b : a;
endmodule

3 9 to 1 multiplexers
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
module top_module( 
input [15:0] a, b, c, d, e, f, g, h, i,
input [3:0] sel,
output [15:0] out );
always @(*) begin
case (sel)
4'd0: out = a;
4'd1: out = b;
4'd2: out = c;
4'd3: out = d;
4'd4: out = e;
4'd5: out = f;
4'd6: out = g;
4'd7: out = h;
4'd8: out = i;
default: out = 16'hffff;
endcase
end
endmodule

4 256 to 1 multiplexers
1
2
3
4
5
6
module top_module( 
input [255:0] in,
input [7:0] sel,
output out );
assign out = in[sel];
endmodule

5 256 to 1 4-bit multiplexers
1
2
3
4
5
6
module top_module( 
input [1023:0] in,
input [7:0] sel,
output [3:0] out );
assign out = {in[sel*4+3], in[sel*4+2], in[sel*4+1], in[sel*4]};
endmodule

3.1.3 Arithmetic Circuits

1 half adder

1
2
3
4
5
module top_module( 
input a, b,
output cout, sum );
assign {cout,sum} = a + b;
endmodule

2 full adder
1
2
3
4
5
module top_module( 
input a, b, cin,
output cout, sum );
assign {cout,sum} = a + b + cin;
endmodule

2 3-bit binary adder

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
module top_module( 
input [2:0] a, b,
input cin,
output [2:0] cout,
output [2:0] sum );
adder adder_1(.a(a[0]), .b(b[0]), .cin(cin), .cout(cout[0]), .sum(sum[0]));
adder adder_2(.a(a[1]), .b(b[1]), .cin(cout[0]), .cout(cout[1]), .sum(sum[1]));
adder adder_3(.a(a[2]), .b(b[2]), .cin(cout[1]), .cout(cout[2]), .sum(sum[2]));
endmodule
//全加器
module adder(
input a, b, cin,
output cout, sum );
assign {cout,sum} = a + b + cin;
endmodule

4 adder

1
2
3
4
5
6
7
module top_module (
input [3:0] x,
input [3:0] y,
output [4:0] sum);
wire cout_1,cout_2,cout_3;
assign sum = x + y;
endmodule

5 signed addition overflow
1
2
3
4
5
6
7
8
module top_module (
input [7:0] a,
input [7:0] b,
output [7:0] s,
output overflow);
assign s = a + b;
assign overflow = a[7] == b[7] & ( a[7] != s[7] | b[7] != s[7]);
endmodule

6 100-bit binary adder
1
2
3
4
5
6
7
module top_module( 
input [99:0] a, b,
input cin,
output cout,
output [99:0] sum );
assign {cout, sum} = a + b + cin;
endmodule

7 4- digit BCD adder
1
2
3
4
5
6
7
8
9
10
11
module top_module( 
input [15:0] a, b,
input cin,
output cout,
output [15:0] sum );
wire [2:0] cout_temp;
bcd_fadd bcd_fadd_0(.a(a[3:0]), .b(b[3:0]), .cin(cin), .cout(cout_temp[0]), .sum(sum[3:0]));
bcd_fadd bcd_fadd_1(.a(a[7:4]), .b(b[7:4]), .cin(cout_temp[0]), .cout(cout_temp[1]), .sum(sum[7:4]));
bcd_fadd bcd_fadd_2(.a(a[11:8]), .b(b[11:8]), .cin(cout_temp[1]), .cout(cout_temp[2]), .sum(sum[11:8]));
bcd_fadd bcd_fadd_3(.a(a[15:12]), .b(b[15:12]), .cin(cout_temp[2]), .cout(cout), .sum(sum[15:12]));
endmodule

3.1.4 Karnaugh Map to Circuit

1 3-variable

1
2
3
4
5
6
7
module top_module(
input a,
input b,
input c,
output out );
assign out = a | ((~a) & c) | (b & (~c));
endmodule

2 4-variable 1
1
2
3
4
5
6
7
8
module top_module(
input a,
input b,
input c,
input d,
output out );
assign out = ((~b) & (~c)) | ((~a) & (~d)) | (b&c&d) | (a&c&d);
endmodule

3 4-variable 2
1
2
3
4
5
6
7
8
module top_module(
input a,
input b,
input c,
input d,
output out );
assign out = a | ((~a) & (~b) & (c));
endmodule

4 4-variable 3
1
2
3
4
5
6
7
8
module top_module(
input a,
input b,
input c,
input d,
output out );
assign out = ~a&~b&~c&d | ~a&~b&c&~d | ~a&b&~c&~d | ~a&b&c&d | a&b&~c&d | a&b&c&~d | a&~b&~c&~d | a&~b&c&d;
endmodule

5 minimum SOP and POS
1
2
3
4
5
6
7
8
9
10
module top_module (
input a,
input b,
input c,
input d,
output out_sop,
output out_pos);
assign out_sop = (c & d) | (~a & c & ~b);
assign out_pos = c & (~b | d) & (~a | d);
endmodule

6 Karnaugh map
1
2
3
4
5
module top_module (
input [4:1] x,
output f );
assign f = (x[3] & ~x[1]) | (~x[3] & x[1] & x[2]);
endmodule

7 Karnaugh map

1
2
3
4
5
module top_module (
input [4:1] x,
output f);
assign f = (x[3] & ~x[1]) | (~x[4] & ~x[2]) | ( x[2] & x[3] & x[4]);
endmodule

8 K-map implemented with a multiplexer

1
2
3
4
5
6
7
8
9
module top_module (
input c,
input d,
output [3:0] mux_in);
assign mux_in[0] = (c | d) ? 1 : 0;
assign mux_in[1] = 0;
assign mux_in[2] = (~d) ? 1 : 0;
assign mux_in[3] = (c & d) ? 1 : 0;
endmodule

3.2 sequential Logic

3.2.1 latches and Flip-Flops

1 DFF

1
2
3
4
5
6
7
8
module top_module (
input clk, // Clocks are used in sequential circuits
input d,
output reg q );//
always @(posedge clk) begin
q <= d;
end
endmodule

2 DFF
1
2
3
4
5
6
7
8
module top_module (
input clk,
input [7:0] d,
output [7:0] q);
always @(posedge clk) begin
q <= d;
end
endmodule

3 DFF with reset
1
2
3
4
5
6
7
8
9
10
11
12
module top_module (
input clk,
input reset, // Synchronous reset
input [7:0] d,
output [7:0] q);
always @(posedge clk) begin
if(reset)
q <= 0;
else
q <= d;
end
endmodule

4 DFF with reset value
1
2
3
4
5
6
7
8
9
10
11
12
module top_module (
input clk,
input reset,
input [7:0] d,
output [7:0] q );
always @(negedge clk) begin
if(reset)
q <= 8'h34;
else
q <= d;
end
endmodule

5 DFF with asynchronous reset
1
2
3
4
5
6
7
8
9
10
11
12
module top_module (
input clk,
input areset, // active high asynchronous reset
input [7:0] d,
output [7:0] q);
always @(posedge clk or posedge areset) begin
if(areset)
q <= 0;
else
q <= d;
end
endmodule

6 DFF with byte enable
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
module top_module (
input clk,
input resetn,
input [1:0] byteena,
input [15:0] d,
output [15:0] q);
always @(posedge clk)begin
if(!resetn)
q <= 0;
else begin
if(byteena[1])
q[15:8] <= d[15:8];
else
q[15:8] <= q[15:8];

if(byteena[0])
q[7:0] <= d[7:0];
else
q[7:0] <= q[7:0];
end
end
endmodule

7 D latch
1
2
3
4
5
6
module top_module (
input d,
input ena,
output q);
assign q = ena ? d : q;
endmodule

8 DFF

1
2
3
4
5
6
7
8
9
10
11
12
module top_module (
input clk,
input d,
input ar, // asynchronous reset
output q);
always @(posedge clk or posedge ar)begin
if(ar)
q <= 0;
else
q <= d;
end
endmodule

9 DFF

1
2
3
4
5
6
7
8
9
10
11
12
module top_module (
input clk,
input d,
input r, // synchronous reset
output q);
always @(posedge clk)begin
if(r)
q <= 0;
else
q <= d;
end
endmodule

10 DFF+gate

1
2
3
4
5
6
7
8
module top_module (
input clk,
input in,
output out);
always @(posedge clk)begin
out <= in ^ out;
end
endmodule

11 mux and DFF

1
2
3
4
5
6
7
8
9
10
11
12
13
module top_module (
input clk,
input L,
input r_in,
input q_in,
output reg Q);
always @(posedge clk) begin
if(L)
Q <= r_in;
else
Q <= q_in;
end
endmodule

12 mux and DFF

1
2
3
4
5
6
7
8
9
10
11
12
13
14
module top_module (
input clk,
input w, R, E, L,
output Q);
always @(posedge clk) begin
if(L)
Q <= R;
else
if(E)
Q <= w;
else
Q <= Q;
end
endmodule

13 DFFs and gate

1
2
3
4
5
6
7
8
9
10
11
12
module top_module (
input clk,
input x,
output z);
reg [2:0] q = 3'b0;
always @(posedge clk)begin
q[0] <= x ^ q[0];
q[1] <= x & ~q[1];
q[2] <= x | ~q[2];
end
assign z = ~(q[0] | q[1] | q[2]);
endmodule

14 creat circuit from truth table (JK)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
module top_module (
input clk,
input j,
input k,
output Q);
always @(posedge clk) begin
case({j,k})
2'b00: Q <= Q;
2'b01: Q <= 0;
2'b10: Q <= 1;
2'b11: Q <= ~Q;
endcase
end
endmodule

15 detect an edge

1
2
3
4
5
6
7
8
9
10
module top_module (
input clk,
input [7:0] in,
output [7:0] pedge);
reg [7:0] in_reg;
always @(posedge clk)begin
in_reg <= in;
pedge <= ~in_reg & in;
end
endmodule

16 detect both edge
1
2



17 edge capture register
1


18 dual-edge triggered flip-flop
1
2
3
4
5
6
7
8
9
10
11
12
13
module top_module (
input clk,
input d,
output q);
reg q1,q2;
always @(posedge clk)begin
q1 <= d;
end
always @(negedge clk)begin
q2 <= d;
end
assign q = clk ? q1 : q2;
endmodule

3.2.2 counters

1 foub-bit binary counter

1
2
3
4
5
6
7
8
9
10
11
module top_module (
input clk,
input reset, // Synchronous active-high reset
output [3:0] q);
always @(posedge clk)begin
if(reset)
q <= 3'b0;
else
q <= q + 1'b1;
end
endmodule

2 decade counter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
module top_module (
input clk,
input reset, // Synchronous active-high reset
output [3:0] q);
always @(posedge clk)begin
if(reset)
q <= 3'b0;
else
if(q == 4'd9)
q <= 0;
else
q <= q + 1'b1;
end
endmodule

3 decade counter again
1
2
3
4
5
6
7
8
9
10
11
12
13
module top_module (
input clk,
input reset,
output [3:0] q);
always @(posedge clk)begin
if(reset)
q <= 4'b1;
else if(q == 4'd10)
q <= 1;
else
q <= q + 1'b1;
end
endmodule

4 slow decade counter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
module top_module (
input clk,
input slowena,
input reset,
output [3:0] q);
always @(posedge clk)begin
if(reset)
q <= 4'b0;
else
if (slowena)
if(q == 4'd9)
q <= 0;
else
q <= q + 1'b1;
else
q <= q;
end
endmodule

5 counter 1-12
1
2
3
4
5
6
7
8
9
10
11
12
13
module top_module (
input clk,
input reset,
input enable,
output [3:0] Q,
output c_enable,
output c_load,
output [3:0] c_d );
assign c_enable = enable;
assign c_load = reset | (Q == 4'd12 & enable);
assign c_d = 4'd1;
count4 the_counter (.clk(clk), .enable(c_enable), .load(c_load), .d(c_d), .Q(Q));
endmodule

13 counter 100
1
2
3
4
5
6
7
8
9
10
11
12
13
14
module top_module (
input clk,
input reset,
output OneHertz,
output [2:0] c_enable);
wire [3:0] q1,q2,q3;
assign c_enable[0] = 1'b1;
assign c_enable[1] = (q1 == 4'd9);
assign c_enable[2] = (q1 == 4'd9 & q2 == 4'd9);
assign OneHertz = (q1 == 4'd9 & q2 == 4'd9 & q3 == 4'd9);
bcdcount counter0 (clk, reset, c_enable[0], q1);
bcdcount counter1 (clk, reset, c_enable[1], q2);
bcdcount counter2 (clk, reset, c_enable[2], q3);
endmodule

14 4- digit decimal counter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
module top_module (
input clk,
input reset, // Synchronous active-high reset
output [3:1] ena,
output [15:0] q);

always @(posedge clk) begin
if (reset) begin
ena <= 3'b0;
end
else begin
if (q[3:0] == 4'd8 ) begin
ena[1] <= 1;
end
else
ena[1] <= 0;

if (q[7:4] == 4'd9 && q[3:0] == 4'd8) begin
ena[2] <= 1;
end
else
ena[2] <= 0;

if (q[11:8] == 4'd9 && q[7:4] == 4'd9 && q[3:0] == 4'd8) begin
ena[3] <= 1;
end
else
ena[3] <= 0;
end
end

always @(posedge clk) begin
if (reset) begin
q <= 16'b0;
end
else begin
if (ena[1]) begin
q[3:0] <= 4'b0;
q[7:4] <= q[7:4] + 1'b1;
end
else begin
q[3:0] <= q[3:0] + 1'b1;
q[7:4] <= q[7:4];
end

if (ena[2]) begin
q[7:4] <= 4'b0;
q[11:8] <= q[11:8] + 1'b1;
end
else
q[11:8] <= q[11:8];

if (ena[3]) begin
q[11:8] <= 4'b0;

if (q[15:12] == 4'd9 )
q[15:12] <= 4'b0;
else
q[15:12] <= q[15:12] + 1'b1;
end
else
q[15:12] <= q[15:12];
end
end
endmodule

15 12-hour clock
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
module top_module(
input clk,
input reset,
input ena,
output pm,
output [7:0] hh,
output [7:0] mm,
output [7:0] ss);
//例化计数器表示秒
wire ssl_2_ssh,ssh_2_mml; //地位向高位进位
cnt cnt_ssl(.clk(clk),.reset(reset),.count_start(ena),.count_end(4'd9),.end_cnt(ssl_2_ssh),.count(ss[3:0]));
cnt cnt_ssh(.clk(clk),.reset(reset),.count_start(ssl_2_ssh),.count_end(4'd5),.end_cnt(ssh_2_mml),.count(ss[7:4]));
//例化计数器表示分钟
wire mml_2_mmh, mmh_2_hh;
cnt cnt_mml(.clk(clk),.reset(reset),.count_start(ssh_2_mml),.count_end(4'd9),.end_cnt(mml_2_mmh),.count(mm[3:0]));
cnt cnt_mmh(.clk(clk),.reset(reset),.count_start(mml_2_mmh),.count_end(4'd5),.end_cnt(mmh_2_hh),.count(mm[7:4]));
//小时计数
reg a_2_p;
always @(posedge clk)begin
if(reset)begin
a_2_p <= 0;
hh <= 8'h12; // 初始条件 12:00:00 AM
end
else if(mmh_2_hh)begin
if(hh == 8'h12)
hh <= 8'h01;
else begin
hh <= hh + 1'b1;
if(hh == 8'h09)
hh <= 8'h10;
if(hh == 8'h11)
a_2_p <= ~ a_2_p;
end
end
end
assign pm = a_2_p;
endmodule

//计数器子模块,可以设置开始和结束条件
module cnt(
input clk,
input reset,
input count_start, //开始计数输入
input [3:0] count_end, //计数到多少停止计数
output end_cnt, //一次计数完成标志
output [3:0] count);
wire add_cnt;
always @(posedge clk)begin
if(reset)begin
count <= 4'd0;
end
else if(add_cnt)begin
if(end_cnt)
count <= 4'd0;
else
count <= count + 1'b1;
end
end
assign add_cnt = count_start; //计数开始条件,当满足了开始计数
assign end_cnt = add_cnt && count == count_end; //计数结束产生一个标志
endmodule

3.2.3 shift registers

1 4-bit shift registers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
module top_module(
input clk,
input areset, // async active-high reset to zero
input load,
input ena,
input [3:0] data,
output reg [3:0] q);
always @(posedge clk or posedge areset) begin
if (areset) begin
q <= 4'b0;
end
else begin
if (load) begin
q <= data;
end
else if (ena) begin
q <= q >> 1;
end
else
q <= q;
end
end
endmodule

2 left/right rotator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

module top_module(
input clk,
input load,
input [1:0] ena,
input [99:0] data,
output reg [99:0] q);
integer i;
always @(posedge clk) begin
if (load) begin
q <= data;
end
else if (ena == 2'b01) begin
q[99] <= q[0];
for (i = 0; i <= 98; i = i + 1)
q[i] <= q[i+1];
end
else if (ena == 2'b10) begin
q[0] <= q[99];
for (i = 1; i <= 99; i = i + 1)
q[i] <= q[i-1];
end
else
q <= q;
end
endmodule

3 left/rignt arthmetic shift by 1 or 8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
module top_module(
input clk,
input load,
input ena,
input [1:0] amount,
input [63:0] data,
output reg [63:0] q);
always @(posedge clk) begin
if (load) begin
q <= data;
end
else if (ena) begin
case (amount)
2'b00: q <= q <<< 1;
2'b01: q <= q <<< 8;
2'b10: q <= {{q[63]},{q[63:1]}};
2'b11: q <= {{8{q[63]}},{q[63:8]}};
endcase
end
else
q <= q;
end
endmodule

4 5-bit LFSR
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
module top_module(
input clk,
input reset, // Active-high synchronous reset to 5'h1
output [4:0] q);
always @ (posedge clk) begin
if (reset) begin
q <= 4'b1;
end
else begin
q[4] <= q[0] ^ 1'b0;
q[3] <= q[4] ;
q[2] <= q[3] ^ q[0];
q[1] <= q[2] ;
q[0] <= q[1] ;
end
end
endmodule

5 3-bit LFSR
1
2
3
4
5
6
7
8
9
10
module top_module (
input [2:0] SW, // R
input [1:0] KEY, // L and clk
output [2:0] LEDR); // Q
always @(posedge KEY[0]) begin
LEDR[0] <= KEY[1] ? SW[0] : LEDR[2];
LEDR[1] <= KEY[1] ? SW[1] : LEDR[0];
LEDR[2] <= KEY[1] ? SW[2] : (LEDR[1] ^ LEDR[2]);
end
endmodule

6 32-bit LFSR
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module top_module(
input clk,
input reset, // Active-high synchronous reset to 32'h1
output [31:0] q );
always @ (posedge clk) begin
if(reset)
q <= 32'h1;
else begin
q <= {q[0], q[31:1]};
q[31] <= q[0] ^ 1'b0;
q[21] <= q[0] ^ q[22];
q[1] <= q[0] ^ q[2];
q[0] <= q[0] ^ q[1];
end
end
endmodule

7 shift register
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
module top_module (
input clk,
input resetn, // synchronous reset
input in,
output out);
reg q_0,q_1,q_2;
always @(posedge clk) begin
if (!resetn) begin
q_0 <= 0;
q_1 <= 0;
q_2 <= 0;
out <= 0;
end
else begin
q_0 <= in;
q_1 <= q_0;
q_2 <= q_1;
out <= q_2;
end
end
endmodule

8 shift register
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
module top_module (
input [3:0] SW,
input [3:0] KEY,
output [3:0] LEDR);
MUXDFF u_1(.clk(KEY[0]), .w(KEY[3]), .E(KEY[1]), .R(SW[3]), .L(KEY[2]), .q(LEDR[3]));
MUXDFF u_2(.clk(KEY[0]), .w(LEDR[3]), .E(KEY[1]), .R(SW[2]), .L(KEY[2]), .q(LEDR[2]));
MUXDFF u_3(.clk(KEY[0]), .w(LEDR[2]), .E(KEY[1]), .R(SW[1]), .L(KEY[2]), .q(LEDR[1]));
MUXDFF u_4(.clk(KEY[0]), .w(LEDR[1]), .E(KEY[1]), .R(SW[0]), .L(KEY[2]), .q(LEDR[0]));
endmodule

module MUXDFF (
input clk,
input w,
input E,
input R,
input L,
output q
);
always @(posedge clk) begin
q <= L ? R : (E ? w : q);
end
endmodule

9 3-input LUT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
module top_module (
input clk,
input enable,
input S,
input A, B, C,
output Z );
reg [7:0] q;
always @(posedge clk) begin
if (enable) begin
q <= {q[6:0], S};
end
else
q <= q;
end
always @(*) begin
case ({A,B,C})
3'b000: Z <= q[0];
3'b001: Z <= q[1];
3'b010: Z <= q[2];
3'b011: Z <= q[3];
3'b100: Z <= q[4];
3'b101: Z <= q[5];
3'b110: Z <= q[6];
3'b111: Z <= q[7];
endcase
end
endmodule

3.2.4 More Circuits

1 Rule 90

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
module top_module(
input clk,
input load,
input [511:0] data,
output [511:0] q );
integer i;
always @(posedge clk)begin
if(load)begin
q <= data;
end
else begin
q[0] <= 1'b0 ^ q[1];
q[511] <= 1'b0 ^ q[510];
for(i = 1; i < 511; i = i + 1)begin
q[i] <= q[i-1] ^ q[i+1];
end
end
end
endmodule

2 Rule 110
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
module top_module(
input clk,
input load,
input [511:0] data,
output [511:0] q);
integer i;
always @(posedge clk)begin
if(load)begin
q <= data;
end
else begin
q[0] <= q[0];
q[511] <= q[511] | q[510];
for(i = 1; i < 511; i = i + 1)begin
q[i] <= (~q[i+1] & (q[i] | q[i-1])) | (q[i+1] & (q[i] ^ q[i-1]));
end
end
end
endmodule

3 Conway’s Game of Life 16x16
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
module top_module(
input clk,
input load,
input [255:0] data,
output [255:0] q );
integer i,m,n;
reg [17:0] g_2d [17:0];
reg [2:0] sum;
// 16×16 -> 18×18
always@(*) begin
g_2d[0] = {q[16*15], q[16*15 +: 16], q[16*16 -1]};
g_2d[17] = {q[16*0], q[16*0 +: 16],q[16*1 -1]};
for(i=1; i<17; i+=1) begin
g_2d[i] = {q[16*(i-1)], q[16*(i-1) +: 16], q[16*i -1]};
end
end
always@(posedge clk) begin
if(load) begin
q <= data;
end else begin
for(m=0; m<16; m+=1) begin
for(n=0; n<16; n+=1) begin
sum = g_2d[m][n] + g_2d[m][n+1] + g_2d[m][n+2] + g_2d[m+1][n] + g_2d[m+1][n+2] + g_2d[m+2][n] + g_2d[m+2][n+1] + g_2d[m+2][n+2];
case(sum)
3'b010: q[16*m+n] <= q[16*m+n];
3'b011: q[16*m+n] <= 1'b1;
default: q[16*m+n] <= 1'b0;
endcase
end
end
end
end
endmodule

3.2.5 Finite State Machines

1 simple FSM 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
module top_module(
input clk,
input areset, // Asynchronous reset to state B
input in,
output out);
parameter A=1'b0, B=1'b1;
reg state, next_state;
always @(*) begin // This is a combinational always block
// State transition logic
if (state == B)
next_state = in ? B : A;
else if(state == A)
next_state = in ? A : B;
else
next_state = next_state;
end
always @(posedge clk, posedge areset) begin // This is a sequential always block
// State flip-flops with asynchronous reset
if (areset) begin
state <= B;
end
else begin
state <= next_state;
end
end
// Output logic
assign out = (state == B);
endmodule

2 simple FSM 1.2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
module top_module(clk, reset, in, out);
input clk;
input reset; // Synchronous reset to state B
input in;
output out;//
reg out;
// Fill in state name declarations
parameter A=1'b0, B=1'b1;
reg present_state, next_state;
always @(posedge clk) begin
if (reset) begin
present_state = B;
end
else begin
case (present_state)
B : if (in == 1'b0)
next_state = A;
else
next_state = present_state;
A : if (in == 1'b0)
next_state = B;
else
next_state = present_state;
endcase
// State flip-flops
present_state = next_state;
end
case (present_state)
// Fill in output logic
B : out = 1;
A : out = 0;
endcase
end
endmodule

// Note the Verilog-1995 module declaration syntax here:
module top_module(clk, reset, in, out);
input clk;
input reset; // Synchronous reset to state B
input in;
output out;
wire out;
// Fill in state name declarations
parameter A=1'b0;
parameter B=1'b1;
reg state;
assign out = state;
always @(posedge clk) begin
if (reset) begin
state = B;
end else begin
case (state)
A: begin state = (in==0)?B:A; end
B: begin state = (in==0)?A:B; end
endcase
end
end
endmodule

3 simple FSM 2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
module top_module(
input clk,
input areset, // Asynchronous reset to OFF
input j,
input k,
output out);
parameter OFF=0, ON=1;
reg state, next_state;
always @(*) begin
if(state == OFF) begin
next_state = (j==1) ? ON : OFF;
end
else if(state == ON) begin
next_state = (k==1) ? OFF : ON;
end
else
next_state = OFF;
end
always @(posedge clk, posedge areset) begin
// State flip-flops with asynchronous reset
if(areset) begin
state <= OFF;
end
else begin
state <= next_state;
end
end
// Output logic
assign out = (state == ON);
endmodule

4 simple FSM 2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
module top_module(
input clk,
input reset, // Asynchronous reset to OFF
input j,
input k,
output out);
parameter OFF=0, ON=1;
reg state, next_state;
always @(*) begin
if(state == OFF) begin
next_state = (j==1) ? ON : OFF;
end
else if(state == ON) begin
next_state = (k==1) ? OFF : ON;
end
else
next_state = OFF;
end
always @(posedge clk) begin
// State flip-flops with asynchronous reset
if(reset) begin
state <= OFF;
end
else begin
state <= next_state;
end
end
// Output logic
assign out = (state == ON);
endmodule

5 Simple state transitions 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
module top_module(
input in,
input [1:0] state,
output [1:0] next_state,
output out);
parameter A=0, B=1, C=2, D=3;
// State transition logic: next_state = f(state, in)
always @(*) begin
case(state)
A : begin next_state = in ? B: A; end
B : begin next_state = in ? B: C; end
C : begin next_state = in ? D: A; end
D : begin next_state = in ? B: C; end
endcase
end
// Output logic: out = f(state) for a Moore state machine
assign out = (state == D);
endmodule

6 Simple one-hot state transitions 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
module top_module(
input in,
input [3:0] state,
output [3:0] next_state,
output out);
parameter A=0, B=1, C=2, D=3;
// State transition logic: Derive an equation for each state flip-flop.
assign next_state[A] = (state[A] & ~in) | (state[C] & ~in);
assign next_state[B] = (state[A] & in) | (state[B] & in) | (state[D] & in);
assign next_state[C] = (state[B] & ~in) | (state[D] & ~in);
assign next_state[D] = (state[C] & in) ;
// Output logic:
assign out = (state[D] == 1);
endmodule

7 Simple FSM3 (asynchronous reset)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
module top_module(
input clk,
input in,
input areset,
output out);
reg [3:0] state, next_state;
parameter A=0, B=1, C=2, D=3;
// State transition logic: Derive an equation for each state flip-flop.
assign next_state[A] = (state[A] & ~in) | (state[C] & ~in);
assign next_state[B] = (state[A] & in) | (state[B] & in) | (state[D] & in);
assign next_state[C] = (state[B] & ~in) | (state[D] & ~in);
assign next_state[D] = (state[C] & in) ;
always @(posedge clk or posedge areset) begin
if(areset) begin
state <= 4'b0001;
end
else begin
state <= next_state;
end
end
// Output logic
assign out = (state == 4'b1000);
endmodule

8 Simple FSM3 (synchronous reset)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
module top_module(
input clk,
input in,
input reset,
output out);
reg [3:0] state, next_state;
parameter A=0, B=1, C=2, D=3;
// State transition logic: Derive an equation for each state flip-flop.
assign next_state[A] = (state[A] & ~in) | (state[C] & ~in);
assign next_state[B] = (state[A] & in) | (state[B] & in) | (state[D] & in);
assign next_state[C] = (state[B] & ~in) | (state[D] & ~in);
assign next_state[D] = (state[C] & in) ;
always @(posedge clk) begin
if(reset) begin
state <= 4'b0001;
end
else begin
state <= next_state;
end
end
// Output logic
assign out = (state == 4'b1000);
endmodule

9 Design a Moore FSM

image-20230417170817564

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
module top_module (
input clk,
input reset,
input [3:1] s,
output fr3,
output fr2,
output fr1,
output reg dfr
);

parameter s0=0,s1=1,s2=2,s3=3,s4=4,s5=5,s6=6;
reg [2:0] state, next_state;
reg [2:0] fr_reg;
assign {fr3, fr2, fr1} = fr_reg;

always @(posedge clk ) begin
if(reset)begin
state <= s3;
end else begin
state <= next_state;
end
end

always @(*)begin
case (state)
s0: begin
next_state = (s[3] == 0) ? s1 : s0;
end
s1: begin
if(s[3] == 1)begin
next_state = s0;
end else if(s[2] == 0)begin
next_state = s2;
end else begin
next_state = s1;
end
end
s2: begin
if(s[1] == 0)begin
next_state = s3;
end else if(s[2] == 1)begin
next_state = s5;
end else begin
next_state = s2;
end
end
s3: begin
next_state = (s[1] == 1) ? s4 : s3;
end
s4: begin
if(s[1] == 0)begin
next_state = s3;
end else if(s[2] == 1)begin
next_state = s5;
end else begin
next_state = s4;
end
end
s5: begin
if(s[3] == 1)begin
next_state = s0;
end else if(s[2] == 0)begin
next_state = s2;
end else begin
next_state = s5;
end
end
default: begin
next_state = s3;
end
endcase
end

always @(*) begin
begin
case (state)
s0 : begin fr_reg = 3'b000; dfr = 0; end
s1 : begin fr_reg = 3'b001; dfr = 1; end
s2 : begin fr_reg = 3'b011; dfr = 1; end
s3 : begin fr_reg = 3'b111; dfr = 1; end
s4 : begin fr_reg = 3'b011; dfr = 0; end
s5 : begin fr_reg = 3'b001; dfr = 0; end
default: begin fr_reg = 3'b111; dfr = 1; end
endcase
end
end

endmodule

10 Lemmings1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
output walk_left,
output walk_right);
parameter LEFT=0, RIGHT=1;
reg state, next_state;
always @(*) begin
if(state == LEFT)begin
if(bump_left)begin
next_state = RIGHT;
end
else begin
next_state = LEFT;
end
end
else begin
if(bump_right)begin
next_state = LEFT;
end
else begin
next_state = RIGHT;
end
end
end
always @(posedge clk, posedge areset) begin
// State flip-flops with asynchronous reset
if(areset)begin
state <= LEFT;
end
else begin
state <= next_state;
end
end
// Output logic
assign walk_left = (state == LEFT);
assign walk_right = (state == RIGHT);

endmodule


11 Lemmings2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
input ground,
output walk_left,
output walk_right,
output aaah );
parameter LEFT=0, RIGHT=1, FALL_L = 2, FALL_R = 3;
reg [1:0] state, next_state;
always @(*) begin
case(state)
LEFT : begin
if(~ground) begin
next_state = FALL_L;
end
else if(bump_left)begin
next_state = RIGHT;
end
else begin
next_state = LEFT;
end
end
RIGHT : begin
if(~ground) begin
next_state = FALL_R;
end
else if(bump_right)begin
next_state = LEFT;
end
else begin
next_state = RIGHT;
end
end
FALL_L : begin
if(~ground) begin
next_state = FALL_L;
end
else begin
next_state = LEFT;
end
end
FALL_R : begin
if(~ground) begin
next_state = FALL_R;
end
else begin
next_state = RIGHT;
end
end
endcase
end
always @(posedge clk, posedge areset) begin
// State flip-flops with asynchronous reset
if(areset)begin
state <= LEFT;
end
else begin
state <= next_state;
end
end
// Output logic
assign walk_left = (state == LEFT);
assign walk_right = (state == RIGHT);
assign aaah = (state == FALL_R | state == FALL_L);
endmodule


12 Lemmings 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
input ground,
input dig,
output walk_left,
output walk_right,
output aaah,
output digging );
parameter LEFT=0, RIGHT=1, FALL_L = 2, FALL_R = 3, DIG_L = 4, DIG_R = 5;
reg [2:0] state, next_state;
always @(*) begin
case(state)
LEFT : begin
if(~ground) begin
next_state = FALL_L;
end
else if(dig) begin
next_state = DIG_L;
end
else if(bump_left)begin
next_state = RIGHT;
end
else begin
next_state = LEFT;
end
end
RIGHT : begin
if(~ground) begin
next_state = FALL_R;
end
else if(dig) begin
next_state = DIG_R;
end
else if(bump_right)begin
next_state = LEFT;
end
else begin
next_state = RIGHT;
end
end
FALL_L : begin
if(~ground) begin
next_state = FALL_L;
end
else begin
next_state = LEFT;
end
end
FALL_R : begin
if(~ground) begin
next_state = FALL_R;
end
else begin
next_state = RIGHT;
end
end
DIG_L : begin
if(~ground) begin
next_state = FALL_L;
end
else begin
next_state = DIG_L;
end
end
DIG_R : begin
if(~ground) begin
next_state = FALL_R;
end
else begin
next_state = DIG_R;
end
end
endcase
end
always @(posedge clk, posedge areset) begin
// State flip-flops with asynchronous reset
if(areset)begin
state <= LEFT;
end
else begin
state <= next_state;
end
end
// Output logic
assign walk_left = (state == LEFT);
assign walk_right = (state == RIGHT);
assign aaah = (state == FALL_R | state == FALL_L);
assign digging = (state == DIG_R | state == DIG_L);
endmodule


13 Lemmings4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
input ground,
input dig,
output walk_left,
output walk_right,
output aaah,
output digging );
parameter LEFT=0, RIGHT=1, FALL_L = 2, FALL_R = 3, DIG_L = 4, DIG_R = 5, SPLAT = 6;
reg [2:0] state, next_state;
reg [4:0] time_cnt;
always @(*) begin
case(state)
LEFT : begin
if(~ground) begin
next_state = FALL_L;
end
else if(dig) begin
next_state = DIG_L;
end
else if(bump_left)begin
next_state = RIGHT;
end
else begin
next_state = LEFT;
end
end
RIGHT : begin
if(~ground) begin
next_state = FALL_R;
end
else if(dig) begin
next_state = DIG_R;
end
else if(bump_right)begin
next_state = LEFT;
end
else begin
next_state = RIGHT;
end
end
FALL_L : begin
if(~ground) begin
next_state = FALL_L;
end
else if(time_cnt > 20) begin
next_state = SPLAT;
end
else begin
next_state = LEFT;
end
end
FALL_R : begin
if(~ground) begin
next_state = FALL_R;
end
else if(time_cnt > 20) begin
next_state = SPLAT;
end
else begin
next_state = RIGHT;
end
end
DIG_L : begin
if(~ground) begin
next_state = FALL_L;
end

else begin
next_state = DIG_L;
end
end
DIG_R : begin
if(~ground) begin
next_state = FALL_R;
end
else begin
next_state = DIG_R;
end
end
SPLAT : begin
next_state = SPLAT;
end
endcase
end
always @(posedge clk or posedge areset) begin
if(areset)begin
time_cnt <= 0;
end
else if(~ground)begin
time_cnt <= time_cnt + 1'b1;
end
else begin
time_cnt <= 0;
end
end
always @(posedge clk, posedge areset) begin
// State flip-flops with asynchronous reset
if(areset)begin
state <= LEFT;
end
else begin
state <= next_state;
end
end
// Output logic
assign walk_left = (state == LEFT);
assign walk_right = (state == RIGHT);
assign aaah = (state == FALL_R | state == FALL_L);
assign digging = (state == DIG_R | state == DIG_L);
endmodule

14 one-hot FSM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
module top_module(
input in,
input [9:0] state,
output [9:0] next_state,
output out1,
output out2);
assign next_state[0] = (state[0] & ~in) | (state[1] & ~in) | (state[2] & ~in) | (state[3] & ~in) | (state[4] & ~in) | (state[7] & ~in) | (state[8] & ~in) | (state[1] & ~in) | (state[9] & ~in);
assign next_state[1] = (state[0] & in) | (state[8] & in) | (state[9] & in);
assign next_state[2] = (state[1] & in);
assign next_state[3] = (state[2] & in);
assign next_state[4] = (state[3] & in);
assign next_state[5] = (state[4] & in);
assign next_state[6] = (state[5] & in);
assign next_state[7] = (state[6] & in) | (state[7] & in);
assign next_state[8] = (state[5] & ~in);
assign next_state[9] = (state[6] & ~in);
assign out1 = state[8] | state[9];
assign out2 = state[7] | state[9];
endmodule


15 PS/2 packet parser
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
module top_module(
input clk,
input [7:0] in,
input reset, // Synchronous reset
output done);
parameter byte1 = 0, byte2 = 1,byte3 = 2, error = 3;
reg[1:0] state, next_state;
// State transition logic (combinational)
always @(*)begin
case(state)
byte1 : begin next_state = in[3] ? byte2 : byte1; end
byte2 : begin next_state = byte3; end
byte3 : begin next_state = error ; end
error : begin next_state = in[3] ? byte2 : byte1 ;end
endcase
end
// State flip-flops (sequential)
always @(posedge clk) begin
if(reset)begin
state <= byte1;
end
else begin
state <= next_state;
end
end
// Output logic
assign done = (state == error);
endmodule

16 PS/2 packet parser and datapath
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
module top_module(
input clk,
input [7:0] in,
input reset, // Synchronous reset
output [23:0] out_bytes,
output done);
// FSM from fsm_ps2
parameter byte1 = 0, byte2 = 1,byte3 = 2, error = 3;
reg[1:0] state, next_state;
// State transition logic (combinational)
always @(*)begin
case(state)
byte1 : begin next_state = in[3] ? byte2 : byte1; end
byte2 : begin next_state = byte3; end
byte3 : begin next_state = error ; end
error : begin next_state = in[3] ? byte2 : byte1 ;end
endcase
end
// State flip-flops (sequential)
always @(posedge clk) begin
if(reset)begin
state <= byte1;
end
else begin
state <= next_state;
end
end
// Output logic
assign done = (state == error);
// New: Datapath to store incoming bytes.
always @(posedge clk)begin
case(state)
byte1 : begin out_bytes[23:16] <= in[3] ? in : 8'b0; end
byte2 : begin out_bytes[15:8] <= in; end
byte3 : begin out_bytes[ 7:0] <= in ; end
error : begin out_bytes[23:16] <= in[3] ? in : 8'b0;end
endcase
end
endmodule

17 serial receiver
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output done);
parameter idel = 0, start = 1, bit1=2, bit2=3, bit3=4, bit4=5, bit5=6, bit6=7, bit7=8, bit8=9, stop = 10, error =11;
reg [3:0] state, next_state;
always @(posedge clk)begin
if(reset)begin
state <= idel;
end
else begin
state <= next_state;
end
end
always @(*)begin
case(state)
idel:begin next_state = ~in ? start : idel; end
start:begin next_state = bit1;end
bit1:begin next_state = bit2;end
bit2:begin next_state = bit3;end
bit3:begin next_state = bit4;end
bit4:begin next_state = bit5;end
bit5:begin next_state = bit6;end
bit6:begin next_state = bit7;end
bit7:begin next_state = bit8;end
bit8:begin next_state = in ? stop : error; end
stop:begin next_state = ~in ? start : idel; end
error : begin next_state = in ? idel : error; end
endcase
end
assign done = (state == stop);
endmodule

18 serial receiver and datapath
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output [7:0] out_byte,
output done);
parameter idel = 0, start = 1, bit1=2, bit2=3, bit3=4, bit4=5, bit5=6, bit6=7, bit7=8, bit8=9, stop = 10, error =11;
reg [3:0] state, next_state;
always @(posedge clk)begin
if(reset)begin
state <= idel;
end
else begin
state <= next_state;
end
end
always @(*)begin
case(state)
idel:begin next_state = ~in ? start : idel; end
start:begin next_state = bit1;end
bit1:begin next_state = bit2;end
bit2:begin next_state = bit3;end
bit3:begin next_state = bit4;end
bit4:begin next_state = bit5;end
bit5:begin next_state = bit6;end
bit6:begin next_state = bit7;end
bit7:begin next_state = bit8;end
bit8:begin next_state = in ? stop : error; end
stop:begin next_state = ~in ? start : idel; end
error : begin next_state = in ? idel : error; end
endcase
end
assign done = (state == stop);
// New: Datapath to latch input bits.
always @(posedge clk)begin
case(state)
start:begin out_byte[0] <= in;end
bit1:begin out_byte[1] <= in;end
bit2:begin out_byte[2] <= in;end
bit3:begin out_byte[3] <= in;end
bit4:begin out_byte[4] <= in;end
bit5:begin out_byte[5] <= in;end
bit6:begin out_byte[6] <= in;end
bit7:begin out_byte[7] <= in; end
endcase
end
endmodule

19 serial receiver and parity checking
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output [7:0] out_byte,
output done
);
reg [8:0] out_reg;

assign out_byte = out_reg[7:0];
parameter idel = 0, start = 1, bit1=2, bit2=3, bit3=4, bit4=5, bit5=6, bit6=7, bit7=8, bit8=9, stop = 10, parity =11, wait_stop=12;
reg [3:0] state, next_state;
always @(posedge clk)begin
if(reset)begin
state <= idel;
end
else begin
state <= next_state;
end
end
always @(*)begin
case(state)
idel:begin next_state = ~in ? start : idel; end
start:begin next_state = bit1;end
bit1:begin next_state = bit2;end
bit2:begin next_state = bit3;end
bit3:begin next_state = bit4;end
bit4:begin next_state = bit5;end
bit5:begin next_state = bit6;end
bit6:begin next_state = bit7;end
bit7:begin next_state = bit8;end
bit8:begin next_state = parity;end
parity:begin next_state = in ? stop : wait_stop;; end
wait_stop:begin next_state = ~in ? wait_stop : idel; end
stop:begin next_state = ~in ? start : idel; end

endcase
end
assign done = (state == stop) && ^out_reg;
// New: Datapath to latch input bits.
always @(posedge clk)begin
case(state)
start:begin out_reg[0] <= in;end
bit1:begin out_reg[1] <= in;end
bit2:begin out_reg[2] <= in;end
bit3:begin out_reg[3] <= in;end
bit4:begin out_reg[4] <= in;end
bit5:begin out_reg[5] <= in;end
bit6:begin out_reg[6] <= in;end
bit7:begin out_reg[7] <= in; end
bit8:begin out_reg[8] <= in; end
endcase
end
endmodule

20 sequence recognition

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
module top_module(
input clk,
input reset, // Synchronous reset
input in,
output disc,
output flag,
output err);
parameter idel = 0, bit1 = 1, bit2=2, bit3=3, bit4=4, bit5=5, bit6=6,bit7 = 7, s_disc= 8,s_flag = 9,s_error=10;
reg [3:0] state, next_state;
always @(posedge clk) begin
if(reset)begin
state <= idel;
end
else begin
state <= next_state;
end
end
always @(*)begin
case(state)
idel : begin next_state = in ? bit1 : idel; end
bit1: begin next_state = in ? bit2 : idel; end
bit2: begin next_state = in ? bit3 : idel; end
bit3: begin next_state = in ? bit4 : idel; end
bit4: begin next_state = in ? bit6 : idel; end
bit6: begin next_state = ~in ? s_disc : bit7; end
bit7: begin next_state = ~in ? s_flag : s_error; end
s_error: begin next_state = in ? s_error : idel; end
s_disc : begin next_state = in ? bit1 : idel; end
s_flag : begin next_state = in ? bit1 : idel; end
endcase
end
assign disc = (state == s_disc);
assign flag = (state == s_flag);
assign err = (state == s_error);
endmodule

21 design a Mealy FSM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
module top_module (
input clk,
input aresetn, // Asynchronous active-low reset
input x,
output z );

parameter s0 = 0, s1 = 1, s2 = 2;
reg[1:0] state,next_state;
always @(posedge clk or negedge aresetn) begin
if(!aresetn)
state <= s0;
else
state <= next_state;
end
always @(*)begin
case(state)
s0: begin next_state = x ? s1 : s0; end
s1: begin next_state = ~x ? s2 : s1; end
s2: begin next_state = x ? s1 : s0; end
default : next_state = s0;
endcase
end
assign z = (state == s2 && x == 1);
endmodule

22 serial two’s complementer (Moore FSM)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
module top_module (
input clk,
input areset,
input x,
output z
);
parameter A=2'b00,B=2'b01,C=2'b10;
reg [1:0] state,next_state;
always @(*) begin
case(state)
A: next_state = x? B:A;
B: next_state = x? C:B;
C: next_state = x? C:B;
default: next_state = A;
endcase
end
always @(posedge clk or posedge areset) begin
if(areset) begin
state <= A;
end
else begin
state <= next_state;
end
end
assign z = state==B;
endmodule

23 serial two’s complementer (Mealy FSM)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
module top_module (
input clk,
input areset,
input x,
output z
);
reg [1:0] state,next_state;
parameter A=2'b01, B=2'b10;

always @(posedge clk or posedge areset) begin
if(areset)begin
state <= A;
end else begin
state <= next_state;
end
end

always @(*)begin
case(state)
A: next_state = x ? B : A;
B: next_state = B;
endcase
end

always @(*)begin
case(state)
A: z = x;
B: z = ~x;
endcase
end
endmodule

24 Q3a: FSM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
module top_module (
input clk,
input reset, // Synchronous reset
input s,
input w,
output z
);
reg [1:0] state, next_state;
parameter A=0, B1=1, B2=2, B3=3;
reg [2:0] cnt=0;
always @(posedge clk) begin
if(reset)begin
state <= A;
cnt <= 0;
end else begin
state <= next_state;
if(state == A)
cnt <= 0;
else if(state == B1)
cnt <= w;
else
cnt <= cnt + w;
end
end

always @(*)begin
case(state)
A: next_state = s ? B1 : A;
B1: next_state = B2;
B2: next_state = B3;
B3: next_state = B1;
endcase
end
assign z = (state == B1) && (cnt==2);
endmodule


25 Q3b: FSM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
module top_module (
input clk,
input reset, // Synchronous reset
input x,
output z);
parameter s0 = 0, s1 = 1, s2 = 2, s3 = 3, s4 = 4;
reg[2:0] state,next_state;

always @(posedge clk) begin
if(reset)
state <= s0;
else
state <= next_state;
end
always @(*)begin
case(state)
s0: begin next_state = x ? s1 : s0; end
s1: begin next_state = x ? s4 : s1; end
s2: begin next_state = x ? s1 : s2; end
s3: begin next_state = x ? s2 : s1; end
s4: begin next_state = x ? s4 : s3; end
default : next_state = s0;
endcase
end
assign z = (state == s3 ||state == s4);
endmodule

26 Q3c: FSM logic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
module top_module (
input clk,
input [2:0] y,
input x,
output Y0,
output z);
parameter s0 = 0, s1 = 1, s2 = 2, s3 = 3, s4 = 4;
reg[2:0] next_state;
always @(*)begin
case(y)
s0: begin next_state = x ? s1 : s0; end
s1: begin next_state = x ? s4 : s1; end
s2: begin next_state = x ? s1 : s2; end
s3: begin next_state = x ? s2 : s1; end
s4: begin next_state = x ? s4 : s3; end
default : next_state = s0;
endcase
end
assign Y0 = next_state[0];
assign z = (y == s3 ||y == s4);
endmodule


27 Q6b: FSM next-state logic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
module top_module (
input [3:1] y,
input w,
output Y2
);
reg [2:0] state,next_state;
parameter A=0,B=1,C=2,D=3,E=4,F=5;
always@(*)begin
case(y)
A:next_state=w?A:B;
B:next_state=w?D:C;
C:next_state=w?D:E;
D:next_state=w?A:F;
E:next_state=w?D:E;
F:next_state=w?D:C;
default:next_state=A;
endcase
end
assign Y2=next_state[1];

endmodule

28 Q6c: FSM one-hot next-state logic

1
2
3
4
5
6
7
8
module top_module (
input [6:1] y,
input w,
output Y2,
output Y4);
assign Y2 = y[1] && !w;
assign Y4 = (y[2] | y[3] | y[5] | y[6]) && w;
endmodule

29 Q6: FSM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
module top_module (
input clk,
input reset, // synchronous reset
input w,
output z);
parameter A=0,B=1,C=2,D=3,E=4,F=5;
reg [2:0] state,next_state;
always @(posedge clk)begin
if(reset)begin
state <= A;
end else begin
state <= next_state;
end
end
always @(*) begin
case (state)
A: next_state = w ? A : B;
B: next_state = w ? D : C;
C: next_state = w ? D : E;
D: next_state = w ? A : F;
E: next_state = w ? D : E;
F: next_state = w ? D : C;
default: next_state = A;
endcase
end
assign z = (state == E) || (state == F);
endmodule

30 Q2a: FSM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
module top_module (
input clk,
input reset, // synchronous reset
input w,
output z);
parameter A=0,B=1,C=2,D=3,E=4,F=5;
reg [2:0] state,next_state;
always @(posedge clk)begin
if(reset)begin
state <= A;
end else begin
state <= next_state;
end
end
always @(*) begin
case (state)
A: next_state = !w ? A : B;
B: next_state = !w ? D : C;
C: next_state = !w ? D : E;
D: next_state = !w ? A : F;
E: next_state = !w ? D : E;
F: next_state = !w ? D : C;
default: next_state = A;
endcase
end
assign z = (state == E) || (state == F);
endmodule


31 Q2b: one-hot FSM equations
1
2
3
4
5
6
7
8
9
module top_module (
input [5:0] y,
input w,
output Y1,
output Y3
);
assign Y1 = y[0] && w;
assign Y3 = (y[1] | y[2] | y[4] | y[5]) && !w;
endmodule

32 Q2a: FSM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
module top_module (
input clk,
input resetn, // active-low synchronous reset
input [3:1] r, // request
output [3:1] g // grant
);
parameter A=0,B=1,C=2,D=3;
reg [1:0] state,next_state;

always @(posedge clk)begin
if(!resetn)begin
state <= A;
end else begin
state <= next_state;
end
end
always @(*) begin
case (state)
A: next_state = r[1] ? B :
(r[2] ? C :
(r[3] ? D : A));
B: next_state = r[1] ? B : A;
C: next_state = r[2] ? C : A;
D: next_state = r[3] ? D : A;
default: next_state = A;
endcase
end
assign g = {(state == D), (state == C), (state == B)} ;
endmodule

33 Q2b: another FSM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
module top_module (
input clk,
input resetn, // active-low synchronous reset
input x,
input y,
output f,
output g
);
parameter A=0,B1=1,C1=2,C2=3,C3=4,D1=5,D2=6,D3=7,D4=8,B2=9;
reg[3:0]state,next_state;
reg cout;
always@(*)begin
case (state)
A:next_state = B1;
B1:next_state = B2;
B2:next_state = x?C1:B2;
C1:next_state = x?C1:C2;
C2:next_state = x?C3:B2;
C3:next_state =y?D1:D2;
D1:next_state =D1;
D2:next_state =y?D4:D3;
D3:next_state =D3;
D4:next_state =D4;
endcase
end
always@(posedge clk)begin
if(~resetn)begin
state<=A;
end
else begin
state<=next_state;
end
end

assign f = (state==B1);
assign g = (state==C3)||(state==D1)||(state==D2)||(state==D4);
endmodule


3.3 Building Larger Circuits

1 Counter with period 1000

1
2
3
4
5
6
7
8
9
10
11
12
13
module top_module (
input clk,
input reset,
output [9:0] q);
always @(posedge clk)begin
if(reset)
q <= 0;
else if(q==10'd999)
q <= 0;
else
q <= q+1;
end
endmodule

2 4-bit shift register and down counter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
module top_module (
input clk,
input shift_ena,
input count_ena,
input data,
output [3:0] q);
always @(posedge clk)begin
if (shift_ena)begin
q[3] <= q[2];
q[2] <= q[1];
q[1] <= q[0];
q[0] <= data;
end
if(count_ena)
q <= q - 1'b1;
end
endmodule

3 FSM: Sequence 1101 recognizer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
module top_module (
input clk,
input reset, // Synchronous reset
input data,
output reg start_shifting
);
parameter state_1 = 2'b00;
parameter state_2 = 2'b01;
parameter state_3 = 2'b10;
parameter state_4 = 2'b11;
reg [1:0] state;
always @(posedge clk) begin
if(reset)begin
start_shifting <= 0;
state <= state_1;
end
else
case(state)
state_1: begin if(data == 1'b1) state <= state_2; else state <= state_1; end
state_2: begin if(data == 1'b1) state <= state_3; else state <= state_1; end
state_3: begin if(data == 1'b0) state <= state_4; else state <= state_3; end
state_4: begin if(data == 1'b1) begin state <= state_1; start_shifting <= 1;end else state <= state_1; end
endcase
end

endmodule

4 FSM: Enable shift register
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
module top_module (
input clk,
input reset, // Synchronous reset
output reg shift_ena);
reg [2:0] state;
parameter state_1 = 3'b00;
parameter state_2 = 3'b01;
parameter state_3 = 3'b10;
parameter state_4 = 3'b11;
always @(posedge clk) begin
if (reset) begin
state = state_1;
end
case (state)
state_1 : begin shift_ena <= 1'b1; state <= state_2; end
state_2 : begin shift_ena <= 1'b1; state <= state_3; end
state_3 : begin shift_ena <= 1'b1; state <= state_4; end
state_4 : begin shift_ena <= 1'b1; state <= 3'b111;end
default : shift_ena <= 1'b0;
endcase
endmodule

5 FSM:The complete FSM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
module top_module (
input clk,
input reset, // Synchronous reset
input data,
output shift_ena,
output counting,
input done_counting,
output done,
input ack );

parameter s1 = 1, s2 = 2, s3 = 3, s4 = 4,s5 = 5,s6 = 6,s7 = 7,s8 = 8,s9 = 9,s10 = 10;
reg [3:0] state,next_state;

always @(posedge clk) begin
if(reset)
state <= s1;
else
state <= next_state;
end
always @(*) begin
case(state)
s1: begin next_state = data ? s2 : s1; end
s2: begin next_state = data ? s3 : s1; end
s3: begin next_state = data ? s3 : s4; end
s4: begin next_state = data ? s5 : s1; end
s5: begin next_state = s6; end
s6: begin next_state = s7; end
s7: begin next_state = s8; end
s8: begin next_state = s9; end
s9: begin next_state = done_counting ? s10 : s9; end
s10 : begin next_state = ack ? s1 : s10; end
default : next_state = s1;
endcase
end
assign shift_ena = (state == s5 || state == s6 || state == s7 || state == s8);
assign counting = state == s9;
assign done = state == s10;
endmodule

6 The complete timer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
module top_module (
input clk,
input reset, // Synchronous reset
input data,
output [3:0] count,
output counting,
output done,
input ack );

reg[3:0] state, next_state;
reg[9:0] cnt_1000;
reg[3:0] delay;

parameter S0=1,S1=2,S2=3,S3=4,B0=5,B1=6,B2=7,B3=8,count_en=9,Wait=10;

always@(posedge clk)begin
if(reset)
state<=S0;
else
state<=next_state;
end
always@(*) begin
case(state)
S0 : next_state = data ? S1:S0;
S1 : next_state = data ? S2:S0;
S2 : next_state = data ? S2:S3;
S3 : next_state = data ? B0:S0;
B0 : next_state = B1;
B1 : next_state = B2;
B2 : next_state = B3;
B3 : next_state = count_en;
count_en : next_state = (count == 4'd0 && cnt_1000 == 10'd999) ? Wait : count_en;
Wait : next_state = ack ? S0 : Wait;
default : next_state = S0;
endcase
end

always@(posedge clk) begin
if (reset)
delay <= 0;
else if(state==B0||state==B1||state==B2||state==B3)
delay <= {delay[2:0],data};
else if(cnt_1000==10'd999)
delay <= delay-1'b1;
end

always@(posedge clk) begin
if(reset)
cnt_1000 <= 0;
else if(cnt_1000==10'd999)
cnt_1000 <= 0;
else if(counting)
cnt_1000 <= cnt_1000+1'b1;
end

assign count = delay;
assign counting = state == count_en;
assign done = state == Wait;

endmodule

7 FSM: One-hot logic equations
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
module top_module(
input d,
input done_counting,
input ack,
input [9:0] state, // 10-bit one-hot current state
output B3_next,
output S_next,
output S1_next,
output Count_next,
output Wait_next,
output done,
output counting,
output shift_ena
); //
parameter S=0, S1=1, S11=2, S110=3, B0=4, B1=5, B2=6, B3=7, Count=8, Wait=9;
assign B3_next = state[B2];
assign S_next = (state[Wait] & ack) | ((state[S] | state[S1] | state[S110]) & !d);
assign S1_next = state[S] & d;
assign Count_next = state[B3] | (state[Count] & !done_counting);
assign Wait_next = (state[Count] & done_counting) | (state[Wait] & !ack);
assign done = state[Wait];
assign counting = state[Count];
assign shift_ena = state[B0] | state[B1] | state[B2] | state[B3] ;

endmodule

4 Verification: Reading Simulations

4.1 Finding bugs in code

1 Mux

1
2
3
4
5
6
7
module top_module (
input sel,
input [7:0] a,
input [7:0] b,
output [7:0]out );
assign out = ({8{sel}} & a) | (~{8{sel}} & b);
endmodule

2 NAND
1
2
3
4
5
module top_module (input a, input b, input c, output out);//
wire temp;
andgate inst1 ( temp, a, b, c, 1'b1,1'b1 );
assign out = ~temp;
endmodule

3 Mux
1
2
3
4
5
6
7
8
9
10
11
12
module top_module (
input [1:0] sel,
input [7:0] a,
input [7:0] b,
input [7:0] c,
input [7:0] d,
output [7:0] out );
wire [7:0] mux0, mux1;
mux2 mux_0 ( sel[0], a, b, mux0 );
mux2 mux_1 ( sel[0], c, d, mux1 );
mux2 mux_2 ( sel[1], mux0, mux1, out );
endmodule

4 Add/sub
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// synthesis verilog_input_version verilog_2001
module top_module (
input do_sub,
input [7:0] a,
input [7:0] b,
output reg [7:0] out,
output reg result_is_zero);
always @(*) begin
case (do_sub)
0: out = a+b;
1: out = a-b;
endcase
if (~(|out))
result_is_zero = 1;
else
result_is_zero = 0;
end
endmodule

5 Case statement
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
module top_module (
input [7:0] code,
output reg [3:0] out,
output reg valid=1
);//

always @(*)
case (code)
8'h45: begin out = 0; valid = 1; end
8'h16: begin out = 1; valid = 1; end
8'h1e: begin out = 2; valid = 1; end
8'h26: begin out = 3; valid = 1; end
8'h25: begin out = 4; valid = 1; end
8'h2e: begin out = 5; valid = 1; end
8'h36: begin out = 6; valid = 1; end
8'h3d: begin out = 7; valid = 1; end
8'h3e: begin out = 8; valid = 1; end
8'h46: begin out = 9; valid = 1; end
default: begin out = 0; valid = 0;end
endcase
endmodule

4.2 Build a circuit from a simulation waveform

1 Combinational circuit 1

1
2
3
4
5
6
module top_module (
input a,
input b,
output q );
assign q = a&b; // Fix me
endmodule

2 Combinational circuit 2
1
2
3
4
5
6
7
8
module top_module (
input a,
input b,
input c,
input d,
output q );
assign q = ((a+b+c+d) == 2) | ((a+b+c+d) == 0) | ((a+b+c+d) == 4); // Fix me
endmodule

3 Combinational circuit 3
1
2
3
4
5
6
7
8
module top_module (
input a,
input b,
input c,
input d,
output q );
assign q = (a&c) | (a&d) | (b&c) | (b&d); // Fix me
endmodule

4 Combinational circuit 4
1
2
3
4
5
6
7
8
module top_module (
input a,
input b,
input c,
input d,
output q );
assign q = b|c;
endmodule

5 Combinational circuit 5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
module top_module (
input [3:0] a,
input [3:0] b,
input [3:0] c,
input [3:0] d,
input [3:0] e,
output [3:0] q );
always @(*)begin
case(c)
4'd0 : q = b;
4'd1 : q = e;
4'd2 : q = a;
4'd3 : q = d;
default : q = 4'hf;
endcase
end
endmodule

6 Combinational circuit 6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module top_module (
input [2:0] a,
output [15:0] q );
always @(*)begin
case(a)
3'b000: q = 16'h1232;
3'b001: q = 16'haee0;
3'b010: q = 16'h27d4;
3'b011: q = 16'h5a0e;
3'b100: q = 16'h2066;
3'b101: q = 16'h64ce;
3'b110: q = 16'hc526;
3'b111: q = 16'h2f19;
endcase
end
endmodule

7 Sequential circuit 7
1
2
3
4
5
6
7
8
module top_module (
input clk,
input a,
output q );
always @(posedge clk)begin
q <= ~a;
end
endmodule

8 Sequential circuit 8
1
2
3
4
5
6
7
8
9
10
11
12
module top_module (
input clock,
input a,
output reg p,
output reg q );
always @(*)begin
if(clock)
p <= a;
end
always @(negedge clock)
q <= a;
endmodule

9 Sequential circuit 9
1
2
3
4
5
6
7
8
9
10
11
12
module top_module (
input clk,
input a,
output [3:0] q );
always @(posedge clk)
if(a)
q <= 4'd4;
else if(q == 4'd6)
q<=0;
else
q <= q + 1'b1;
endmodule

10 Sequential circuit 10
1
2
3
4
5
6
7
8
9
10
11
12
13
module top_module (
input clk,
input a,
input b,
output q,
output state );
always @(posedge clk)begin
if(a==b)
state <= a;
end
assign q = (a==b) ? state : ~state;
endmodule

5 Verification: Writing Testbenches

1 clock

1
2
3
4
5
6
module top_module ( );
reg clk;
initial clk = 0;
always #5 clk = ~clk;
dut dut_0(clk);
endmodule

2 Testbench1
1
2
3
4
5
6
7
8
9
module top_module ( output reg A, output reg B );
initial begin
A = 0; B = 0;
#10 A = 1;
#5 B = 1;
#5 A = 0;
#20 B = 0;
end
endmodule

3 AND gate
1
2
3
4
5
6
7
8
9
10
11
12
module top_module();
reg [1:0] in;
wire out;
initial in = 2'd00;
initial #20 in[1] = 1;
initial begin
#10 in[0] = 1;
#10 in[0] = 0;
#10 in[0] = 1;
end
andgate u0(in, out);
endmodule

4 Testbench2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
module top_module();
reg clk;
reg in;
reg [2:0] s;
wire out;
always #5 clk = ~clk;
initial begin
clk = 0;
in = 0;
s = 3'd2;
#10 s = 3'd6;
#10 s = 3'd2; in = 1;
#10 s = 3'd7; in = 0;
#10 s = 3'd0; in = 1;
#30 in = 0;
end
q7 u0(clk, in, s, out);
endmodule

5 T flip-flop
1
2
3
4
5
6
7
8
9
10
11
12
13
module top_module ();
reg clk, reset, t;
wire q;
always #5 clk = ~clk;
initial begin
clk = 0;
reset =0;
t = 0;
#10 reset = 1;
#10 reset = 0; t = 1;
end
tff u0( clk, reset, t,q);
endmodule

上一篇:
APB总线
下一篇:
Hello World
本文目录
本文目录