Multiplexer

Definition of mux: A multiplexer is a combinational circuit that selects one out of multiple input signals depending upon the state of select line. A 2^N:1 multiplexer with ‘N’ select lines can select 1 out of 2^N inputs. In other words, the multiplexer connects the output to one of its inputs based upon the value held at the select lines. A multiplexer (or commonly called as MUX) is also termed as data selector. Common functions of a multiplexer include concentrating the multiple data lines onto one single line. It can also be used as a data selector or clock selector.

Multiplexers can be categorized based upon the number of inputs:
  • 2-input mux: A 2:1 mux has 2 data input lines and 1 select line. The state of select line decides which of the inputs propagates to the output. The truth table of 2x1 mux is given below. As it shows, when SEL is 1, OUT follows IN2 and when SEL is 0, OUT follows IN1.
2:1 mux truth table, 2x1 mux truth table, 2 to 1 mux truth table, 2 by 1 mux truth table, 2 by 1 multiplexer, 2 to 1 multiplexer, 2x1 multiplexer truth table
Figure 1: Truth table of 2x1 mux
The logic circuit and symbol of 2x1 mux is shown in figure 2. Let us assume logical area of a 2:1 mux to be A.
Mux symbol, a 2:1 mux can be built using 2 2-input AND gates and an inverter.
Figure 2(a): Logic diagram of 2x1 mux                                               Figure 2(b): Schematic symbol of 2x1 mux
  • 3-input mux: A 3:1 mux has 2 select lines and 3 inputs. As a mux with 2 select lines can represent at max 4 inputs, a 3:1 mux repeats some inputs for 2 combinations. The truth table for 3-input mux is given below. As can be seen, for SEL value "10" and "11", IN2 is selected at the output (this is one of the 3 possible scenarios, repetition of IN0 or IN1 is also possible).
A 3:1 multiplexer has 2 select lines and 3 inputs. One of these inputs propagates to the output depending upon the state of select lines.
Figure 3: Truth table for 3x1 mux
The schematic symbol and structural representation (in terms of 2x1 muxes) for 3:1 mux is shown in figure 4 below. As can be figured out, 1 3x1 mux can be built using 2 2x1 muxes.
3-input mux, 3:1 mux, 3x1 mux, 3 by 1 mux, 3-input multiplexer, 3:1 multiplexer, 3x1 multiplexer schematic
Figure 4(a): Schematic symbol for 3x1 mux Figure                           4(b): Structural symbol for 3:1 mux using 2x1 muxes

  • 4-input mux: A 4:1 mux has 2 select lines and 4 inputs. The truth table for 4x1 mux is shown below:
4-input mux, 4-input multiplexer, 4x1 mux, 4x1 multiplexer, 4 by 1 mux, 4 by 1  multiplexer, 4:1 mux, 4:1 multiplexer truth table
Figure 5: Truth table for 4:1 mux
Figure 6 below shows the schematic symbol and structural symbol of 4:1 mux using 2:1 muxes. As is evident, a 4:1 mux can be built from 3 2:1 muxes.

A 4:1 mux has 4 inputs and 2 select lines. Depending upon the state of select lines, output selects one of the inputs
Figure 6(a): 4x1 mux schematic symbol     Figure 6(b): 4:1 mux structural representation with 2x1 muxes

  • 8-input mux: An 8x1 mux has 3 select lines and 8 inputs. The truth table for 8x1 mux is shown below:
An 8:1 mux has 8 inputs and 3 select lines. Depending upon the state of select lines, an input is connected to the output
Figure 7: Truth table for 8:1 mux
The structural representation using 2x1 muxes, and schematic symbol for the same is as shown below in figure 8. An 8-input mux can be implemented using 7 2-input muxes.
8-input mux, 8-input multiplexer, 8:1 mux, 8:1 multiplexer, 8 by 1 mux, 8 by 1 mux schematic, 8x1 mux schematic, 8x1 multiplexer, 8:1 mux using 2:1 mux
Figure 8(a): Schematic symbol for 8x1 mux                    Figure 8(b): Structure of 8x1 mux  with 2x1 mux                                              

  • 16-input mux: A 16x1 mux can be implemented from 15 2:1 muxes. It has 4 select lines and 16 inputs. Output follows one of the inputs depending upon the state of the select lines.

Also read:


Multicycle paths handling in STA

In the post Multicycle paths - the architectural perspective, we discussed about the architectural aspects of multicycle paths. In this post, we will discuss how multicycle paths are handling in backend optimization and timing analysis:

How multi-cycle paths are handled in STA: By default, in STA, all the timing paths are considered to have default setup and hold timings; i.e., all the timing paths should be covered in either half cycle or single cycle depending upon the nature of path (see setup-hold checks part 1 and setup-hold checks part 2 for reference). However, it is possible to convey the information to STA engine regarding a path being multi-cycle. There is an  SDC command "set_multicycle_path" for the same. Let us elaborate it with the help of an example:

Path from ff1 to ff2 is a multicycle path
Figure 3: Path from ff1/Q to ff2/D is multicycle path

Let us assume a multi-cycle timing path (remember, it has to be ensured by architecture) wherein both launch and capture flops are positive edge-triggered as shown in figure 3.  The default setup and hold checks for this path will be as shown in red in figure 4. We can tell STA engine to time this path in 3 cycles instead of default one cycle with the help of set_multicycle_path SDC command:

                                    set_multicycle_path 3 -setup -from ff1/Q -to ff2/D

Above command will shift both setup and hold checks forward by two cycles. That is, setup check will now become 3 cycle check and hold will be 2 cycle check as shown in blue in figure 4. This is because, by default, STA engine considers hold check one active edge prior to setup check, which, in this case, is after 3 cycles.

When you apply multicycle path only for setup, hold also moves along as default hold check is one edge prior to setup check
Figure 4: Setup and hold checks before and after applying multicyle for setup-only

However, this is not the desired scenario in most of the cases. As we discussed earlier, multi-cycle paths are achieved by either gating the clock path or data path for required number of cycles. So, the required hold check in most cases is 0 cycle. This is done through same command with switch "-hold" telling the STA engine to pull hold back to zero cycle check.

                               set_multicycle_path -hold 2 -from ff1/Q -to ff2/D

The above command will bring back the hold check 2 cycles back to zero cycle. This is as shown in figure 5 in blue.

On applying multicycle path for hold, hold check comes back to where it was intended. It does not impact setup check
Figure 5: Setup and hold checks after applying multi-cycle exceptions for both setup and hold


We need to keep in mind the following statement:

Setting a multi-cycle path for setup affects the hold check by same number of cycles as setup check in the same direction. However, applying a multi-cycle path for hold check does not affect setup check.

So, in the above example, both the statements combined will give the desired setup and hold checks. Please note that there might be a case where only setup or hold multi-cycle is sufficient, but that is the need of the design and depends on how FSM has been modeled.


What if both clock periods are not equal: In the above example, for simplicity, we assumed that launch and capture clock periods are equal. However, this may not be true always. As discussed in multicycle path - the architectural perspective, it makes more sense to have multi-cycle paths where there is a difference in clock periods. The setup and hold checks for multicycle paths is not as simple in this case as it was when we considered both the clocks to be of same frequency. Let us consider a case where launch clock period is twice the capture clock period as shown in figure 6 below.

Setup and hold cheks in case of multicycle paths  for clocks differing in frequencies
Figure 6: Default setup and hold checks for case where capture clock period is half that of launch clock

Now, the question is, defining a multi-cycle path, what clock period will be added to the setup check, launch or capture? The answer depends upon the architecture and FSM of the design. Once you know it, the same can be modelled in timing constraints. There is a switch in the SDC command to provide for which of the clock periods is to be added. "set_multicycle_path -start" means that the path is a multi-cycle for that many cycles of launch clock. Similarly, "set_multicycle_path -end" means that the path is a multicycle for that many cycles of capture clock. Let the above given path be a multicycle of 2. Let us see below how it changes with -start and -end options.

      1. set_multicycle_path -start: This will cause a cycle of launch clock to be added in setup check. As expected, on applying a hold multicycle path of 1, the hold will return back to 0 cycle check. Figure 7 below shows the effect of below two commands on setup and hold checks. As is shown, setup check gets relaxed by one launch clock cycle.

                      set_multicycle_path 2 -setup -from ff1/Q -to ff2/D -start
                      set_multicycle_path 1 -hold   -from ff1/Q -to ff2/D -start

