5
\$\begingroup\$

I saw in many VHDL codes that data/control outputs are first assigned to signals and then to output ports, and not instantly to the output ports.

I'll give an example:

entity ex is
port (clk, rst : in std_logic;
      ....
      data_out : out std_logic);
end entity;

Architecture ex of ex is
signal data_out_sig : std_logic;
Begin
    process(clk,rst)
    begin
       ....
       data_out_sig <= some_data;
       ....
    end process;
data_out <= data_out_sig;
End Architecture;

My question is, why do we not assign some_data instantly to the data_out port? Why does it "have to go through" the signal data_out_sig? Does this have anything to do with synthesis? Is it common practice?

Thanks!

\$\endgroup\$
3
\$\begingroup\$

I will tell you a scenario. Suppose you are creating an entity with

2 input ports : A,B

2 output ports : C,D

Suppose the output C is generated from A and B using some logic. And Suppose D is found to be directly related with C. For example:

D = compliment of C

So it is compelling to write in the code: D = not C directly, instead of using a logic expression with and A and B. However VHDL semantics don't allow you to read the output port C and hence you cannot implement such an expression. So what you can do is turn that port into a buffer port. Some people also make use in/out port for this purpose. But that makes thing complex. So a simple solution is to use some local internal signal C_int, and "use" it like the output port inside your code. So that you can implement the logic for C into this internal signal, read it and manipulate with it. Finally assigning this internal signal to the output port, outside all the process blocks, completes the requirement. An example illustration of what is happening inside the circuit:

enter image description here

\$\endgroup\$
4
\$\begingroup\$

It's because you couldn't read from ports of type OUT in VHDL.

If the value driving an OUT port was to be read within the design, a signal had to used to hold it, then that signal assigned to the OUT port.

The capability to do so was added in VHDL-2008. However, a huge amount of designs were created before 2008 and before take-up of VHDL-2008 became available in software tools. These designs would therefore use the signal-drives-OUT method.

As an aside, it depends upon your circumstances as an engineer but the option to use VHDL-2008 may well not be available to you. Some companies will require design revisions to be synthesised or simulated by a specific version of software (Quartus, Xilinx ISE, ModelSim etc.) with no changes to the design project settings, so you cannot use VHDL-2008. I have worked in a great many companies that do this, defence companies for example. Moving to a newer version of software introduces an unnecessary risk of unexpected changes that can discredit all the testing and experience gained with that firmware so far, with the time and expense that go with that. So there is a lot of value in writing 'middle of the road' VHDL that will be accepted by the widest range of software tools that you can, rather than using syntax specific to VHDL-2008 or VHDL-2002. The downsides of this are few or none - I'm not aware of anything that you can't do in the earlier versions that vast majority of designs require. As I said, it depends upon your circumstances and is something to consider. For me, I would definitely use signal-drives-OUT. Being completely portable between software tools and versions is valuable to me and one of my priorities.

\$\endgroup\$
3
\$\begingroup\$

If the signal from an output port also is read back you have to use the 'buffer' port type.

That by itself would not be a problem but if that 'output' port goes up a hierarchical chain of modules you have to change the output of each model to 'buffer'.

To avoid the hassle it is easiest to use a local variable and in one place assign that to the output.

I prefer to use that technique only for output ports that are also read back but I can image somebody preferring to use it all the time.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ You can read back from OUT ports in VHDL-2008. So, this is either obsolete practice or a concession to obsolete tools. \$\endgroup\$ Dec 29 '17 at 19:25
0
\$\begingroup\$

Notice that data_out is defined as an output. That means it can only be written to. However, you cannot read from it.

So you can directly go

data_out <= some_data;

That works fine. But suppose some_data needed to be continuously modified.

For my purposes of these examples, I will assume the data types are integers and not std_logic like in your original post.

I cannot do

data_out <= data_out + 1

because this would require a read prior to adding the one. Since you cannot read from data_out, this would not work.

I could do

data_out <= some_data + 1

and this would work, but in doing so, I can no longer manipulate the result in the future because it is now stored in data_out and can no longer be read from.

If I want to manipulate the result in the future, then I have to go

data_out_sig <= some_data + 1; --can continue to reading and modify the result in the future data_out <= data_out_sig;

So you can assign data instantly to the output if you don't need to ever manipulate what is stored in data_out. For example, a conditional branch could decide that the output needs to be a '1' or '0'. You could write this directly to the output without an intermediary.

data_out <= 1;

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.