ElectronicBadger
ElectronicBadger

Reputation: 49

VHDL - Port mapping - Map different ports of a component into different entities

I've been working on a VHDL project for a few weeks, and functionnality-wise everything's going very smoothly. I can simulate and program my DE0-nano FPGA devellopement board to check if what I'm doing is working, and it is. However, I'm starting to worry about the readability of the source code as the project is rapidly expanding.

As far as my experience is concerned, I'm a university student in electronical engineering and have followed many courses on electronics, but I'm a complete noob concerning VHDL. (Although I could say my knowledge of VHDL has grown immensely during these past few weeks)

THE QUESTION :

My problem is that I have several components whose ports I'd like to map individually into DIFFERENT high-level entities. Say you've got an adder.vhd, well I'd like to provide operand A from operandA.vhd and operand B from operandB.vhd, meaning that I'd like to map port A of adder.vhd into operandA.vhd, and port B of adder.vhd into operandB.vhd.

The solution I'm currently using is that I map my signals following the hierarchical order of my entities, and if operandB.vhd is buried at another level entirely than operandA.vhd, I map the signals all the way through to the highest level entity that is required, then back down into the adder.vhd, in a single port map specifying ports A and B at the same time as I believe is required.

However, I find this solution very messy as it accumulates signals in my high-level entities that are only there for routing purposes. What's more, to continue on the adder.vhd analogy, I'd like several entities to provide operandsA or B (at different times, I'm not going to drive different values on the same input ports) so applying the current solution means I'll have numerous near-duplicate assignements too.

Is there another solution ? I couldn't find any documentation on this, and I fear this is a hard constraint of the language, but I may not know quack as I'm just starting VHDL.

This may also be a design error on my side, as I'm more accustomed to actual electronic design than VHDL circuit description. Connecting a component's ports to a bunch of other different components is very natural, but may not be how VHDL works.

EXPLICATIVE BLOCK DIAGRAMS :

What I'm currently doing : https://i.sstatic.net/CJVjg.gif enter image description here

What I want to do : https://i.sstatic.net/hrNwF.gif enter image description here

EXAMPLE CODE :

--  ********************************************
--
--  TOP-LEVEL ENTITY, in a file topLevel.vhd

entity topLevel is
    port
    (
    -- Any ports, not useful for the problem at hand
    );
end entity topLevel ;

architecture topLevel_Architecture of topLevel is

    --  HERE :  I have to accumulate signals just to get my data from the two subEntityA & B to computeFromAB.
    --
    --          I can't just map subEntityA and subEntityB as low-level entites into computeFromAB, as they provide data
    --          that I need elsewhere in the circuit. Well, I could do that but then I'd still have to get the "otherSignalFromX"
    --          through the same method.
    --          
    --          I'd rather directly map SEPARATELY (if that's possible)
    --              - operandA & operandB into computeFromAB
    --              - otherSignalFromA & otherSignalFromB into topLevel

    --  The signals I use to get my data from subEntityA and subEntityB to computeFromAB
    SIGNAL operandA : std_logic_vector(7 downto 0)  := ( others => '0' ) ;
    SIGNAL operandB : std_logic_vector(7 downto 0)  := ( others => '0' ) ;

    -- Other signals that I do not need to get to computeFromAB
    SIGNAL otherSignalFromA : std_logic ;
    SIGNAL otherSignalFromB : std_logic ;

begin

-- PORT MAP : subEntityA.vhd
    subEntityA : entity work.subEntityA
    PORT MAP(
    -- The first signal I'd like to get through to computeFromAB
    operandA => operandA,
    -- Other signals
    otherSignalFromA => otherSignalFromA
    );

-- PORT MAP : subEntityB.vhd
    subEntityB : entity work.subEntityB
    PORT MAP(
    -- The second signal I'd like to get through to computeFromAB
    operandB => operandB,
    -- Other signals
    otherSignalFromB => otherSignalFromB
    );