When provided with -start switch, shifts in setup and hold checks happen in multiples of launch clock period.
Figure 8: Setup and hold checks with -start option provided with set_multicycle_path

       2. set_multicycle_path -end: This will cause a cycle of capture clock to be added in setup check. As expected, on applying a hold multicycle path of 1, the hold will return back to 0 cycle check. Figure 8 below shows the effect of below two commands on setup and hold checks. As is shown, setup gets relaxed by one cycle of capture clock.
                      set_multicycle_path 2 -setup -from ff1/Q -to ff2/D -end
                      set_multicycle_path 1 -hold   -from ff1/Q -to ff2/D -end

When provided with -end option, shifts in setup and hold checks happen in multiples of capture clock period.
Figure 9: Setup and hold checks with -end option provided with set_multicycle_path

Why is it important to apply multi-cycle paths: To achieve optimum area, power and timing, all the timing paths must be timed at the desired frequencies. Optimization engine will know about a path being multicycle only when it is told through SDC commands in timing constraints. If we dont specify a multicycle path as multicycle, optimization engine will consider it as a single cycle path and will try to use bigger drive strength cells to meet timing. This will result in more area and power; hence, more cost. So, all multicycle paths must be correctly specified as multicycle paths during timing optimization and timing analysis.

Also read:

VLSI n EDA : Now on Facebook

Hello guys!! Check out our new facebook page and get connected for all the latest posts. Just "like" the page and find all the updates right on your wall.

You can find our page at the below link:

https://www.facebook.com/vlsiuniverse/

Please help us reach your friends and colleagues.

VHDL code for clock divider

A clock divider is used to get a divided version of a clock. Clock dividers are a very important component of digital design, and are used ubiquitously.

VHDL code for a configurable clock divider: Following is the VHDL code for a configurable divider. It can divide by any number with 50% duty cycle. It makes use of a dual edge-triggered decrement counter, with configurable load; thereby enabling it to divide by any number.

Following is the entity and architecture definitions of top module for clock divider. It takes generic parameter max_bits, which puts a limit on the maximum division that can be obtained with the help of this divider. It takes the divide_value as input, the division ratio of output clock with respect to input clock. The output clock is a divided version of input clock depending on the value of divide_value. We have instantiated a component decr_counter, which takes a parameter and counts downto 0 as discussed in further detail below.

-- This module is for a configurable divider that takes value from a counter and toggles the output clock whenever it receives all zero count.
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_UNSIGNED.all;

ENTITY configurable_divider IS
    GENERIC (
        MAX_BITS : INTEGER := 10
            );
    PORT (
        in_clk : IN bit;
        rst : IN bit;
        out_clk : OUT bit;
        divide_value : IN bit_vector(MAX_BITS DOWNTO 0)
         );
END ENTITY;

ARCHITECTURE behavioral OF configurable_divider IS
    -- Declaring a component of configurable_decr_counter
    COMPONENT configurable_decr_counter
        GENERIC (
            MAX_BITS : INTEGER := 10
                );
        PORT (
            clk : IN bit;
            rst : IN bit;
            load_count : IN bit_vector (MAX_BITS DOWNTO 0);
            count : OUT bit_vector (MAX_BITS DOWNTO 0)
             );
    END COMPONENT;
    -- signal declarations
    SIGNAL load_count_reg : bit_vector (MAX_BITS DOWNTO 0);
    SIGNAL curr_count_value : bit_vector (MAX_BITS DOWNTO 0);
    signal out_clk_int : bit;
