TTL74185

Aus der Mikrocontroller.net Artikelsammlung, mit Beiträgen verschiedener Autoren (siehe Versionsgeschichte)
Wechseln zu: Navigation, Suche

Übersicht

Nachbau des Standard TTL 74185 (6 bit binary zu BCD).
Siehe Forum: http://www.mikrocontroller.net/topic/55594 .

  • Code ist nicht simuliert, läuft aber einwandfrei durch Synthese.
  • Wandelt man den Eingang zu einem Integer wird der Code besser lesbar.

Es werden hier verschiedene Varianten gezeigt:

Realisierung als einzelne logische Gleichungen

Zuerst die mit logischen Gleichungen für die Ausgänge. Um es dem Synthese-Tool leichter zu machen, wird das untere Eingangsbit nicht mit ausgewertet. Durch die select Anweisung beschreibt man eine Wahrheitstabelle die einfach in LUTs und Multiplexer umgewandelt wird (Xilinx). Bei Altera mit den 6 Input LUTs spart man sich die Multiplexer.

Code

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;

--vhdl description of 74185
--6bit binary to 2 digits BCD decoder

ENTITY ttl74185 IS
  PORT (
    binary_i : IN  STD_LOGIC_VECTOR(5 DOWNTO 0);
    bcd_o    : OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END ttl74185;

ARCHITECTURE behave OF ttl74185 IS
  --integers are better readable for humans
  SIGNAL conv_input : integer RANGE 2**5-1 DOWNTO 0;
  
BEGIN  -- behave
 conv_input <= to_integer(unsigned(binary_i(5 DOWNTO 1)));
  
  bcd_o(0) <= binary_i(0);

  WITH conv_input SELECT
    bcd_o(1) <=
    '1' WHEN    1,'1' WHEN  3, '1' WHEN  6, '1' WHEN  8,
    '1' WHEN   11,'1' WHEN 13, '1' WHEN 16, '1' WHEN 18,
    '1' WHEN   21,'1' WHEN 23, '1' WHEN 26, '1' WHEN 28,
    '1' WHEN   31,
    '0' WHEN OTHERS;

  WITH conv_input SELECT
    bcd_o(2) <=
    '1' WHEN    2,'1' WHEN  3, '1' WHEN  7, '1' WHEN 8,  
    '1' WHEN   12,'1' WHEN 13, '1' WHEN 17, '1' WHEN 18, 
    '1' WHEN   22,'1' WHEN 23, '1' WHEN 27, '1' WHEN 28, 
    '0' WHEN OTHERS;
              
  WITH conv_input SELECT
    bcd_o(3) <=
    '1' WHEN    4,'1' WHEN  9, '1' WHEN 14, '1' WHEN 19,  
    '1' WHEN   24,'1' WHEN 29,
    '0' WHEN OTHERS;

  WITH conv_input SELECT
    bcd_o(4) <=
    '1' WHEN  5,'1' WHEN  6, '1' WHEN  7, '1' WHEN  8, '1' WHEN  9,  
    '1' WHEN 15,'1' WHEN 16, '1' WHEN 17, '1' WHEN 18, '1' WHEN 19,  
    '1' WHEN 25,'1' WHEN 26, '1' WHEN 27, '1' WHEN 28, '1' WHEN 29,  
    '0' WHEN OTHERS;

 WITH conv_input SELECT
    bcd_o(5) <=
    '1' WHEN 10,'1' WHEN 11, '1' WHEN 12, '1' WHEN 13, '1' WHEN 14,  
    '1' WHEN 15,'1' WHEN 16, '1' WHEN 17, '1' WHEN 18, '1' WHEN 19,  
    '1' WHEN 30,'1' WHEN 31,
    '0' WHEN OTHERS;
 
  WITH conv_input SELECT
    bcd_o(6) <=
    '1' WHEN 20,'1' WHEN 21, '1' WHEN 22, '1' WHEN 23, '1' WHEN 24,  
    '1' WHEN 25,'1' WHEN 26, '1' WHEN 27, '1' WHEN 28, '1' WHEN 29,  
    '1' WHEN 30,'1' WHEN 31,
    '0' WHEN OTHERS;
   
   bcd_o(7) <= '0';

  END behave;

Synthese Ergebnis

   Found 32x1-bit ROM for signal <bcd_o<4>>.
   Found 16x1-bit ROM for signal <$mux0000>.
   Found 16x1-bit ROM for signal <$mux0001>.
   Summary:

inferred 3 ROM(s).

Macro Statistics

  1. ROMs  : 3
16x1-bit ROM                                          : 2
32x1-bit ROM                                          : 1


Design Statistics

  1. IOs  : 14

Cell Usage :

  1. BELS  : 12
  2. GND  : 1
  3. LUT3  : 1
  4. LUT4  : 7
  5. MUXF5  : 3
  6. IO Buffers  : 14
  7. IBUF  : 6
  8. OBUF  : 8


Number of Slices:                       4  out of    768     0%  
Number of 4 input LUTs:                 8  out of   1536     0%  
Number of IOs:                         14
Number of bonded IOBs:                 14  out of     63    22%  


  Maximum combinational path delay: 9.599ns


 Total number of paths / destination ports: 36 / 7

Delay: 9.599ns (Levels of Logic = 4)

 Source:            binary_i<3> (PAD)
 Destination:       bcd_o<4> (PAD)
 Data Path: binary_i<3> to bcd_o<4>
                               Gate     Net
   Cell:in->out      fanout   Delay   Delay  Logical Name (Net Name)
   ----------------------------------------  ------------
    IBUF:I->O             8   0.821   1.422  binary_i_3_IBUF (binary_i_3_IBUF)
    LUT4:I0->O            1   0.551   0.000  _or0000_F (N16)
    MUXF5:I0->O           1   0.360   0.801  _or0000 (bcd_o_2_OBUF)
    OBUF:I->O                 5.644          bcd_o_2_OBUF (bcd_o<2>)
   ----------------------------------------
   Total                      9.599ns (7.376ns logic, 2.223ns route)
                                      (76.8% logic, 23.2% route)

Konstanten Array

Code

Jetzt eine zweite Variante als ROM-Feld. Diese ist im Xilinx FPGA größer (5 statt 4 slices). Und ungünstiger im Routing die die Signale auf einen Punkt (ROM) und dann wieder von diesem weg geführt werden. Aber dafür auf den ersten Blick verständlich, besonders wenn man den Ausgangsvektor in hex schreibt. Das verstehen auch die Tools besser, diese Variante läuft schneller durch.

ARCHITECTURE behave2 OF ttl74185 IS

    SIGNAL conv_input : INTEGER RANGE 2**6-1 DOWNTO 0;
    TYPE T_BIN2_TO_BCD_TABLE IS ARRAY (natural RANGE <>) OF STD_LOGIC_VECTOR(7 DOWNTO 0);

      CONSTANT C_BIN2_TO_BCD_TABLE  : T_BIN2_TO_BCD_TABLE(0 TO 2**6 - 1) :=
      (X"00", X"01", X"02", X"03", X"04", X"05", X"06", X"07", X"08", X"09",
       X"10", X"11", X"12", X"13", X"14", X"15", X"16", X"17", X"18", X"19",
       X"20", X"21", X"22", X"23", X"24", X"25", X"26", X"27", X"28", X"29",
       X"30", X"31", X"32", X"33", X"34", X"35", X"36", X"37", X"38", X"39",
       X"40", X"41", X"42", X"43", X"44", X"45", X"46", X"47", X"48", X"49",
       X"50", X"51", X"52", X"53", X"54", X"55", X"56", X"57", X"58", X"59",
       X"60", X"61", X"62", X"63");

  BEGIN  -- behave
   conv_input <= to_INTEGER(unsigned(binary_i));
   bcd_o      <= C_BIN2_TO_BCD_TABLE(conv_input);

  END behave2;

Synthese Ergebnis

Macro Statistics

  1. ROMs  : 1
64x8-bit ROM                                          : 1


Design Statistics

  1. IOs  : 14

Cell Usage :

  1. BELS  : 15
  2. GND  : 1
  3. LUT3  : 1
  4. LUT4  : 9
  5. MUXF5  : 4
  6. IO Buffers  : 14
  7. IBUF  : 6
  8. OBUF  : 8
Number of Slices:                       5  out of    768     0%  
Number of 4 input LUTs:                10  out of   1536     0%  
Number of IOs:                         14
Number of bonded IOBs:                 14  out of     63    22%  


  Maximum combinational path delay: 9.650ns


 Total number of paths / destination ports: 44 / 7

Delay: 9.650ns (Levels of Logic = 4)

 Source:            binary_i<3> (PAD)
 Destination:       bcd_o<4> (PAD)
 Data Path: binary_i<3> to bcd_o<4>
                               Gate     Net
   Cell:in->out      fanout   Delay   Delay  Logical Name (Net Name)
   ----------------------------------------  ------------
    IBUF:I->O            10   0.821   1.473  binary_i_3_IBUF (binary_i_3_IBUF)
    LUT4:I0->O            1   0.551   0.000  Mrom__rom00007 (N11)
    MUXF5:I1->O           1   0.360   0.801  Mrom__rom0000_f5_2 (Mrom__rom0000_f53)
    OBUF:I->O                 5.644          bcd_o_4_OBUF (bcd_o<4>)
   ----------------------------------------
   Total                      9.650ns (7.376ns logic, 2.274ns route)
                                      (76.4% logic, 23.6% route)


SELECT

Code

 ARCHITECTURE behave3 OF ttl74185 IS
     SIGNAL conv_input : INTEGER RANGE 2**6-1 DOWNTO 0;
     TYPE T_BIN2_TO_BCD_TABLE IS ARRAY (natural RANGE <>) OF STD_LOGIC_VECTOR(7 DOWNTO 0);

    BEGIN  -- behave
     conv_input <= to_INTEGER(unsigned(binary_i));

     WITH conv_input SELECT
       bcd_o <=
        X"00" WHEN  0,  X"01" WHEN  1,  X"02" WHEN  2,  X"03" WHEN  3,  X"04" WHEN  4,
        X"05" WHEN  5,  X"06" WHEN  6,  X"07" WHEN  7,  X"08" WHEN  8,  X"09" WHEN  9, 
        X"10" WHEN 10,  X"11" WHEN 11,  X"12" WHEN 12,  X"13" WHEN 13,  X"14" WHEN 14,
        X"15" WHEN 15,  X"16" WHEN 16,  X"17" WHEN 17,  X"18" WHEN 18,  X"19" WHEN 19, 
        X"20" WHEN 20,  X"21" WHEN 21,  X"22" WHEN 22,  X"23" WHEN 23,  X"24" WHEN 24,
        X"25" WHEN 25,  X"26" WHEN 26,  X"27" WHEN 27,  X"28" WHEN 28,  X"29" WHEN 29, 
        X"30" WHEN 30,  X"31" WHEN 31,  X"32" WHEN 32,  X"33" WHEN 33,  X"34" WHEN 34,
        X"35" WHEN 35,  X"36" WHEN 36,  X"37" WHEN 37,  X"38" WHEN 38,  X"39" WHEN 39, 
        X"40" WHEN 40,  X"41" WHEN 41,  X"42" WHEN 42,  X"43" WHEN 43,  X"44" WHEN 44,
        X"45" WHEN 45,  X"46" WHEN 46,  X"47" WHEN 47,  X"48" WHEN 48,  X"49" WHEN 49, 
        X"50" WHEN 50,  X"51" WHEN 51,  X"52" WHEN 52,  X"53" WHEN 53,  X"54" WHEN 54,
        X"55" WHEN 55,  X"56" WHEN 56,  X"57" WHEN 57,  X"58" WHEN 58,  X"59" WHEN 59, 
        X"60" WHEN 60,  X"61" WHEN 61,  X"52" WHEN 62,  X"63" WHEN 63; 
   END behave3;

Synthese Ergebnis

HDL Synthesis Report

Macro Statistics

  1. ROMs  : 1
64x8-bit ROM                                          : 1


Design Statistics

  1. IOs  : 14

Cell Usage :

  1. BELS  : 15
  2. GND  : 1
  3. LUT3  : 1
  4. LUT4  : 9
  5. MUXF5  : 4
  6. IO Buffers  : 14
  7. IBUF  : 6
  8. OBUF  : 8

Device utilization summary:


Selected Device : 3s50vq100-4

Number of Slices:                       5  out of    768     0%  
Number of 4 input LUTs:                10  out of   1536     0%  
Number of IOs:                         14
Number of bonded IOBs:                 14  out of     63    22%  
 Total number of paths / destination ports: 44 / 7

Delay: 9.650ns (Levels of Logic = 4)

 Source:            binary_i<3> (PAD)
 Destination:       bcd_o<4> (PAD)
 Data Path: binary_i<3> to bcd_o<4>
                               Gate     Net
   Cell:in->out      fanout   Delay   Delay  Logical Name (Net Name)
   ----------------------------------------  ------------
    IBUF:I->O            10   0.821   1.473  binary_i_3_IBUF (binary_i_3_IBUF)
    LUT4:I0->O            1   0.551   0.000  Mrom_bcd_o7 (N11)
    MUXF5:I1->O           1   0.360   0.801  Mrom_bcd_o_f5_2 (Mrom_bcd_o_f53)
    OBUF:I->O                 5.644          bcd_o_4_OBUF (bcd_o<4>)
   ----------------------------------------
   Total                      9.650ns (7.376ns logic, 2.274ns route)
                                      (76.4% logic, 23.6% route)

CASE

Code

ARCHITECTURE behave4 OF ttl74185 IS
          SIGNAL conv_input : INTEGER RANGE 2**6-1 DOWNTO 0;
          TYPE T_BIN2_TO_BCD_TABLE IS ARRAY (NATURAL RANGE <>) OF STD_LOGIC_VECTOR(7 DOWNTO 0);

        BEGIN  -- behave
          conv_input <= to_INTEGER(UNSIGNED(binary_i));

          PROCESS(conv_input)
          begin
           CASE conv_input IS
            WHEN 0   => bcd_o <= X"00";  WHEN  1 => bcd_o <= X"01";  WHEN  2 => bcd_o <= X"02";  WHEN  3 => bcd_o <= X"03";
            WHEN 5   => bcd_o <= X"05";  WHEN  6 => bcd_o <= X"06";  WHEN  7 => bcd_o <= X"07";  WHEN  8 => bcd_o <= X"08";
            WHEN 10  => bcd_o <= X"10";  WHEN 11 => bcd_o <= X"11";  WHEN 12 => bcd_o <= X"12";  WHEN 13 => bcd_o <= X"13";
            WHEN 15  => bcd_o <= X"15";  WHEN 16 => bcd_o <= X"16";  WHEN 17 => bcd_o <= X"17";  WHEN 18 => bcd_o <= X"18";
            WHEN 20  => bcd_o <= X"20";  WHEN 21 => bcd_o <= X"21";  WHEN 22 => bcd_o <= X"22";  WHEN 23 => bcd_o <= X"23";
            WHEN 25  => bcd_o <= X"25";  WHEN 26 => bcd_o <= X"26";  WHEN 27 => bcd_o <= X"27";  WHEN 28 => bcd_o <= X"28";
            WHEN 30  => bcd_o <= X"30";  WHEN 31 => bcd_o <= X"31";  WHEN 32 => bcd_o <= X"32";  WHEN 33 => bcd_o <= X"33";
            WHEN 35  => bcd_o <= X"35";  WHEN 36 => bcd_o <= X"36";  WHEN 37 => bcd_o <= X"37";  WHEN 38 => bcd_o <= X"38";
            WHEN 40  => bcd_o <= X"40";  WHEN 41 => bcd_o <= X"41";  WHEN 42 => bcd_o <= X"42";  WHEN 43 => bcd_o <= X"43";
            WHEN 45  => bcd_o <= X"45";  WHEN 46 => bcd_o <= X"46";  WHEN 47 => bcd_o <= X"47";  WHEN 48 => bcd_o <= X"48";
            WHEN 50  => bcd_o <= X"50";  WHEN 51 => bcd_o <= X"51";  WHEN 52 => bcd_o <= X"52";  WHEN 53 => bcd_o <= X"53";
            WHEN 55  => bcd_o <= X"55";  WHEN 56 => bcd_o <= X"56";  WHEN 57 => bcd_o <= X"57";  WHEN 58 => bcd_o <= X"58";
            WHEN 60  => bcd_o <= X"60";  WHEN 61 => bcd_o <= X"61";  WHEN 62 => bcd_o <= X"62";  WHEN 63 => bcd_o <= X"63";

            WHEN 4  => bcd_o <= X"04";
            WHEN 9  => bcd_o <= X"09";
            WHEN 14 => bcd_o <= X"14";
            WHEN 19 => bcd_o <= X"19";
            WHEN 24 => bcd_o <= X"24";
            WHEN 29 => bcd_o <= X"29";
            WHEN 34 => bcd_o <= X"34";
            WHEN 39 => bcd_o <= X"39";
            WHEN 44 => bcd_o <= X"44";
            WHEN 49 => bcd_o <= X"49";
            WHEN 54 => bcd_o <= X"54";
            WHEN 59 => bcd_o <= X"59";
          END case;
        END process;

        END behave4;

Synthese Ergebnis

Macro Statistics

  1. ROMs  : 1
64x8-bit ROM                                          : 1


RTL Top Level Output File Name  : ttl74185.ngr Top Level Output File Name  : ttl74185 Output Format  : NGC Optimization Goal  : Area Keep Hierarchy  : NO

Design Statistics

  1. IOs  : 14

Cell Usage :

  1. BELS  : 15
  2. GND  : 1
  3. LUT3  : 1
  4. LUT4  : 9
  5. MUXF5  : 4
  6. IO Buffers  : 14
  7. IBUF  : 6
  8. OBUF  : 8

Selected Device : 3s50vq100-4

Number of Slices:                       5  out of    768     0%  
Number of 4 input LUTs:                10  out of   1536     0%  
Number of IOs:                         14
Number of bonded IOBs:                 14  out of     63    22%  

All values displayed in nanoseconds (ns)

Delay: 9.650ns (Levels of Logic = 4)

 Source:            binary_i<3> (PAD)
 Destination:       bcd_o<4> (PAD)
 Data Path: binary_i<3> to bcd_o<4>
                               Gate     Net
   Cell:in->out      fanout   Delay   Delay  Logical Name (Net Name)
   ----------------------------------------  ------------
    IBUF:I->O            10   0.821   1.473  binary_i_3_IBUF (binary_i_3_IBUF)
    LUT4:I0->O            1   0.551   0.000  Mrom_bcd_o7 (N11)
    MUXF5:I1->O           1   0.360   0.801  Mrom_bcd_o_f5_2 (Mrom_bcd_o_f53)
    OBUF:I->O                 5.644          bcd_o_4_OBUF (bcd_o<4>)
   ----------------------------------------
   Total                      9.650ns (7.376ns logic, 2.274ns route)
                                      (76.4% logic, 23.6% route)

Mit ADD3IFGREATER4 Komponente

Im Thread wurde ein Dokument hochgeladen, das eine weitere Variante der binär zu BCD Wandlung zeigt. Kernstück ist eine 4 input -> 4 output Komponente. Damit lassen sich regelmäßige Strukturen (Treppen) zur Wandlung von Binärzahlen beliebiger Breite aufbauen. Das ist dann schon der einzige Vorteil. Gezeigt wird der im Dokument genannte Code nach eine synthesegerechten Überarbeitung als Variante I. Das zweite Beispiel zeigt die reguläre Struktur durch Instanziierung der 4->4 Komponente. Beide Varianten belegen fünf Slices.

Code I

 ARCHITECTURE behave5a OF ttl74185 IS
 BEGIN

   bcd_o(0) <= binary_i(0);

   PROCESS(binary_i)
     VARIABLE v_tmp : UNSIGNED(12 DOWNTO 0);
   BEGIN
     v_tmp := "0000" & UNSIGNED(binary_i) & "000";

     FOR i IN 0 TO 2 LOOP
       IF v_tmp(9 DOWNTO 6) > UNSIGNED'("0100") THEN
         v_tmp(9 DOWNTO 6) := "0011" + v_tmp(9 DOWNTO 6);
       END IF;
       v_tmp( 12 DOWNTO 1) := v_tmp( 11 DOWNTO 0);
     END LOOP;  -- i 
     bcd_o(7 DOWNTO 1) <= STD_LOGIC_VECTOR(v_tmp(12 DOWNTO 6));
   END PROCESS;
 END behave5a;

Synthese Ergebnis I

Code II

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;

ENTITY add3whengreater4 IS
  
  PORT (
    operand_i : IN  STD_LOGIC_VECTOR(3 DOWNTO 0);
    result_i  : OUT STD_LOGIC_VECTOR(3 DOWNTO 0));

END add3whengreater4;

ARCHITECTURE behave OF add3whengreater4 IS

BEGIN  -- behave

  WITH operand_i SELECT
    result_i <= 
    X"0" WHEN X"0",
    X"1" WHEN X"1",
    X"2" WHEN X"2",
    X"3" WHEN X"3",
    X"4" WHEN X"4",
    X"8" WHEN X"5",
    X"9" WHEN X"6",
    X"A" WHEN X"7",
    X"B" WHEN X"8",
    X"C" WHEN X"9",
    "----" WHEN others;
--     X"0" WHEN X"A",
--     X"0" WHEN X"B",
--     X"0" WHEN X"C",
--     X"0" WHEN X"D",
--     X"0" WHEN X"E",
--     X"0" WHEN X"F";
  END behave;


ARCHITECTURE behave5b OF ttl74185 IS

  SIGNAL c1  : STD_LOGIC_VECTOR(6 DOWNTO 0);
  SIGNAL c2  : STD_LOGIC_VECTOR(6 DOWNTO 0);
  SIGNAL c3  : STD_LOGIC_VECTOR(6 DOWNTO 0);
  SIGNAL op1 : STD_LOGIC_VECTOR(3 DOWNTO 0);
  SIGNAL op2 : STD_LOGIC_VECTOR(3 DOWNTO 0);
  SIGNAL op3 : STD_LOGIC_VECTOR(3 DOWNTO 0);
  
BEGIN  -- behave5b
--below c1
  op1 <= '0' & binary_i(5 DOWNTO 3);
  c1_stage : ENTITY work.add3whengreater4 PORT MAP (
    operand_i => op1,
    result_i  => c1(6 DOWNTO 3));

  c1(2 DOWNTO 0) <= binary_i(2 DOWNTO 0);

--below c2
  op2 <= c1(5 DOWNTO 3) & binary_i(2);
  c2_stage : ENTITY work.add3whengreater4 PORT MAP (
    operand_i => op2,
    result_i  => c2(5 DOWNTO 2));

  c2(6)          <= c1(6);
  c2(1 DOWNTO 0) <= c1(1 DOWNTO 0);

--below c3
  op3 <= c2(4 DOWNTO 2) & binary_i(1);
  c3_stage : ENTITY work.add3whengreater4 PORT MAP (
    operand_i => op3,
    result_i  => c3(4 DOWNTO 1));

  c3(6 DOWNTO 5) <= c2(6 DOWNTO 5);
  c3(0)          <= c2(0);

--output

  bcd_o(0)          <= c3(0);
  bcd_o(4 DOWNTO 1) <= c3(4 DOWNTO 1);
  bcd_o(5)          <= c2(5);
  bcd_o(6)          <= c1(6);

END behave5b;

Synthese Ergebnis II

Zusammenfassung

Es gibt etliche synthetisierbare VHDL Lösungen für diesen einfachen Decoder. Die Optimierung der Tools verläuft vertikal vom Eingang zum Ausgang, horizontale Bezüge sind nicht ersichtlich. Deshalb wird bei der Beschreibung mit Ausgangsfelder der einzelne Ausgang nicht verkürzt (z. B. BCD(0)). Wünschenswert ist eine kompakte Beschreibung als Feld, die dennoch aufspaltbar und somit optimierbar ist. Vielleicht sollte der Ausgang nicht als Vektor deklariert werden?