-- PORT MAP : computeFromAB.vhd
    computeFromAB : entity work.computeFromAB
    PORT MAP(
    -- The "useful" signals
    operandA => operandA,
    operandB => operandB
    );


-- PROCESSES, ETC, OF TOPLEVEL ENTITY

end topLevel_Architecture ;



--  ********************************************
--
--  OPERAND A ENTITY, in a file subEntityA.vhd

entity subEntityA is
    port
    (
    -- The first signal I'd like to get through to computeFromAB
    operandA : OUT std_logic_vector(7 downto 0)
    -- Other signals
    otherSignalFromA : OUT std_logic ;
    );
end entity subEntityA ;

-- ARCHITECTURE, PROCESSES OF subEntityA



--  ********************************************
--
--  OPERAND B ENTITY, in a file subEntityB.vhd

entity subEntityB is
    port
    (
    -- The second signal I'd like to get through to computeFromAB
    operandB : OUT std_logic_vector(7 downto 0)
    -- Other signals
    otherSignalFromB : OUT std_logic ;
    );
end entity subEntityB ;

-- ARCHITECTURE, PROCESSES OF subEntityB


--  ********************************************
--
--  COMPUTATION FROM OPERANDS A & B ENTITY, in a file computationFromAB.vhd

entity computeFromAB is
    port
    (
    operandA : IN std_logic_vector(7 downto 0) ;
    operandB : IN std_logic_vector(7 downto 0)
    );

--  ARCHITECTURE, PROCESSES OF computeFromAB

Thanks for reading, and thanks for any input you may provide.

EDIT 1 : Thanks for removing the "dictionary" tag, no idea why it was there.

EDIT 2 : added some example code, though I'm not sure if it's any help

EDIT 3 : added illustrative block diagrams

Upvotes: 4

Views: 4554

Answers (2)

Bob
Bob

Reputation: 44

Your problem is one of organization, and not thinking about this as simply an interconnect of rather simple elements. As such, your latter block diagram is what you are actually doing in your code, not the former.

Here is what you should do: Put each submodule entity/architecture pair in its own file. Compile it into library work. Then in your toplevel code wire it up simply, like so:

U0 : entity work.subEntityA 
   PORT MAP(operandA         => operandA, 
            otherSignalFromA => otherSignalFromA);

U1 : entity work.subEntityB
   PORT MAP(operandB         => operandB, 
            otherSignalFromB => otherSignalFromB);

U2 : entity work.computeFromAB
   PORT MAP(operandA => operandA, 
            operandB => operandB);

U3 : entity work.C
   PORT MAP(otherSignalFromA => otherSignalFromA, 
            otherSignalFromB => otherSignalFromB );

You used the construct "entity work.module_name" in your example code, and that is good practice. Let the default binding do its job and AVOID configuration files.

As your code grows, you end up putting all 4 of these into one entity/arch pair (making another level of hierarchy) and continuing. I recommend your toplevel be wiring only. Leave the logic to the submodules.

Yes, its gets more complicated as your portlists and generic lists grow, but that is what hierarchy is for, to help you organize it.

Upvotes: 1

jarno
jarno

Reputation: 149

Why don't you just wrap entities A + B + computeFromAb together creating entityAB. Then route otherSignalA and otherSignalB through the toplevel into entityC. The idea would be to cratea neat submodules to wrap and hide other modules. This also helps if and when you need to replicate some of the logic later on.

It might be that the signaling and design becomes a bit complex but that's usually a sure sign of the original idea being too complex. So whenever you are feeling confused with your own code then that's the time to go back to pen and paper and rething what you are actually trying to accomplish ;)

Also at some point you are not sure anymore where some signal is coming and where should it be going. That's the time you curse your signal naming conventions - if you had any - and come up with something more reasonable.

Add 100 more modules to your top level entity and you start to understand how the top level integrators feel in projects and why some of them have serious mental problems.

Upvotes: 1

Related Questions