45 개 NAND (또는 43 개)
45는 절대 최소값 인 것 같지만 트릭으로 43 개의 NAND에 도달 할 수 있습니다. 가장 큰 숫자가 올바르게 인코딩되었다고 가정하면.
888, 889, 898, 899, 988, 989, 998, 999는 00으로 2 MSB로 인코딩되며, 디코딩을 위해 43 개의 NAND 만 필요합니다.
그러나, 디코딩 사양에서, 이들은 무시되도록 지정되어 있으며, 이는 무엇이든 될 수 있음을 의미한다. 이보다 자유로운 사양은 더 적은 수의 게이트를 요구할 수 있지만, 그 반대의 경우도 마찬가지입니다. 이를 위해서는 45 개의 게이트가 필요합니다. 이러한 절약은 실제 회로에 실질적인 이점을 줄 수 있습니다.
또한 게이트가 몇 개 더 포함되어 훨씬 더 효율적이고 빠른 회로를 발견했습니다.
이번에는 연필로 그려진 회로 이미지가 없습니다. 아마 나중에
회로는 명백한 Verilog 코드로 제공되며 테스트가 포함 된 상태에서 실행할 수 있습니다.
Verilog 코드 :
// Densely packed decimal (DPD) to decimal, circuit in Verilog.
// 45 NANDs only, which seems to be minimal.
//
// By Kim Øyhus 2019 (c) into (CC BY-SA 3.0.)
// This work is licensed under the Creative Commons Attribution 3.0
// Unported License. To view a copy of this license, visit
// https://creativecommons.org/licenses/by-sa/3.0/
//
// This is my entry to win this Programming Puzzle & Code Golf
// at Stack Exchange:
// /codegolf/176557/densely-packed-decimal-dpd-to-decimal-with-logic-gates
//
// TASK:
// 3 decimal digits are stored in 10 bits in the DPD format,
// and this circuit transforms them into 3 decimal digits in
// 4 bits each, BCD format.
//
// 45 gates seem to be the smallest possible NAND circuit there is
// for this task, but I can get even lower by a trick, to 43:
// I assume that the largest numbers are correctly encoded.
// 888, 889, 898, 899, 988, 989, 998, 999 are to be encoded
// with the 2 MSB as 00, requiring just 43 NANDs for decoding.
//
// However, in the specification for decoding, they are specified
// to be ignored, meaning they can be anything. It is a reasonable
// assumption that this freer specification could require even fewer
// gates, but the opposite is true. 45 gates are required for this.
// This saving could give real benefits for real circuits.
//
// This DPD format seems to be used a lot for storing decimal numbers
// in computers and IO for ALUs, even though it is stored as 12 bits
// per 3 digits inside the ALUs and for other calculations.
// It is also used in many patents.
module decode1000 ( in_000, in_001, in_002, in_003, in_004, in_005, in_006, in_007, in_008, in_009, out000, out001, out002, out003, out004, out005, out006, out007, out008, out009, out010, out011 );
input in_000, in_001, in_002, in_003, in_004, in_005, in_006, in_007, in_008, in_009;
output out000, out001, out002, out003, out004, out005, out006, out007, out008, out009, out010, out011;
wire wir000, wir001, wir002, wir003, wir004, wir005, wir006, wir007, wir008, wir009, wir010, wir011, wir012, wir013, wir014, wir015, wir016, wir017, wir018, wir019, wir020, wir021, wir022, wir023, wir024, wir025, wir026, wir027, wir028, wir029, wir030, wir031, wir032;
nand gate000 ( wir000, in_007, in_007 );
nand gate001 ( wir001, in_003, in_001 );
nand gate002 ( wir002, in_002, in_003 );
nand gate003 ( wir003, wir001, in_006 );
nand gate004 ( wir004, wir002, in_001 );
nand gate005 ( wir005, wir001, wir001 );
nand gate006 ( wir006, in_005, in_001 );
nand gate007 ( wir007, wir006, in_003 );
nand gate008 ( out008, wir000, wir000 );
nand gate009 ( wir008, wir004, wir007 );
nand gate010 ( wir009, wir005, in_006 );
nand gate011 ( wir010, wir007, wir007 );
nand gate012 ( wir011, wir009, in_002 );
nand gate013 ( wir012, wir011, wir009 );
nand gate014 ( wir013, wir011, wir011 );
nand gate015 ( wir014, in_008, wir013 );
nand gate016 ( wir015, in_009, wir013 );
nand gate017 ( wir016, wir010, wir014 );
nand gate018 ( wir017, wir014, wir005 );
nand gate019 ( wir018, wir015, wir015 );
nand gate020 ( wir019, wir011, wir008 );
nand gate021 ( wir020, wir019, wir006 );
nand gate022 ( wir021, wir010, wir018 );
nand gate023 ( wir022, wir020, wir004 );
nand gate024 ( wir023, wir016, wir008 );
nand gate025 ( out001, wir023, wir023 );
nand gate026 ( out003, wir022, wir022 );
nand gate027 ( wir024, wir005, wir008 );
nand gate028 ( wir025, wir012, wir002 );
nand gate029 ( wir026, wir019, in_003 );
nand gate030 ( wir027, in_004, in_004 );
nand gate031 ( out007, wir024, wir009 );
nand gate032 ( out011, wir026, wir026 );
nand gate033 ( wir028, wir017, in_005 );
nand gate034 ( wir029, in_000, in_000 );
nand gate035 ( wir030, wir026, in_008 );
nand gate036 ( out005, wir028, wir028 );
nand gate037 ( out009, wir030, wir030 );
nand gate038 ( out000, wir029, wir029 );
nand gate039 ( wir031, wir026, in_009 );
nand gate040 ( out004, wir027, wir027 );
nand gate041 ( out010, wir031, wir031 );
nand gate042 ( wir032, out003, wir018 );
nand gate043 ( out006, wir003, wir032 );
nand gate044 ( out002, wir025, wir021 );
endmodule
module test;
reg [ 9:0] AB; // input DPD
wire [11:0] C; // output BCD
decode1000 U1 (
.in_000 (AB[ 0]),
.in_001 (AB[ 1]),
.in_002 (AB[ 2]),
.in_003 (AB[ 3]),
.in_004 (AB[ 4]),
.in_005 (AB[ 5]),
.in_006 (AB[ 6]),
.in_007 (AB[ 7]),
.in_008 (AB[ 8]),
.in_009 (AB[ 9]),
.out000 ( C[ 0]),
.out001 ( C[ 1]),
.out002 ( C[ 2]),
.out003 ( C[ 3]),
.out004 ( C[ 4]),
.out005 ( C[ 5]),
.out006 ( C[ 6]),
.out007 ( C[ 7]),
.out008 ( C[ 8]),
.out009 ( C[ 9]),
.out010 ( C[10]),
.out011 ( C[11])
);
initial AB=0; //unary=0; binary=0
always #1 AB = AB+1;
initial begin
$display("\t\ttime,\tinn 10bit \tout 3x4bit");
$monitor("%d,\t%b %b %b\t%b %b %b\t %d%d%d",$time, AB[9:7],AB[6:4],AB[3:0], C[11:8], C[7:4], C[3:0], C[11:8], C[7:4], C[3:0]);
end
initial #1023 $finish;
endmodule
// How I run and test it:
// iverilog -o decode1000 decode1000.v
// vvp decode1000