element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
FPGA
  • Technologies
  • More
FPGA
Blog The Art of FPGA Design - Post 12
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join FPGA to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: fpgaguru
  • Date Created: 25 Sep 2018 6:57 PM Date Created
  • Views 898 views
  • Likes 7 likes
  • Comments 1 comment
  • vhdl
  • xilinx_art
  • guest writer
  • fpga_art
Related
Recommended

The Art of FPGA Design - Post 12

fpgaguru
fpgaguru
25 Sep 2018

The Universal MUX Building Block

 

The next example in the series of generic building blocks is a multiplexer. This is a combinatorial block - if we need pipelining we can always add that separately to keep it as generic as possible - with an input port I of N elements, an UNSIGNED SEL port and an output port O, which is one of the N elements of the input port I selected by SEL. We want of course the I and SEL ports to be unconstrained arrays. The most generic solution would be one with a generic base type T also passed as an argument to the MUX module instantiation like we have seen in the generic DELAY post but this is VHDL-2008 only and is not supported by Vivado synthesis yet. The next best thing is a different generic MUX module for every different base type, one for STD_LOGIC, one for BOOLEAN, one for STD_LOGIC_VECTOR, SIGNED, UNSIGNED, SFIXED, CFIXED and so on.

Since all the vector types mentioned are actually arrays of STD_LOGIC we could create first a generic STD_LOGIC MUX module and then build all the other ones as parallel instantiations of STD_LOGIC MUXes with a for generate. So let's start with a generic STD_LOGIC MUX:

 

library IEEE; 
use IEEE.STD_LOGIC_1164.all;
use
IEEE.NUMERIC_STD.all; 

entity MUX is port(I:in STD_LOGIC_VECTOR; – unconstrained vector of STD_LOGIC
       SEL:in UNSIGNED;       – unconstrained size selection port
       O:out STD_LOGIC);
end
MUX; 

architecture
TEST of MUX is
begin
 
assert (2**SEL'length<=I'length) and (I'length<2**(SEL'length+1)) report "Ports I and SEL have inconsistent sizes!" severity warning; – severity level can be note, warning or error
  O<=I(TO_INTEGER(SEL)+I'low); – I is not necessarily 0 based so we add I'low to SEL
end TEST;

 

Since the I and SEL input ports are unconstrained, it is a good coding practice to add assert statement(s) to check for port size consistency. The assert is ignored during synthesis, at most you might get a message in the synthesis log, but during functional simulation you will definitely get a message and depending on the severity level and simulator you can even stop the simulation and inspect the design to see why things are not as expected.

 

The other notable thing is that the MUX itself is just one line of behavioral VHDL code, all we need to do is convert the UNSIGNED SEL to INTEGER, add I'low in case the actual signal connected to the I port is not zero based and then select the I element to assign to O. Now we can build any type of multiplexer by instantiating one MUX for every STD_LOGIC bit of the O output. As an example here is how an SFIXED multiplexer called SMUX would look like:

 

library IEEE; 
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all; 

use work.TYPES_PKG.all; – we need this packge we introduced earlier for SFIXED type support 

entity SMUX is port(I:in SFIXED_VECTOR; – unconstrained vector of SFIXED, itself an unconstrained vector of STD_LOGIC
       SEL:in UNSIGNED;    – unconstrained size selection port
       O:out SFIXED);
end SMUX; 

architecture TEST of SMUX is
begin
  lk:for K in 0 to O'length-1 generate
      
signal II:STD_LOGIC_VECTOR(I(K)'length-1 downto 0);
    
begin
       lj:for J in II'range generate
            II(J)<=I(K+I'low)(J+I(K)'low); – I might not be zero based and I(K) might not be zero based either
         
end generate;
       mx:
entity work.MUX port map(I=>II,  – we need the intermediate II signal to convert from SFIXED to STD_LOGIC_VECTOR
                                   SEL=>SEL, O=>O(K+O'low)); – O might not be zero based
    
end generate;
end TEST;

 

The intermediate II signal has two roles, to convert from SFIXED to STD_LOGIC and to avoid problems when I(K) has negative range since STD_LOGIC_VECTOR is restricted to positive ranges only. Muxes for other types like STD_LOGIC_VECTOR, SIGNED, UNSIGNED, CFIXED and so on are very similar and all are based on the same STD_LOGIC MUX module instantiated many times.

 

The question we need to ask now is if all this two-level hierarchical decomposition of a generic multiplexer is really required, beyond its educational aspects? After all, we can index an input port or internal signal I which is an array of virtually any user-defined base type in just one line of code, by indexing the I array using TO_INTEGER(SEL) directly. The answer to this question is yes and no.

 

If the synthesis tool gives you an optimal implementation of such a multiplexer inferred from one line of behavioral code then that is ideal - one line of code is simple to understand and maintain, faster to simulate and all the two-level hierarchy of generic mixes is unnecessarily complicated. But if the synthesis result is not optimal, for example uses too many LUT6es or has too many logic levels and cannot meet the desired clock speed then the coding style I have just introduced can become a life saver. But before even asking if the behavioral synthesis result is optimal or not, we need to be able to set up expectations and be able to answer questions like "how many LUT6es and logic levels are required to implement a 1024-input mux (or any other size)". Answering this question properly requires an understanding of the configurable logic block (CLB) slice, in particular a little know resource called FxMUXes.

 

This will make the object of my next weekly post.

 

Back to the top: The Art of FPGA Design

  • Sign in to reply

Top Comments

  • mjardini
    mjardini over 6 years ago +3
    Nice series. Thank you for sharing it with us. Only hint: add a ping back link to the index The Art of FPGA Design or The Art of FPGA Design Series
Parents
  • mjardini
    mjardini over 6 years ago

    Nice series. Thank you for sharing it with us.

     

    Only hint: add a ping back link to the index image

     

    The Art of FPGA Design or The Art of FPGA Design Series

    • Cancel
    • Vote Up +3 Vote Down
    • Sign in to reply
    • More
    • Cancel
Comment
  • mjardini
    mjardini over 6 years ago

    Nice series. Thank you for sharing it with us.

     

    Only hint: add a ping back link to the index image

     

    The Art of FPGA Design or The Art of FPGA Design Series

    • Cancel
    • Vote Up +3 Vote Down
    • Sign in to reply
    • More
    • Cancel
Children
No Data
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube