논리 게이트를 사용하여 밀도가 높은 10 진수 (DPD) ~ 10 진수


13

TNB에서 nandgame의 최근 인기 와 내 자신의 이전 도전 에서 영감을 얻었습니다 .

배경

밀도가 높은 10 진수 (DPD) 는 10 진수를 이진수로 효율적으로 저장하는 방법입니다. 10 비트에 3 개의 10 진수 (000 ~ 999)를 저장하는데, 이는 1 비트를 4 비트에 저장하는 순진 BCD보다 훨씬 효율적입니다.

변환 표

DPD는 위에서 아래로 간단한 패턴 일치를 통해 비트와 숫자 사이를 쉽게 변환하도록 설계되었습니다. 각 비트 패턴은 숫자의 상위 자릿수 (8-9) 수, 위치 및 비트를 이동하여 소수 표현을 형성하는 방법을 정의합니다.

다음은 DPD의 10 비트에서 3 개의 10 진수로의 변환 표입니다. 각 10 진수는 4 비트 이진 (BCD)으로 표시됩니다. 양쪽은 최상위 자릿수에서 가장 왼쪽으로 오른쪽에서 왼쪽으로 쓰여집니다.

Bits                 =>  Decimal         (Digit range)

a b c d e f 0 g h i  =>  0abc 0def 0ghi  (0-7) (0-7) (0-7)

a b c d e f 1 0 0 i  =>  0abc 0def 100i  (0–7) (0–7) (8–9)
a b c g h f 1 0 1 i  =>  0abc 100f 0ghi  (0–7) (8–9) (0–7)
g h c d e f 1 1 0 i  =>  100c 0def 0ghi  (8–9) (0–7) (0–7)

g h c 0 0 f 1 1 1 i  =>  100c 100f 0ghi  (8–9) (8–9) (0–7)
d e c 0 1 f 1 1 1 i  =>  100c 0def 100i  (8–9) (0–7) (8–9)
a b c 1 0 f 1 1 1 i  =>  0abc 100f 100i  (0–7) (8–9) (8–9)
x x c 1 1 f 1 1 1 i  =>  100c 100f 100i  (8–9) (8–9) (8–9)

표기법

  • 소문자 문자 a로는 i소수점 표현에 복사되는 비트입니다.
  • 01상기 입력 또는 출력 비트 패턴의 정확한 비트이다.
  • x 비트는 변환에서 무시됩니다.

직무

2 입력 NAND 게이트 를 사용하여 10 비트 DPD를 12 비트 BCD로 변환 하는 논리 회로를 구축하십시오 .

강조된 비트는 패턴 일치 비트입니다.

DPD                    Decimal  BCD
0 0 0 0 0 0 0 1 0 1    005      0000 0000 0101
            ^
0 0 0 1 1 0 0 0 1 1    063      0000 0110 0011
            ^
0 0 0 1 1 1 1 0 0 1    079      0000 0111 1001
            ^ ^ ^
0 0 0 0 0 1 1 0 1 0    090      0000 1001 0000
            ^ ^ ^
0 0 0 1 0 1 1 1 1 0    098      0000 1001 1000
      ^ ^   ^ ^ ^
1 0 1 0 1 1 1 0 1 0    592      0101 1001 0010
            ^ ^ ^
0 0 1 1 0 0 1 1 0 1    941      1001 0100 0001
            ^ ^ ^
1 1 0 0 1 1 1 1 1 1    879      1000 0111 1001
      ^ ^   ^ ^ ^
1 1 1 0 0 0 1 1 1 0    986      1001 1000 0110
      ^ ^   ^ ^ ^
0 0 1 1 1 1 1 1 1 1    999      1001 1001 1001
      ^ ^   ^ ^ ^
1 1 1 1 1 1 1 1 1 1    999      1001 1001 1001
      ^ ^   ^ ^ ^

득점 및 당첨 기준

점수는 회로에 사용 된 2 입력 NAND 게이트 의 수입니다 . 가장 낮은 점수가 이깁니다.

2 입력 NAND 게이트로 작은 구성 요소를 정의한 후 최종 구성에 사용할 수 있습니다. 구성 요소에 2 입력 NAND 게이트가 X포함 된 경우 N각 사용량이 점수 에 X추가 N됩니다. 기본 논리 게이트의 경우 다음을 의미합니다.

  • NOT : +1
  • 2 입력 AND : +2
  • 2 입력 OR : +3
  • 2 입력 XOR : +4

원자 코드 골프가 승리 기준 태그 이고 코드 도전 이 다른 태그에 포함되지 않은 승리 기준이있는 질문에 대한 것이기 때문에 Luis의 편집을 롤백 했습니다 .
피터 테일러

이것은 여전히 ​​분명하지 않습니다. 본인은 글자가 무엇인지에 대한 설명이있을 필요하다고 생각 a하는 i의미와 변환하는 과정. 단지 예제를 보여주고 이해하기를 바라기보다는 단계를 진행하십시오.
mbomb007

@ mbomb007, 아마도 내 언어 중 하나가 SML이기 때문에 분명합니다. 첫 번째 코드 블록은 실제로 패턴 일치 언어참조 구현입니다 (SMLNJ에서 더 잘 작동하지만 MLton에서보다 각 명령문의 결과를 에코합니다).
피터 테일러

@ mbomb007 변환 테이블의 패턴 일치 특성을 명확히하려고했습니다. 도움이 되나요?
Bubbler

1
@Bubbler 네, 도움이되었습니다
mbomb007

답변:


4

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

3

65 62 60 58 낸드

같은 입력에 촬영 i0i9같은과 출력 o0o9, oa, ob우리가를

t0 = nand(i6, i7)
t1 = nand(t0, t0)
t2 = nand(i3, i4)
o0 = nand(nand(nand(t2, i3), t1), nand(nand(t2, i8), t1))
t3 = nand(o0, o0)
t4 = nand(i0, t3)
o1 = nand(t4, t4)
t5 = nand(i1, t3)
o2 = nand(t5, t5)
o3 = i2
# Score 13 for the first decimal digit

u0 = nand(i6, i8)
u1 = nand(u0, t0)
u2 = nand(i4, t2)
o4 = nand(nand(nand(u2, u0), u2), nand(u1, t0))
u3 = nand(o4, o4)
u4 = nand(o0, i8)
u5 = nand(u4, u4)
u6 = nand(u3, nand(nand(u5, i0), nand(u4, i3)))
o5 = nand(u6, u6)
u7 = nand(u3, nand(nand(u5, i1), nand(u4, i4)))
o6 = nand(u7, u7)
o7 = i5
# Score 20 for the second decimal digit

o8 = nand(nand(nand(nand(i4, i8), o0), t1), nand(nand(i6, u1), i6))
v2 = nand(o8, o8)
v3 = nand(i6, i6)
v4 = nand(i7, i7)
v5 = nand(v2, nand(nand(i6, nand(nand(i7, i0), nand(v4, i3))), nand(v3, i7)))
o9 = nand(v5, v5)
v6 = nand(v2, nand(nand(i6, nand(nand(i7, i1), nand(v4, i4))), nand(v3, i8)))
oa = nand(v6, v6)
ob = i9
# Score 25 for the third decimal digit

구성의 정확성을 검증하기위한 Python 테스트 프레임 워크

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.