---
###### tags : `數位 IC 設計`
---
# HDLBits 習題
> HDLBits 連結 : https://hdlbits.01xz.net/wiki/Main_Page
## Getting Started
### Getting Started
:::spoiler 解答
```verilog=
module top_module( output one );
assign one = 1'b1;
endmodule
```
:::
### Output Zero
:::spoiler 解答
```verilog=
module top_module(
output zero
);
assign zero = 1'b0;
endmodule
```
:::
## Basics
### Simple Wire
:::spoiler 解答
```verilog=
module top_module( input in, output out );
assign out = in;
endmodule
```
:::
### Four Wire
:::spoiler 解答
```verilog=
module top_module(a, b, c, w, x, y, z);
input a, b, c;
output w, x, y, z;
assign w = a;
assign x = b;
assign y = b;
assign z = c;
endmodule
```
:::
:::spoiler 用連接運算子也可以
```verilog=
module top_module(a, b, c, w, x, y, z);
input a, b, c;
output w, x, y, z;
assign {w, x, y, z} = {a, b, b, c};
endmodule
```
:::
### Inverter
:::spoiler 解答
```verilog=
module top_module( input in, output out );
assign out = ~in;
endmodule
```
:::
### And Gate
:::spoiler 解答
```verilog=
module top_module(
input a,
input b,
output out );
assign out = a & b;
endmodule
```
:::
### NOR Gate
:::spoiler 解答
```verilog=
module top_module(
input a,
input b,
output out );
assign out = ~(a | b);
endmodule
```
:::
### XNOR Gate
:::spoiler 解答
```verilog=
module top_module(
input a,
input b,
output out );
assign out = ~(a ^ b);
endmodule
```
:::
### Declaring Wires
:::spoiler 解答
```verilog=
`default_nettype none
module top_module(
input a,
input b,
input c,
input d,
output out,
output out_n );
wire tmp_and_1, tmp_and_2, tmp_or_1;
assign tmp_and_1 = a & b;
assign tmp_and_2 = c & d;
assign tmp_or_1 = tmp_and_1 | tmp_and_2;
assign out = tmp_or_1;
assign out_n = ~tmp_or_1;
endmodule
```
:::
### 7458 chip
:::spoiler 單純使用 `assign`
```verilog=
module top_module (
input p1a, p1b, p1c, p1d, p1e, p1f,
output p1y,
input p2a, p2b, p2c, p2d,
output p2y );
assign p1y = ((p1a & p1b & p1c) | (p1e & p1f & p1d));
assign p2y = ((p2a & p2b) | (p2c & p2d));
endmodule
```
:::
:::spoiler 使用暫存的 `wire`
```verilog=
module top_module (
input p1a, p1b, p1c, p1d, p1e, p1f,
output p1y,
input p2a, p2b, p2c, p2d,
output p2y );
wire tmp_1_abc, tmp_1_def;
wire tmp_2_ab, tmp_2_cd;
assign tmp_1_abc = p1a & p1b & p1c;
assign tmp_1_def = p1d & p1e & p1f;
assign tmp_2_ab = p2a & p2b;
assign tmp_2_cd = p2c & p2d;
assign p1y = tmp_1_abc | tmp_1_def;
assign p2y = tmp_2_ab | tmp_2_cd;
endmodule
```
:::
## Vectors
### Vectors
:::spoiler 解答
```verilog=
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 o0 = vec[0];
assign o1 = vec[1];
assign o2 = vec[2];
endmodule
```
:::
### Vectors in more details
:::spoiler 解答
```verilog=
`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
```
:::
### Vector part select
:::spoiler 解答
```verilog=
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
```
:::
### Bitwise Operators
:::spoiler 解答
```verilog=
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;
assign out_or_logical = a || b;
assign out_not[5:3] = ~b;
assign out_not[2:0] = ~a;
endmodule
```
:::
### Four Input Gates
:::spoiler 解答
```verilog=
module top_module(
input [3:0] in,
output out_and,
output out_or,
output out_xor
);
assign out_and = ∈
assign out_or = |in;
assign out_xor = ^in;
endmodule
```
:::
### Vector Concatenation Operator
:::spoiler 解答
```verilog=
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
```
:::
### Vector Reversal 1
:::spoiler 解答
```verilog=
module top_module(
input [7:0] in,
output [7:0] out
);
assign out = {in[0], in[1], in[2], in[3], in[4], in[5], in[6], in[7]};
endmodule
```
:::
### Replication Operator
:::spoiler 解答
```verilog=
module top_module (
input [7:0] in,
output [31:0] out );//
assign out = {{24{in[7]}}, in};
endmodule
```
:::
### More replication
:::spoiler 解答
```verilog=
module top_module (
input a, b, c, d, e,
output [24:0] out );
wire [24:0] top, bottom;
assign top = {{5{a}}, {5{b}}, {5{c}}, {5{d}}, {5{e}}};
assign bottom = {5{a, b, c, d, e}};
assign out = ~top ^ bottom;
endmodule
```
:::
## Modules : Hierarchy
### Modules
:::spoiler by position
```verilog=
module top_module ( input a, input b, output out );
mod_a mod_a1(a, b, out);
endmodule
```
:::
:::spoiler by name
```verilog=
module top_module ( input a, input b, output out );
mod_a mod_a1(.in1(a), .in2(b), .out(out));
endmodule
```
:::
### Connecting ports by position
:::spoiler 解答
```verilog=
module top_module (
input a,
input b,
input c,
input d,
output out1,
output out2
);
mod_a mod_a1(out1, out2, a, b, c, d);
endmodule
```
:::
### Connecting ports by name
:::spoiler 解答
```verilog=
module top_module (
input a,
input b,
input c,
input d,
output out1,
output out2
);
mod_a mod_a1(.out1(out1), .out2(out2), .in1(a), .in2(b), .in3(c), .in4(d));
endmodule
```
:::
### Three modules
:::spoiler 解答
```verilog=
module top_module ( input clk, input d, output q );
wire q1, q2, q3;
my_dff my_dff1(.clk(clk), .d(d), .q(q1));
my_dff my_dff2(.clk(clk), .d(q1), .q(q2));
my_dff my_dff3(.clk(clk), .d(q2), .q(q3));
assign q = q3;
endmodule
```
:::
### Modules and Vectors
:::spoiler 解答
```verilog=
module top_module (
input clk,
input [7:0] d,
input [1:0] sel,
output [7:0] q
);
wire [7:0] q1, q2, q3;
my_dff8 my_dff8_1(.clk(clk), .d(d), .q(q1));
my_dff8 my_dff8_2(.clk(clk), .d(q1), .q(q2));
my_dff8 my_dff8_3(.clk(clk), .d(q2), .q(q3));
always @(sel, d, q1, q2, q3) begin
case (sel)
2'b00: q = d;
2'b01: q = q1;
2'b10: q = q2;
2'b11: q = q3;
default: q = d;
endcase
end
endmodule
```
:::
### Adder1
:::spoiler 解答
```verilog=
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire lower_cin, lower_cout, upper_cout;
wire [15:0] lower_sum, upper_sum;
assign lower_cin = 1'b0;
add16 add16_1(.a(a[15:0]), .b(b[15:0]), .cin(lower_cin), .sum(lower_sum), .cout(lower_cout));
add16 add16_2(.a(a[31:16]), .b(b[31:16]), .cin(lower_cout), .sum(upper_sum), .cout(upper_cout));
assign sum = {upper_sum, lower_sum};
endmodule
```
:::
### Adder2
:::spoiler 解答
```verilog=
module top_module (
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire cin, lower_cout;
wire [15:0] lower_sum, upper_sum;
add16 add16_1(.a(a[15:0]), .b(b[15:0]), .cin(cin), .sum(lower_sum), .cout(lower_cout));
add16 add16_2(.a(a[31:16]), .b(b[31:16]), .cin(lower_cout), .sum(upper_sum));
assign sum = {upper_sum, lower_sum};
endmodule
module add1 ( input a, input b, input cin, output sum, output cout );
assign {cout, sum} = a + b + cin;
endmodule
```
:::
### Carry select adder
:::spoiler 解答
```verilog=
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire cin_0, cin_1, lower_cout;
wire [15:0] lower_sum, upper_sum_0, upper_sum_1, upper_sum;
assign cin_0 = 0;
assign cin_1 = 1;
add16 add16_low(.a(a[15:0]), .b(b[15:0]), .sum(lower_sum), .cout(lower_cout));
add16 add16_high0(.a(a[31:16]), .b(b[31:16]), .cin(cin_0), .sum(upper_sum_0));
add16 add16_high1(.a(a[31:16]), .b(b[31:16]), .cin(cin_1), .sum(upper_sum_1));
always @(lower_cout, upper_sum_0, upper_sum_1) begin
if (lower_cout == 0)
upper_sum = upper_sum_0;
else
upper_sum = upper_sum_1;
end
assign sum = {upper_sum, lower_sum};
endmodule
```
:::
### Adder-subtractor
:::spoiler 解答
```verilog=
module top_module(
input [31:0] a,
input [31:0] b,
input sub,
output [31:0] sum
);
wire lower_cout;
wire [15:0] lower_sum, upper_sum;
wire [31:0] sub_sel, converted_b;
assign sub_sel = {32{sub}};
assign converted_b = b ^ sub_sel;
add16 add16_low(.a(a[15:0]), .b(converted_b[15:0]), .cin(sub), .sum(lower_sum), .cout(lower_cout));
add16 add16_high(.a(a[31:16]), .b(converted_b[31:16]), .cin(lower_cout), .sum(upper_sum));
assign sum = {upper_sum, lower_sum};
endmodule
```
:::
## Procedures
### always blocks (combinational)
:::spoiler 解答
```verilog=
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
```
:::
### always blocks (clocked)
:::spoiler 解答
```verilog=
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
```
:::
### if statement
:::spoiler 解答
```verilog=
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) : a;
always @(*) begin
if (sel_b1) begin
if (sel_b2) begin
out_always = b;
end
else
out_always = a;
end
else
out_always = a;
end
endmodule
```
:::
### if statement latches
:::spoiler 解答
```verilog=
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 = 1'b0;
end
endmodule
```
:::
### Case statement
:::spoiler 解答
```verilog=
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'b000: out = data0;
3'b001: out = data1;
3'b010: out = data2;
3'b011: out = data3;
3'b100: out = data4;
3'b101: out = data5;
default: out = 4'h0;
endcase
end
endmodule
```
:::
### Priority encoder
:::spoiler 解答
```verilog=
module top_module (
input [3:0] in,
output reg [1:0] pos );
always @(in) begin
case (in)
4'b0010, 4'b0110, 4'b1010, 4'b1110: pos = 2'b01;
4'b0100, 4'b1100: pos = 2'b10;
4'b1000: pos = 2'b11;
default: pos = 2'b00;
endcase
end
endmodule
```
:::
### Priority encode with casez
:::spoiler 解答
```verilog=
module top_module (
input [7:0] in,
output reg [2:0] pos );
always @(in) begin
casez (in)
8'bzzzzzzz1: pos = 3'b000;
8'bzzzzzz10: pos = 3'b001;
8'bzzzzz100: pos = 3'b010;
8'bzzzz1000: pos = 3'b011;
8'bzzz10000: pos = 3'b100;
8'bzz100000: pos = 3'b101;
8'bz1000000: pos = 3'b110;
8'b10000000: pos = 3'b111;
default: pos = 3'b000;
endcase
end
endmodule
```
:::
### Avoiding latches
:::spoiler 解答
```verilog=
module top_module (
input [15:0] scancode,
output reg left,
output reg down,
output reg right,
output reg up );
always @(scancode) begin
left = 1'b0; down = 1'b0; right = 1'b0; up = 1'b0;
case (scancode)
16'he06b: left = 1'b1;
16'he072: down = 1'b1;
16'he074: right = 1'b1;
16'he075: up = 1'b1;
endcase
end
endmodule
```
:::
## More Verilog Features
### Conditional ternary operator
:::spoiler 解答
```verilog=
module top_module (
input [7:0] a, b, c, d,
output [7:0] min);//
// assign intermediate_result1 = compare? true: false;
wire [7:0] cmp_1, cmp_2;
assign cmp_1 = (a < b) ? a : b;
assign cmp_2 = (c < d) ? c : d;
assign min = (cmp_1 < cmp_2) ? cmp_1 : cmp_2;
endmodule
```
:::
### Reduction operator
:::spoiler 解答
```verilog=
module top_module (
input [7:0] in,
output parity);
assign parity = ^in;
endmodule
```
:::
### Reduction: Even wider gates
:::spoiler 解答
```verilog=
module top_module(
input [99:0] in,
output out_and,
output out_or,
output out_xor
);
assign out_and = ∈
assign out_or = |in;
assign out_xor = ^in;
endmodule
```
:::
### Combinational for-loop: Vector reversal 2
:::spoiler 解答
```verilog=
module top_module(
input [99:0] in,
output [99:0] out
);
always @(*) begin
for (integer i = 0; i <= 99; i = i + 1) begin
out[i] = in[99 - i];
end
end
endmodule
```
:::
### Combinational for-loop: 255-bits Population count
:::spoiler 解答
```verilog=
module top_module(
input [254:0] in,
output [7:0] out );
integer i;
always @(*) begin
out = 8'd0;
for (i = 0; i < 255; i = i + 1) begin
out = out + in[i];
end
end
endmodule
```
:::
### Generate for-loop: 100-bit binary adder
:::spoiler 使用 always 與 for-loop
```verilog=
module top_module(
input [99:0] a, b,
input cin,
output [99:0] cout,
output [99:0] sum );
always @(*) begin
{cout[0], sum[0]} = a[0] + b[0] + cin;
for (int i = 1; i < 100; i = i + 1) begin
{cout[i], sum[i]} = a[i] + b[i] + cout[i-1];
end
end
endmodule
```
:::
:::spoiler 使用 generate
```verilog=
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)
assign {cout[0], sum[0]} = a[0] + b[0] + cin;
else
assign {cout[i], sum[i]} = a[i] + b[i] + cout[i-1];
end
endgenerate
endmodule
```
:::
### Generate for-loop: 100-bit BCD adder
:::spoiler 解答
```verilog=
module top_module(
input [399:0] a, b,
input cin,
output cout,
output [399:0] sum );
reg [99:0] carry;
generate
genvar i;
for (i = 0; i < 100; i = i + 1) begin: adder
if (i == 0)
bcd_fadd bcd_fadd(.a(a[3:0]), .b(b[3:0]), .cin(cin), .cout(carry[i]), .sum(sum[3:0]));
else
bcd_fadd bcd_fadd(.a(a[4*i+3:4*i]), .b(b[4*i+3:4*i]), .cin(carry[i-1]), .cout(carry[i]), .sum(sum[4*i+3:4*i]));
end
assign cout = carry[99];
endgenerate
endmodule
```
:::
## Combinational Logic
### Basic Gates
#### Wire
:::spoiler 解答
```verilog=
module top_module (
input in,
output out);
assign out = in;
endmodule
```
:::
#### GND
:::spoiler 解答
```verilog=
module top_module (
output out);
assign out = 1'b0;
endmodule
```
:::
#### NOR
:::spoiler 解答
```verilog=
module top_module (
input in1,
input in2,
output out);
assign out = ~(in1 | in2);
endmodule
```
:::
#### Another gate
:::spoiler 解答
```verilog=
module top_module (
input in1,
input in2,
output out);
assign out = in1 & (~in2);
endmodule
```
:::
#### Two gates
:::spoiler 解答
```verilog=
module top_module (
input in1,
input in2,
input in3,
output out);
assign out = ~(in1 ^ in2) ^ in3;
endmodule
```
:::
#### More logic gates
:::spoiler 解答
```verilog=
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
```
:::
#### 7420 chip
:::spoiler 解答
```verilog=
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
```
:::
#### Truth tables
:::spoiler 解答
```verilog=
module top_module(
input x3,
input x2,
input x1, // three inputs
output f // one output
);
assign f = (~x1 & x2 & ~x3) | (x1 & x2 & ~x3) | (x1 & ~x2 & x3) | (x1 & x2 & x3);
endmodule
```
:::
#### Two bit equality
:::spoiler 解答
```verilog=
module top_module ( input [1:0] A, input [1:0] B, output z );
assign z = (A == B) ? 1'b1 : 1'b0;
endmodule
```
:::
#### Simple circuit A
:::spoiler 解答
```verilog=
module top_module (input x, input y, output z);
assign z = (x ^ y) & x;
endmodule
```
:::
#### Simple circuit B
:::spoiler 解答
```verilog=
module top_module ( input x, input y, output z );
assign z = ~(x ^ y);
endmodule
```
:::
#### Combine circuit A and B
:::spoiler 解答
```verilog=
module top_module (input x, input y, output z);
wire z1, z2, z3, z4;
assign z1 = (x ^ y) & x;
assign z2 = ~(x ^ y);
assign z3 = (x ^ y) & x;
assign z4 = ~(x ^ y);
assign z = (z1 | z2) ^ (z3 & z4);
endmodule
```
:::
#### Ring or vibrate?
:::spoiler 解答
```verilog=
module top_module (
input ring,
input vibrate_mode,
output ringer, // Make sound
output motor // Vibrate
);
assign ringer = ring & ~vibrate_mode;
assign motor = ring & vibrate_mode;
endmodule
```
:::
#### Thermostat
:::spoiler 解答
```verilog=
module top_module (
input too_cold,
input too_hot,
input mode,
input fan_on,
output heater,
output aircon,
output fan
);
assign heater = too_cold & mode;
assign aircon = too_hot & ~mode;
assign fan = fan_on | heater | aircon;
endmodule
```
:::
#### 3-bit population count
:::spoiler 解答
```verilog=
module top_module(
input [2:0] in,
output [1:0] out );
assign out = in[0] + in[1] + in[2];
endmodule
```
:::
#### Gates and vectors
:::spoiler 解答
```verilog=
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 = in[3:1] & in[2:0];
assign out_any = in[3:1] | in[2:0];
assign out_different = in ^ {in[0], in[3:1]};
endmodule
```
:::
#### Even longer vectors
:::spoiler 解答
```verilog=
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 ^ {in[0], in[99:1]};
endmodule
```
:::
### Multiplexers
#### 2-to-1 multiplexer
:::spoiler 解答
```verilog=
module top_module(
input a, b, sel,
output out );
reg o;
always @(*) begin
if (sel)
o = b;
else
o = a;
end
assign out = o;
endmodule
```
:::
#### 2-to-1 bus multiplexer
:::spoiler 解答
```verilog=
module top_module(
input [99:0] a, b,
input sel,
output [99:0] out );
assign out = sel ? b : a;
endmodule
```
:::
#### 9-to-1 multiplexer
:::spoiler 解答
```verilog=
module top_module(
input [15:0] a, b, c, d, e, f, g, h, i,
input [3:0] sel,
output [15:0] out );
reg [15:0] out_tmp;
always @(*) begin
case (sel)
4'b0000: out_tmp = a;
4'b0001: out_tmp = b;
4'b0010: out_tmp = c;
4'b0011: out_tmp = d;
4'b0100: out_tmp = e;
4'b0101: out_tmp = f;
4'b0110: out_tmp = g;
4'b0111: out_tmp = h;
4'b1000: out_tmp = i;
default: out_tmp = 16'hffff;
endcase
end
assign out = out_tmp;
endmodule
```
:::
#### 256-to-1 multiplexer
:::spoiler 解答
```verilog=
module top_module(
input [255:0] in,
input [7:0] sel,
output out );
assign out = in[sel];
endmodule
```
:::
#### 256-to-1 4-bit multiplexer
:::spoiler 第一種解法
```verilog=
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
```
:::
:::spoiler 第二種解法
```verilog=
module top_module(
input [1023:0] in,
input [7:0] sel,
output [3:0] out );
assign out = in[sel * 4+:4];
endmodule
```
:::
### Arithmetic Circuits
#### Half adder
:::spoiler 直接用加法
```verilog=
module top_module(
input a, b,
output cout, sum );
assign {cout, sum} = a + b;
endmodule
```
:::
:::spoiler 使用邏輯閘
```verilog=
module top_module(
input a, b,
output cout, sum );
assign sum = a ^ b;
assign cout = a & b;
endmodule
```
:::
#### Full adder
:::spoiler 直接用加法
```verilog=
module top_module(
input a, b, cin,
output cout, sum );
assign {cout, sum} = a + b + cin;
endmodule
```
:::
:::spoiler 使用邏輯閘
```verilog=
module top_module(
input a, b, cin,
output cout, sum );
assign sum = a ^ b ^ cin;
assign cout = (a & b) | (b & cin) | (cin & a);
endmodule
```
:::
#### 3-bit binary adder
:::spoiler 使用加法
```verilog=
module top_module(
input [2:0] a, b,
input cin,
output [2:0] cout,
output [2:0] sum );
assign {cout[0], sum[0]} = a[0] + b[0] + cin;
assign {cout[1], sum[1]} = a[1] + b[1] + cout[0];
assign {cout[2], sum[2]} = a[2] + b[2] + cout[1];
endmodule
```
:::
:::spoiler 使用邏輯閘
```verilog=
module top_module(
input [2:0] a, b,
input cin,
output [2:0] cout,
output [2:0] sum );
assign cout[0] = (a[0] & b[0]) | (a[0] & cin) | (cin & b[0]);
assign sum[0] = a[0] ^ b[0] ^ cin;
assign cout[1] = (a[1] & b[1]) | (a[1] & cout[0]) | (cout[0] & b[1]);
assign sum[1] = a[1] ^ b[1] ^ cout[0];
assign cout[2] = (a[2] & b[2]) | (a[2] & cout[1]) | (cout[1] & b[2]);
assign sum[2] = a[2] ^ b[2] ^ cout[1];
endmodule
```
:::
#### Adder
:::spoiler 解答
```verilog=
module top_module (
input [3:0] x,
input [3:0] y,
output [4:0] sum);
assign sum = x + y;
endmodule
```
:::
#### Signed addition overflow
:::spoiler 解答
```verilog=
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] & s[7]) | (a[7] & b[7] & ~s[7]);
endmodule
```
:::
#### 100-bit binary adder
:::spoiler 解答
```verilog=
module top_module(
input [99:0] a, b,
input cin,
output cout,
output [99:0] sum );
assign {cout, sum} = a + b + cin;
endmodule
```
:::
#### 4-digit BCD adder
:::spoiler 解答
```verilog=
module top_module (
input [15:0] a, b,
input cin,
output cout,
output [15:0] sum );
wire carry_0, carry_1, carry_2;
bcd_fadd bcd_fadd0(.a(a[3:0]), .b(b[3:0]), .cin(cin), .cout(carry_0), .sum(sum[3:0]));
bcd_fadd bcd_fadd1(.a(a[7:4]), .b(b[7:4]), .cin(carry_0), .cout(carry_1), .sum(sum[7:4]));
bcd_fadd bcd_fadd2(.a(a[11:8]), .b(b[11:8]), .cin(carry_1), .cout(carry_2), .sum(sum[11:8]));
bcd_fadd bcd_fadd3(.a(a[15:12]), .b(b[15:12]), .cin(carry_2), .cout(cout), .sum(sum[15:12]));
endmodule
```
:::
### Karnaugh Map to Circuit
#### 3-variable
:::spoiler 解答
```verilog=
module top_module(
input a,
input b,
input c,
output out );
assign out = a | (~a & b) | (~a & ~b & c);
endmodule
```
:::
#### 4-variable
:::spoiler 解答
```verilog=
module top_module(
input a,
input b,
input c,
input d,
output out );
assign out = (~b & ~c) | (~a & ~d) | (a & c & d) | (~a & b & c);
endmodule
```
:::
#### 4-variable
:::spoiler 解答
```verilog=
module top_module(
input a,
input b,
input c,
input d,
output out );
assign out = a | (~a & ~b & c);
endmodule
```
:::
#### 4-variable
:::spoiler 解答
```verilog=
module top_module(
input a,
input b,
input c,
input d,
output out );
assign out = a ^ b ^ c ^ d;
endmodule
```
:::
#### Minimum SOP and POS
:::spoiler 解答
```verilog=
module top_module (
input a,
input b,
input c,
input d,
output out_sop,
output out_pos
);
// assign out_sop = (b & c & d) | (~a & ~b & c & ~d);
// assign out_pos = (c | ~d) & (c | d | a) & (~c | d | ~a) & (a | ~b | ~c | d);
assign out_sop = (c & d) | (~a & ~b & c);
assign out_pos = ~((~c | ~d) & (a | b | ~c));
endmodule
```
:::
#### Karnaugh map
:::spoiler 解答
```verilog=
module top_module (
input [4:1] x,
output f );
assign f = (x[1] & x[2] & ~x[3] & x[4]) | (~x[1] & x[3]);
endmodule
```
:::
#### Karnaugh map
:::spoiler 解答
```verilog=
module top_module (
input [4:1] x,
output f
);
assign f = (~x[1] & x[3]) | (x[1] & x[2] & x[3] & x[4]) | (x[1] & ~x[2] & ~x[4]) | (~x[2] & ~x[3] & ~x[4]);
endmodule
```
:::
#### K-map implemented with a multiplexer
:::spoiler 解答
```verilog=
module top_module (
input c,
input d,
output [3:0] mux_in
);
assign mux_in[0] = c | d;
assign mux_in[1] = 1'b0;
assign mux_in[2] = ~d;
assign mux_in[3] = c & d;
endmodule
```
:::
## Sequential Logic
### Latches and Flip-Flops
#### D flip-flop
:::spoiler 解答
```verilog=
module top_module (
input clk, // Clocks are used in sequential circuits
input d,
output reg q );//
// Use a clocked always block
// copy d to q at every positive edge of clk
// Clocked always blocks should use non-blocking assignments
always @(posedge clk) begin
q <= d;
end
endmodule
```
:::
#### D flip-flops
:::spoiler 解答
```verilog=
module top_module (
input clk,
input [7:0] d,
output reg [7:0] q
);
always @(posedge clk) begin
q <= d;
end
endmodule
```
:::
#### DFF with reset
:::spoiler 解答
```verilog=
module top_module (
input clk,
input reset, // Synchronous reset
input [7:0] d,
output reg [7:0] q
);
always @(posedge clk) begin
if (reset)
q <= 8'h00;
else
q <= d;
end
endmodule
```
:::
#### DFF with reset value
:::spoiler 解答
```verilog=
module top_module (
input clk,
input reset,
input [7:0] d,
output reg [7:0] q
);
always @(negedge clk) begin
if (reset)
q <= 8'h34;
else
q <= d;
end
endmodule
```
:::
#### DFF with asynchronous reset
:::spoiler 解答
```verilog=
module top_module (
input clk,
input areset, // active high asynchronous reset
input [7:0] d,
output reg [7:0] q
);
always @(posedge clk, posedge areset) begin
if (areset)
q <= 8'h00;
else
q <= d;
end
endmodule
```
:::
#### DFF with byte enable
:::spoiler 單純使用 case
```verilog=
module top_module (
input clk,
input resetn,
input [1:0] byteena,
input [15:0] d,
output reg [15:0] q
);
always @(posedge clk) begin
case ({resetn, byteena})
3'b000: q <= q;
3'b001: q[7:0] <= 8'h00;
3'b010: q[15:8] <= 8'h00;
3'b011: q[15:0] <= 16'h00;
3'b100: q <= q;
3'b101: q[7:0] <= d[7:0];
3'b110: q[15:8] = d[15:8];
3'b111: q <= d;
default: q <= d;
endcase
end
endmodule
```
:::
:::spoiler 使用 if 與 case
```verilog=
module top_module (
input clk,
input resetn,
input [1:0] byteena,
input [15:0] d,
output reg [15:0] q
);
always @(posedge clk) begin
if (resetn == 1'b0)
q <= 16'h0000;
else begin
case (byteena)
2'b00: q <= q;
2'b01: q[7:0] <= d[7:0];
2'b10: q[15:8] <= d[15:8];
2'b11: q <= d;
default: q <= d;
endcase
end
end
endmodule
```
:::
#### D Latch
:::spoiler 解答
```verilog=
module top_module (
input d,
input ena,
output reg q);
always @(ena) begin
if (ena)
q <= d;
else
q <= q;
end
endmodule
```
:::
#### DFF
:::spoiler 解答
```verilog=
module top_module (
input clk,
input d,
input ar, // asynchronous reset
output reg q);
always @(posedge clk, posedge ar) begin
if (ar)
q <= 1'b0;
else
q <= d;
end
endmodule
```
:::
#### DFF
:::spoiler 解答
```verilog=
module top_module (
input clk,
input d,
input r, // synchronous reset
output reg q);
always @(posedge clk) begin
if (r)
q <= 1'b0;
else
q <= d;
end
endmodule
```
:::
#### DFF+gate
:::spoiler 解答
```verilog=
module top_module (
input clk,
input in,
output reg out);
always @(posedge clk) begin
out <= out ^ in;
end
endmodule
```
:::
#### Mux and DFF
:::spoiler 解答
```verilog=
module top_module (
input clk,
input L,
input r_in,
input q_in,
output reg Q);
always @(posedge clk) begin
if (L == 1'b1)
Q <= r_in;
else
Q <= q_in;
end
endmodule
```
:::
#### Mux and DFF
:::spoiler 解答
```verilog=
module top_module (
input clk,
input w, R, E, L,
output reg Q
);
always @(posedge clk) begin
if (L == 1'b1)
Q <= R;
else begin
if (E == 1'b1)
Q <= w;
else
Q <= Q;
end
end
endmodule
```
:::
#### DFF and gates
:::spoiler 解答
```verilog=
module top_module (
input clk,
input x,
output reg z
);
reg [2:0] q;
always @(posedge clk) begin
q[2] <= q[2] ^ x;
q[1] <= ~q[1] & x;
q[0] <= ~q[0] | x;
end
// 因為 z 不包含在循序電路中,因此不能放在 always block 中,使用 assign 即可。
assign z = ~(|q);
endmodule
```
:::
#### Create circuit from truth table
:::spoiler
```verilog=
module top_module (
input clk,
input j,
input k,
output reg Q);
always @(posedge clk) begin
case ({j, k})
2'b00: Q <= Q;
2'b01: Q <= 1'b0;
2'b10: Q <= 1'b1;
2'b11: Q <= ~Q;
endcase
end
endmodule
```
:::
#### Detect and edge
:::spoiler 解答
```verilog=
module top_module (
input clk,
input [7:0] in,
output reg [7:0] pedge
);
reg [7:0] last_in; // stores the last input
always @(posedge clk) begin
last_in <= in;
pedge <= (last_in ^ in) & in;
// 可以化簡成 pedge <= in & ~last_in;
end
endmodule
```
:::
#### Detect both edges
:::spoiler 解答
```verilog=
module top_module (
input clk,
input [7:0] in,
output reg [7:0] anyedge
);
reg [7:0] last_in; // stores the last input
always @(posedge clk) begin
last_in <= in;
anyedge <= last_in ^ in;
end
endmodule
```
:::
#### Edge capture register
:::spoiler 解答
```verilog=
module top_module (
input clk,
input reset,
input [31:0] in,
output [31:0] out
);
reg [31:0] last_in;
reg [31:0] last_reset;
always @(posedge clk) begin
last_in <= in;
if (reset)
out <= 32'h00000000;
else
out <= (last_in & ~in) | out;
end
endmodule
```
:::
#### Dual-edge triggered flip-flop
:::spoiler 解答
```verilog=
module top_module (
input clk,
input d,
output reg q
);
reg q_1, q_2;
always @(posedge clk) begin
q_1 <= d ^ q_2;
end
always @(negedge clk) begin
q_2 <= d ^ q_1;
end
assign q = q_1 ^ q_2;
endmodule
```
:::
### Counters
#### Four-bit binary counter
:::spoiler 解答
```verilog=
module top_module (
input clk,
input reset, // Synchronous active-high reset
output reg [3:0] q);
always @(posedge clk) begin
if (reset)
q <= 4'h0;
else
q <= q + 1;
end
endmodule
```
:::
#### Decade counter
:::spoiler 解答
```verilog=
module top_module (
input clk,
input reset, // Synchronous active-high reset
output reg [3:0] q);
always @(posedge clk) begin
if (reset || q == 4'b1001)
q <= 4'h0;
else
q <= q + 1;
end
endmodule
```
:::
#### Decade counter again
:::spoiler 解答
```verilog=
module top_module (
input clk,
input reset,
output reg [3:0] q);
always @(posedge clk) begin
if (reset || q == 4'b1010)
q <= 4'b0001;
else
q <= q + 1;
end
endmodule
```
:::
#### Slow decade counter
:::spoiler 解答
```verilog=
module top_module (
input clk,
input slowena,
input reset,
output [3:0] q);
always @(posedge clk) begin
if (reset || (q == 4'h9 && slowena))
q <= 4'h0;
else
q <= q + slowena;
end
endmodule
```
:::
#### Counter 1-12
:::spoiler 解答
```verilog=
module top_module (
input clk,
input reset,
input enable,
output [3:0] Q,
output c_enable,
output c_load,
output [3:0] c_d
);
count4 the_counter (clk, c_enable, c_load, c_d, Q);
assign c_enable = enable;
assign c_load = reset | ((enable) && (Q == 4'd12));
assign c_d = c_load ? 4'd1 : 4'd0;
endmodule
```
:::
這題的題目在解釋上較為不清楚,以下為各個訊號實際上的意義 :
* `c_enable` : 用於輸出給 testbench 的 enable 訊號,直接由原本的 enable 訊號 assign 即可。
* `c_load` : 用於輸出給 testbench 的 load 訊號,當 counter 需要載入數值時,需要將 c_load 設為 1 ,因此只有在 reset 以及 counter 數到 12 時才要進行更新數值,載入 1 。
* `c_d` : 用於輸出給 testbench 的 data 訊號,當 counter 需要做載入時, c_d 為需要載入的值,因此只有當 c_load 為 1 時,才會需要 c_d 為 1 ,其餘時間則為 0 。
#### Counter 1000
:::spoiler 解答
```verilog=
module top_module (
input clk,
input reset,
output OneHertz,
output [2:0] c_enable
);
reg [3:0] ten, hundred, thousand;
// bcdcount (input clk, input reset, input enable, output [3:0] Q);
bcdcount counter0 (clk, reset, c_enable[0], ten);
bcdcount counter1 (clk, reset, c_enable[1], hundred);
bcdcount counter2 (clk, reset, c_enable[2], thousand);
assign c_enable[0] = 1'b1;
assign c_enable[1] = (ten == 4'd9) ? 1'b1 : 1'b0;
assign c_enable[2] = (hundred == 4'd9 && c_enable[1]) ? 1'b1 : 1'b0;
assign OneHertz = (thousand == 4'd9 && c_enable[1] && c_enable[2]) ? 1'b1 : 1'b0;
endmodule
```
:::
#### 4-digit decimal counter
:::spoiler 較為複雜的解答
```verilog=
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[1] <= 1'b0;
q[3:0] <= 4'd0;
end
else if (q[3:0] == 4'd8) begin
ena[1] <= 1'b1;
q[3:0] <= q[3:0] + 4'd1;
end
else if (q[3:0] == 4'd9) begin
ena[1] <= 1'b0;
q[3:0] <= 4'd0;
end
else begin
ena[1] <= 1'b0;
q[3:0] <= q[3:0] + 4'd1;
end
end
always @(posedge clk) begin
if (reset)begin
ena[2] <= 1'b0;
q[7:4] <= 4'd0;
end
else if (q[7:4] == 4'd9 && q[3:0] == 4'd8) begin
ena[2] <= 1'b1;
q[7:4] <= q[7:4] + ena[1];
end
else if (q[7:4] == 4'd9 && q[3:0] == 4'd9) begin
ena[2] <= 1'b0;
q[7:4] <= 4'd0;
end
else begin
ena[2] <= 1'b0;
q[7:4] <= q[7:4] + ena[1];
end
end
always @(posedge clk) begin
if (reset)begin
ena[3] <= 1'b0;
q[11:8] <= 4'd0;
end
else if (q[11:8] == 4'd9 && q[7:4] == 4'd9 && q[3:0] == 4'd8) begin
ena[3] <= 1'b1;
q[11:8] <= q[11:8] + ena[2];
end
else if (q[11:8] == 4'd9 && q[7:4] == 4'd9 && q[3:0] == 4'd9) begin
ena[3] <= 1'b0;
q[11:8] <= 4'd0;
end
else begin
ena[3] <= 1'b0;
q[11:8] <= q[11:8] + ena[2];
end
end
always @(posedge clk) begin
if (reset)begin
q[15:12] <= 4'd0;
end
else if (q[15:12] == 4'd9 && q[11:8] == 4'd9 && q[7:4] == 4'd9 && q[3:0] == 4'd9) begin
q[15:12] <= 4'd0;
end
else begin
q[15:12] <= q[15:12] + ena[3];
end
end
endmodule
```
:::
:::spoiler 較為精簡的解答
```verilog=
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)
q <= 16'h0000;
else if (q[15:12] == 4'h9 && q[11:8] == 4'h9 && q[7:4] == 4'h9 && q[3:0] == 4'h9)
q <= 16'h0000;
else if (q[11:8] == 4'h9 && q[7:4] == 4'h9 && q[3:0] == 4'h9) begin
q[11:0] <= 12'h000;
q[15:12] <= q[15:12] + 4'h1;
end
else if (q[7:4] == 4'h9 && q[3:0] == 4'h9) begin
q[7:0] <= 8'h00;
q[11:8] <= q[11:8] + 4'h1;
end
else if (q[3:0] == 4'h9) begin
q[3:0] <= 4'h0;
q[7:4] <= q[7:4] + 4'h1;
end
else
q <= q + 16'h0001;
end
assign ena[1] = (q[3:0] == 4'h9) ? 1'b1: 1'b0;
assign ena[2] = (q[7:4] == 4'h9 && ena[1]) ? 1'b1: 1'b0;
assign ena[3] = (q[11:8] == 4'h9 && ena[2]) ? 1'b1: 1'b0;
endmodule
```
:::
#### 12-hour clock
:::spoiler 解答
```verilog=
module top_module(
input clk,
input reset,
input ena,
output pm,
output [7:0] hh,
output [7:0] mm,
output [7:0] ss);
always @(posedge clk) begin
if (reset) begin
hh <= 8'h12;
mm <= 8'h00;
ss <= 8'h00;
pm <= 1'b0;
end
else if (ena) begin
if (hh == 8'h11 && mm == 8'h59 && ss == 8'h59) begin
hh <= 8'h12;
mm <= 8'h00;
ss <= 8'h00;
pm <= ~pm;
end
else if (hh == 8'h12 && mm == 8'h59 && ss == 8'h59) begin
hh <= 8'h01;
mm <= 8'h00;
ss <= 8'h00;
end
else if (hh == 8'h09 && mm == 8'h59 && ss == 8'h59) begin
hh <= 8'h10;
mm <= 8'h00;
ss <= 8'h00;
end
else if (mm == 8'h59 && ss == 8'h59) begin
hh <= hh + 8'h01;
mm <= 8'h00;
ss <= 8'h00;
end
else if (mm[3:0] == 4'h9 && ss == 8'h59) begin
mm[7:4] <= mm[7:4] + 4'h1;
mm[3:0] <= 4'h0;
ss <= 8'h00;
end
else if (ss == 8'h59) begin
mm <= mm + 8'h01;
ss <= 8'h00;
end
else if (ss[3:0] == 4'h9) begin
ss[7:4] <= ss[7:4] + 4'h1;
ss[3:0] <= 4'h0;
end
else
ss <= ss + 8'h01;
end
end
endmodule
```
:::
### Shift Registers
#### 4-bit shift register
:::spoiler 解答
```verilog=
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, posedge areset) begin
if (areset)
q <= 4'b0000;
else if (load)
q <= data;
else if (ena)
q <= q >> 1;
end
endmodule
```
:::
#### left/right rotator
:::spoiler 解答
```verilog=
module top_module(
input clk,
input load,
input [1:0] ena,
input [99:0] data,
output reg [99:0] q);
always @(posedge clk) begin
if (load)
q <= data;
else if (ena == 2'b01) // rotate to the right
q <= {q[0], q[99:1]};
else if (ena == 2'b10) // rotate to the left
q <= {q[98:0], q[99]};
end
endmodule
```
:::
#### left/right arithmetic shift by 1 or 8
:::spoiler 解答
```verilog=
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)
q <= data;
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]};
default: q <= q << 1;
endcase
end
end
endmodule
```
:::
#### 5-bit LFSR
:::spoiler 解答
```verilog=
module top_module(
input clk,
input reset, // Active-high synchronous reset to 5'h1
output [4:0] q
);
always @(posedge clk) begin
if (reset)
q <= 5'h1;
else
q <= {q[0], q[4], q[3] ^ q[0], q[2:1]};
end
endmodule
```
:::
#### 3-bit LFSR
:::spoiler 解答
```verilog=
module top_module (
input [2:0] SW, // R
input [1:0] KEY, // L and clk
output [2:0] LEDR); // Q
reg [2:0] LEDR_next; // dq flip flop input
assign LEDR_next = KEY[1] ? SW : {LEDR[1] ^ LEDR[2], LEDR[0], LEDR[2]} ;
always @(posedge KEY[0]) begin
LEDR <= LEDR_next;
end
endmodule
```
:::
#### 32-bit LFSR
:::spoiler 解答
```verilog=
module top_module(
input clk,
input reset, // Active-high synchronous reset to 32'h1
output [31:0] q
);
reg [31:0] q_next;
// taps at bit position 32, 22, 2, 1
always @(*) begin
q_next[31] <= q[0];
q_next[21] <= q[0] ^ q[22];
q_next[1] <= q[0] ^ q[2];
q_next[0] <= q[0] ^ q[1];
q_next[30:22] <= q[31:23];
q_next[20:2] <= q[21:3];
end
always @(posedge clk) begin
if (reset)
q <= 32'h1;
else
q <= q_next;
end
endmodule
```
:::
#### Shift register
:::spoiler 解答
```verilog=
module top_module (
input clk,
input resetn, // synchronous reset
input in,
output out);
reg [3:0] ff;
reg [3:0] ff_next;
always @(*) begin
ff_next[3] = in;
ff_next[2:0] = ff[3:1];
out = ff[0];
end
always @(posedge clk) begin
if (!resetn)
ff <= 4'h0;
else
ff <= ff_next;
end
endmodule
```
:::
#### Shift register
:::spoiler 解答
```verilog=
```
:::
### More Circuits
#### Rule 90
:::spoiler 解答
```verilog=
module top_module(
input clk,
input load,
input [511:0] data,
output [511:0] q );
always @(posedge clk) begin
if (load)
q <= data;
else begin
for (int i = 1; i <= 510; i = i + 1)
q[i] <= q[i-1] ^ q[i+1];
q[511] <= q[510];
q[0] <= q[1];
end
end
endmodule
```
:::
#### Rule 110
:::spoiler 解答
```verilog=
```
:::
### Finite State Machine
#### Simple FSM 1 (asynchronous reset)
:::spoiler 解答
```verilog=
module top_module(
input clk,
input areset, // Asynchronous reset to state B
input in,
output out);
parameter A=0, B=1;
reg state, next_state;
always @(*) begin // This is a combinational always block
// State transition logic
case (state)
A: begin
if (in == 1'b1)
next_state = A;
else
next_state = B;
end
B: begin
if (in == 1'b1)
next_state = B;
else
next_state = A;
end
endcase
end
always @(posedge clk, posedge areset) begin // This is a sequential always block
// State flip-flops with asynchronous reset
if (areset)
state <= B;
else
state <= next_state;
end
// Output logic
assign out = (state == A) ? 1'b0 : 1'b1;
endmodule
```
:::
#### Simple FSM 1 (synchronous reset)
:::spoiler 解答
```verilog=
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;
// state transition logic
always @(*) begin
case (present_state)
A: begin
if (in == 1'b1)
next_state = A;
else
next_state = B;
end
B: begin
if (in == 1'b1)
next_state = B;
else
next_state = A;
end
endcase
end
// state flip-flops
always @(posedge clk) begin
if (reset)
present_state <= B;
else
present_state <= next_state;
end
// output logic
assign out = (present_state == B) ? 1'b1 : 1'b0;
endmodule
```
:::
#### Simple FSM 2 (asynchronous reset)
:::spoiler 解答
```verilog=
module top_module(
input clk,
input areset, // Asynchronous reset to OFF
input j,
input k,
output out); //
parameter OFF = 1'b0, ON = 1'b1;
reg state, next_state;
always @(*) begin
// State transition logic
case (state)
ON: begin
if (k == 1'b1)
next_state = OFF;
else
next_state = ON;
end
OFF: begin
if (j == 1'b1)
next_state = ON;
else
next_state = OFF;
end
endcase
end
always @(posedge clk, posedge areset) begin
// State flip-flops with asynchronous reset
if (areset)
state <= OFF;
else
state <= next_state;
end
// Output logic
assign out = (state == ON) ? 1'b1 : 1'b0;
endmodule
```
:::
#### Simple FSM 2 (synchronous reset)
:::spoiler 解答
```verilog=
module top_module(
input clk,
input reset, // Synchronous reset to OFF
input j,
input k,
output out); //
parameter OFF = 1'b0, ON = 1'b1;
reg state, next_state;
always @(*) begin
// State transition logic
case (state)
ON: begin
if (k == 1'b1)
next_state = OFF;
else
next_state = ON;
end
OFF: begin
if (j == 1'b1)
next_state = ON;
else
next_state = OFF;
end
default: begin
next_state = ON;
end
endcase
end
always @(posedge clk) begin
// State flip-flops with synchronous reset
if (reset)
state <= OFF;
else
state <= next_state;
end
// Output logic
assign out = (state == ON) ? 1'b1 : 1'b0;
endmodule
```
:::
#### Simple state transition 3
:::spoiler 解答
```verilog=
module top_module(
input in,
input [1:0] state,
output [1:0] next_state,
output out); //
parameter A = 2'b00, B = 2'b01, C = 2'b10, D = 2'b11;
// State transition logic: next_state = f(state, in)
always @(*) begin
case (state)
A: begin
if (in == 1'b1)
next_state = B;
else
next_state = A;
end
B: begin
if (in == 1'b1)
next_state = B;
else
next_state = C;
end
C: begin
if (in == 1'b1)
next_state = D;
else
next_state = A;
end
D: begin
if (in == 1'b1)
next_state = B;
else
next_state = C;
end
endcase
end
// Output logic: out = f(state) for a Moore state machine
assign out = (state == D) ? 1'b1 : 1'b0;
endmodule
```
:::
#### Simple one-hot state transition 3
:::spoiler 解答
```verilog=
```
:::
#### Simple FSM 3 (asynchronous reset)
:::spoiler 解答
```verilog=
module top_module(
input clk,
input in,
input areset,
output out); //
parameter A = 2'b00;
parameter B = 2'b01;
parameter C = 2'b10;
parameter D = 2'b11;
reg [1:0] state, next_state;
// State transition logic
always @(*) begin
case (state)
A: begin
if (in == 1'b1)
next_state = B;
else
next_state = A;
end
B: begin
if (in == 1'b1)
next_state = B;
else
next_state = C;
end
C: begin
if (in == 1'b1)
next_state = D;
else
next_state = A;
end
D: begin
if (in == 1'b1)
next_state = B;
else
next_state = C;
end
default: next_state = A;
endcase
end
// State flip-flops with asynchronous reset
always @(posedge clk, posedge areset) begin
if (areset)
state <= A;
else
state <= next_state;
end
// Output logic
assign out = (state == D) ? 1'b1 : 1'b0;
endmodule
```
:::
#### Simple FSM 3 (synchronous reset)
:::spoiler 解答
```verilog=
module top_module(
input clk,
input in,
input reset,
output out); //
parameter A = 2'b00;
parameter B = 2'b01;
parameter C = 2'b10;
parameter D = 2'b11;
reg [1:0] state, next_state;
// State transition logic
always @(*) begin
case (state)
A: begin
if (in == 1'b1)
next_state = B;
else
next_state = A;
end
B: begin
if (in == 1'b1)
next_state = B;
else
next_state = C;
end
C: begin
if (in == 1'b1)
next_state = D;
else
next_state = A;
end
D: begin
if (in == 1'b1)
next_state = B;
else
next_state = C;
end
default: next_state = A;
endcase
end
// State flip-flops with synchronous reset
always @(posedge clk) begin
if (reset)
state <= A;
else
state <= next_state;
end
// Output logic
assign out = (state == D) ? 1'b1 : 1'b0;
endmodule
```
:::
#### Design a Moore FSM
:::spoiler 解答
```verilog=
```
:::
#### Lemmings 1
:::spoiler 解答
```verilog=
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 = 1'b0, RIGHT = 1'b1;
reg state, next_state;
// State transition logic
always @(*) begin
case (state)
LEFT: begin
if (bump_left)
next_state = RIGHT;
else
next_state = LEFT;
end
RIGHT: begin
if (bump_right)
next_state = LEFT;
else
next_state = RIGHT;
end
default: next_state = LEFT;
endcase
end
// State flip-flops with asynchronous reset
always @(posedge clk, posedge areset) begin
if (areset)
state <= LEFT;
else
state <= next_state;
end
// Output logic
assign walk_left = (state == LEFT) ? 1'b1 : 1'b0;
assign walk_right = (state == RIGHT) ? 1'b1 : 1'b0;
endmodule
```
:::
#### Lemmings 2
:::spoiler 解答
```verilog=
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 );
// bump left, so turn right
// bump right, so turn left
// if there is no ground, so aaah
parameter [1:0] left = 2'd0, right = 2'd1, fall = 2'd2;
reg [1:0] state, next_state;
parameter last_left = 1'b0, last_right = 1'b1;
reg last_move;
// state transition logic
always @(*) begin
case (state)
left: begin
last_move = last_left;
if (!ground)
next_state = fall;
else if (bump_left)
next_state = right;
else
next_state = left;
end
right: begin
last_move = last_right;
if (!ground)
next_state = fall;
else if (bump_right)
next_state = left;
else
next_state = right;
end
fall: begin
if (!ground)
next_state = fall;
else if (last_move == last_left)
next_state = left;
else
next_state = right;
end
default: begin
next_state = left;
end
endcase
end
// state flip-flop registers
always @(posedge clk, posedge areset) begin
if (areset)
state <= left;
else
state <= next_state;
end
// output logic
assign walk_left = (state == left) ? 1'b1 : 1'b0;
assign walk_right = (state == right) ? 1'b1 : 1'b0;
assign aaah = (state == fall) ? 1'b1 : 1'b0;
endmodule
```
:::