BEGIN
    PROCESS
    BEGIN
        WAIT UNTIL in_clk'EVENT;
            IF to_StdLogicVector(curr_count_value) = 1 THEN
                out_clk_int <= NOT out_clk_int;
            END IF;
    END PROCESS;
    out_clk <= out_clk_int;
    -- Instantiating configurable_decr_counter
    decr_counter : configurable_decr_counter GENERIC MAP (
                                                            MAX_BITS
                                                                      )
                                                          PORT MAP (
                                                            clk => in_clk,
                                                            rst => rst,
                                                            load_count => divide_value,
                                                            count => curr_count_value
                                                                   );

END ARCHITECTURE behavioral;


Given below is the entity and architecture definition of decr_counter module. It keeps on decrementing until it reaches value 0. On reaching zero, it loads itself with a pre-determined value that is provided as an input to the counter from its top module.

-- This is the VHDL code for a configurable dual edge-triggered decrement counter.
library IEEE;

use IEEE.std_logic_1164.all;
use IEEE.std_logic_UNSIGNED.all;

ENTITY configurable_decr_counter IS
    GENERIC (
        MAX_BITS : INTEGER := 10
            );
    -- Port definitions
    PORT (
        clk : IN bit;
        rst : IN bit;
        load_count : IN bit_vector (MAX_BITS DOWNTO 0);
        count : OUT bit_vector (MAX_BITS DOWNTO 0)
         );
END ENTITY;


ARCHITECTURE behavioral OF configurable_decr_counter IS
    SIGNAL count_value : std_logic_vector (MAX_BITS DOWNTO 0);
BEGIN
    PROCESS(clk,rst)
    BEGIN
        IF rst = '1' THEN
            count <= "000000";
            count_value <= "000001";
        ELSIF clk'EVENT THEN
            IF count_value = 1 THEN
                count_value <= to_StdLogicVector(load_count);
            ELSE
                count_value <= count_value - 1;
            END IF;
            count <= to_bitvector(count_value);
        END IF;
    END PROCESS;
END ARCHITECTURE behavioral;


By the way, this code is not synthesizable, although it will simulate perfectly. We have to make a simple modification to the code to make it synthesizable. Any guesses what makes this code not being synthesized by a synthesis tool? Hope you’ve found this post useful. Let us know what you think in the comments.

Also read:



Bubble errors and bubble error correction

Bubble error correction is a very common term associated to flash ADCs (see flash ADC block diagram) wherein the output produced by comparators stage is expected to be a thermometer code. However, due to multiple non-idealities and mismatches in comparators and their inputs, the output may not be a symbol of thermometer code, but has some irregularities. So, the thermometer to binary converter stage may not be able to convert it to binary code as it is generally a state machine that accepts only thermometer code as input and may produce a garbage output if provided some other input that is not thermometer code. There may be some zeroes in-between a series of ones. For example, the output may be “01011111” instead of “01111111”. “01011111”, when fed to thermometer to binary converter will produce garbage value. Either “01111111” should be given or “00111111” or “00011111”. This will reduce the error. The presence of zeroes in a series of ones or presence of ones in a series of zeroes in the comparators’ output is termed as bubble error. And the removal of these bubbles from near-thermometer code is termed as bubble error correction.

Kinds of bubble errors: Bubble errors are categorized by their order. A first order bubble error means there is only single ‘1’ between a series of zeroes or vice-versa. For example, “0010001101” has two first order bubbler, on second bit from right and third bit from left. Similarly, “01100001111” has a second order bubble. “00011100000000010111” has one third-order and one first-order bubble.


What circuit can be used to correct bubble errors? The simplest circuit that can be used to correct bubble errors is majority-of-three circuit. In it, each output is compared with one output on the left and one on the right. The majority of the three is finally produced at the output. This is how a near-thermometer code will be converted to a thermometer code. However, a majority of three circuit will be able to correct bubble errors of first order only. There are more sophisticated circuits for second and higher order bubble correction.

            Hope you’ve found this post useful. Let us know what you think in the comments.

Computing capability of today's laptops

A small laptop computer today has more computing capability than the equipment used to send a man to moon a few years ago.
Today, computers have made tremendous progress in terms of computing capability. The capability of the simplest laptop today is more than the whole system that was used to send a man to moon in 1970's. In fact, it is many many times more than that.