Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

using "if generate" for modular entity design in VHDL

Status
Not open for further replies.

shaiko

Advanced Member level 5
Joined
Aug 20, 2011
Messages
2,644
Helped
303
Reputation
608
Reaction score
297
Trophy points
1,363
Activity points
18,302
Hello,

I need to implement 2 types of uarts. One with a parity error generator and another without.
The obvious way to do that is to create 2 different .VHD files with a different entity and architecture in each one.

But I want to implement them in the same .VHD file and have the synthesis tool decide wich one to implement based on some parameters in the file?
Is there a way to do that with the "if generate" statement?
 

Yes. you would include generics that add the parity generator.

eg:

Code:
entity my_uart is
generic (
  INCLUDE_PARITY   : boolean;
);

.....

parity_gen : if INCLUDE_PARITY generate
 
  --put the parity generater bit here. Can be processes or component instantiations, or both (and signal connections)

end generate parity_gen;

no_parity_gen : if not INCLUDE_PARITY generate

  --do the connections with no parity generator

end generate no_parity_gen;

VHDL 2008 actually allows you to use if/elseif/else for generates, as well as case statements.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Hi TrickyDicky,

Thanks for the help. But as far as I understand the above is per entity...
This isn't exactly what I'm looking for...I want to choose between 2 different types of components (with separate entities and architectures - NOT changes inside the entity. For example:

synchronous : boolean; -- the control word


synchronous_fifo : if synchronous generate

entity syn_fifo is
port
(
....................
);
end entity syn_fifo;

architecture rtl_syn_fifo of syn_fifo is
begin
.............................
end architecture rtl_syn_fifo;

end generate synchronous_fifo;


-- otherwise generate the asynchronous variant


asynchronous_fifo : if not synchronous generate

entity asyn_fifo is
port
(
....................
);
end entity asyn_fifo;

architecture rtl_asyn_fifo of asyn_fifo is
begin
.............................
end architecture rtl_asyn_fifo;

end generate asynchronous_fifo;
 

you cannot dynically generate an entity, the same way you cannot create an entity inside an arcitecture. It doesnt work like that. Think of it in terms of real hardware. You have a choice of 2 chips to put on the board. On some boards you pick chip X and others you pick chip Y. chip X and Y are completly separate from each other.

You HAVE to have separate entities for sync and async fifos, and then you instantiate them in a 3rd entity. Of course you dont need to do that, you can put any architectural code inside a generate statement.
 

You HAVE to have separate entities for sync and async fifos, and then you instantiate them in a 3rd entity. Of course you dont need to do that, you can put any architectural code inside a generate statement.

True, but this way I won't be able to control the actual ports...

For example: a synchronous FIFO will have only one clock for read and write. While the asynchronous FIFO will have 2 seperate clock ports (one for read and one for write).

Using only one entity for both sync and async FIFO's means that if we choose to implement the sync FIFO we will have unused ports in that entity.
 

Unconnected ports will just dissapear when compiled...
you cannot do it another way. You have to put in the ports for the worst case (ie. everything connected).

You cannot add or remove ports dynamically (again, think of it like real chips. How would you remove pins?)
 

You cannot add or remove ports dynamically (again, think of it like real chips. How would you remove pins?)

This analogy is not complete. The number of ports is fixed, but the number of bits in a port can change for each instance with a generic. If there is a clock_vector port, there can be 1, 2 or any number of clocks with the same entity and architecture.
 

I understand what you're saying. But I see it differently...I look at precompilation as a "pre-manufacturing" state of the chip state that can proceed in a chosen path.
One path will yield x pins and another x+1
 

Basically - the answer is no - you can only use generates inside an architecture. But you can use generics (like std_match says) to change port sizes.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
I think the only way to do what I want is use some kind of scripting language...
 

I still think you'll find it much easier to have the two vhd files and then use generates to instantiate the one you want.
 

I agree.
But I also think that if what I propose was possible to do it would've been very usefull
 

I get a compiler warning (not error) when trying to generate the following:

first_path: if synchronous = '1' generate
some_output <= value_x;
end generate;

second_path: if synchronous = '0' generate
some_output <= value_y;
end generate;


The compiler shows: "port 'some_output' may have multiple sources"

surely "some_output" is driven only by one signal (per chosen synthesis path). So, why does it show such a message?
Did I do something wrong?
 

Wouldnt it be better to make synchronous a boolean generic rather than a std_logic? otherwise someone could enter the options 'X', 'U' etc.

But no you did nothing wrong, its just a old VHDL limitation that got fixed with VHDL2008 since now you can use elseif/else on generates.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
"may have multiple sources" is a strange warning. A design compiler should be able to figure it out for constant generate expressions. And either stop compilation with an error or accept the code.

I never noticed a similar warning with a design compiler, I'm using integer generate constants however.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
TrickyDicky,
I avoid using booleans. For conformaty reasons I write all the "if" statements in my code to be "if something = something_else".
But you're correct - I can use "bit" instead.

FvM,
It's not the design compiler, it's the simulator (modelsim) that shows the ambiguous warning.
 

I avoid using booleans. For conformaty reasons I write all the "if" statements in my code to be "if something = something_else".
But you're correct - I can use "bit" instead.

Any particular reason? thats exactly why VHDL has a strong typing system, to allow appropriate types in appropriate places.
There is also nothing wrong with using types other than std_logic(_vector) in a port. It can actually help clarity.
 

The reason I avoid booleans as well as integeters (as much as possible) is to give emphasis that there're real electrical voltage levels standing behind the words we write...

After all, we're describing hardware - not programming in JAVA.
But that's just my conservative coding style...
 

The reason I avoid booleans as well as integeters (as much as possible) is to give emphasis that there're real electrical voltage levels standing behind the words we write...
I think, the argument doesn't apply to configuration constants. You also shouldn't ignore the abstracting aspect of HDL.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top