It didn't go as expected.
The comparator doesn't use NAND/NOR because it actually makes it larger and/or bigger, and what matters is the critical path along the cascade. Fortunately A21OI is here and helps! the 4 gates are not in the critical datapath so over-optimising for speed is less interesting than optimising for area.

The tested source code is there : https://github.com/YannGuidon/miniMAC_tx/blob/main/src/gPEAC18.v
/* This module compares a 18-bit number to the modulus.
Compare a bitvector with the constant 258114 = 0x3F042 = 111111000001000010
Any number equal or above raises X */
module Compare_modulus(
input wire [17:0] A,
input wire En,
output wire X
);
wire t1, t2, t3, t4, t5, t6, t7, _unused;
assign _unused = A[0]; // The LSB has no effect.
// first layer
(* keep *) sg13g2_and4_1 L1a3_1(.X(t1), .A(A[17]), .B(A[16]), .C(A[15]), .D(En));
(* keep *) sg13g2_and3_1 L1a3_2(.X(t2), .A(A[14]), .B(A[13]), .C(A[12]));
(* keep *) sg13g2_or3_1 L1o3_1(.X(t3), .A(A[11]), .B(A[10]), .C(A[ 9]));
(* keep *) sg13g2_or3_1 L1o3_2(.X(t4), .A(A[ 3]), .B(A[ 2]), .C(A[ 1]));
// 2nd layer
(* keep *) sg13g2_or3_1 L2o3_3(.X(t5), .A(t3), .B(A[ 8]), .C(A[ 7]));
(* keep *) sg13g2_or3_1 L2o3_4(.X(t6), .A(t4), .B(A[ 5]), .C(A[ 4]));
// 3rd layer
(* keep *) sg13g2_a21o_2 L3ao_1(.X(t7), .A1(t6), .A2(A[6]), .B1(t5));
// Last stage
(* keep *) sg13g2_and3_1 L4a3_3(.X( X), .A(t1), .B(t2), .C(t7));
endmodule
.
I just realised I could do some bubble-pushing and shave a bit...
The A21O can be turned into A21OI then feed to the AND3 turned into NOR3.
The other AND3s are turned to NAND3s.

.
Yann Guidon / YGDES
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.