aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWarrick Lo <warrick.s.z.lo@gmail.com>2026-02-04 15:58:18 -0800
committerWarrick Lo <warrick.s.z.lo@gmail.com>2026-02-04 15:58:18 -0800
commit84a3a165abca3a301701326c09361a537b940ac3 (patch)
treec6abb4b510164053c3fac4107c110be87e9c4426
parentRedesign state machine (diff)
Add testbenchHEADmaster
-rw-r--r--task1/card7seg.qwsbin0 -> 639 bytes
-rw-r--r--task1/card7seg.sv34
-rw-r--r--task1/tb_card7seg.sv113
-rw-r--r--task4/scorehand.sv1
-rw-r--r--task4/task4.qwsbin0 -> 639 bytes
-rw-r--r--task4/tb_task4.sv144
-rw-r--r--task5/tb_datapath.sv338
-rw-r--r--task5/tb_scorehand.sv109
-rw-r--r--task5/tb_statemachine.sv268
-rw-r--r--task5/tb_task5.sv256
-rw-r--r--task5/vish_stacktrace.vstf32
11 files changed, 1252 insertions, 43 deletions
diff --git a/task1/card7seg.qws b/task1/card7seg.qws
new file mode 100644
index 0000000..689e37a
--- /dev/null
+++ b/task1/card7seg.qws
Binary files differ
diff --git a/task1/card7seg.sv b/task1/card7seg.sv
index 507c988..ef9d5c7 100644
--- a/task1/card7seg.sv
+++ b/task1/card7seg.sv
@@ -2,22 +2,20 @@ module card7seg(SW, HEX0);
input logic [3:0] SW;
output logic [6:0] HEX0;
- always_comb begin
- case (SW)
- 1: HEX0 <= 7'b0001000;
- 2: HEX0 <= 7'b0100100;
- 3: HEX0 <= 7'b0110000;
- 4: HEX0 <= 7'b0011001;
- 5: HEX0 <= 7'b0010010;
- 6: HEX0 <= 7'b0000010;
- 7: HEX0 <= 7'b1111000;
- 8: HEX0 <= 7'b0000000;
- 9: HEX0 <= 7'b0010000;
- 10: HEX0 <= 7'b1000000;
- 11: HEX0 <= 7'b1100001;
- 12: HEX0 <= 7'b0011000;
- 13: HEX0 <= 7'b0001001;
- default: HEX0 <= 7'b1111111;
- endcase
- end
+ always_comb case (SW)
+ 1: HEX0 <= 7'b0001000;
+ 2: HEX0 <= 7'b0100100;
+ 3: HEX0 <= 7'b0110000;
+ 4: HEX0 <= 7'b0011001;
+ 5: HEX0 <= 7'b0010010;
+ 6: HEX0 <= 7'b0000010;
+ 7: HEX0 <= 7'b1111000;
+ 8: HEX0 <= 7'b0000000;
+ 9: HEX0 <= 7'b0010000;
+ 10: HEX0 <= 7'b1000000;
+ 11: HEX0 <= 7'b1100001;
+ 12: HEX0 <= 7'b0011000;
+ 13: HEX0 <= 7'b0001001;
+ default: HEX0 <= 7'b1111111;
+ endcase
endmodule: card7seg
diff --git a/task1/tb_card7seg.sv b/task1/tb_card7seg.sv
index 3a985c9..5d68861 100644
--- a/task1/tb_card7seg.sv
+++ b/task1/tb_card7seg.sv
@@ -1,8 +1,113 @@
+`define ACE 7'b0001000
+`define TWO 7'b0100100
+`define THREE 7'b0110000
+`define FOUR 7'b0011001
+`define FIVE 7'b0010010
+`define SIX 7'b0000010
+`define SEVEN 7'b1111000
+`define EIGHT 7'b0000000
+`define NINE 7'b0010000
+`define TEN 7'b1000000
+`define JACK 7'b1100001
+`define QUEEN 7'b0011000
+`define KING 7'b0001001
+`define BLANK 7'b1111111
+
module tb_card7seg();
+ logic err;
+ logic [3:0] SW;
+ logic [6:0] HEX0;
+
+ card7seg DUT(SW, HEX0);
+
+ task check;
+ input logic [6:0] expected;
+
+ if (HEX0 !== expected) begin
+ err = 1;
+ $display("FAILED: HEX is incorrect.",);
+ end
+ endtask: check
+
+
+ initial begin
+ err = 0;
+
+ SW = 4'd0;
+ #5;
+ check(`BLANK);
+ #5;
+
+ SW = 4'd1;
+ #5;
+ check(`ACE);
+ #5;
+
+ SW = 4'd2;
+ #5;
+ check(`TWO);
+ #5;
+
+ SW = 4'd3;
+ #5;
+ check(`THREE);
+ #5;
+
+ SW = 4'd4;
+ #5;
+ check(`FOUR);
+ #5;
+
+ SW = 4'd5;
+ #5;
+ check(`FIVE);
+ #5;
+
+ SW = 4'd6;
+ #5;
+ check(`SIX);
+ #5;
+
+ SW = 4'd7;
+ #5;
+ check(`SEVEN);
+ #5;
+
+ SW = 4'd8;
+ #5;
+ check(`EIGHT);
+ #5;
+
+ SW = 4'd9;
+ #5;
+ check(`NINE);
+ #5;
+
+ SW = 4'd10;
+ #5;
+ check(`TEN);
+ #5;
+
+ SW = 4'd11;
+ #5;
+ check(`JACK);
+ #5;
+
+ SW = 4'd12;
+ #5;
+ check(`QUEEN);
+ #5;
+
+ SW = 4'd13;
+ #5;
+ check(`KING);
+ #5;
+
+ if (~err)
+ $display("All tests passed.");
-// Your testbench goes here. Make sure your tests exercise the entire design
-// in the .sv file. Note that in our tests the simulator will exit after
-// 10,000 ticks (equivalent to "initial #10000 $finish();").
-
+ #10;
+ $stop;
+ end
endmodule
diff --git a/task4/scorehand.sv b/task4/scorehand.sv
index a472873..a6c40d6 100644
--- a/task4/scorehand.sv
+++ b/task4/scorehand.sv
@@ -23,5 +23,4 @@ module scorehand(card1, card2, card3, total);
else
total = sum;
end
-
endmodule: scorehand
diff --git a/task4/task4.qws b/task4/task4.qws
new file mode 100644
index 0000000..689e37a
--- /dev/null
+++ b/task4/task4.qws
Binary files differ
diff --git a/task4/tb_task4.sv b/task4/tb_task4.sv
index 0cc9c84..d27fa8d 100644
--- a/task4/tb_task4.sv
+++ b/task4/tb_task4.sv
@@ -1,7 +1,143 @@
+`define ACE 7'b0001000
+`define TWO 7'b0100100
+`define THREE 7'b0110000
+`define FOUR 7'b0011001
+`define FIVE 7'b0010010
+`define SIX 7'b0000010
+`define SEVEN 7'b1111000
+`define EIGHT 7'b0000000
+`define NINE 7'b0010000
+`define TEN 7'b1000000
+`define JACK 7'b1100001
+`define QUEEN 7'b0011000
+`define KING 7'b0001001
+`define BLANK 7'b1111111
+
module tb_task4();
+ logic err, resetb, slow_clock, CLOCK_50;
+ logic [3:0] KEY;
+ logic [6:0] HEX0, HEX1, HEX2, HEX3, HEX4, HEX5;
+ logic [9:0] LEDR;
+
+ assign KEY[0] = slow_clock;
+ assign KEY[3] = resetb;
+
+ task5 DUT(CLOCK_50, KEY, LEDR, HEX5, HEX4, HEX3, HEX2, HEX1, HEX0);
+
+ task check;
+ input logic [6:0] expected_HEX0, expected_HEX1, expected_HEX2,
+ expected_HEX3, expected_HEX4, expected_HEX5;
+ input logic [9:0] expected_LEDR;
+
+ if (HEX0 !== expected_HEX0) begin
+ err = 1;
+ $display("FAILED: HEX0 is incorrect.",);
+ end
+ if (HEX1 !== expected_HEX1) begin
+ err = 1;
+ $display("FAILED: HEX1 is incorrect.",);
+ end
+ if (HEX2 !== expected_HEX2) begin
+ err = 1;
+ $display("FAILED: HEX2 is incorrect.",);
+ end
+ if (HEX3 !== expected_HEX3) begin
+ err = 1;
+ $display("FAILED: HEX3 is incorrect.",);
+ end
+ if (HEX4 !== expected_HEX4) begin
+ err = 1;
+ $display("FAILED: HEX4 is incorrect.",);
+ end
+ if (HEX5 !== expected_HEX5) begin
+ err = 1;
+ $display("FAILED: HEX5 is incorrect.",);
+ end
+ if (LEDR !== expected_LEDR) begin
+ err = 1;
+ $display("FAILED: LEDR is incorrect.",);
+ end
+ endtask: check
+
+ initial forever begin
+ slow_clock = 1'b0;
+ #5;
+ slow_clock = 1'b1;
+ #5;
+ end
+
+ initial begin
+ err = 0;
+
+ /* Reset. */
+
+ $display("Test 1");
+
+ resetb = 1'b0;
+
+ #10;
+
+ resetb = 1'b1;
+
+ check(`BLANK, `BLANK, `BLANK, `BLANK, `BLANK, `BLANK, 10'b00_0000_0000);
+
+ /* Test for natural win. Player: 9T, dealer: A2. */
+
+ $display("Test 2.1");
+
+ force tb_task5.DUT.dp.new_card = 4'd9;
+
+ #10;
+
+ check(`NINE, `BLANK, `BLANK, `BLANK, `BLANK, `BLANK, 10'b00_0000_1001);
+
+ $display("Test 2.2");
+
+ force tb_task5.DUT.dp.new_card = 4'd1;
+
+ #10;
+
+ check(`NINE, `BLANK, `BLANK, `ACE, `BLANK, `BLANK, 10'b00_0001_1001);
+
+ $display("Test 2.3");
+
+ force tb_task5.DUT.dp.new_card = 4'd10;
+
+ #10;
+
+ check(`NINE, `TEN, `BLANK, `ACE, `BLANK, `BLANK, 10'b00_0001_1001);
+
+ $display("Test 2.4");
+
+ force tb_task5.DUT.dp.new_card = 4'd2;
+
+ #10;
+
+ check(`NINE, `TEN, `BLANK, `ACE, `TWO, `BLANK, 10'b00_0011_1001);
+
+ $display("Test 2.5");
+
+ /* Load anything. */
+ force tb_task5.DUT.dp.new_card = 4'd10;
+
+ #10;
+
+ check(`NINE, `TEN, `BLANK, `ACE, `TWO, `BLANK, 10'b01_0011_1001);
+
+ $display("Test 2.6");
+
+ resetb = 1'b0;
+
+ #10;
+
+ resetb = 1'b1;
+
+ check(`BLANK, `BLANK, `BLANK, `BLANK, `BLANK, `BLANK, 10'b00_0000_0000);
-// Your testbench goes here. Make sure your tests exercise the entire design
-// in the .sv file. Note that in our tests the simulator will exit after
-// 100,000 ticks (equivalent to "initial #100000 $finish();").
+ if (~err)
+ $display("All tests passed.");
-endmodule
+ #10;
+ $stop;
+ end
+endmodule: tb_task4
diff --git a/task5/tb_datapath.sv b/task5/tb_datapath.sv
index 64ff5ab..823ead5 100644
--- a/task5/tb_datapath.sv
+++ b/task5/tb_datapath.sv
@@ -1,7 +1,337 @@
+`define ACE 7'b0001000
+`define TWO 7'b0100100
+`define THREE 7'b0110000
+`define FOUR 7'b0011001
+`define FIVE 7'b0010010
+`define SIX 7'b0000010
+`define SEVEN 7'b1111000
+`define EIGHT 7'b0000000
+`define NINE 7'b0010000
+`define TEN 7'b1000000
+`define JACK 7'b1100001
+`define QUEEN 7'b0011000
+`define KING 7'b0001001
+`define BLANK 7'b1111111
+
module tb_datapath();
+ logic err, slow_clock, fast_clock, resetb,
+ load_pcard1, load_pcard2, load_pcard3,
+ load_dcard1, load_dcard2, load_dcard3;
+ logic [3:0] pcard3_out, pscore_out, dscore_out;
+ logic [6:0] HEX0, HEX1, HEX2, HEX3, HEX4, HEX5;
+
+ datapath DUT(slow_clock, fast_clock, resetb,
+ load_pcard1, load_pcard2, load_pcard3,
+ load_dcard1, load_dcard2, load_dcard3,
+ pcard3_out, pscore_out, dscore_out,
+ HEX5, HEX4, HEX3, HEX2, HEX1, HEX0);
+
+ task check;
+ input logic [3:0] expected_pscore, expected_dscore;
+ input logic [6:0] expected_HEX0, expected_HEX1, expected_HEX2,
+ expected_HEX3, expected_HEX4, expected_HEX5;
+
+ if (pscore_out !== expected_pscore) begin
+ err = 1;
+ $display("FAILED: pscore_out is incorrect.",);
+ end
+ if (dscore_out !== expected_dscore) begin
+ err = 1;
+ $display("FAILED: dscore_out is incorrect.",);
+ end
+ if (HEX0 !== expected_HEX0) begin
+ err = 1;
+ $display("FAILED: HEX0 is incorrect.",);
+ end
+ if (HEX1 !== expected_HEX1) begin
+ err = 1;
+ $display("FAILED: HEX1 is incorrect.",);
+ end
+ if (HEX2 !== expected_HEX2) begin
+ err = 1;
+ $display("FAILED: HEX2 is incorrect.",);
+ end
+ if (HEX3 !== expected_HEX3) begin
+ err = 1;
+ $display("FAILED: HEX3 is incorrect.",);
+ end
+ if (HEX4 !== expected_HEX4) begin
+ err = 1;
+ $display("FAILED: HEX4 is incorrect.",);
+ end
+ if (HEX5 !== expected_HEX5) begin
+ err = 1;
+ $display("FAILED: HEX5 is incorrect.",);
+ end
+ endtask: check
+
+ initial forever begin
+ slow_clock = 1'b0;
+ #5;
+ slow_clock = 1'b1;
+ #5;
+ end
+
+ initial begin
+ err = 0;
+
+ {resetb, load_pcard1, load_pcard2, load_pcard3,
+ load_pcard1, load_pcard2, load_pcard3}
+ = 7'b0;
+
+ #10;
+
+ resetb = 1'b1;
+
+ /* Player: AK8, dealer: TJ9. */
+
+ /* Load A. */
+
+ $display("Test 1.1");
+
+ force tb_datapath.DUT.new_card = 4'd1;
+ load_pcard1 = 1'b1;
+
+ #10;
+
+ check(4'd1, 4'd0, `ACE, `BLANK, `BLANK, `BLANK, `BLANK, `BLANK);
+ load_pcard1 = 1'b0;
+
+ /* Load T. */
+
+ $display("Test 1.2");
+
+ force tb_datapath.DUT.new_card = 4'd10;
+ load_dcard1 = 1'b1;
+
+ #10;
+
+ check(4'd1, 4'd0, `ACE, `BLANK, `BLANK, `TEN, `BLANK, `BLANK);
+ load_dcard1 = 1'b0;
+
+ /* Load K. */
+
+ $display("Test 1.3");
+
+ force tb_datapath.DUT.new_card = 4'd13;
+ load_pcard2 = 1'b1;
+
+ #10;
+
+ check(4'd1, 4'd0, `ACE, `KING, `BLANK, `TEN, `BLANK, `BLANK);
+ load_pcard2 = 1'b0;
+
+ /* Load J. */
+
+ $display("Test 1.4");
+
+ force tb_datapath.DUT.new_card = 4'd11;
+ load_dcard2 = 1'b1;
+
+ #10;
+
+ check(4'd1, 4'd0, `ACE, `KING, `BLANK, `TEN, `JACK, `BLANK);
+ load_dcard2 = 1'b0;
+
+ /* Load 8. */
+
+ $display("Test 1.5");
+
+ force tb_datapath.DUT.new_card = 4'd8;
+ load_pcard3 = 1'b1;
+
+ #10;
+
+ check(4'd9, 4'd0, `ACE, `KING, `EIGHT, `TEN, `JACK, `BLANK);
+ load_pcard3 = 1'b0;
+
+ /* Load 9. */
+
+ $display("Test 1.6");
+
+ force tb_datapath.DUT.new_card = 4'd9;
+ load_dcard3 = 1'b1;
+
+ #10;
+
+ check(4'd9, 4'd9, `ACE, `KING, `EIGHT, `TEN, `JACK, `NINE);
+ load_dcard3 = 1'b0;
+
+ /* Reset. */
+
+ $display("Test 1.7");
+
+ resetb = 1'b0;
+
+ #10;
+
+ check(4'd0, 4'd0, `BLANK, `BLANK, `BLANK, `BLANK, `BLANK, `BLANK);
+ resetb = 1'b1;
+
+ /* Player: 234, dealer: 567. */
+
+ /* Load 2. */
+
+ $display("Test 2.1");
+
+ force tb_datapath.DUT.new_card = 4'd2;
+ load_pcard1 = 1'b1;
+
+ #10;
+
+ check(4'd2, 4'd0, `TWO, `BLANK, `BLANK, `BLANK, `BLANK, `BLANK);
+ load_pcard1 = 1'b0;
+
+ /* Load 5. */
+
+ $display("Test 2.2");
+
+ force tb_datapath.DUT.new_card = 4'd5;
+ load_dcard1 = 1'b1;
+
+ #10;
+
+ check(4'd2, 4'd5, `TWO, `BLANK, `BLANK, `FIVE, `BLANK, `BLANK);
+ load_dcard1 = 1'b0;
+
+ /* Load 3. */
+
+ $display("Test 2.3");
+
+ force tb_datapath.DUT.new_card = 4'd3;
+ load_pcard2 = 1'b1;
+
+ #10;
+
+ check(4'd5, 4'd5, `TWO, `THREE, `BLANK, `FIVE, `BLANK, `BLANK);
+ load_pcard2 = 1'b0;
+
+ /* Load 6. */
+
+ $display("Test 2.4");
+
+ force tb_datapath.DUT.new_card = 4'd6;
+ load_dcard2 = 1'b1;
+
+ #10;
+
+ check(4'd5, 4'd1, `TWO, `THREE, `BLANK, `FIVE, `SIX, `BLANK);
+ load_dcard2 = 1'b0;
+
+ /* Load 4. */
+
+ $display("Test 2.5");
+
+ force tb_datapath.DUT.new_card = 4'd4;
+ load_pcard3 = 1'b1;
+
+ #10;
+
+ check(4'd9, 4'd1, `TWO, `THREE, `FOUR, `FIVE, `SIX, `BLANK);
+ load_pcard3 = 1'b0;
+
+ /* Load 7. */
+
+ $display("Test 2.6");
+
+ force tb_datapath.DUT.new_card = 4'd7;
+ load_dcard3 = 1'b1;
+
+ #10;
+
+ check(4'd9, 4'd8, `TWO, `THREE, `FOUR, `FIVE, `SIX, `SEVEN);
+ load_dcard3 = 1'b0;
+
+ /* Reset. */
+
+ $display("Test 2.7");
+
+ resetb = 1'b0;
+
+ #10;
+
+ check(4'd0, 4'd0, `BLANK, `BLANK, `BLANK, `BLANK, `BLANK, `BLANK);
+ resetb = 1'b1;
+
+ /* Player: 89, dealer: JQK. */
+
+ /* Load 8. */
+
+ $display("Test 3.1");
+
+ force tb_datapath.DUT.new_card = 4'd8;
+ load_pcard1 = 1'b1;
+
+ #10;
+
+ check(4'd8, 4'd0, `EIGHT, `BLANK, `BLANK, `BLANK, `BLANK, `BLANK);
+ load_pcard1 = 1'b0;
+
+ /* Load J. */
+
+ $display("Test 3.2");
+
+ force tb_datapath.DUT.new_card = 4'd11;
+ load_dcard1 = 1'b1;
+
+ #10;
+
+ check(4'd8, 4'd0, `EIGHT, `BLANK, `BLANK, `JACK, `BLANK, `BLANK);
+ load_dcard1 = 1'b0;
+
+ /* Load 9. */
+
+ $display("Test 3.3");
+
+ force tb_datapath.DUT.new_card = 4'd9;
+ load_pcard2 = 1'b1;
+
+ #10;
+
+ check(4'd7, 4'd0, `EIGHT, `NINE, `BLANK, `JACK, `BLANK, `BLANK);
+ load_pcard2 = 1'b0;
+
+ #10;
+
+ /* Load Q. */
+
+ $display("Test 3.4");
+
+ force tb_datapath.DUT.new_card = 4'd12;
+ load_dcard2 = 1'b1;
+
+ #10;
+
+ check(4'd7, 4'd0, `EIGHT, `NINE, `BLANK, `JACK, `QUEEN, `BLANK);
+ load_dcard2 = 1'b0;
+
+ /* Load K. */
+
+ $display("Test 3.5");
+
+ force tb_datapath.DUT.new_card = 4'd13;
+ load_dcard3 = 1'b1;
+
+ #10;
+
+ check(4'd7, 4'd0, `EIGHT, `NINE, `BLANK, `JACK, `QUEEN, `KING);
+ load_dcard3 = 1'b0;
+
+ /* Reset. */
+
+ $display("Test 3.6");
+
+ resetb = 1'b0;
+
+ #10;
+
+ check(4'd0, 4'd0, `BLANK, `BLANK, `BLANK, `BLANK, `BLANK, `BLANK);
+ resetb = 1'b1;
-// Your testbench goes here. Make sure your tests exercise the entire design
-// in the .sv file. Note that in our tests the simulator will exit after
-// 10,000 ticks (equivalent to "initial #10000 $finish();").
+ if (~err)
+ $display("All tests passed.");
-endmodule
+ #10;
+ $stop;
+ end
+endmodule: tb_datapath
diff --git a/task5/tb_scorehand.sv b/task5/tb_scorehand.sv
index 0d8f9d8..721cfb0 100644
--- a/task5/tb_scorehand.sv
+++ b/task5/tb_scorehand.sv
@@ -1,7 +1,108 @@
module tb_scorehand();
+ logic err;
+ logic [3:0] card1, card2, card3, total;
+ scorehand DUT(card1, card2, card3, total);
-// Your testbench goes here. Make sure your tests exercise the entire design
-// in the .sv file. Note that in our tests the simulator will exit after
-// 10,000 ticks (equivalent to "initial #10000 $finish();").
+ task check;
+ input logic [3:0] expected;
+ if (total !== expected) begin
+ err = 1;
+ $display("FAILED: total is incorrect.");
+ end
+ endtask: check;
-endmodule
+ initial begin
+ #10000;
+ $stop;
+ end
+
+ initial begin
+ err = 0;
+
+ /* (9 + 9 + 9) % 10 = 7. */
+
+ $display("Test 1");
+ card1 = 4'd9;
+ card2 = 4'd9;
+ card3 = 4'd9;
+ #5;
+ check(4'd7);
+ #5;
+
+ /* (9 + 9 + 0) % 10 = 8. */
+
+ $display("Test 2");
+ card1 = 4'd9;
+ card2 = 4'd9;
+ card3 = 4'd0;
+ #5;
+ check(4'd8);
+ #5;
+
+ /* (T + K + A) % 10 = 1. */
+
+ $display("Test 3");
+ card1 = 4'd10;
+ card2 = 4'd13;
+ card3 = 4'd1;
+ #5;
+ check(4'd1);
+ #5;
+
+ /* (J + Q + K) % 10 = 0. */
+
+ $display("Test 4");
+ card1 = 4'd11;
+ card2 = 4'd12;
+ card3 = 4'd13;
+ #5;
+ check(4'd0);
+ #5;
+
+ /* (A + 2 + 3) % 10 = 6. */
+
+ $display("Test 5");
+ card1 = 4'd1;
+ card2 = 4'd2;
+ card3 = 4'd3;
+ #5;
+ check(4'd6);
+ #5;
+
+ /* (9 + 0 + 0) % 10 = 9. */
+
+ $display("Test 6");
+ card1 = 4'd9;
+ card2 = 4'd0;
+ card3 = 4'd0;
+ #5;
+ check(4'd9);
+ #5;
+
+ /* (9 + T + 0) % 10 = 9. */
+
+ $display("Test 7");
+ card1 = 4'd9;
+ card2 = 4'd10;
+ card3 = 4'd0;
+ #5;
+ check(4'd9);
+ #5;
+
+ /* (9 + A + 0) % 10 = 0. */
+
+ $display("Test 8");
+ card1 = 4'd9;
+ card2 = 4'd1;
+ card3 = 4'd0;
+ #5;
+ check(4'd0);
+ #5;
+
+ if (~err)
+ $display("All tests passed.");
+
+ #10;
+ $stop;
+ end
+endmodule: tb_scorehand
diff --git a/task5/tb_statemachine.sv b/task5/tb_statemachine.sv
index 032359f..da4c601 100644
--- a/task5/tb_statemachine.sv
+++ b/task5/tb_statemachine.sv
@@ -1,7 +1,267 @@
module tb_statemachine();
+ logic err, slow_clock, resetb, load_pcard1, load_pcard2, load_pcard3,
+ load_dcard1, load_dcard2, load_dcard3,
+ player_win_light, dealer_win_light;
+ logic [3:0] dscore, pscore, pcard3;
-// Your testbench goes here. Make sure your tests exercise the entire design
-// in the .sv file. Note that in our tests the simulator will exit after
-// 10,000 ticks (equivalent to "initial #10000 $finish();").
+ statemachine DUT(slow_clock, resetb, dscore, pscore, pcard3,
+ load_pcard1, load_pcard2, load_pcard3,
+ load_dcard1, load_dcard2, load_dcard3,
+ player_win_light, dealer_win_light);
-endmodule
+ task check;
+ input logic [7:0] expected;
+
+ if (load_pcard1 !== expected[7]) begin
+ err = 1;
+ $display("FAILED: load_pcard1 is incorrect.",);
+ end
+ if (load_pcard2 !== expected[6]) begin
+ err = 1;
+ $display("FAILED: load_pcard2 is incorrect.",);
+ end
+ if (load_pcard3 !== expected[5]) begin
+ err = 1;
+ $display("FAILED: load_pcard3 is incorrect.",);
+ end
+ if (load_dcard1 !== expected[4]) begin
+ err = 1;
+ $display("FAILED: load_dcard1 is incorrect.",);
+ end
+ if (load_dcard2 !== expected[3]) begin
+ err = 1;
+ $display("FAILED: load_dcard2 is incorrect.",);
+ end
+ if (load_dcard3 !== expected[2]) begin
+ err = 1;
+ $display("FAILED: load_dcard3 is incorrect.",);
+ end
+ if (player_win_light !== expected[1]) begin
+ err = 1;
+ $display("FAILED: player_win_light is incorrect.",);
+ end
+ if (dealer_win_light !== expected[0]) begin
+ err = 1;
+ $display("FAILED: dealer_win_light is incorrect.",);
+ end
+ endtask: check
+
+ initial forever begin
+ slow_clock = 1'b0;
+ #5;
+ slow_clock = 1'b1;
+ #5;
+ end
+
+ initial begin
+ #10000;
+ $stop;
+ end
+
+ initial begin
+ err = 0;
+ pcard3 = 4'b0;
+
+ /* Natural 9 vs natural 8: deal four cards, player win. */
+
+ $display("Test 1");
+
+ resetb = 1'b0;
+ pscore = 4'd9;
+ dscore = 4'd8;
+
+ #10;
+
+ resetb = 1'b1;
+
+ check(8'b10000000); #10;
+ check(8'b00010000); #10;
+ check(8'b01000000); #10;
+ check(8'b00001000); #10;
+ check(8'b00000000); #10;
+ check(8'b00000010); #10;
+
+ /* Natural 8 vs natural 9: deal four cards, dealer win. */
+
+ $display("Test 2");
+
+ resetb = 1'b0;
+ pscore = 4'd8;
+ dscore = 4'd9;
+
+ #10;
+
+ resetb = 1'b1;
+
+ check(8'b10000000); #10;
+ check(8'b00010000); #10;
+ check(8'b01000000); #10;
+ check(8'b00001000); #10;
+ check(8'b00000000); #10;
+ check(8'b00000001); #10;
+
+ /* 7 vs 6: deal four cards, player win. */
+
+ $display("Test 3");
+
+ resetb = 1'b0;
+ pscore = 4'd7;
+ dscore = 4'd6;
+
+ #10;
+
+ resetb = 1'b1;
+
+ check(8'b10000000); #10;
+ check(8'b00010000); #10;
+ check(8'b01000000); #10;
+ check(8'b00001000); #10;
+ check(8'b00000000); #10;
+ check(8'b00000010); #10;
+
+ /* 7 vs 5: player stands, dealer hits, dealer win. */
+
+ $display("Test 4");
+
+ resetb = 1'b0;
+ pscore = 4'd7;
+ dscore = 4'd5;
+
+ #10;
+
+ resetb = 1'b1;
+
+ check(8'b10000000); #10;
+ check(8'b00010000); #10;
+ check(8'b01000000); #10;
+ check(8'b00001000); #10;
+
+ /* Dealer 3rd card is a 3. */
+ check(8'b00000100);
+ dscore = 4'd8;
+ #10;
+
+ check(8'b00000001); #10;
+
+ /* 3 vs 4: player hits and gets 7, dealer hits, dealer win. */
+
+ $display("Test 5");
+
+ resetb = 1'b0;
+ pscore = 4'd3;
+ dscore = 4'd4;
+
+ #10;
+
+ resetb = 1'b1;
+
+ check(8'b10000000); #10;
+ check(8'b00010000); #10;
+ check(8'b01000000); #10;
+ check(8'b00001000); #10;
+
+ /* Player draws a 7. */
+ pcard3 = 4'd7;
+ pscore = 4'b0;
+ check(8'b00100000);
+ #10;
+
+ /* Dealer 3rd card is a 3. */
+ check(8'b00000100);
+ dscore = 4'd8;
+ #10;
+
+ check(8'b00000001); #10;
+
+ /* 0 vs 3: player hits and gets 8, dealer stands, player win. */
+
+ $display("Test 6");
+
+ resetb = 1'b0;
+ pscore = 4'd0;
+ dscore = 4'd3;
+
+ #10;
+
+ resetb = 1'b1;
+
+ check(8'b10000000); #10;
+ check(8'b00010000); #10;
+ check(8'b01000000); #10;
+ check(8'b00001000); #10;
+
+ /* Player draws a 8. */
+ pcard3 = 4'd8;
+ pscore = 4'd8;
+ check(8'b00100000);
+ #10;
+
+ check(8'b00000010); #10;
+
+ /* 5 vs 0: player hits and gets 9, dealer hits, tie. */
+
+ $display("Test 7");
+
+ resetb = 1'b0;
+ pscore = 4'd5;
+ dscore = 4'd0;
+
+ #10;
+
+ resetb = 1'b1;
+
+ check(8'b10000000); #10;
+ check(8'b00010000); #10;
+ check(8'b01000000); #10;
+ check(8'b00001000); #10;
+
+ /* Player draws a 9. */
+ pcard3 = 4'd9;
+ pscore = 4'd4;
+ check(8'b00100000);
+ #10;
+
+ /* Dealer 3rd card is a 4. */
+ check(8'b00000100);
+ dscore = 4'd4;
+ #10;
+
+ check(8'b00000011); #10;
+
+ /* 5 vs 0: player hits and gets 9, dealer hits, dealer win. */
+
+ $display("Test 8");
+
+ resetb = 1'b0;
+ pscore = 4'd5;
+ dscore = 4'd0;
+
+ #10;
+
+ resetb = 1'b1;
+
+ check(8'b10000000); #10;
+ check(8'b00010000); #10;
+ check(8'b01000000); #10;
+ check(8'b00001000); #10;
+
+ /* Player draws a 9. */
+ pcard3 = 4'd9;
+ pscore = 4'd4;
+ check(8'b00100000);
+ #10;
+
+ /* Dealer 3rd card is a 5. */
+ check(8'b00000100);
+ dscore = 4'd5;
+ #10;
+
+ check(8'b00000001); #10;
+
+ if (~err)
+ $display("All tests passed.");
+
+ #10;
+ $stop;
+ end
+endmodule: tb_statemachine
diff --git a/task5/tb_task5.sv b/task5/tb_task5.sv
index 934e417..acca80c 100644
--- a/task5/tb_task5.sv
+++ b/task5/tb_task5.sv
@@ -1,7 +1,255 @@
+`define ACE 7'b0001000
+`define TWO 7'b0100100
+`define THREE 7'b0110000
+`define FOUR 7'b0011001
+`define FIVE 7'b0010010
+`define SIX 7'b0000010
+`define SEVEN 7'b1111000
+`define EIGHT 7'b0000000
+`define NINE 7'b0010000
+`define TEN 7'b1000000
+`define JACK 7'b1100001
+`define QUEEN 7'b0011000
+`define KING 7'b0001001
+`define BLANK 7'b1111111
+
module tb_task5();
+ logic err, resetb, slow_clock, CLOCK_50;
+ logic [3:0] KEY;
+ logic [6:0] HEX0, HEX1, HEX2, HEX3, HEX4, HEX5;
+ logic [9:0] LEDR;
+
+ assign KEY[0] = slow_clock;
+ assign KEY[3] = resetb;
+
+ task5 DUT(CLOCK_50, KEY, LEDR, HEX5, HEX4, HEX3, HEX2, HEX1, HEX0);
+
+ task check;
+ input logic [6:0] expected_HEX0, expected_HEX1, expected_HEX2,
+ expected_HEX3, expected_HEX4, expected_HEX5;
+ input logic [9:0] expected_LEDR;
+
+ if (HEX0 !== expected_HEX0) begin
+ err = 1;
+ $display("FAILED: HEX0 is incorrect.",);
+ end
+ if (HEX1 !== expected_HEX1) begin
+ err = 1;
+ $display("FAILED: HEX1 is incorrect.",);
+ end
+ if (HEX2 !== expected_HEX2) begin
+ err = 1;
+ $display("FAILED: HEX2 is incorrect.",);
+ end
+ if (HEX3 !== expected_HEX3) begin
+ err = 1;
+ $display("FAILED: HEX3 is incorrect.",);
+ end
+ if (HEX4 !== expected_HEX4) begin
+ err = 1;
+ $display("FAILED: HEX4 is incorrect.",);
+ end
+ if (HEX5 !== expected_HEX5) begin
+ err = 1;
+ $display("FAILED: HEX5 is incorrect.",);
+ end
+ if (LEDR !== expected_LEDR) begin
+ err = 1;
+ $display("FAILED: LEDR is incorrect.",);
+ end
+ endtask: check
+
+ initial forever begin
+ slow_clock = 1'b0;
+ #5;
+ slow_clock = 1'b1;
+ #5;
+ end
+
+ initial begin
+ err = 0;
+
+ /* Reset. */
+
+ $display("Test 1");
+
+ resetb = 1'b0;
+
+ #10;
+
+ resetb = 1'b1;
+
+ check(`BLANK, `BLANK, `BLANK, `BLANK, `BLANK, `BLANK, 10'b00_0000_0000);
+
+ /* Test for natural win. Player: 9T, dealer: A2. */
+
+ $display("Test 2.1");
+
+ force tb_task5.DUT.dp.new_card = 4'd9;
+
+ #10;
+
+ check(`NINE, `BLANK, `BLANK, `BLANK, `BLANK, `BLANK, 10'b00_0000_1001);
+
+ $display("Test 2.2");
+
+ force tb_task5.DUT.dp.new_card = 4'd1;
+
+ #10;
+
+ check(`NINE, `BLANK, `BLANK, `ACE, `BLANK, `BLANK, 10'b00_0001_1001);
+
+ $display("Test 2.3");
+
+ force tb_task5.DUT.dp.new_card = 4'd10;
+
+ #10;
+
+ check(`NINE, `TEN, `BLANK, `ACE, `BLANK, `BLANK, 10'b00_0001_1001);
+
+ $display("Test 2.4");
+
+ force tb_task5.DUT.dp.new_card = 4'd2;
+
+ #10;
+
+ check(`NINE, `TEN, `BLANK, `ACE, `TWO, `BLANK, 10'b00_0011_1001);
+
+ $display("Test 2.5");
+
+ /* Load anything. */
+ force tb_task5.DUT.dp.new_card = 4'd10;
+
+ #10;
+
+ check(`NINE, `TEN, `BLANK, `ACE, `TWO, `BLANK, 10'b01_0011_1001);
+
+ $display("Test 2.6");
+
+ resetb = 1'b0;
+
+ #10;
+
+ resetb = 1'b1;
+
+ check(`BLANK, `BLANK, `BLANK, `BLANK, `BLANK, `BLANK, 10'b00_0000_0000);
+
+ /* Test for player stand, dealer hit. Player: 34, dealer: 678. */
+
+ $display("Test 3.1");
+
+ force tb_task5.DUT.dp.new_card = 4'd3;
+
+ #10;
+
+ check(`THREE, `BLANK, `BLANK, `BLANK, `BLANK, `BLANK, 10'b00_0000_0011);
+
+ $display("Test 3.2");
+
+ force tb_task5.DUT.dp.new_card = 4'd6;
+
+ #10;
+
+ check(`THREE, `BLANK, `BLANK, `SIX, `BLANK, `BLANK, 10'b00_0110_0011);
+
+ $display("Test 3.3");
+
+ force tb_task5.DUT.dp.new_card = 4'd4;
+
+ #10;
+
+ check(`THREE, `FOUR, `BLANK, `SIX, `BLANK, `BLANK, 10'b00_0110_0111);
+
+ $display("Test 3.4");
+
+ force tb_task5.DUT.dp.new_card = 4'd7;
+
+ #10;
+
+ check(`THREE, `FOUR, `BLANK, `SIX, `SEVEN, `BLANK, 10'b00_0011_0111);
+
+ $display("Test 3.5");
+
+ force tb_task5.DUT.dp.new_card = 4'd8;
+
+ #10;
+
+ check(`THREE, `FOUR, `BLANK, `SIX, `SEVEN, `EIGHT, 10'b01_0001_0111);
+
+ $display("Test 3.6");
+
+ resetb = 1'b0;
+
+ #10;
+
+ resetb = 1'b1;
+
+ check(`BLANK, `BLANK, `BLANK, `BLANK, `BLANK, `BLANK, 10'b00_0000_0000);
+
+ /* Test for player hit, dealer hit. Player: 4JQ, dealer: 672. */
+
+ $display("Test 4.1");
+
+ force tb_task5.DUT.dp.new_card = 4'd4;
+
+ #10;
+
+ check(`FOUR, `BLANK, `BLANK, `BLANK, `BLANK, `BLANK, 10'b00_0000_0100);
+
+ $display("Test 4.2");
+
+ force tb_task5.DUT.dp.new_card = 4'd6;
+
+ #10;
+
+ check(`FOUR, `BLANK, `BLANK, `SIX, `BLANK, `BLANK, 10'b00_0110_0100);
+
+ $display("Test 4.3");
+
+ force tb_task5.DUT.dp.new_card = 4'd11;
+
+ #10;
+
+ check(`FOUR, `JACK, `BLANK, `SIX, `BLANK, `BLANK, 10'b00_0110_0100);
+
+ $display("Test 4.4");
+
+ force tb_task5.DUT.dp.new_card = 4'd7;
+
+ #10;
+
+ check(`FOUR, `JACK, `BLANK, `SIX, `SEVEN, `BLANK, 10'b00_0011_0100);
+
+ $display("Test 4.5");
+
+ force tb_task5.DUT.dp.new_card = 4'd12;
+
+ #10;
+
+ check(`FOUR, `JACK, `QUEEN, `SIX, `SEVEN, `BLANK, 10'b00_0011_0100);
+
+ $display("Test 4.6");
+
+ force tb_task5.DUT.dp.new_card = 4'd2;
+
+ #10;
+
+ check(`FOUR, `JACK, `QUEEN, `SIX, `SEVEN, `BLANK, 10'b01_0011_0100);
+
+ $display("Test 4.7");
+
+ resetb = 1'b0;
+
+ #10;
+
+ resetb = 1'b1;
+
+ check(`BLANK, `BLANK, `BLANK, `BLANK, `BLANK, `BLANK, 10'b00_0000_0000);
-// Your testbench goes here. Make sure your tests exercise the entire design
-// in the .sv file. Note that in our tests the simulator will exit after
-// 100,000 ticks (equivalent to "initial #100000 $finish();").
+ if (~err)
+ $display("All tests passed.");
-endmodule
+ #10;
+ $stop;
+ end
+endmodule: tb_task5
diff --git a/task5/vish_stacktrace.vstf b/task5/vish_stacktrace.vstf
new file mode 100644
index 0000000..cf80805
--- /dev/null
+++ b/task5/vish_stacktrace.vstf
@@ -0,0 +1,32 @@
+# Current time Wed Feb 04 08:26:32 2026
+# ModelSim - Intel FPGA Edition Stack Trace
+# Program = vish
+# Id = "2020.1"
+# Version = "2020.02"
+# Date = "Feb 28 2020"
+# Platform = win32pe
+
+Exception c0000005 has occurred at address 006430e7. Traceback:
+# 0 0x006430e7: 'WinMain + 0xe9d57'
+# 1 0x0064ebd4: 'WinMain + 0xf5844'
+# 2 0x006503ef: 'WinMain + 0xf705f'
+# 3 0x0065060b: 'WinMain + 0xf727b'
+# 4 0x6c9539f1: 'TclNREvalObjv + 0x3e1'
+StackWalk failed 299
+# End of Stack Trace
+
+# Current time Wed Feb 04 14:27:24 2026
+# ModelSim - Intel FPGA Edition Stack Trace
+# Program = vish
+# Id = "2020.1"
+# Version = "2020.02"
+# Date = "Feb 28 2020"
+# Platform = win32pe
+
+Exception c0000005 has occurred at address 6cd89e6f. Traceback:
+# 0 0x6cd89e6f: 'Tcl_GetString + 0xf'
+# 1 0x6cd71f5a: 'TclListObjSetElement + 0x31a'
+# 2 0x6cce3a49: 'TclNRRunCallbacks + 0x49'
+StackWalk failed 299
+# End of Stack Trace
+