From 969ad757896924dd09f8b58a949129a08e320df1 Mon Sep 17 00:00:00 2001
From: TimRudy <3942818+TimRudy@users.noreply.github.com>
Date: Sun, 4 Oct 2020 22:23:47 -0400
Subject: [PATCH] More initial
---
device-index.md | 1 +
source-7400/74181-tb.v | 2742 ++++++++++++++++++++++++++++++++++++++++
source-7400/74181.v | 318 +++++
3 files changed, 3061 insertions(+)
create mode 100644 source-7400/74181-tb.v
create mode 100644 source-7400/74181.v
diff --git a/device-index.md b/device-index.md
index f03bcee..d924049 100644
--- a/device-index.md
+++ b/device-index.md
@@ -43,6 +43,7 @@
## Comparators, Adders, Arithmetic Logic Units
[7485](source-7400/7485.v) 4-bit magnitude comparator
+[74181](source-7400/74181.v) 4-bit arithmetic logic unit
[74283](source-7400/74283.v) 4-bit binary full adder with fast carry
## Flip-Flops
diff --git a/source-7400/74181-tb.v b/source-7400/74181-tb.v
new file mode 100644
index 0000000..22dc53a
--- /dev/null
+++ b/source-7400/74181-tb.v
@@ -0,0 +1,2742 @@
+// Test: 4-bit arithmetic logic unit
+
+// Notes:
+//
+// - active-high data convention is used for all tests below (unless specially indicated);
+// see datasheet for differences between active-high and active-low data convention;
+// for many of the Select inputs, the data convention used affects the operation performed;
+// however, the following operations are consistent and unaffected by active-high or active-low:
+// Select == 1001 (Add)
+// Select == 0110 (Subtract)
+// Select == 1100 (A PLUS A or Shift Left)
+// Select == 0011 (MINUS 1)
+//
+// - Mode == 0 is for arithmetic (carry is included in calculations);
+// Mode == 1 is for logic (carry is irrelevant)
+//
+// - C_in, C_out carry signals are inverted compared to A, B and F signals;
+// for example, with active-high data, A_bar == 0 means zero, C_in == 1 means no carry in
+//
+// - CP_bar output is carry propagate to another unit (for carry lookahead across multiple units);
+// CG_bar output is carry generate to another unit ( " " )
+//
+// - Equal flag output is a valid comparator output only in a specific configuration:
+// the operation must be Select == 0110 (Subtract) with C_in == 1;
+// also in this configuration, Equal and C_out can be used together to indicate B < A or B > A
+//
+// * see notes below explaining the Subtract operation, its range of values and use of the carry
+//
+// * see IceChips Technical Notes regarding performance and carry lookahead: in particular, be aware
+// that there is a compromise in using this device with arbitrary WIDTH parameter greater than
+// design value of 4; for a real-world application, where performance is concerned, you will want
+// to use carry lookahead that is hierarchical, meaning multiple 74181 units and a 74182 unit
+//
+// * refer to the datasheets of the 74181 and the 74182 for information on using CP_bar and CG_bar
+// to create carry lookahead across multiple devices
+
+module test;
+
+`TBASSERT_METHOD(tbassert)
+`TBASSERT_2_METHOD(tbassert2)
+`TBASSERT_2R_METHOD(tbassert2R)
+`TBASSERT_2I_METHOD(tbassert2I)
+`CASE_TBASSERT_2R_METHOD(case_tbassert2R, tbassert2R)
+`CASE_TBASSERT_2I_METHOD(case_tbassert2I, tbassert2I)
+
+localparam WIDTH = 5;
+
+// DUT inputs
+reg [3:0] Select;
+reg Mode;
+reg C_in;
+reg [WIDTH-1:0] A_bar;
+reg [WIDTH-1:0] B_bar;
+
+// DUT outputs
+wire CP_bar;
+wire CG_bar;
+wire Equal;
+wire C_out;
+wire [WIDTH-1:0] F_bar;
+
+// DUT
+ttl_74181 #(.WIDTH(WIDTH), .DELAY_RISE(5), .DELAY_FALL(3)) dut(
+ .Select(Select),
+ .Mode(Mode),
+ .C_in(C_in),
+ .A_bar(A_bar),
+ .B_bar(B_bar),
+ .CP_bar(CP_bar),
+ .CG_bar(CG_bar),
+ .Equal(Equal),
+ .C_out(C_out),
+ .F_bar(F_bar)
+);
+
+initial
+begin
+ integer i;
+ integer j;
+ integer k;
+ reg C_in_value;
+ reg [WIDTH-1:0] A_value;
+ reg [WIDTH-1:0] B_value;
+ reg C_out_value;
+ reg [WIDTH-1:0] F_value;
+
+ $dumpfile("74181-tb.vcd");
+ $dumpvars;
+
+ // the following set of tests are for: arithmetic
+
+ Mode = 1'b0;
+
+ // the following set of tests are for: arithmetic: add
+
+ // Notes:
+ //
+ // 1. the Carry signals are inverted compared to the A, B and F signals:
+ // C_in == 1 is a no carry
+ // C_out == 1 is a no carry
+ //
+ // 2. value of Carry output:
+ // the Carry output, if present, contributes the positional value of 1 in the next group
+ // of 5 bits: 1<<5 == 32
+ //
+ // 3. details about the Carry Propagate (CP_bar) and Carry Generate (CG_bar) output signals:
+ //
+ // * in this note, number of bits will refer to the device design value of 4, rather than
+ // the number of bits in this test bench; correspondingly, the maximum representable value
+ // will be 15 in context of this discussion
+ //
+ // - the signals are only meaningful for Add and Subtract operations; they do not have meaning
+ // for the other 14 arithmetic operations
+ //
+ // - the signals are used in the context of multiple units operating on a longer word length:
+ // the adjacent (higher) unit needs to know this unit's Carry output (its Carry input);
+ // the Carry value can be determined in a faster manner than by waiting for each internal
+ // Carry to ripple through the bit calculations of this unit; instead, the calculation is
+ // parallelized by gathering the overall magnitude given by A and B inputs, and using this
+ // as threshold/overflow information as follows
+ //
+ // - the magnitude of all 4 A and B inputs summed together is either below the threshold
+ // (there will be no Carry output); or above the threshold at value 16 or greater, meaning
+ // there is overflow (a Carry output); or equal to the threshold at value 15, where overflow
+ // will or will not occur depending on the Carry input
+ //
+ // - "Carry Generate" indicates that unconditionally there must be a Carry output, since
+ // the magnitude is already an overflow value (16 or greater)
+ //
+ // - "Carry Propagate" indicates that there will be a Carry output precisely if
+ // there is a Carry input (magnitude is at the threshold 15)
+ //
+ // - by definition the signals are independent of the Carry input; this is important in their
+ // functional purpose, which is at the longer word length; the purpose is to feed the Carry
+ // input at the lowest bit directly into calculating the Carry input at the next unit's
+ // lowest bit, with minimal gate delay (hence: carry lookahead, and there is no ripple carry)
+ //
+ // - external logic is required for this: the Carry input of this unit is gated together
+ // with Carry Propagate and Carry Generate to create the next unit's Carry input
+ //
+ // - the speed-up obtained by using the CP_bar and CG_bar signals becomes more significant
+ // as the number of 74181 units rises
+ //
+ // for Add, the information provided by the signals is as follows:
+ //
+ // a) if using active-low data convention:
+ //
+ // - CP_bar and CG_bar are active-low: a 0 gives the indication
+ // - CP_bar alone indicates that result F == 15
+ // - CG_bar alone indicates that result F >= 16 (overflow)
+ //
+ // b) if using active-high data convention:
+ //
+ // - CP_bar and CG_bar are active-high: a 1 gives the indication
+ // - roles are swapped: CG_bar is Carry Propagate and CP_bar is Carry Generate
+ // - CG_bar alone indicates that result F == 15
+ // - CG_bar and CP_bar together indicate that result F >= 16 (overflow)
+ //
+ // c) this table summarizes the signal values:
+ //
+ // Convention Range CP_bar CG_bar
+ // ___________ ________ ______ ______
+ //
+ // active-low F < 15 1 1
+ // active-low F == 15 0 1
+ // active-low F > 15 X 0 (* CG_bar takes priority here)
+ //
+ // active-high F < 15 X 0 (* CG_bar takes priority here)
+ // active-high F == 15 0 1 (* this shows CG_bar acts as Carry Propagate)
+ // active-high F > 15 1 1
+ //
+ // * X is don't-care (it takes value 0 or 1 depending on inputs)
+ //
+ // * there are three sets of tests below to cover the ranges
+ //
+ // * these details are noted here in the interest of behavioural testing; however, the
+ // signal values do not need to concern the designer, because a 74182 or equivalent logic
+ // will receive CP_bar and CG_bar and pass the required signal to the adjacent 74181 unit
+ //
+ // 4. the function (independent of active-high or active-low data choice):
+ // Select == 4'b1001 is:
+ // F = A PLUS B PLUS Carry
+
+ Select = 4'b1001;
+
+ // all zeroes + Carry 0 -> Sum all 0s + Carry 0
+ A_bar = {WIDTH{1'b0}};
+ B_bar = {WIDTH{1'b0}};
+ C_in = 1'b1;
+#7
+ tbassert(F_bar == 5'b00000, "Test 1");
+ tbassert(C_out == 1'b1, "Test 1");
+ tbassert(CP_bar == 1'b0, "Test 1");
+ tbassert(CG_bar == 1'b0, "Test 1");
+ // * Note: is not an Equal comparison since operation is not arithmetic: subtract
+ tbassert(Equal == 1'b0, "Test 1");
+#0
+ // all ones (31 + 31) + Carry 1 -> Sum all 1s (31) + Carry 1 (1<<5 == 32)
+ A_bar = {WIDTH{1'b1}};
+ B_bar = {WIDTH{1'b1}};
+ C_in = 1'b0;
+#6
+ tbassert(F_bar == 5'b11111, "Test 2");
+ tbassert(C_out == 1'b0, "Test 2");
+ tbassert(CP_bar == 1'b1, "Test 2");
+ tbassert(CG_bar == 1'b1, "Test 2");
+ // * Note: is not an Equal comparison since operation is not arithmetic: subtract
+ // * Note: beyond this, the Equal output test will be skipped until arithmetic: subtract
+ tbassert(Equal == 1'b1, "Test 2");
+#0
+
+ // repeat tests: Carry input is set then clear (meaning, respectively, no Carry then Carry)
+
+ for (i = 3; i <= 4; i++)
+ begin
+ case (i)
+ 3:
+ begin
+ C_in = 1'b1;
+ end
+ 4:
+ begin
+ C_in = 1'b0;
+ end
+ endcase
+
+ // the following set of tests show the Carry output unaffected by the Carry input
+ // (Carry output is Carry 0)
+
+ // 1 + 1 -> 2 + Carry input
+ A_bar = 5'b00001;
+ B_bar = 5'b00001;
+#10
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b00010, "Test", "1", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b00011, "Test", "1", i);
+ tbassert2R(C_out == 1'b1, "Test", "1", i);
+ tbassert2R(CP_bar == 1'b1, "Test", "1", i);
+ tbassert2R(CG_bar == 1'b0, "Test", "1", i);
+#0
+ // 1 + 2 -> 3 + Carry input
+ // A_bar = 5'b00001;
+ B_bar = 5'b00010;
+#10
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b00011, "Test", "2", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b00100, "Test", "2", i);
+ tbassert2R(C_out == 1'b1, "Test", "2", i);
+ tbassert2R(CP_bar == 1'b0, "Test", "2", i);
+ tbassert2R(CG_bar == 1'b0, "Test", "2", i);
+#0
+ // same on the other inputs
+ A_bar = 5'b00010;
+ B_bar = 5'b00001;
+#10
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b00011, "Test", "3", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b00100, "Test", "3", i);
+ tbassert2R(C_out == 1'b1, "Test", "3", i);
+ tbassert2R(CP_bar == 1'b0, "Test", "3", i);
+ tbassert2R(CG_bar == 1'b0, "Test", "3", i);
+#0
+
+ // the following set of tests show the Carry output affected by the Carry input
+
+ // zeroes on either side and all ones (0 + 31) -> Sum all 1s (31) + Carry input
+ A_bar = 5'b00000;
+ B_bar = 5'b11111;
+#10
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b11111, "Test", "4", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b00000, "Test", "4", i);
+ case_tbassert2R(C_in == 1'b1, C_out == 1'b1, "Test", "4", i);
+ case_tbassert2R(C_in == 1'b0, C_out == 1'b0, "Test", "4", i);
+ tbassert2R(CP_bar == 1'b0, "Test", "4", i);
+ tbassert2R(CG_bar == 1'b1, "Test", "4", i);
+#0
+ // same on the other inputs
+ A_bar = 5'b11111;
+ B_bar = 5'b00000;
+#10
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b11111, "Test", "5", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b00000, "Test", "5", i);
+ case_tbassert2R(C_in == 1'b1, C_out == 1'b1, "Test", "5", i);
+ case_tbassert2R(C_in == 1'b0, C_out == 1'b0, "Test", "5", i);
+ tbassert2R(CP_bar == 1'b0, "Test", "5", i);
+ tbassert2R(CG_bar == 1'b1, "Test", "5", i);
+#0
+ // 16 + 15 -> 31 + Carry input
+ A_bar = 5'b10000;
+ B_bar = 5'b01111;
+#10
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b11111, "Test", "6", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b00000, "Test", "6", i);
+ case_tbassert2R(C_in == 1'b1, C_out == 1'b1, "Test", "6", i);
+ case_tbassert2R(C_in == 1'b0, C_out == 1'b0, "Test", "6", i);
+ tbassert2R(CP_bar == 1'b0, "Test", "6", i);
+ tbassert2R(CG_bar == 1'b1, "Test", "6", i);
+#0
+ // all input bits transition from previous (15 + 16) -> 31 + Carry input
+ A_bar = 5'b01111;
+ B_bar = 5'b10000;
+ C_in = ~C_in;
+#10
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b11111, "Test", "7", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b00000, "Test", "7", i);
+ case_tbassert2R(C_in == 1'b1, C_out == 1'b1, "Test", "7", i);
+ case_tbassert2R(C_in == 1'b0, C_out == 1'b0, "Test", "7", i);
+ tbassert2R(CP_bar == 1'b0, "Test", "7", i);
+ tbassert2R(CG_bar == 1'b1, "Test", "7", i);
+#0
+ C_in = ~C_in;
+#10
+
+ // the following set of tests show the Carry output unaffected by the Carry input
+ // (Carry output is Carry 1)
+
+ // 16 + 16 -> 32 + Carry input
+ A_bar = 5'b10000;
+ B_bar = 5'b10000;
+#10
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b00000, "Test", "8", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b00001, "Test", "8", i);
+ tbassert2R(C_out == 1'b0, "Test", "8", i);
+ tbassert2R(CP_bar == 1'b1, "Test", "8", i);
+ tbassert2R(CG_bar == 1'b1, "Test", "8", i);
+#0
+ // 16 + 18 -> 34 + Carry input
+ // A_bar = 5'b10000;
+ B_bar = 5'b10010;
+#10
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b00010, "Test", "9", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b00011, "Test", "9", i);
+ tbassert2R(C_out == 1'b0, "Test", "9", i);
+ tbassert2R(CP_bar == 1'b1, "Test", "9", i);
+ tbassert2R(CG_bar == 1'b1, "Test", "9", i);
+#0
+ // 16 + 17 -> 33 + Carry input
+ // A_bar = 5'b10000;
+ B_bar = 5'b10001;
+#10
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b00001, "Test", "10", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b00010, "Test", "10", i);
+ tbassert2R(C_out == 1'b0, "Test", "10", i);
+ tbassert2R(CP_bar == 1'b1, "Test", "10", i);
+ tbassert2R(CG_bar == 1'b1, "Test", "10", i);
+#0
+
+ // the following set of tests show the Carry output unaffected by the Carry input
+ // (Carry output is Carry 0)
+
+ // all input bits transition from previous (15 + 14) -> 29 + Carry input
+ A_bar = 5'b01111;
+ B_bar = 5'b01110;
+ C_in = ~C_in;
+#10
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b11101, "Test", "11", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b11110, "Test", "11", i);
+ tbassert2R(C_out == 1'b1, "Test", "11", i);
+ tbassert2R(CP_bar == 1'b1, "Test", "11", i);
+ tbassert2R(CG_bar == 1'b0, "Test", "11", i);
+#0
+ C_in = ~C_in;
+
+ end
+
+ // end repeat tests
+#0
+
+ // 2 + 2 + Carry 0 -> 4
+ A_bar = 5'b00010;
+ B_bar = 5'b00010;
+ C_in = 1'b1;
+#6
+ tbassert(F_bar == 5'b00100, "Test 5");
+ tbassert(C_out == 1'b1, "Test 5");
+ tbassert(CP_bar == 1'b1, "Test 5");
+ tbassert(CG_bar == 1'b0, "Test 5");
+#0
+ // 2 + 2 + Carry 1 -> 5
+ // A_bar = 5'b00010;
+ // B_bar = 5'b00010;
+ C_in = 1'b0;
+#6
+ tbassert(F_bar == 5'b00101, "Test 6");
+ tbassert(C_out == 1'b1, "Test 6");
+ tbassert(CP_bar == 1'b1, "Test 6");
+ tbassert(CG_bar == 1'b0, "Test 6");
+#0
+ // 3 + 5 + Carry 1 -> 9
+ A_bar = 5'b00011;
+ B_bar = 5'b00101;
+ C_in = 1'b0;
+#6
+ tbassert(F_bar == 5'b01001, "Test 7");
+ tbassert(C_out == 1'b1, "Test 7");
+ tbassert(CP_bar == 1'b1, "Test 7");
+ tbassert(CG_bar == 1'b0, "Test 7");
+#0
+ // 13 + 13 + Carry 1 -> 27
+ A_bar = 5'b01101;
+ B_bar = 5'b01101;
+ C_in = 1'b0;
+#6
+ tbassert(F_bar == 5'b11011, "Test 8");
+ tbassert(C_out == 1'b1, "Test 8");
+ tbassert(CP_bar == 1'b1, "Test 8");
+ tbassert(CG_bar == 1'b0, "Test 8");
+#0
+ // 13 + 17 + Carry 1 -> 31
+ A_bar = 5'b01101;
+ B_bar = 5'b10001;
+ C_in = 1'b0;
+#6
+ tbassert(F_bar == 5'b11111, "Test 9");
+ tbassert(C_out == 1'b1, "Test 9");
+ tbassert(CP_bar == 1'b1, "Test 9");
+ tbassert(CG_bar == 1'b0, "Test 9");
+#0
+ // 17 + 17 + Carry 1 -> 35
+ A_bar = 5'b10001;
+ B_bar = 5'b10001;
+ C_in = 1'b0;
+#6
+ tbassert(F_bar == 5'b00011, "Test 10");
+ tbassert(C_out == 1'b0, "Test 10");
+ tbassert(CP_bar == 1'b1, "Test 10");
+ tbassert(CG_bar == 1'b1, "Test 10");
+#0
+ // 7 + 27 + Carry 1 -> 35
+ A_bar = 5'b00111;
+ B_bar = 5'b11011;
+ C_in = 1'b0;
+#6
+ tbassert(F_bar == 5'b00011, "Test 11");
+ tbassert(C_out == 1'b0, "Test 11");
+ tbassert(CP_bar == 1'b1, "Test 11");
+ tbassert(CG_bar == 1'b1, "Test 11");
+#0
+ // 19 + 31 + Carry 1 -> 51
+ A_bar = 5'b10011;
+ B_bar = 5'b11111;
+ C_in = 1'b0;
+#6
+ tbassert(F_bar == 5'b10011, "Test 12");
+ tbassert(C_out == 1'b0, "Test 12");
+ tbassert(CP_bar == 1'b1, "Test 12");
+ tbassert(CG_bar == 1'b1, "Test 12");
+#0
+ // 23 + 29 + Carry 0 -> 52
+ A_bar = 5'b10111;
+ B_bar = 5'b11101;
+ C_in = 1'b1;
+#6
+ tbassert(F_bar == 5'b10100, "Test 13");
+ tbassert(C_out == 1'b0, "Test 13");
+ tbassert(CP_bar == 1'b1, "Test 13");
+ tbassert(CG_bar == 1'b1, "Test 13");
+#0
+ // 23 + 29 + Carry 1 -> 53
+ // A_bar = 5'b10111;
+ // B_bar = 5'b11101;
+ C_in = 1'b0;
+#6
+ tbassert(F_bar == 5'b10101, "Test 14");
+ tbassert(C_out == 1'b0, "Test 14");
+ tbassert(CP_bar == 1'b1, "Test 14");
+ tbassert(CG_bar == 1'b1, "Test 14");
+#0
+
+ // the following set of tests show transitions between input bits that are set to ones
+ // with null effect on outputs
+
+ // 3 + 5 + Carry 0 -> 8
+ A_bar = 5'b00011;
+ B_bar = 5'b00101;
+ C_in = 1'b1;
+#6
+ tbassert(F_bar == 5'b01000, "Test 15");
+ tbassert(C_out == 1'b1, "Test 15");
+ tbassert(CP_bar == 1'b1, "Test 15");
+ tbassert(CG_bar == 1'b0, "Test 15");
+#0
+ // 2 + 5 + Carry 1 -> 8
+ A_bar = 5'b00010;
+ // B_bar = 5'b00101;
+ C_in = 1'b0;
+#6
+ tbassert(F_bar == 5'b01000, "Test 16");
+ tbassert(C_out == 1'b1, "Test 16");
+ tbassert(CP_bar == 1'b0, "Test 16");
+ tbassert(CG_bar == 1'b0, "Test 16");
+#0
+ // 19 + 29 + Carry 0 -> 48
+ A_bar = 5'b10011;
+ B_bar = 5'b11101;
+ C_in = 1'b1;
+#6
+ tbassert(F_bar == 5'b10000, "Test 17");
+ tbassert(C_out == 1'b0, "Test 17");
+ tbassert(CP_bar == 1'b1, "Test 17");
+ tbassert(CG_bar == 1'b1, "Test 17");
+#0
+ // 29 + 18 + Carry 1 -> 48
+ A_bar = 5'b11101;
+ B_bar = 5'b10010;
+ C_in = 1'b0;
+#6
+ tbassert(F_bar == 5'b10000, "Test 18");
+ tbassert(C_out == 1'b0, "Test 18");
+ tbassert(CP_bar == 1'b1, "Test 18");
+ tbassert(CG_bar == 1'b1, "Test 18");
+#25
+
+ // the following set of tests show the largest input values at which CG_bar output remains clear
+ // (CP_bar output is not necessarily clear in this range so CG_bar takes priority)
+ // (* because these tests use active-high data convention but the device pins are named
+ // according to active-low data convention, the roles of the two outputs as seen here
+ // are swapped: CG_bar is Carry Propagate and CP_bar is Carry Generate!)
+
+ // 14 + 16 + Carry 0 -> 30
+ A_bar = 5'b01110;
+ B_bar = 5'b10000;
+ C_in = 1'b1;
+#7
+ tbassert(F_bar == 5'b11110, "Test 19");
+ tbassert(C_out == 1'b1, "Test 19");
+ tbassert(CP_bar == 1'b0, "Test 19");
+ tbassert(CG_bar == 1'b0, "Test 19");
+#0
+ // 29 + 1 + Carry 0 -> 30
+ A_bar = 5'b11101;
+ B_bar = 5'b00001;
+ // C_in = 1'b1;
+#7
+ tbassert(F_bar == 5'b11110, "Test 20");
+ tbassert(C_out == 1'b1, "Test 20");
+ tbassert(CP_bar == 1'b1, "Test 20");
+ tbassert(CG_bar == 1'b0, "Test 20");
+#0
+ // 0 + 30 + Carry 0 -> 30
+ A_bar = 5'b00000;
+ B_bar = 5'b11110;
+ // C_in = 1'b1;
+#7
+ tbassert(F_bar == 5'b11110, "Test 21");
+ tbassert(C_out == 1'b1, "Test 21");
+ tbassert(CP_bar == 1'b0, "Test 21");
+ tbassert(CG_bar == 1'b0, "Test 21");
+#0
+ // 29 + 1 + Carry 1 -> 31
+ A_bar = 5'b11101;
+ B_bar = 5'b00001;
+ C_in = 1'b0;
+#7
+ tbassert(F_bar == 5'b11111, "Test 22");
+ tbassert(C_out == 1'b1, "Test 22");
+ tbassert(CP_bar == 1'b1, "Test 22");
+ tbassert(CG_bar == 1'b0, "Test 22");
+#0
+
+ // the following set of tests show the specific input values at which CG_bar output
+ // becomes set while CP_bar output remains clear
+ // (* because these tests use active-high data convention but the device pins are named
+ // according to active-low data convention, the roles of the two outputs as seen here
+ // are swapped: CG_bar is Carry Propagate and CP_bar is Carry Generate!)
+
+ // 10 + 21 + Carry 0 -> 31
+ A_bar = 5'b01010;
+ B_bar = 5'b10101;
+ C_in = 1'b1;
+#7
+ tbassert(F_bar == 5'b11111, "Test 23");
+ tbassert(C_out == 1'b1, "Test 23");
+ tbassert(CP_bar == 1'b0, "Test 23");
+ tbassert(CG_bar == 1'b1, "Test 23");
+#0
+ // 9 + 22 + Carry 1 -> 32
+ A_bar = 5'b01001;
+ B_bar = 5'b10110;
+ C_in = 1'b0;
+#7
+ tbassert(F_bar == 5'b00000, "Test 24");
+ tbassert(C_out == 1'b0, "Test 24");
+ tbassert(CP_bar == 1'b0, "Test 24");
+ tbassert(CG_bar == 1'b1, "Test 24");
+#0
+ // 26 + 5 + Carry 1 -> 32
+ A_bar = 5'b11010;
+ B_bar = 5'b00101;
+ C_in = 1'b0;
+#7
+ tbassert(F_bar == 5'b00000, "Test 25");
+ tbassert(C_out == 1'b0, "Test 25");
+ tbassert(CP_bar == 1'b0, "Test 25");
+ tbassert(CG_bar == 1'b1, "Test 25");
+#0
+ // 26 + 5 + Carry 0 -> 31
+ A_bar = 5'b11010;
+ B_bar = 5'b00101;
+ C_in = 1'b1;
+#7
+ tbassert(F_bar == 5'b11111, "Test 26");
+ tbassert(C_out == 1'b1, "Test 26");
+ tbassert(CP_bar == 1'b0, "Test 26");
+ tbassert(CG_bar == 1'b1, "Test 26");
+#0
+
+ // the following set of tests show the overflow values at which CG_bar output and CP_bar output
+ // are both set
+ // (* because these tests use active-high data convention but the device pins are named
+ // according to active-low data convention, the roles of the two outputs as seen here
+ // are swapped: CG_bar is Carry Propagate and CP_bar is Carry Generate!)
+
+ // 31 + 2 + Carry 0 -> 33
+ A_bar = 5'b11111;
+ B_bar = 5'b00010;
+ C_in = 1'b1;
+#7
+ tbassert(F_bar == 5'b00001, "Test 27");
+ tbassert(C_out == 1'b0, "Test 27");
+ tbassert(CP_bar == 1'b1, "Test 27");
+ tbassert(CG_bar == 1'b1, "Test 27");
+#0
+ // 28 + 8 + Carry 0 -> 36
+ A_bar = 5'b11100;
+ B_bar = 5'b01000;
+ C_in = 1'b1;
+#7
+ tbassert(F_bar == 5'b00100, "Test 28");
+ tbassert(C_out == 1'b0, "Test 28");
+ tbassert(CP_bar == 1'b1, "Test 28");
+ tbassert(CG_bar == 1'b1, "Test 28");
+#75
+
+ // the following set of tests are for: arithmetic: subtract
+
+ // Notes:
+ //
+ // 1. the Carry input signal is inverted compared to the A, B and F signals:
+ // C_in == 1 is a no carry
+ //
+ // 2. the Carry output signal:
+ // C_out == 1 is a borrow, which is also equivalent to "no carry";
+ // the two possible values of C_out correspond to the two possible results of Subtract:
+ //
+ // - if the result F is positive, it is the "normal" case (because input numbers A and B
+ // are positive also) and there is nothing to do: C_out == 0, meaning no borrow
+ //
+ // - if the result F is negative, it is the "underflow" case: the number needs some
+ // interpretation and this is through using the Carry output value: C_out == 1,
+ // meaning borrow (see value of Carry output, next)
+ //
+ // * in different hardware implementations or computer processor architectures, the ALU
+ // Carry output bit (equivalent to the Carry flag stored as state) can use 0 or 1
+ // to represent the borrow for the Subtract operation; this is just a convention,
+ // and the convention for the 74181 is hereby documented
+ // (see IceChips Technical Notes for further information)
+ //
+ // 3. value of Carry output:
+ // if it is a borrow (C_out == 1), the Carry output contributes the positional value of -1
+ // in the next group of 5 bits: -1<<5 == -32
+ //
+ // 4. the A input (minuend) is an unsigned, positive number only;
+ // the B input (subtrahend) is an unsigned, positive number only;
+ // the F output result is a signed number (see next)
+ //
+ // 5. signed number representation and range:
+ // it's useful to note this method of representing a signed number: one bit at the highest
+ // position of a representation can be considered to have a negative value; if present
+ // (equal to 1), then this bit will provide the sign of the number with the correct magnitude
+ // as follows
+ //
+ // a) in 5 bits, the smallest negative number that can be represented looks like the following:
+ // the highest bit position is special, and is given a positional value of -16
+ // instead of 16:
+ // 1 1 1 1 1
+ // -16 + 8 + 4 + 2 + 1 == -1
+ //
+ // b) in 5 bits, the largest negative number is:
+ // 1 0 0 0 0
+ // -16 + 0 + 0 + 0 + 0 == -16
+ //
+ // c) in 5 bits (when it is a signed number), a positive number cannot exceed this magnitude
+ // so as not to use the high bit value:
+ // 0 1 1 1 1
+ // 0 + 8 + 4 + 2 + 1 == 15
+ //
+ // d) however, 6 bits could be used as well; if we wish to use the first 5 bits to represent
+ // numbers up to 31, a signed number representation for this is:
+ // 0 1 1 1 1 1
+ // 0 + 16 + 8 + 4 + 2 + 1 == 31
+ //
+ // e) in 6 bits, a negative number looks like the following:
+ // 1 0 1 1 1 1
+ // -32 + 0 + 8 + 4 + 2 + 1 == -17
+ //
+ // 6. ones complement operation gives subtraction:
+ // the base operation for this device is not actually twos complement addition but ones
+ // complement addition; consequently, there is an extra "MINUS 1" in the function expression;
+ // here is an example of applying the operation to 14 and 5 (F output result == 9):
+ //
+ // a) provide A input == 14:
+ // 0 1 1 1 0
+ // 0 + 8 + 4 + 2 + 0 == 14
+ //
+ // b) provide B input == 5:
+ // 0 0 1 0 1
+ // 0 + 0 + 4 + 0 + 1 == 5
+ //
+ // c) provide C_in input == 1 (the default input, meaning: no Carry):
+ // 0 0 0 0 1
+ // 0 + 0 + 0 + 0 + 1 == 1
+ //
+ // d) ones complement of 5 ("~5"):
+ // 1 1 0 1 0
+ // -16 + 8 + 0 + 2 + 0 == -6
+ //
+ // e) ones complement addition operation A PLUS ~B:
+ // 0 1 1 1 0 == 14
+ // 1 1 0 1 0 == -6
+ // + _________________
+ // 1 0 1 0 0 0 == 8 with a carry out bit
+ //
+ // f) therefore the ones complement addition by itself is:
+ // A PLUS ~B == A MINUS B MINUS 1 (with a carry out bit)
+ //
+ // g) however, the carry in bit is used in a "PLUS Carry" as well; recall that this bit
+ // is inverted compared to its arithmetic value*, and in the present case, from (c),
+ // the bit value is 1; so here is the operation A PLUS ~B PLUS Carry:
+ // 1 0 1 0 0 0 == 8 with a carry out bit
+ // 0 0 0 0 1 == 1
+ // + _________________
+ // 1 0 1 0 0 1 == 9 with a carry out bit (this bit is also inverted**)
+ //
+ // * the inverted definitions of the Carry input and Carry output signals for this
+ // device are a convenience for doing arithmetic and for signal connection between
+ // devices with a minimal gate delay
+ //
+ // ** the carry out bit 1 here appears actually as C_out output == 0
+ //
+ // h) the overall subtraction operation is*:
+ // A PLUS ~B PLUS Carry == A MINUS B MINUS 1 PLUS Carry
+ //
+ // * subject to the appropriate definition of "Carry"
+ // (think of it as: invert B and invert the carry in; perform addition; then invert
+ // the carry out)
+ //
+ // 7. details about the numerical ranges of inputs, outputs, and the resulting Carry output:
+ // for Subtract, the values of A and B inputs and the Carry input divide into
+ // three domains as follows
+ //
+ // * as mentioned, A and B are always positive, unsigned numbers
+ //
+ // * F positive includes F equal to zero
+ //
+ // a) Domain 1: B < A*, result F is positive
+ // - always C_out == 0
+ // - "no underflow" case: the result (a small number which is a positive
+ // difference) is exactly the number that it appears to be
+ //
+ // * extends to B <= A in the case of C_in == 0, because with this Carry in
+ // value of 1 and B == A, result F will still be zero and not go negative
+ // (see Domain 3)
+ //
+ // b) Domain 2: B > A, result F is negative
+ // - here B cannot be zero (as A is zero or greater)
+ // - always C_out == 1
+ // - "underflow" case: the result is interpreted as the correct negative
+ // number by adding -32 (Borrow: -1<<5 == -32)
+ //
+ // c) Domain 3: B == A with C_in == 1 (no Carry in), result F == -1
+ // (successful Equal comparison)
+ // - C_in == 1 is a requirement
+ // - always C_out == 1
+ // - "underflow" case as above
+ // - Equal == 1
+ //
+ // 8. details about the Carry Propagate (CP_bar) and Carry Generate (CG_bar) output signals:
+ //
+ // * in this note, number of bits will refer to the device design value of 4, rather than
+ // the number of bits in this test bench
+ //
+ // - the signals are only meaningful for Add and Subtract operations; they do not have meaning
+ // for the other 14 arithmetic operations
+ //
+ // - the signals are used in the context of multiple units operating on a longer word length:
+ // the adjacent (higher) unit needs to know this unit's Carry output (its Carry input);
+ // the Carry value can be determined in a faster manner than by waiting for each internal
+ // Carry to ripple through the bit calculations of this unit; instead, the calculation is
+ // parallelized by gathering the overall magnitude given by A and B inputs, and using this
+ // as threshold/underflow information as follows
+ //
+ // - the magnitude of all 4 A and B inputs (difference) is either above the threshold
+ // (there will be no Borrow); or below the threshold at value -1 or less, meaning
+ // there is underflow (a Borrow); or equal to the threshold at value 0, where underflow
+ // will or will not occur depending on the Carry input
+ //
+ // - "Carry Generate" indicates that unconditionally there must be a Borrow, since
+ // the magnitude is already an underflow value (-1 or less)
+ //
+ // - "Carry Propagate" indicates that there will be a Borrow/no Borrow precisely if
+ // there is no Carry input/Carry input (magnitude is at the threshold 0)
+ //
+ // - by definition the signals are independent of the Carry input; this is important in their
+ // functional purpose, which is at the longer word length; the purpose is to feed the Carry
+ // input at the lowest bit directly into calculating the Carry input at the next unit's
+ // lowest bit, with minimal gate delay (hence: carry lookahead, and there is no ripple carry)
+ //
+ // - external logic is required for this: the Carry input of this unit is gated together
+ // with Carry Propagate and Carry Generate to create the next unit's Carry input
+ //
+ // - the speed-up obtained by using the CP_bar and CG_bar signals becomes more significant
+ // as the number of 74181 units rises
+ //
+ // for Subtract, the information provided by the signals is as follows:
+ //
+ // a) if using active-low data convention:
+ //
+ // - CP_bar and CG_bar are active-high: a 1 gives the indication
+ // - roles are swapped: CG_bar is Carry Propagate and CP_bar is Carry Generate
+ // - CG_bar alone indicates that result F == 0
+ // - CG_bar and CP_bar together indicate that result F < 0 (underflow)
+ //
+ // b) if using active-high data convention:
+ //
+ // - CP_bar and CG_bar are active-low: a 0 gives the indication
+ // - CP_bar alone indicates that result F == 0
+ // - CG_bar alone indicates that result F < 0 (underflow)
+ //
+ // c) this table summarizes the signal values:
+ //
+ // Convention Range CP_bar CG_bar
+ // ___________ ________ ______ ______
+ //
+ // active-low F > 0 X 0 (* CG_bar takes priority here)
+ // active-low F == 0 0 1 (* this shows CG_bar acts as Carry Propagate)
+ // active-low F < 0 1 1
+ //
+ // active-high F > 0 1 1
+ // active-high F == 0 0 1
+ // active-high F < 0 X 0 (* CG_bar takes priority here)
+ //
+ // * X is don't-care (it takes value 0 or 1 depending on inputs)
+ //
+ // * there are three sets of tests below to cover the ranges
+ //
+ // * these details are noted here in the interest of behavioural testing; however, the
+ // signal values do not need to concern the designer, because a 74182 or equivalent logic
+ // will receive CP_bar and CG_bar and pass the required signal to the adjacent 74181 unit
+ //
+ // 9. the function (independent of active-high or active-low data choice):
+ // Select == 4'b0110 is:
+ // F = A MINUS B MINUS 1 PLUS Carry
+
+ // Mode = 1'b0;
+
+ Select = 4'b0110;
+
+ // all zeroes (0 - 0 - 1) + Carry 1 -> 0 (with C_out == 0, meaning: no Borrow)
+ // (Domain 1)
+ A_bar = {WIDTH{1'b0}};
+ B_bar = {WIDTH{1'b0}};
+ C_in = 1'b0;
+#7
+ tbassert(F_bar == 5'b00000, "Test 29");
+ tbassert(C_out == 1'b0, "Test 29");
+ tbassert(CP_bar == 1'b0, "Test 29");
+ tbassert(CG_bar == 1'b1, "Test 29");
+ // * Note: is not an Equal comparison since C_in == 0
+ tbassert(Equal == 1'b0, "Test 29");
+#0
+ // all zeroes (0 - 0 - 1) + Carry 0 -> -1 (with Equal == 1, C_out == 1, meaning: Borrow)
+ // (Domain 3)
+ // A_bar = {WIDTH{1'b0}};
+ // B_bar = {WIDTH{1'b0}};
+ C_in = 1'b1;
+#7
+ tbassert(F_bar == 5'b11111, "Test 30");
+ tbassert(C_out == 1'b1, "Test 30");
+ tbassert(CP_bar == 1'b0, "Test 30");
+ tbassert(CG_bar == 1'b1, "Test 30");
+ // * Note: is an Equal comparison since C_in == 1
+ tbassert(Equal == 1'b1, "Test 30");
+#0
+ // all ones (31 - 31 - 1) + Carry 0 -> -1 (with Equal == 1, C_out == 1)
+ // (Domain 3)
+ A_bar = {WIDTH{1'b1}};
+ B_bar = {WIDTH{1'b1}};
+ // C_in = 1'b1;
+#7
+ tbassert(F_bar == 5'b11111, "Test 31");
+ tbassert(C_out == 1'b1, "Test 31");
+ tbassert(CP_bar == 1'b0, "Test 31");
+ tbassert(CG_bar == 1'b1, "Test 31");
+ // * Note: is an Equal comparison since C_in == 1
+ tbassert(Equal == 1'b1, "Test 31");
+#0
+ // all ones (31 - 31 - 1) + Carry 1 -> 0 (with C_out == 0)
+ // (Domain 1)
+ // A_bar = {WIDTH{1'b1}};
+ // B_bar = {WIDTH{1'b1}};
+ C_in = 1'b0;
+#7
+ tbassert(F_bar == 5'b00000, "Test 32");
+ tbassert(C_out == 1'b0, "Test 32");
+ tbassert(CP_bar == 1'b0, "Test 32");
+ tbassert(CG_bar == 1'b1, "Test 32");
+ // * Note: is not an Equal comparison since C_in == 0
+ tbassert(Equal == 1'b0, "Test 32");
+#0
+
+ // repeat tests: Carry input is set then clear (meaning, respectively, no Carry then Carry)
+
+ for (i = 33; i <= 34; i++)
+ begin
+ case (i)
+ 33:
+ begin
+ C_in = 1'b1;
+ end
+ 34:
+ begin
+ C_in = 1'b0;
+ end
+ endcase
+
+ // the following set of tests show B > A, therefore result F is negative
+ // with Carry output C_out == 1, meaning: Borrow
+ // (Domain 2)
+
+ // 0 - 16 - 1 + Carry -> 15 or 16 + Borrow 1 (-1<<5 == -32) (total -17 or -16)
+ A_bar = 5'b00000;
+ B_bar = 5'b10000;
+#10
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b01111, "Test", "1", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b10000, "Test", "1", i);
+ tbassert2R(C_out == 1'b1, "Test", "1", i);
+ tbassert2R(CP_bar == 1'b0, "Test", "1", i);
+ tbassert2R(CG_bar == 1'b0, "Test", "1", i);
+ tbassert2R(Equal == 1'b0, "Test", "1", i);
+#0
+ // 0 - 31 - 1 + Carry -> 0 or 1 (total -32 or -31)
+ A_bar = 5'b00000;
+ B_bar = 5'b11111;
+#10
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b00000, "Test", "2", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b00001, "Test", "2", i);
+ tbassert2R(C_out == 1'b1, "Test", "2", i);
+ tbassert2R(CP_bar == 1'b0, "Test", "2", i);
+ tbassert2R(CG_bar == 1'b0, "Test", "2", i);
+ tbassert2R(Equal == 1'b0, "Test", "2", i);
+#0
+ // 1 - 31 - 1 + Carry -> 1 or 2 (total -31 or -30)
+ A_bar = 5'b00001;
+ // B_bar = 5'b11111;
+#10
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b00001, "Test", "3", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b00010, "Test", "3", i);
+ tbassert2R(C_out == 1'b1, "Test", "3", i);
+ tbassert2R(CP_bar == 1'b0, "Test", "3", i);
+ tbassert2R(CG_bar == 1'b0, "Test", "3", i);
+ tbassert2R(Equal == 1'b0, "Test", "3", i);
+#0
+ // 16 - 31 - 1 + Carry -> 16 or 17 (total -16 or -15)
+ A_bar = 5'b10000;
+ // B_bar = 5'b11111;
+#10
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b10000, "Test", "4", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b10001, "Test", "4", i);
+ tbassert2R(C_out == 1'b1, "Test", "4", i);
+ tbassert2R(CP_bar == 1'b0, "Test", "4", i);
+ tbassert2R(CG_bar == 1'b0, "Test", "4", i);
+ tbassert2R(Equal == 1'b0, "Test", "4", i);
+#0
+ // 30 - 31 - 1 + Carry -> 30 or 31 (total -2 or -1)
+ A_bar = 5'b11110;
+ // B_bar = 5'b11111;
+#10
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b11110, "Test", "5", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b11111, "Test", "5", i);
+ tbassert2R(C_out == 1'b1, "Test", "5", i);
+ tbassert2R(CP_bar == 1'b0, "Test", "5", i);
+ tbassert2R(CG_bar == 1'b0, "Test", "5", i);
+ case_tbassert2R(C_in == 1'b1, Equal == 1'b0, "Test", "5", i);
+ // * Note: is not an Equal comparison since C_in == 0
+ case_tbassert2R(C_in == 1'b0, Equal == 1'b1, "Test", "5", i);
+#0
+ // 15 - 30 - 1 + Carry -> 16 or 17 (total -16 or -15)
+ A_bar = 5'b01111;
+ B_bar = 5'b11110;
+#7
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b10000, "Test", "6", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b10001, "Test", "6", i);
+ tbassert2R(C_out == 1'b1, "Test", "6", i);
+ tbassert2R(CP_bar == 1'b1, "Test", "6", i);
+ tbassert2R(CG_bar == 1'b0, "Test", "6", i);
+ tbassert2R(Equal == 1'b0, "Test", "6", i);
+#0
+ // 15 - 17 - 1 + Carry -> 29 or 30 (total -3 or -2)
+ // A_bar = 5'b01111;
+ B_bar = 5'b10001;
+#7
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b11101, "Test", "7", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b11110, "Test", "7", i);
+ tbassert2R(C_out == 1'b1, "Test", "7", i);
+ tbassert2R(CP_bar == 1'b1, "Test", "7", i);
+ tbassert2R(CG_bar == 1'b0, "Test", "7", i);
+ tbassert2R(Equal == 1'b0, "Test", "7", i);
+#0
+ // 0 - 15 - 1 + Carry -> 16 or 17 (total -16 or -15)
+ A_bar = 5'b00000;
+ B_bar = 5'b01111;
+#10
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b10000, "Test", "8", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b10001, "Test", "8", i);
+ tbassert2R(C_out == 1'b1, "Test", "8", i);
+ tbassert2R(CP_bar == 1'b0, "Test", "8", i);
+ tbassert2R(CG_bar == 1'b0, "Test", "8", i);
+ tbassert2R(Equal == 1'b0, "Test", "8", i);
+#0
+ // 1 - 2 - 1 + Carry -> 30 or 31 (total -2 or -1)
+ A_bar = 5'b00001;
+ B_bar = 5'b00010;
+#10
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b11110, "Test", "9", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b11111, "Test", "9", i);
+ tbassert2R(C_out == 1'b1, "Test", "9", i);
+ tbassert2R(CP_bar == 1'b1, "Test", "9", i);
+ tbassert2R(CG_bar == 1'b0, "Test", "9", i);
+ case_tbassert2R(C_in == 1'b1, Equal == 1'b0, "Test", "9", i);
+ // * Note: is not an Equal comparison since C_in == 0
+ case_tbassert2R(C_in == 1'b0, Equal == 1'b1, "Test", "9", i);
+#0
+ // 1 - 13 - 1 + Carry -> 19 or 20 (total -13 or -12)
+ // A_bar = 5'b00001;
+ B_bar = 5'b01101;
+#10
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b10011, "Test", "10", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b10100, "Test", "10", i);
+ tbassert2R(C_out == 1'b1, "Test", "10", i);
+ tbassert2R(CP_bar == 1'b0, "Test", "10", i);
+ tbassert2R(CG_bar == 1'b0, "Test", "10", i);
+ tbassert2R(Equal == 1'b0, "Test", "10", i);
+#0
+ // 13 - 14 - 1 + Carry -> 30 or 31 (total -2 or -1)
+ A_bar = 5'b01101;
+ B_bar = 5'b01110;
+#10
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b11110, "Test", "11", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b11111, "Test", "11", i);
+ tbassert2R(C_out == 1'b1, "Test", "11", i);
+ tbassert2R(CP_bar == 1'b1, "Test", "11", i);
+ tbassert2R(CG_bar == 1'b0, "Test", "11", i);
+ case_tbassert2R(C_in == 1'b1, Equal == 1'b0, "Test", "11", i);
+ // * Note: is not an Equal comparison since C_in == 0
+ case_tbassert2R(C_in == 1'b0, Equal == 1'b1, "Test", "11", i);
+#45
+
+ // the following set of tests show B < A, therefore result F is positive
+ // with Carry output C_out == 0, meaning: no Borrow
+ // (Domain 1)
+
+ // 31 - 16 - 1 + Carry -> 14 or 15
+ A_bar = 5'b11111;
+ B_bar = 5'b10000;
+#10
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b01110, "Test", "12", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b01111, "Test", "12", i);
+ tbassert2R(C_out == 1'b0, "Test", "12", i);
+ tbassert2R(CP_bar == 1'b1, "Test", "12", i);
+ tbassert2R(CG_bar == 1'b1, "Test", "12", i);
+ tbassert2R(Equal == 1'b0, "Test", "12", i);
+#0
+ // 20 - 16 - 1 + Carry -> 3 or 4
+ A_bar = 5'b10100;
+ // B_bar = 5'b10000;
+#10
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b00011, "Test", "13", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b00100, "Test", "13", i);
+ tbassert2R(C_out == 1'b0, "Test", "13", i);
+ tbassert2R(CP_bar == 1'b1, "Test", "13", i);
+ tbassert2R(CG_bar == 1'b1, "Test", "13", i);
+ tbassert2R(Equal == 1'b0, "Test", "13", i);
+#0
+ // 16 - 4 - 1 + Carry -> 11 or 12
+ A_bar = 5'b10000;
+ B_bar = 5'b00100;
+#10
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b01011, "Test", "14", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b01100, "Test", "14", i);
+ tbassert2R(C_out == 1'b0, "Test", "14", i);
+ tbassert2R(CP_bar == 1'b1, "Test", "14", i);
+ tbassert2R(CG_bar == 1'b1, "Test", "14", i);
+ tbassert2R(Equal == 1'b0, "Test", "14", i);
+#0
+ // 26 - 23 - 1 + Carry -> 2 or 3
+ A_bar = 5'b11010;
+ B_bar = 5'b10111;
+#10
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b00010, "Test", "15", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b00011, "Test", "15", i);
+ tbassert2R(C_out == 1'b0, "Test", "15", i);
+ tbassert2R(CP_bar == 1'b1, "Test", "15", i);
+ tbassert2R(CG_bar == 1'b1, "Test", "15", i);
+ tbassert2R(Equal == 1'b0, "Test", "15", i);
+#0
+ // 6 - 3 - 1 + Carry -> 2 or 3
+ A_bar = 5'b00110;
+ B_bar = 5'b00011;
+#7
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b00010, "Test", "16", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b00011, "Test", "16", i);
+ tbassert2R(C_out == 1'b0, "Test", "16", i);
+ tbassert2R(CP_bar == 1'b1, "Test", "16", i);
+ tbassert2R(CG_bar == 1'b1, "Test", "16", i);
+ tbassert2R(Equal == 1'b0, "Test", "16", i);
+#0
+ // 22 - 21 - 1 + Carry -> 0 or 1
+ A_bar = 5'b10110;
+ B_bar = 5'b10101;
+#7
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b00000, "Test", "17", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b00001, "Test", "17", i);
+ tbassert2R(C_out == 1'b0, "Test", "17", i);
+ tbassert2R(CP_bar == 1'b1, "Test", "17", i);
+ tbassert2R(CG_bar == 1'b1, "Test", "17", i);
+ tbassert2R(Equal == 1'b0, "Test", "17", i);
+#0
+ // 2 - 1 - 1 + Carry -> 0 or 1
+ A_bar = 5'b00010;
+ B_bar = 5'b00001;
+#7
+ case_tbassert2R(C_in == 1'b1, F_bar == 5'b00000, "Test", "18", i);
+ case_tbassert2R(C_in == 1'b0, F_bar == 5'b00001, "Test", "18", i);
+ tbassert2R(C_out == 1'b0, "Test", "18", i);
+ tbassert2R(CP_bar == 1'b1, "Test", "18", i);
+ tbassert2R(CG_bar == 1'b1, "Test", "18", i);
+ tbassert2R(Equal == 1'b0, "Test", "18", i);
+
+ end
+
+ // end repeat tests
+#25
+
+ // the following set of tests show the smallest positive difference values at which both
+ // CG_bar output and CP_bar output remain set
+ // (Domain 1)
+ // (* using active-high data convention, the functionality of the two outputs aligns with
+ // the pin names: CP_bar is Carry Propagate and CG_bar is Carry Generate)
+
+ // 7 - 6 - 1 + Carry 0 -> 0
+ A_bar = 5'b00111;
+ B_bar = 5'b00110;
+ C_in = 1'b1;
+#7
+ tbassert(F_bar == 5'b00000, "Test 35");
+ tbassert(C_out == 1'b0, "Test 35");
+ tbassert(CP_bar == 1'b1, "Test 35");
+ tbassert(CG_bar == 1'b1, "Test 35");
+ tbassert(Equal == 1'b0, "Test 35");
+#0
+ // 17 - 16 - 1 + Carry 0 -> 0
+ A_bar = 5'b10001;
+ B_bar = 5'b10000;
+ C_in = 1'b1;
+#7
+ tbassert(F_bar == 5'b00000, "Test 36");
+ tbassert(C_out == 1'b0, "Test 36");
+ tbassert(CP_bar == 1'b1, "Test 36");
+ tbassert(CG_bar == 1'b1, "Test 36");
+ tbassert(Equal == 1'b0, "Test 36");
+#0
+ // 1 - 0 - 1 + Carry 1 -> 1
+ A_bar = 5'b00001;
+ B_bar = 5'b00000;
+ C_in = 1'b0;
+#7
+ tbassert(F_bar == 5'b00001, "Test 37");
+ tbassert(C_out == 1'b0, "Test 37");
+ tbassert(CP_bar == 1'b1, "Test 37");
+ tbassert(CG_bar == 1'b1, "Test 37");
+ tbassert(Equal == 1'b0, "Test 37");
+#0
+ // 1 - 0 - 1 + Carry 0 -> 0
+ // A_bar = 5'b00001;
+ // B_bar = 5'b00000;
+ C_in = 1'b1;
+#7
+ tbassert(F_bar == 5'b00000, "Test 38");
+ tbassert(C_out == 1'b0, "Test 38");
+ tbassert(CP_bar == 1'b1, "Test 38");
+ tbassert(CG_bar == 1'b1, "Test 38");
+ tbassert(Equal == 1'b0, "Test 38");
+#45
+
+ // the following set of tests show successful Equal comparison
+ // (Domain 3);
+ // these are also the specific input values at which CP_bar output becomes clear
+ // while CG_bar output remains set
+ // (* using active-high data convention, the functionality of the two outputs aligns with
+ // the pin names: CP_bar is Carry Propagate and CG_bar is Carry Generate)
+
+ // a - a - 1 + Carry 0 -> -1 (with Equal == 1, C_out == 1)
+ C_in = 1'b1;
+
+ // repeat tests: all A input values, all B input values
+
+ for (i = 0; i <= 31; i++)
+ begin
+ A_bar = i;
+ B_bar = i;
+#10
+ tbassert2(F_bar == 5'b11111, "Test", (1 + i), "39");
+ tbassert2(C_out == 1'b1, "Test", (1 + i), "39");
+ tbassert2(CP_bar == 1'b0, "Test", (1 + i), "39");
+ tbassert2(CG_bar == 1'b1, "Test", (1 + i), "39");
+ // * Note: is an Equal comparison since C_in == 1
+ tbassert2(Equal == 1'b1, "Test", (1 + i), "39");
+
+ end
+
+ // end repeat tests
+#25
+
+ // the following set of tests show Equal comparison where Equal and C_out can be used together
+ // to indicate B < A or B > A
+
+ // B < A (difference 6 - 5) -> Equal == 0, C_out == 0
+ // (Domain 1)
+ A_bar = 5'b00110;
+ B_bar = 5'b00101;
+ // C_in = 1'b1;
+#10
+ tbassert(F_bar == 5'b00000, "Test 40");
+ tbassert(C_out == 1'b0, "Test 40");
+ tbassert(CP_bar == 1'b1, "Test 40");
+ tbassert(CG_bar == 1'b1, "Test 40");
+ // * Note: is an Equal comparison since C_in == 1
+ tbassert(Equal == 1'b0, "Test 40");
+#0
+ // B > A (difference 5 - 6) -> Equal == 0, C_out == 1
+ // (Domain 2)
+ A_bar = 5'b00101;
+ B_bar = 5'b00110;
+ // C_in = 1'b1;
+#10
+ tbassert(F_bar == 5'b11110, "Test 41");
+ tbassert(C_out == 1'b1, "Test 41");
+ tbassert(CP_bar == 1'b1, "Test 41");
+ tbassert(CG_bar == 1'b0, "Test 41");
+ // * Note: is an Equal comparison since C_in == 1
+ tbassert(Equal == 1'b0, "Test 41");
+#0
+ // B < A (difference 28 - 23) -> Equal == 0, C_out == 0
+ // (Domain 1)
+ A_bar = 5'b11100;
+ B_bar = 5'b10111;
+ // C_in = 1'b1;
+#10
+ tbassert(F_bar == 5'b00100, "Test 42");
+ tbassert(C_out == 1'b0, "Test 42");
+ tbassert(CP_bar == 1'b1, "Test 42");
+ tbassert(CG_bar == 1'b1, "Test 42");
+ // * Note: is an Equal comparison since C_in == 1
+ tbassert(Equal == 1'b0, "Test 42");
+#0
+ // B > A (difference 23 - 28) -> Equal == 0, C_out == 1
+ // (Domain 2)
+ A_bar = 5'b10111;
+ B_bar = 5'b11100;
+ // C_in = 1'b1;
+#10
+ tbassert(F_bar == 5'b11010, "Test 43");
+ tbassert(C_out == 1'b1, "Test 43");
+ tbassert(CP_bar == 1'b1, "Test 43");
+ tbassert(CG_bar == 1'b0, "Test 43");
+ // * Note: is an Equal comparison since C_in == 1
+ tbassert(Equal == 1'b0, "Test 43");
+#45
+
+ // the following set of tests show the underflow values at which CG_bar output becomes clear
+ // (CP_bar output is not necessarily clear in this range so CG_bar takes priority)
+ // (Domain 2)
+ // (* using active-high data convention, the functionality of the two outputs aligns with
+ // the pin names: CP_bar is Carry Propagate and CG_bar is Carry Generate)
+
+ // 13 - 14 - 1 + Carry 1 -> -1
+ A_bar = 5'b01101;
+ B_bar = 5'b01110;
+ C_in = 1'b0;
+#7
+ tbassert(F_bar == 5'b11111, "Test 44");
+ tbassert(C_out == 1'b1, "Test 44");
+ tbassert(CP_bar == 1'b1, "Test 44");
+ tbassert(CG_bar == 1'b0, "Test 44");
+ // * Note: is not an Equal comparison since C_in == 0
+ tbassert(Equal == 1'b1, "Test 44");
+#0
+ // 13 - 14 - 1 + Carry 0 -> -2
+ // A_bar = 5'b01101;
+ // B_bar = 5'b01110;
+ C_in = 1'b1;
+#7
+ tbassert(F_bar == 5'b11110, "Test 45");
+ tbassert(C_out == 1'b1, "Test 45");
+ tbassert(CP_bar == 1'b1, "Test 45");
+ tbassert(CG_bar == 1'b0, "Test 45");
+ tbassert(Equal == 1'b0, "Test 45");
+#0
+ // 4 - 6 - 1 + Carry 1 -> -2
+ A_bar = 5'b00100;
+ B_bar = 5'b00110;
+ C_in = 1'b0;
+#7
+ tbassert(F_bar == 5'b11110, "Test 46");
+ tbassert(C_out == 1'b1, "Test 46");
+ tbassert(CP_bar == 1'b0, "Test 46");
+ tbassert(CG_bar == 1'b0, "Test 46");
+ tbassert(Equal == 1'b0, "Test 46");
+#0
+ // 5 - 7 - 1 + Carry 0 -> -3
+ A_bar = 5'b00101;
+ B_bar = 5'b00111;
+ C_in = 1'b1;
+#7
+ tbassert(F_bar == 5'b11101, "Test 47");
+ tbassert(C_out == 1'b1, "Test 47");
+ tbassert(CP_bar == 1'b0, "Test 47");
+ tbassert(CG_bar == 1'b0, "Test 47");
+ tbassert(Equal == 1'b0, "Test 47");
+#75
+
+ // the following set of tests are for: arithmetic incorporating logic
+
+ // Notes:
+ //
+ // 1. the Carry Propagate (CP_bar) and Carry Generate (CG_bar) output signal values are not
+ // of consequence for the following arithmetic incorporating logic operations; they do not
+ // have the values and semantics that they have for basic Add and Subtract;
+ // however, their values are demonstrated in some cases and without full coverage,
+ // in the interest of behavioural testing
+
+ // the following set of tests are for: arithmetic incorporating logic: output dependent only on A
+
+ // Notes:
+ //
+ // 1. these three functions are independent of active-high or active-low data choice
+
+ // Mode = 1'b0;
+
+ // reference test case (same as the larger list of repeated tests to follow)
+ Select = 4'b0000; // function: A PLUS Carry
+ A_bar = 5'b10110; // expected output: 5'b10110 + 1'b1 == 5'b10111 (no Carry out)
+ B_bar = 5'b00011;
+ C_in = 1'b0;
+#10
+ tbassert(F_bar == 5'b10111, "Test 48");
+ tbassert(C_out == 1'b1, "Test 48");
+ tbassert(CP_bar == 1'b0, "Test 48");
+ tbassert(CG_bar == 1'b0, "Test 48");
+ // * Note: is not an Equal comparison since operation is not arithmetic: subtract
+ tbassert(Equal == 1'b0, "Test 48");
+#0
+ // reference test case
+ Select = 4'b1100; // function: A PLUS A (SHIFT LEFT) PLUS Carry
+ A_bar = 5'b10110; // expected output: 5'b01100 + 1'b1 == 5'b01101 (with Carry out)
+ B_bar = 5'b00011;
+ // C_in = 1'b0;
+#10
+ tbassert(F_bar == 5'b01101, "Test 49");
+ tbassert(C_out == 1'b0, "Test 49");
+ tbassert(CP_bar == 1'b1, "Test 49");
+ tbassert(CG_bar == 1'b1, "Test 49");
+ tbassert(Equal == 1'b0, "Test 49");
+#0
+ // reference test case
+ Select = 4'b1111; // function: A MINUS 1 PLUS Carry
+ A_bar = 5'b10110; // expected output: 5'b10110 - 1'b1 + 1'b0 == 5'b10101 (with C_out == 0)
+ B_bar = 5'b00011; // (Domain 1: Subtract semantics for the Carry output)
+ C_in = 1'b1;
+#10
+ tbassert(F_bar == 5'b10101, "Test 50");
+ tbassert(C_out == 1'b0, "Test 50");
+ tbassert(CP_bar == 1'b1, "Test 50");
+ tbassert(CG_bar == 1'b1, "Test 50");
+ tbassert(Equal == 1'b0, "Test 50");
+#0
+
+ // repeat tests: three Select input values
+
+ for (i = 1; i <= 3; i++)
+ begin
+ case (i)
+ 1:
+ begin
+ Select = 4'b0000; // function: A PLUS Carry
+ end
+ 2:
+ begin
+ Select = 4'b1100; // function: A PLUS A (SHIFT LEFT) PLUS Carry
+ end
+ 3:
+ begin
+ Select = 4'b1111; // function: A MINUS 1 PLUS Carry
+ end
+ endcase
+
+ // repeat tests: A input takes a range of representative values
+
+ for (j = 1; j <= 8; j++)
+ begin
+ case (j)
+ 1:
+ begin
+ A_bar = 5'b00001;
+ end
+ 2:
+ begin
+ A_bar = 5'b00111;
+ end
+ 3:
+ begin
+ A_bar = 5'b11001;
+ end
+ 4:
+ begin
+ A_bar = 5'b11110;
+ end
+ 5:
+ begin
+ A_bar = 5'b00000;
+ end
+ 6:
+ begin
+ A_bar = 5'b11111;
+ end
+ 7:
+ begin
+ A_bar = 5'b10101;
+ end
+ 8:
+ begin
+ A_bar = 5'b01010;
+ end
+ endcase
+
+ // repeat tests: all B input values
+
+ for (k = 0; k <= 31; k++)
+ begin
+ B_bar = k;
+ C_in = 1'b1;
+#10
+ case_tbassert2I(Select == 4'b0000, F_bar == A_bar + 1'b0, "Test", j, (50 + i));
+ case_tbassert2I(Select == 4'b0000, C_out == 1'b1, "Test", j, (50 + i));
+
+ case_tbassert2I(Select == 4'b1100, F_bar == A_bar + A_bar + 1'b0, "Test", j, (50 + i));
+ case_tbassert2I(Select == 4'b1100, C_out == ~A_bar[WIDTH - 1], "Test", j, (50 + i));
+
+ case_tbassert2I(Select == 4'b1111, F_bar == A_bar - 1'b1 + 1'b0, "Test", j, (50 + i));
+ case_tbassert2I(Select == 4'b1111 && (A_bar == 5'b00000), C_out == 1'b1, "Test", j, (50 + i));
+ case_tbassert2I(Select == 4'b1111 && (A_bar != 5'b00000), C_out == 1'b0, "Test", j, (50 + i));
+
+ // these tests are unaffected by the Carry input:
+ case_tbassert2I(Select == 4'b0000, CP_bar == 1'b0, "Test", j, (50 + i));
+ case_tbassert2I(Select == 4'b0000 && (A_bar == 5'b11111), CG_bar == 1'b1, "Test", j, (50 + i));
+ case_tbassert2I(Select == 4'b0000 && (A_bar != 5'b11111), CG_bar == 1'b0, "Test", j, (50 + i));
+
+ case_tbassert2I(Select == 4'b1100 && (A_bar == 5'b00000), CP_bar == 1'b0, "Test", j, (50 + i));
+ case_tbassert2I(Select == 4'b1100 && (A_bar != 5'b00000), CP_bar == 1'b1, "Test", j, (50 + i));
+ case_tbassert2I(Select == 4'b1100, CG_bar == A_bar[WIDTH - 1], "Test", j, (50 + i));
+
+ case_tbassert2I(Select == 4'b1111 && (A_bar == 5'b00000), CP_bar == 1'b0, "Test", j, (50 + i));
+ case_tbassert2I(Select == 4'b1111 && (A_bar != 5'b00000), CP_bar == 1'b1, "Test", j, (50 + i));
+ case_tbassert2I(Select == 4'b1111, CG_bar == 1'b1, "Test", j, (50 + i));
+#0
+ C_in = 1'b0;
+#10
+ // these tests differ from above (affected by the Carry input):
+ case_tbassert2I(Select == 4'b0000, F_bar == A_bar + 1'b1, "Test", j, (50 + i));
+ case_tbassert2I(Select == 4'b0000 && (A_bar == 5'b11111), C_out == 1'b0, "Test", j, (50 + i));
+ case_tbassert2I(Select == 4'b0000 && (A_bar != 5'b11111), C_out == 1'b1, "Test", j, (50 + i));
+
+ case_tbassert2I(Select == 4'b1100, F_bar == A_bar + A_bar + 1'b1, "Test", j, (50 + i));
+ case_tbassert2I(Select == 4'b1100, C_out == ~A_bar[WIDTH - 1], "Test", j, (50 + i));
+
+ case_tbassert2I(Select == 4'b1111, F_bar == A_bar - 1'b1 + 1'b1, "Test", j, (50 + i));
+ case_tbassert2I(Select == 4'b1111, C_out == 1'b0, "Test", j, (50 + i));
+
+ // these tests are identical to above (unaffected by the Carry input):
+ case_tbassert2I(Select == 4'b0000, CP_bar == 1'b0, "Test", j, (50 + i));
+ case_tbassert2I(Select == 4'b0000 && (A_bar == 5'b11111), CG_bar == 1'b1, "Test", j, (50 + i));
+ case_tbassert2I(Select == 4'b0000 && (A_bar != 5'b11111), CG_bar == 1'b0, "Test", j, (50 + i));
+
+ case_tbassert2I(Select == 4'b1100 && (A_bar == 5'b00000), CP_bar == 1'b0, "Test", j, (50 + i));
+ case_tbassert2I(Select == 4'b1100 && (A_bar != 5'b00000), CP_bar == 1'b1, "Test", j, (50 + i));
+ case_tbassert2I(Select == 4'b1100, CG_bar == A_bar[WIDTH - 1], "Test", j, (50 + i));
+
+ case_tbassert2I(Select == 4'b1111 && (A_bar == 5'b00000), CP_bar == 1'b0, "Test", j, (50 + i));
+ case_tbassert2I(Select == 4'b1111 && (A_bar != 5'b00000), CP_bar == 1'b1, "Test", j, (50 + i));
+ case_tbassert2I(Select == 4'b1111, CG_bar == 1'b1, "Test", j, (50 + i));
+
+ end
+
+ // end repeat B input values
+
+ end
+
+ // end repeat A input values
+
+ end
+
+ // end repeat Select input values
+#75
+
+ // the following set of tests are for: arithmetic incorporating logic: output independent of A, B
+
+ // Notes:
+ //
+ // 1. this function is independent of active-high or active-low data choice
+
+ // Mode = 1'b0;
+
+ Select = 4'b0011; // function: MINUS 1 PLUS Carry
+
+ // reference test case
+ A_bar = 5'b10110; // expected output: 5'b11111 + 1'b0 == 5'b11111 (with C_out == 1)
+ B_bar = 5'b00011; // (Domain 2: Subtract semantics for the Carry output)
+ C_in = 1'b1;
+#10
+ tbassert(F_bar == 5'b11111, "Test 54");
+ tbassert(C_out == 1'b1, "Test 54");
+ tbassert(CP_bar == 1'b0, "Test 54");
+ tbassert(CG_bar == 1'b1, "Test 54");
+ // * Note: is not an Equal comparison since operation is not arithmetic: subtract
+ // * Note: beyond this, the Equal output test will be skipped
+ tbassert(Equal == 1'b1, "Test 54");
+#0
+
+ // repeat tests: Carry input is set then clear (meaning, respectively, no Carry then Carry)
+
+ for (i = 1; i <= 2; i++)
+ begin
+ case (i)
+ 1:
+ begin
+ C_in = 1'b1; // expected output: 5'b11111 + 1'b0 == 5'b11111 (with C_out == 1)
+ end
+ 2:
+ begin
+ C_in = 1'b0; // expected output: 5'b11111 + 1'b1 == 5'b00000 (with C_out == 0)
+ end
+ endcase
+
+ // repeat tests: A, B inputs take a range of representative values
+
+ for (j = 1; j <= 10; j++)
+ begin
+ case (j)
+ 1:
+ begin
+ A_bar = 5'b00001;
+ B_bar = 5'b00001;
+ end
+ 2:
+ begin
+ A_bar = 5'b00111;
+ B_bar = 5'b00001;
+ end
+ 3:
+ begin
+ A_bar = 5'b00000;
+ B_bar = 5'b00001;
+ end
+ 4:
+ begin
+ A_bar = 5'b11111;
+ B_bar = 5'b00001;
+ end
+ 5:
+ begin
+ A_bar = 5'b00000;
+ B_bar = 5'b00000;
+ end
+ 6:
+ begin
+ A_bar = 5'b11111;
+ B_bar = 5'b11111;
+ end
+ 7:
+ begin
+ A_bar = 5'b01010;
+ B_bar = 5'b11100;
+ end
+ 8:
+ begin
+ A_bar = 5'b01000;
+ B_bar = 5'b11111;
+ end
+ 9:
+ begin
+ A_bar = 5'b10111;
+ B_bar = 5'b00000;
+ end
+ 10:
+ begin
+ A_bar = 5'b11100;
+ B_bar = 5'b11100;
+ end
+ endcase
+#10
+ case_tbassert2I(C_in == 1'b1, F_bar == 5'b11111, "Test", j, (54 + i));
+ case_tbassert2I(C_in == 1'b0, F_bar == 5'b00000, "Test", j, (54 + i));
+ case_tbassert2I(C_in == 1'b1, C_out == 1'b1, "Test", j, (54 + i));
+ case_tbassert2I(C_in == 1'b0, C_out == 1'b0, "Test", j, (54 + i));
+
+ // these tests are unaffected by the Carry input:
+ tbassert2I(CP_bar == 1'b0, "Test", j, (54 + i));
+ tbassert2I(CG_bar == 1'b1, "Test", j, (54 + i));
+
+ end
+
+ // end repeat A, B input values
+
+ end
+
+ // end repeat Carry input values
+#75
+
+ // the following set of tests are for: arithmetic incorporating logic: output dependent on A, B
+
+ // Notes:
+ //
+ // 1. these ten functions are dependent on active-high data choice
+ // (see datasheet for the functions for active-low data)
+
+ // Mode = 1'b0;
+
+ // reference test case (same as the larger list of repeated tests to follow)
+ Select = 4'b0001; // function: A OR B PLUS Carry
+ A_bar = 5'b10110; // expected output: 5'b10111 + 1'b1 == 5'b11000 (no Carry out)
+ B_bar = 5'b00011;
+ C_in = 1'b0;
+#10
+ tbassert(F_bar == 5'b11000, "Test 57");
+ tbassert(C_out == 1'b1, "Test 57");
+ tbassert(CP_bar == 1'b0, "Test 57");
+ tbassert(CG_bar == 1'b0, "Test 57");
+#0
+ // reference test case
+ Select = 4'b0010; // function: A OR (NOT B) PLUS Carry
+ A_bar = 5'b10110; // expected output: 5'b11110 + 1'b1 == 5'b11111 (no Carry out)
+ B_bar = 5'b00011;
+ // C_in = 1'b0;
+#7
+ tbassert(F_bar == 5'b11111, "Test 58");
+ tbassert(C_out == 1'b1, "Test 58");
+ tbassert(CP_bar == 1'b0, "Test 58");
+ tbassert(CG_bar == 1'b0, "Test 58");
+#0
+ // reference test case
+ Select = 4'b0100; // function: A PLUS (A AND (NOT B)) PLUS Carry
+ A_bar = 5'b10110; // expected output: 5'b10110 + 5'b10100 + 1'b1 == 5'b01011 (with Carry out)
+ B_bar = 5'b00011;
+ // C_in = 1'b0;
+#7
+ tbassert(F_bar == 5'b01011, "Test 59");
+ tbassert(C_out == 1'b0, "Test 59");
+ tbassert(CP_bar == 1'b1, "Test 59");
+ tbassert(CG_bar == 1'b1, "Test 59");
+#0
+ // reference test case
+ Select = 4'b0101; // function: (A OR B) PLUS (A AND (NOT B)) PLUS Carry
+ A_bar = 5'b10110; // expected output: 5'b10111 + 5'b10100 + 1'b1 == 5'b01100 (with Carry out)
+ B_bar = 5'b00011;
+ // C_in = 1'b0;
+#7
+ tbassert(F_bar == 5'b01100, "Test 60");
+ tbassert(C_out == 1'b0, "Test 60");
+ tbassert(CP_bar == 1'b1, "Test 60");
+ tbassert(CG_bar == 1'b1, "Test 60");
+#0
+ // reference test case
+ Select = 4'b0111; // function: (A AND (NOT B)) MINUS 1 PLUS Carry
+ A_bar = 5'b10110; // expected output: 5'b10100 - 1'b1 + 1'b0 == 5'b10011 (with C_out == 0)
+ B_bar = 5'b00011; // (Domain 1: Subtract semantics for the Carry output)
+ C_in = 1'b1;
+#7
+ tbassert(F_bar == 5'b10011, "Test 61");
+ tbassert(C_out == 1'b0, "Test 61");
+ tbassert(CP_bar == 1'b1, "Test 61");
+ tbassert(CG_bar == 1'b1, "Test 61");
+#0
+ // reference test case
+ Select = 4'b1000; // function: A PLUS (A AND B) PLUS Carry
+ A_bar = 5'b10110; // expected output: 5'b10110 + 5'b00010 + 1'b0 == 5'b11000 (no Carry out)
+ B_bar = 5'b00011;
+ // C_in = 1'b1;
+#7
+ tbassert(F_bar == 5'b11000, "Test 62");
+ tbassert(C_out == 1'b1, "Test 62");
+ tbassert(CP_bar == 1'b1, "Test 62");
+ tbassert(CG_bar == 1'b0, "Test 62");
+#0
+ // reference test case
+ Select = 4'b1010; // function: (A OR (NOT B)) PLUS (A AND B) PLUS Carry
+ A_bar = 5'b10110; // expected output: 5'b11110 + 5'b00010 + 1'b0 == 5'b00000 (with Carry out)
+ B_bar = 5'b00011;
+ // C_in = 1'b1;
+#7
+ tbassert(F_bar == 5'b00000, "Test 63");
+ tbassert(C_out == 1'b0, "Test 63");
+ tbassert(CP_bar == 1'b1, "Test 63");
+ tbassert(CG_bar == 1'b1, "Test 63");
+#0
+ // reference test case
+ Select = 4'b1011; // function: (A AND B) MINUS 1 PLUS Carry
+ A_bar = 5'b10110; // expected output: 5'b00010 - 1'b1 + 1'b0 == 5'b00001 (with C_out == 0)
+ B_bar = 5'b00011; // (Domain 1: Subtract semantics for the Carry output)
+ // C_in = 1'b1;
+#7
+ tbassert(F_bar == 5'b00001, "Test 64");
+ tbassert(C_out == 1'b0, "Test 64");
+ tbassert(CP_bar == 1'b1, "Test 64");
+ tbassert(CG_bar == 1'b1, "Test 64");
+#0
+ // reference test case
+ Select = 4'b1101; // function: A PLUS (A OR B) PLUS Carry
+ A_bar = 5'b10110; // expected output: 5'b10110 + 5'b10111 + 1'b1 == 5'b01110 (with Carry out)
+ B_bar = 5'b00011;
+ C_in = 1'b0;
+#7
+ tbassert(F_bar == 5'b01110, "Test 65");
+ tbassert(C_out == 1'b0, "Test 65");
+ tbassert(CP_bar == 1'b1, "Test 65");
+ tbassert(CG_bar == 1'b1, "Test 65");
+#0
+ // reference test case
+ Select = 4'b1110; // function: A PLUS (A OR (NOT B)) PLUS Carry
+ A_bar = 5'b10110; // expected output: 5'b10110 + 5'b11110 + 1'b1 == 5'b10101 (with Carry out)
+ B_bar = 5'b00011;
+ // C_in = 1'b0;
+#7
+ tbassert(F_bar == 5'b10101, "Test 66");
+ tbassert(C_out == 1'b0, "Test 66");
+ tbassert(CP_bar == 1'b1, "Test 66");
+ tbassert(CG_bar == 1'b1, "Test 66");
+#0
+
+ // repeat tests: ten Select input values in binary complementary pairs
+ // (* this completes the set of 16 Select input values for 16 arithmetic operations)
+
+ for (i = 1; i <= 10; i++)
+ begin
+ case (i)
+ 1:
+ begin
+ Select = 4'b0001; // function: A OR B PLUS Carry
+ end
+ 2:
+ begin
+ Select = 4'b0010; // function: A OR (NOT B) PLUS Carry
+ end
+ 3:
+ begin
+ Select = 4'b0100; // function: A PLUS (A AND (NOT B)) PLUS Carry
+ end
+ 4:
+ begin
+ Select = 4'b0101; // function: (A OR B) PLUS (A AND (NOT B)) PLUS Carry
+ end
+ 5:
+ begin
+ Select = 4'b0111; // function: (A AND (NOT B)) MINUS 1 PLUS Carry
+ end
+ 6:
+ begin
+ Select = 4'b1000; // function: A PLUS (A AND B) PLUS Carry
+ end
+ 7:
+ begin
+ Select = 4'b1010; // function: (A OR (NOT B)) PLUS (A AND B) PLUS Carry
+ end
+ 8:
+ begin
+ Select = 4'b1011; // function: (A AND B) MINUS 1 PLUS Carry
+ end
+ 9:
+ begin
+ Select = 4'b1101; // function: A PLUS (A OR B) PLUS Carry
+ end
+ 10:
+ begin
+ Select = 4'b1110; // function: A PLUS (A OR (NOT B)) PLUS Carry
+ end
+ endcase
+
+ // repeat tests: all A input values
+
+ for (j = 0; j <= 31; j++)
+ begin
+ A_bar = j;
+
+ // repeat tests: all B input values
+
+ for (k = 0; k <= 31; k++)
+ begin
+ B_bar = k;
+ C_in = 1'b1;
+#10
+ case_tbassert2I(Select == 4'b0001, F_bar == (A_bar | B_bar) + 1'b0, "Test", (1 + j), (66 + i));
+ case_tbassert2I(Select == 4'b0001, C_out == 1'b1, "Test", (1 + j), (66 + i));
+
+ case_tbassert2I(Select == 4'b0010, F_bar == (A_bar | ~B_bar) + 1'b0, "Test", (1 + j), (66 + i));
+ case_tbassert2I(Select == 4'b0010, C_out == 1'b1, "Test", (1 + j), (66 + i));
+
+ case_tbassert2I(Select == 4'b0100, F_bar == A_bar + (A_bar & ~B_bar) + 1'b0, "Test", (1 + j), (66 + i));
+ // tests are left out: Carry output is dependent on the data
+
+ case_tbassert2I(Select == 4'b0101, F_bar == (A_bar | B_bar) + (A_bar & ~B_bar) + 1'b0, "Test", (1 + j), (66 + i));
+ // tests are left out: Carry output is dependent on the data
+
+ case_tbassert2I(Select == 4'b0111, F_bar == (A_bar & ~B_bar) - 1'b1 + 1'b0, "Test", (1 + j), (66 + i));
+ case_tbassert2I(Select == 4'b0111 && ((A_bar & ~B_bar) - 1'b1 == 5'b11111), C_out == 1'b1, "Test", (1 + j), (66 + i));
+ case_tbassert2I(Select == 4'b0111 && ((A_bar & ~B_bar) - 1'b1 != 5'b11111), C_out == 1'b0, "Test", (1 + j), (66 + i));
+
+ case_tbassert2I(Select == 4'b1000, F_bar == A_bar + (A_bar & B_bar) + 1'b0, "Test", (1 + j), (66 + i));
+ // tests are left out: Carry output is dependent on the data
+
+ case_tbassert2I(Select == 4'b1010, F_bar == (A_bar | ~B_bar) + (A_bar & B_bar) + 1'b0, "Test", (1 + j), (66 + i));
+ // tests are left out: Carry output is dependent on the data
+
+ case_tbassert2I(Select == 4'b1011, F_bar == (A_bar & B_bar) - 1'b1 + 1'b0, "Test", (1 + j), (66 + i));
+ case_tbassert2I(Select == 4'b1011 && ((A_bar & B_bar) - 1'b1 == 5'b11111), C_out == 1'b1, "Test", (1 + j), (66 + i));
+ case_tbassert2I(Select == 4'b1011 && ((A_bar & B_bar) - 1'b1 != 5'b11111), C_out == 1'b0, "Test", (1 + j), (66 + i));
+
+ case_tbassert2I(Select == 4'b1101, F_bar == A_bar + (A_bar | B_bar) + 1'b0, "Test", (1 + j), (66 + i));
+ // tests are left out: Carry output is dependent on the data
+
+ case_tbassert2I(Select == 4'b1110, F_bar == A_bar + (A_bar | ~B_bar) + 1'b0, "Test", (1 + j), (66 + i));
+ // tests are left out: Carry output is dependent on the data
+
+ // these tests are unaffected by the Carry input:
+ case_tbassert2I(Select == 4'b0001, CP_bar == 1'b0, "Test", (1 + j), (66 + i));
+
+ case_tbassert2I(Select == 4'b0010, CP_bar == 1'b0, "Test", (1 + j), (66 + i));
+
+ case_tbassert2I(Select == 4'b0111 && ((A_bar & ~B_bar) - 1'b1 == 5'b11111), CP_bar == 1'b0, "Test", (1 + j), (66 + i));
+ case_tbassert2I(Select == 4'b0111 && ((A_bar & ~B_bar) - 1'b1 != 5'b11111), CP_bar == 1'b1, "Test", (1 + j), (66 + i));
+
+ case_tbassert2I(Select == 4'b1011 && ((A_bar & B_bar) - 1'b1 == 5'b11111), CP_bar == 1'b0, "Test", (1 + j), (66 + i));
+ case_tbassert2I(Select == 4'b1011 && ((A_bar & B_bar) - 1'b1 != 5'b11111), CP_bar == 1'b1, "Test", (1 + j), (66 + i));
+#0
+ C_in = 1'b0;
+#10
+ // these tests differ from above (affected by the Carry input):
+ case_tbassert2I(Select == 4'b0001, F_bar == (A_bar | B_bar) + 1'b1, "Test", (1 + j), (66 + i));
+ case_tbassert2I(Select == 4'b0001 && ((A_bar | B_bar) == 5'b11111), C_out == 1'b0, "Test", (1 + j), (66 + i));
+ case_tbassert2I(Select == 4'b0001 && ((A_bar | B_bar) != 5'b11111), C_out == 1'b1, "Test", (1 + j), (66 + i));
+
+ case_tbassert2I(Select == 4'b0010, F_bar == (A_bar | ~B_bar) + 1'b1, "Test", (1 + j), (66 + i));
+ case_tbassert2I(Select == 4'b0010 && ((A_bar | ~B_bar) == 5'b11111), C_out == 1'b0, "Test", (1 + j), (66 + i));
+ case_tbassert2I(Select == 4'b0010 && ((A_bar | ~B_bar) != 5'b11111), C_out == 1'b1, "Test", (1 + j), (66 + i));
+
+ case_tbassert2I(Select == 4'b0100, F_bar == A_bar + (A_bar & ~B_bar) + 1'b1, "Test", (1 + j), (66 + i));
+ // tests are left out: Carry output is dependent on the data
+
+ case_tbassert2I(Select == 4'b0101, F_bar == (A_bar | B_bar) + (A_bar & ~B_bar) + 1'b1, "Test", (1 + j), (66 + i));
+ // tests are left out: Carry output is dependent on the data
+
+ case_tbassert2I(Select == 4'b0111, F_bar == (A_bar & ~B_bar) - 1'b1 + 1'b1, "Test", (1 + j), (66 + i));
+ case_tbassert2I(Select == 4'b0111 && ((A_bar & ~B_bar) != 5'b11111), C_out == 1'b0, "Test", (1 + j), (66 + i));
+ // tests are left out: Carry output is dependent on the data
+
+ case_tbassert2I(Select == 4'b1000, F_bar == A_bar + (A_bar & B_bar) + 1'b1, "Test", (1 + j), (66 + i));
+ // tests are left out: Carry output is dependent on the data
+
+ case_tbassert2I(Select == 4'b1010, F_bar == (A_bar | ~B_bar) + (A_bar & B_bar) + 1'b1, "Test", (1 + j), (66 + i));
+ // tests are left out: Carry output is dependent on the data
+
+ case_tbassert2I(Select == 4'b1011, F_bar == (A_bar & B_bar) - 1'b1 + 1'b1, "Test", (1 + j), (66 + i));
+ case_tbassert2I(Select == 4'b1011, C_out == 1'b0, "Test", (1 + j), (66 + i));
+
+ case_tbassert2I(Select == 4'b1101, F_bar == A_bar + (A_bar | B_bar) + 1'b1, "Test", (1 + j), (66 + i));
+ // tests are left out: Carry output is dependent on the data
+
+ case_tbassert2I(Select == 4'b1110, F_bar == A_bar + (A_bar | ~B_bar) + 1'b1, "Test", (1 + j), (66 + i));
+ // tests are left out: Carry output is dependent on the data
+
+ // these tests are identical to above (unaffected by the Carry input):
+ case_tbassert2I(Select == 4'b0001, CP_bar == 1'b0, "Test", (1 + j), (66 + i));
+
+ case_tbassert2I(Select == 4'b0010, CP_bar == 1'b0, "Test", (1 + j), (66 + i));
+
+ case_tbassert2I(Select == 4'b0111 && ((A_bar & ~B_bar) - 1'b1 == 5'b11111), CP_bar == 1'b0, "Test", (1 + j), (66 + i));
+ case_tbassert2I(Select == 4'b0111 && ((A_bar & ~B_bar) - 1'b1 != 5'b11111), CP_bar == 1'b1, "Test", (1 + j), (66 + i));
+
+ case_tbassert2I(Select == 4'b1011 && ((A_bar & B_bar) - 1'b1 == 5'b11111), CP_bar == 1'b0, "Test", (1 + j), (66 + i));
+ case_tbassert2I(Select == 4'b1011 && ((A_bar & B_bar) - 1'b1 != 5'b11111), CP_bar == 1'b1, "Test", (1 + j), (66 + i));
+
+ end
+
+ // end repeat B input values
+
+ end
+
+ // end repeat A input values
+
+ end
+
+ // end repeat Select input values
+#75
+
+ // the following set of tests are for: logic
+
+ // Notes:
+ //
+ // 1. the Carry, Carry Propagate (CP_bar) and Carry Generate (CG_bar) output signal values are not
+ // of consequence for the logic operations;
+ // however, the Carry output value is demonstrated in some cases and without full coverage,
+ // in the interest of behavioural testing
+ //
+ // 2. the Carry input has no effect on logic operations; this is demonstrated in these tests
+
+ Mode = 1'b1;
+
+ // the following set of tests are for: logic: output dependent only on A
+
+ // Notes:
+ //
+ // 1. these two functions are independent of active-high or active-low data choice
+
+ // reference test case (same as the larger list of repeated tests to follow)
+ Select = 4'b0000; // function: NOT A
+ A_bar = 5'b10110; // expected output: 5'b01001
+ B_bar = 5'b00011;
+ C_in = 1'b1;
+#10
+ tbassert(F_bar == 5'b01001, "Test 77");
+ tbassert(C_out == 1'b1, "Test 77");
+#0
+
+ // repeat tests: two complementary Select input values
+
+ for (i = 1; i <= 2; i++)
+ begin
+ case (i)
+ 1:
+ begin
+ Select = 4'b0000; // function: NOT A
+ end
+ 2:
+ begin
+ Select = 4'b1111; // function: A
+ end
+ endcase
+
+ // repeat tests: A input takes a range of representative values
+
+ for (j = 1; j <= 8; j++)
+ begin
+ case (j)
+ 1:
+ begin
+ A_bar = 5'b00001;
+ end
+ 2:
+ begin
+ A_bar = 5'b00111;
+ end
+ 3:
+ begin
+ A_bar = 5'b11001;
+ end
+ 4:
+ begin
+ A_bar = 5'b11110;
+ end
+ 5:
+ begin
+ A_bar = 5'b00000;
+ end
+ 6:
+ begin
+ A_bar = 5'b11111;
+ end
+ 7:
+ begin
+ A_bar = 5'b10101;
+ end
+ 8:
+ begin
+ A_bar = 5'b01010;
+ end
+ endcase
+
+ // repeat tests: all B input values
+
+ for (k = 0; k <= 31; k++)
+ begin
+ B_bar = k;
+ C_in = 1'b0;
+#7
+ case_tbassert2I(Select == 4'b0000, F_bar == ~A_bar, "Test", j, (77 + i));
+ case_tbassert2I(Select == 4'b0000 && (~A_bar != 5'b00000), C_out == 1'b1, "Test", j, (77 + i));
+ case_tbassert2I(Select == 4'b0000 && (~A_bar == 5'b00000), C_out == C_in, "Test", j, (77 + i));
+
+ case_tbassert2I(Select == 4'b1111, F_bar == A_bar, "Test", j, (77 + i));
+ case_tbassert2I(Select == 4'b1111 && (A_bar != 5'b00000), C_out == 1'b0, "Test", j, (77 + i));
+ case_tbassert2I(Select == 4'b1111 && (A_bar == 5'b00000), C_out == C_in, "Test", j, (77 + i));
+#0
+ C_in = 1'b1;
+#7
+ // these tests are identical to above (unaffected by the Carry input):
+ case_tbassert2I(Select == 4'b0000, F_bar == ~A_bar, "Test", j, (77 + i));
+ case_tbassert2I(Select == 4'b0000 && (~A_bar != 5'b00000), C_out == 1'b1, "Test", j, (77 + i));
+
+ case_tbassert2I(Select == 4'b1111, F_bar == A_bar, "Test", j, (77 + i));
+ case_tbassert2I(Select == 4'b1111 && (A_bar != 5'b00000), C_out == 1'b0, "Test", j, (77 + i));
+
+ // these tests differ from above (affected by the Carry input):
+ // * Note: beyond this, tests for Carry output will be skipped
+ case_tbassert2I(Select == 4'b0000 && (~A_bar == 5'b00000), C_out == C_in, "Test", j, (77 + i));
+
+ case_tbassert2I(Select == 4'b1111 && (A_bar == 5'b00000), C_out == C_in, "Test", j, (77 + i));
+
+ end
+
+ // end repeat B input values
+
+ end
+
+ // end repeat A input values
+
+ end
+
+ // end repeat Select input values
+#75
+
+ // the following set of tests are for: logic: output dependent only on B
+
+ // Notes:
+ //
+ // 1. these two functions are independent of active-high or active-low data choice
+
+ // Mode = 1'b1;
+
+ // repeat tests: two complementary Select input values
+
+ for (i = 1; i <= 2; i++)
+ begin
+ case (i)
+ 1:
+ begin
+ Select = 4'b0101; // function: NOT B
+ end
+ 2:
+ begin
+ Select = 4'b1010; // function: B
+ end
+ endcase
+
+ // repeat tests: B input takes a range of representative values
+
+ for (j = 1; j <= 8; j++)
+ begin
+ case (j)
+ 1:
+ begin
+ B_bar = 5'b00001;
+ end
+ 2:
+ begin
+ B_bar = 5'b00111;
+ end
+ 3:
+ begin
+ B_bar = 5'b11001;
+ end
+ 4:
+ begin
+ B_bar = 5'b11110;
+ end
+ 5:
+ begin
+ B_bar = 5'b00000;
+ end
+ 6:
+ begin
+ B_bar = 5'b11111;
+ end
+ 7:
+ begin
+ B_bar = 5'b01010;
+ end
+ 8:
+ begin
+ B_bar = 5'b10101;
+ end
+ endcase
+
+ // repeat tests: all A input values
+
+ for (k = 0; k <= 31; k++)
+ begin
+ A_bar = k;
+ C_in = 1'b0;
+#7
+ case_tbassert2I(Select == 4'b0101, F_bar == ~B_bar, "Test", j, (79 + i));
+
+ case_tbassert2I(Select == 4'b1010, F_bar == B_bar, "Test", j, (79 + i));
+#0
+ C_in = 1'b1;
+#7
+ // these tests are identical to above (unaffected by the Carry input):
+ case_tbassert2I(Select == 4'b0101, F_bar == ~B_bar, "Test", j, (79 + i));
+
+ case_tbassert2I(Select == 4'b1010, F_bar == B_bar, "Test", j, (79 + i));
+
+ end
+
+ // end repeat A input values
+
+ end
+
+ // end repeat B input values
+
+ end
+
+ // end repeat Select input values
+#75
+
+ // the following set of tests are for: logic: output independent of A, B
+
+ // Notes:
+ //
+ // 1. these two functions are dependent on active-high data choice
+
+ // Mode = 1'b1;
+
+ // repeat tests: two complementary Select input values
+
+ for (i = 1; i <= 2; i++)
+ begin
+ case (i)
+ 1:
+ begin
+ Select = 4'b0011; // function: 0
+ end
+ 2:
+ begin
+ Select = 4'b1100; // function: 1
+ end
+ endcase
+
+ // repeat tests: A, B inputs take a range of values
+
+ for (j = 1; j <= 11; j++)
+ begin
+ case (j)
+ 1:
+ begin
+ A_bar = 5'b00001;
+ B_bar = 5'b00001;
+ end
+ 2:
+ begin
+ A_bar = 5'b00111;
+ B_bar = 5'b00001;
+ end
+ 3:
+ begin
+ A_bar = 5'b11110;
+ B_bar = 5'b00001;
+ end
+ 4:
+ begin
+ A_bar = 5'b10101;
+ B_bar = 5'b00001;
+ end
+ 5:
+ begin
+ A_bar = 5'b00000;
+ B_bar = 5'b00000;
+ end
+ 6:
+ begin
+ A_bar = 5'b11111;
+ B_bar = 5'b11111;
+ end
+ 7:
+ begin
+ A_bar = 5'b00001;
+ B_bar = 5'b10000;
+ end
+ 8:
+ begin
+ A_bar = 5'b11111;
+ B_bar = 5'b11000;
+ end
+ 9:
+ begin
+ A_bar = 5'b01000;
+ B_bar = 5'b11111;
+ end
+ 10:
+ begin
+ A_bar = 5'b10111;
+ B_bar = 5'b00000;
+ end
+ 11:
+ begin
+ A_bar = 5'b11101;
+ B_bar = 5'b11101;
+ end
+ endcase
+
+ C_in = 1'b0;
+#7
+ case_tbassert2I(Select == 4'b0011, F_bar == 5'b00000, "Test", j, (81 + i));
+
+ case_tbassert2I(Select == 4'b1100, F_bar == 5'b11111, "Test", j, (81 + i));
+#0
+ C_in = 1'b1;
+#7
+ // these tests are identical to above (unaffected by the Carry input):
+ case_tbassert2I(Select == 4'b0011, F_bar == 5'b00000, "Test", j, (81 + i));
+
+ case_tbassert2I(Select == 4'b1100, F_bar == 5'b11111, "Test", j, (81 + i));
+
+ end
+
+ // end repeat A, B input values
+
+ end
+
+ // end repeat Select input values
+#75
+
+ // the following set of tests are for: logic: output dependent on A, B
+
+ // Notes:
+ //
+ // 1. these ten functions are dependent on active-high data choice
+ // (see tests below, under "the use of active-low data convention",
+ // that show the functions for active-low data)
+
+ // Mode = 1'b1;
+
+ // repeat tests: ten Select input values in binary complementary pairs
+ // (* this completes the set of 16 Select input values for 16 logic operations)
+
+ for (i = 1; i <= 10; i++)
+ begin
+ case (i)
+ 1:
+ begin
+ Select = 4'b0001; // function: NOT (A OR B)
+ end
+ 2:
+ begin
+ Select = 4'b0010; // function: (NOT A) AND B == NOT (A OR (NOT B)) by DeMorgan's rule
+ end
+ 3:
+ begin
+ Select = 4'b0100; // function: NOT (A AND B)
+ end
+ 4:
+ begin
+ Select = 4'b0110; // function: A XOR B
+ end
+ 5:
+ begin
+ Select = 4'b0111; // function: A AND (NOT B) == NOT ((NOT A) OR B) by DeMorgan's rule
+ end
+ 6:
+ begin
+ Select = 4'b1000; // function: (NOT A) OR B
+ end
+ 7:
+ begin
+ Select = 4'b1001; // function: NOT (A XOR B)
+ end
+ 8:
+ begin
+ Select = 4'b1011; // function: A AND B
+ end
+ 9:
+ begin
+ Select = 4'b1101; // function: A OR (NOT B)
+ end
+ 10:
+ begin
+ Select = 4'b1110; // function: A OR B
+ end
+ endcase
+
+ // repeat tests: all A input values
+
+ for (j = 0; j <= 31; j++)
+ begin
+ A_bar = j;
+
+ // repeat tests: all B input values
+
+ for (k = 0; k <= 31; k++)
+ begin
+ B_bar = k;
+ C_in = 1'b0;
+#10
+ case_tbassert2I(Select == 4'b0001, F_bar == ~(A_bar | B_bar), "Test", (1 + j), (83 + i));
+
+ case_tbassert2I(Select == 4'b0010, F_bar == (~A_bar & B_bar), "Test", (1 + j), (83 + i));
+
+ case_tbassert2I(Select == 4'b0100, F_bar == ~(A_bar & B_bar), "Test", (1 + j), (83 + i));
+
+ case_tbassert2I(Select == 4'b0110, F_bar == (A_bar ^ B_bar), "Test", (1 + j), (83 + i));
+
+ case_tbassert2I(Select == 4'b0111, F_bar == (A_bar & ~B_bar), "Test", (1 + j), (83 + i));
+
+ case_tbassert2I(Select == 4'b1000, F_bar == (~A_bar | B_bar), "Test", (1 + j), (83 + i));
+
+ case_tbassert2I(Select == 4'b1001, F_bar == ~(A_bar ^ B_bar), "Test", (1 + j), (83 + i));
+
+ case_tbassert2I(Select == 4'b1011, F_bar == (A_bar & B_bar), "Test", (1 + j), (83 + i));
+
+ case_tbassert2I(Select == 4'b1101, F_bar == (A_bar | ~B_bar), "Test", (1 + j), (83 + i));
+
+ case_tbassert2I(Select == 4'b1110, F_bar == (A_bar | B_bar), "Test", (1 + j), (83 + i));
+#0
+ C_in = 1'b1;
+#10
+ // these tests are identical to above (unaffected by the Carry input):
+ case_tbassert2I(Select == 4'b0001, F_bar == ~(A_bar | B_bar), "Test", (1 + j), (83 + i));
+
+ case_tbassert2I(Select == 4'b0010, F_bar == (~A_bar & B_bar), "Test", (1 + j), (83 + i));
+
+ case_tbassert2I(Select == 4'b0100, F_bar == ~(A_bar & B_bar), "Test", (1 + j), (83 + i));
+
+ case_tbassert2I(Select == 4'b0110, F_bar == (A_bar ^ B_bar), "Test", (1 + j), (83 + i));
+
+ case_tbassert2I(Select == 4'b0111, F_bar == (A_bar & ~B_bar), "Test", (1 + j), (83 + i));
+
+ case_tbassert2I(Select == 4'b1000, F_bar == (~A_bar | B_bar), "Test", (1 + j), (83 + i));
+
+ case_tbassert2I(Select == 4'b1001, F_bar == ~(A_bar ^ B_bar), "Test", (1 + j), (83 + i));
+
+ case_tbassert2I(Select == 4'b1011, F_bar == (A_bar & B_bar), "Test", (1 + j), (83 + i));
+
+ case_tbassert2I(Select == 4'b1101, F_bar == (A_bar | ~B_bar), "Test", (1 + j), (83 + i));
+
+ case_tbassert2I(Select == 4'b1110, F_bar == (A_bar | B_bar), "Test", (1 + j), (83 + i));
+
+ end
+
+ // end repeat B input values
+
+ end
+
+ // end repeat A input values
+
+ end
+
+ // end repeat Select input values
+#75
+
+ // the following set of tests show the use of active-low data convention
+ // for arithmetic Add and Subtract and some logic operations
+
+ // the following set of tests are for: arithmetic: add
+
+ // Notes:
+ //
+ // 1. this function is independent of active-high or active-low data choice; the behaviour
+ // is identical when the represented numbers are identical but all bits are inverted
+
+ Mode = 1'b0;
+
+ Select = 4'b1001;
+
+ // repeat tests: Carry input values
+
+ for (i = 1; i <= 2; i++)
+ begin
+ case (i)
+ 1:
+ begin
+ C_in = 1'b1;
+ end
+ 2:
+ begin
+ C_in = 1'b0;
+ end
+ endcase
+
+ // repeat tests: A input takes a range of representative values
+
+ for (j = 1; j <= 8; j++)
+ begin
+ case (j)
+ 1:
+ begin
+ A_bar = 5'b00001;
+ end
+ 2:
+ begin
+ A_bar = 5'b00111;
+ end
+ 3:
+ begin
+ A_bar = 5'b11001;
+ end
+ 4:
+ begin
+ A_bar = 5'b11110;
+ end
+ 5:
+ begin
+ A_bar = 5'b00000;
+ end
+ 6:
+ begin
+ A_bar = 5'b11111;
+ end
+ 7:
+ begin
+ A_bar = 5'b10101;
+ end
+ 8:
+ begin
+ A_bar = 5'b01010;
+ end
+ endcase
+
+ // repeat tests: all B input values
+
+ for (k = 0; k <= 31; k++)
+ begin
+ B_bar = k;
+
+ A_value = ~A_bar;
+ B_value = ~B_bar;
+ C_in_value = C_in; // remove the inversion of the Carry for use in mathematical statement
+#10
+ F_value = ~F_bar;
+ C_out_value = C_out; // " "
+
+ tbassert2I({C_out_value, F_value} == {1'b0, A_value} + {1'b0, B_value} + C_in_value, "Test", j, (93 + i));
+
+ end
+
+ // end repeat B input values
+
+ end
+
+ // end repeat A input values
+
+ end
+
+ // end repeat Carry input values
+#45
+
+ // the following set of tests are for: arithmetic: subtract
+
+ // Notes:
+ //
+ // 1. this function is independent of active-high or active-low data choice; the behaviour
+ // is identical when the represented numbers are identical but all bits are inverted
+
+ // Mode = 1'b0;
+
+ Select = 4'b0110;
+
+ // repeat tests: Carry input values
+
+ for (i = 1; i <= 2; i++)
+ begin
+ case (i)
+ 1:
+ begin
+ C_in = 1'b1;
+ end
+ 2:
+ begin
+ C_in = 1'b0;
+ end
+ endcase
+
+ // repeat tests: A input takes a range of representative values
+
+ for (j = 1; j <= 8; j++)
+ begin
+ case (j)
+ 1:
+ begin
+ A_bar = 5'b00001;
+ end
+ 2:
+ begin
+ A_bar = 5'b00111;
+ end
+ 3:
+ begin
+ A_bar = 5'b11001;
+ end
+ 4:
+ begin
+ A_bar = 5'b11110;
+ end
+ 5:
+ begin
+ A_bar = 5'b00000;
+ end
+ 6:
+ begin
+ A_bar = 5'b11111;
+ end
+ 7:
+ begin
+ A_bar = 5'b10101;
+ end
+ 8:
+ begin
+ A_bar = 5'b01010;
+ end
+ endcase
+
+ // repeat tests: all B input values
+
+ for (k = 0; k <= 31; k++)
+ begin
+ B_bar = k;
+
+ A_value = ~A_bar;
+ B_value = ~B_bar;
+ C_in_value = C_in; // remove the inversion of the Carry for use in mathematical statement
+#10
+ F_value = ~F_bar;
+ C_out_value = C_out; // " "
+
+ tbassert2I({C_out_value, F_value} == {1'b0, A_value} - {1'b0, B_value} + {WIDTH{1'b1}} + C_in_value, "Test", j, (95 + i));
+
+ end
+
+ // end repeat B input values
+
+ end
+
+ // end repeat A input values
+
+ end
+
+ // end repeat Carry input values
+#45
+
+ // the following set of tests are for: logic: output dependent on A, B
+
+ // Notes:
+ //
+ // 1. these ten functions are dependent on active-low data choice; they are different from
+ // the functions seen above for active-high data (see datasheet)
+
+ Mode = 1'b1;
+
+ // repeat tests: ten Select input values in binary complementary pairs
+
+ for (i = 1; i <= 10; i++)
+ begin
+ case (i)
+ 1:
+ begin
+ Select = 4'b0001; // function: NOT (A AND B)
+ end
+ 2:
+ begin
+ Select = 4'b0010; // function: (NOT A) OR B
+ end
+ 3:
+ begin
+ Select = 4'b0100; // function: NOT (A OR B)
+ end
+ 4:
+ begin
+ Select = 4'b0110; // function: NOT (A XOR B)
+ end
+ 5:
+ begin
+ Select = 4'b0111; // function: A OR (NOT B)
+ end
+ 6:
+ begin
+ Select = 4'b1000; // function: (NOT A) AND B == NOT (A OR (NOT B)) by DeMorgan's rule
+ end
+ 7:
+ begin
+ Select = 4'b1001; // function: A XOR B
+ end
+ 8:
+ begin
+ Select = 4'b1011; // function: A OR B
+ end
+ 9:
+ begin
+ Select = 4'b1101; // function: A AND (NOT B) == NOT ((NOT A) OR B) by DeMorgan's rule
+ end
+ 10:
+ begin
+ Select = 4'b1110; // function: A AND B
+ end
+ endcase
+
+ // repeat tests: A, B inputs take a range of representative values
+
+ for (j = 1; j <= 18; j++)
+ begin
+ case (j)
+ 1:
+ begin
+ A_bar = 5'b00001;
+ B_bar = 5'b00001;
+ end
+ 2:
+ begin
+ A_bar = 5'b00111;
+ B_bar = 5'b00001;
+ end
+ 3:
+ begin
+ A_bar = 5'b11001;
+ B_bar = 5'b00001;
+ end
+ 4:
+ begin
+ A_bar = 5'b11110;
+ B_bar = 5'b00001;
+ end
+ 5:
+ begin
+ A_bar = 5'b00000;
+ B_bar = 5'b00001;
+ end
+ 6:
+ begin
+ A_bar = 5'b11111;
+ B_bar = 5'b00001;
+ end
+ 7:
+ begin
+ A_bar = 5'b10101;
+ B_bar = 5'b00001;
+ end
+ 8:
+ begin
+ A_bar = 5'b01010;
+ B_bar = 5'b00001;
+ end
+ 9:
+ begin
+ A_bar = 5'b00000;
+ B_bar = 5'b00000;
+ end
+ 10:
+ begin
+ A_bar = 5'b11111;
+ B_bar = 5'b11111;
+ end
+ 11:
+ begin
+ A_bar = 5'b00001;
+ B_bar = 5'b10000;
+ end
+ 12:
+ begin
+ A_bar = 5'b00111;
+ B_bar = 5'b11110;
+ end
+ 13:
+ begin
+ A_bar = 5'b11110;
+ B_bar = 5'b10000;
+ end
+ 14:
+ begin
+ A_bar = 5'b01010;
+ B_bar = 5'b11100;
+ end
+ 15:
+ begin
+ A_bar = 5'b01000;
+ B_bar = 5'b11111;
+ end
+ 16:
+ begin
+ A_bar = 5'b10111;
+ B_bar = 5'b00000;
+ end
+ 17:
+ begin
+ A_bar = 5'b11100;
+ B_bar = 5'b11100;
+ end
+ 18:
+ begin
+ A_bar = 5'b11011;
+ B_bar = 5'b11011;
+ end
+ endcase
+
+ A_value = ~A_bar;
+ B_value = ~B_bar;
+#10
+ F_value = ~F_bar;
+
+ case_tbassert2I(Select == 4'b0001, F_value == ~(A_value & B_value), "Test", j, (97 + i));
+
+ case_tbassert2I(Select == 4'b0010, F_value == (~A_value | B_value), "Test", j, (97 + i));
+
+ case_tbassert2I(Select == 4'b0100, F_value == ~(A_value | B_value), "Test", j, (97 + i));
+
+ case_tbassert2I(Select == 4'b0110, F_value == ~(A_value ^ B_value), "Test", j, (97 + i));
+
+ case_tbassert2I(Select == 4'b0111, F_value == (A_value | ~B_value), "Test", j, (97 + i));
+
+ case_tbassert2I(Select == 4'b1000, F_value == (~A_value & B_value), "Test", j, (97 + i));
+
+ case_tbassert2I(Select == 4'b1001, F_value == (A_value ^ B_value), "Test", j, (97 + i));
+
+ case_tbassert2I(Select == 4'b1011, F_value == (A_value | B_value), "Test", j, (97 + i));
+
+ case_tbassert2I(Select == 4'b1101, F_value == (A_value & ~B_value), "Test", j, (97 + i));
+
+ case_tbassert2I(Select == 4'b1110, F_value == (A_value & B_value), "Test", j, (97 + i));
+
+ end
+
+ // end repeat A, B input values
+
+ end
+
+ // end repeat Select input values
+#10
+ $finish;
+end
+
+endmodule
diff --git a/source-7400/74181.v b/source-7400/74181.v
new file mode 100644
index 0000000..7a67b75
--- /dev/null
+++ b/source-7400/74181.v
@@ -0,0 +1,318 @@
+// 4-bit arithmetic logic unit
+
+// Notes:
+//
+// - can be used with active-high or active-low data convention (see datasheet);
+// for many of the Select inputs, the data convention used affects the operation performed;
+// however, the following operations are consistent and unaffected by active-high or active-low:
+// Select == 1001 (Add)
+// Select == 0110 (Subtract)
+// Select == 1100 (A PLUS A or Shift Left)
+// Select == 0011 (MINUS 1)
+//
+// - Mode == 0 is for arithmetic (carry is included in calculations);
+// Mode == 1 is for logic (carry is irrelevant)
+//
+// - C_in, C_out carry signals are inverted compared to A, B and F signals;
+// for example, with active-high data, A_bar == 0 means zero, C_in == 1 means no carry in
+//
+// - CP_bar output is carry propagate to another unit (for carry lookahead across multiple units);
+// CG_bar output is carry generate to another unit ( " " )
+//
+// - Equal flag output is a valid comparator output only in a specific configuration:
+// the operation must be Select == 0110 (Subtract) with C_in == 1;
+// also in this configuration, Equal and C_out can be used together to indicate B < A or B > A
+//
+// * refer to test bench file 74181-tb.v that comes with your 74181 device for notes
+// and functional specs, before you attempt to create a fully working circuit
+
+module ttl_74181 #(parameter WIDTH = 4, DELAY_RISE = 0, DELAY_FALL = 0)
+(
+ input [3:0] Select,
+ input Mode,
+ input C_in,
+ input [WIDTH-1:0] A_bar,
+ input [WIDTH-1:0] B_bar,
+ output CP_bar,
+ output CG_bar,
+ output Equal,
+ output C_out,
+ output [WIDTH-1:0] F_bar
+);
+
+//------------------------------------------------//
+reg CP_computed;
+reg CG_computed;
+wire Equal_computed;
+reg C_in_bar;
+reg C_computed_bar;
+reg C_computed;
+reg [WIDTH-1:0] F_computed;
+wire [WIDTH-1:0] P_internal;
+wire [WIDTH-1:0] G_internal;
+wire [WIDTH-1:0] CG_internal;
+
+generate
+ genvar i;
+ for (i = 0; i < WIDTH; i = i + 1)
+ begin: gen_internals
+ // first layer: internal propagate and generate signals from each A, B bit pair
+ // used for carry output C (in the logic section), and used for
+ // carry lookahead outputs CP and CG
+ //
+ assign P_internal[i] = ~(A_bar[i] & ~B_bar[i] & Select[2] | A_bar[i] & B_bar[i] & Select[3]);
+ assign G_internal[i] = ~(A_bar[i] | B_bar[i] & Select[0] | ~B_bar[i] & Select[1]);
+
+ // second layer: internal carry generate signals from the propagate and generate signals,
+ // used for carry lookahead output CG
+ //
+ // the generated code has this structure (terms are then joined by |):
+ // CG_internal[0] = P_internal[1] & P_internal[2] & P_internal[3] & G_internal[0];
+ // CG_internal[1] = P_internal[2] & P_internal[3] & G_internal[1];
+ // CG_internal[2] = P_internal[3] & G_internal[2];
+ // CG_internal[3] = G_internal[3];
+ //
+ if (i < WIDTH - 1)
+ begin
+ assign CG_internal[i] = (&P_internal[(WIDTH - 1):(i + 1)]) & G_internal[i];
+ end
+ else
+ begin
+ assign CG_internal[i] = G_internal[i];
+ end
+ end
+endgenerate
+
+always @(*)
+begin
+ if (!Mode)
+ begin
+ // arithmetic
+
+ C_in_bar = ~C_in;
+
+ // add (A PLUS B PLUS Carry)
+ if (Select == 4'b1001)
+ begin
+ {C_computed_bar, F_computed} = {1'b0, A_bar} + {1'b0, B_bar} + C_in_bar;
+ end
+
+ // subtract (A MINUS B MINUS 1 PLUS Carry)
+ if (Select == 4'b0110)
+ begin
+ {C_computed_bar, F_computed} = {1'b0, A_bar} - {1'b0, B_bar} + {WIDTH{1'b1}} + C_in_bar;
+ end
+
+ // other arithmetic incorporating logic
+
+ // A PLUS Carry
+ if (Select == 4'b0000)
+ begin
+ {C_computed_bar, F_computed} = {1'b0, A_bar} + C_in_bar;
+ end
+
+ // A OR B PLUS Carry
+ if (Select == 4'b0001)
+ begin
+ {C_computed_bar, F_computed} = {1'b0, A_bar | B_bar} + C_in_bar;
+ end
+
+ // A OR (NOT B) PLUS Carry
+ if (Select == 4'b0010)
+ begin
+ {C_computed_bar, F_computed} = {1'b0, A_bar | ~B_bar} + C_in_bar;
+ end
+
+ // MINUS 1 PLUS Carry
+ if (Select == 4'b0011)
+ begin
+ {C_computed_bar, F_computed} = {WIDTH{1'b1}} + C_in_bar;
+ end
+
+ // A PLUS (A AND (NOT B)) PLUS Carry
+ if (Select == 4'b0100)
+ begin
+ {C_computed_bar, F_computed} = {1'b0, A_bar} + {1'b0, A_bar & ~B_bar} + C_in_bar;
+ end
+
+ // (A OR B) PLUS (A AND (NOT B)) PLUS Carry
+ if (Select == 4'b0101)
+ begin
+ {C_computed_bar, F_computed} = {1'b0, A_bar | B_bar} + {1'b0, A_bar & ~B_bar} + C_in_bar;
+ end
+
+ // (A AND (NOT B)) MINUS 1 PLUS Carry
+ if (Select == 4'b0111)
+ begin
+ {C_computed_bar, F_computed} = {1'b0, A_bar & ~B_bar} + {WIDTH{1'b1}} + C_in_bar;
+ end
+
+ // A PLUS (A AND B) PLUS Carry
+ if (Select == 4'b1000)
+ begin
+ {C_computed_bar, F_computed} = {1'b0, A_bar} + {1'b0, A_bar & B_bar} + C_in_bar;
+ end
+
+ // (A OR (NOT B)) PLUS (A AND B) PLUS Carry
+ if (Select == 4'b1010)
+ begin
+ {C_computed_bar, F_computed} = {1'b0, A_bar | ~B_bar} + {1'b0, A_bar & B_bar} + C_in_bar;
+ end
+
+ // (A AND B) MINUS 1 PLUS Carry
+ if (Select == 4'b1011)
+ begin
+ {C_computed_bar, F_computed} = {1'b0, A_bar & B_bar} + {WIDTH{1'b1}} + C_in_bar;
+ end
+
+ // A PLUS A (SHIFT LEFT) PLUS Carry
+ if (Select == 4'b1100)
+ begin: sum_block
+ reg [WIDTH:0] extra_width_sum;
+
+ extra_width_sum = A_bar << 1;
+
+ {C_computed_bar, F_computed} = extra_width_sum + C_in_bar;
+ end
+
+ // A PLUS (A OR B) PLUS Carry
+ if (Select == 4'b1101)
+ begin
+ {C_computed_bar, F_computed} = {1'b0, A_bar} + {1'b0, A_bar | B_bar} + C_in_bar;
+ end
+
+ // A PLUS (A OR (NOT B)) PLUS Carry
+ if (Select == 4'b1110)
+ begin
+ {C_computed_bar, F_computed} = {1'b0, A_bar} + {1'b0, A_bar | ~B_bar} + C_in_bar;
+ end
+
+ // A MINUS 1 PLUS Carry
+ if (Select == 4'b1111)
+ begin
+ {C_computed_bar, F_computed} = {1'b0, A_bar} + {WIDTH{1'b1}} + C_in_bar;
+ end
+
+ C_computed = ~C_computed_bar;
+ end
+ else
+ begin
+ // logic
+
+ // NOT A
+ if (Select == 4'b0000)
+ begin
+ F_computed = ~A_bar;
+ end
+
+ // NOT (A OR B)
+ if (Select == 4'b0001)
+ begin
+ F_computed = ~(A_bar | B_bar);
+ end
+
+ // (NOT A) AND B
+ if (Select == 4'b0010)
+ begin
+ F_computed = ~A_bar & B_bar;
+ end
+
+ // 0
+ if (Select == 4'b0011)
+ begin
+ F_computed = {WIDTH{1'b0}};
+ end
+
+ // NOT (A AND B)
+ if (Select == 4'b0100)
+ begin
+ F_computed = ~(A_bar & B_bar);
+ end
+
+ // NOT B
+ if (Select == 4'b0101)
+ begin
+ F_computed = ~B_bar;
+ end
+
+ // A XOR B
+ if (Select == 4'b0110)
+ begin
+ F_computed = A_bar ^ B_bar;
+ end
+
+ // A AND (NOT B)
+ if (Select == 4'b0111)
+ begin
+ F_computed = A_bar & ~B_bar;
+ end
+
+ // (NOT A) OR B
+ if (Select == 4'b1000)
+ begin
+ F_computed = ~A_bar | B_bar;
+ end
+
+ // NOT (A XOR B)
+ if (Select == 4'b1001)
+ begin
+ F_computed = ~(A_bar ^ B_bar);
+ end
+
+ // B
+ if (Select == 4'b1010)
+ begin
+ F_computed = B_bar;
+ end
+
+ // A AND B
+ if (Select == 4'b1011)
+ begin
+ F_computed = A_bar & B_bar;
+ end
+
+ // 1
+ if (Select == 4'b1100)
+ begin
+ F_computed = {WIDTH{1'b1}};
+ end
+
+ // A OR (NOT B)
+ if (Select == 4'b1101)
+ begin
+ F_computed = A_bar | ~B_bar;
+ end
+
+ // A OR B
+ if (Select == 4'b1110)
+ begin
+ F_computed = A_bar | B_bar;
+ end
+
+ // A
+ if (Select == 4'b1111)
+ begin
+ F_computed = A_bar;
+ end
+
+ // third layer: carry bit
+ C_computed = C_in & (&P_internal) | (|CG_internal);
+ end
+
+ // third layer: carry lookahead bits aggregated from the above terms
+ CP_computed = ~(&P_internal);
+ CG_computed = ~(|CG_internal);
+end
+
+// output
+assign Equal_computed = &F_computed;
+
+//------------------------------------------------//
+
+assign #(DELAY_RISE, DELAY_FALL) CP_bar = CP_computed;
+assign #(DELAY_RISE, DELAY_FALL) CG_bar = CG_computed;
+assign #(DELAY_RISE, DELAY_FALL) Equal = Equal_computed;
+assign #(DELAY_RISE, DELAY_FALL) C_out = C_computed;
+assign #(DELAY_RISE, DELAY_FALL) F_bar = F_computed;
+
+endmodule