--- ###### 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 = &in; 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 = &in; 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 ``` :::