1

Please take a look at the following code, specifically the 3 commented lines at the end. I simulated this with Questasim 10.6c:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity alias_extname_driving_signal is
port(
  clk : in std_logic
);
end alias_extname_driving_signal;

architecture primary of alias_extname_driving_signal is

  signal buried_control_vector16 : std_logic_vector(15 downto 0) := (others => '0');

begin

 buried_control_vector16 <= std_logic_vector(unsigned(buried_control_vector16) + 1) when rising_edge(clk);

end architecture primary;




library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity alias_extname_driving_signal_tb is
end alias_extname_driving_signal_tb;

architecture primary of alias_extname_driving_signal_tb is

  signal clk : std_logic := '0';
  signal control_vector16 : std_logic_vector(15 downto 0) := (others => '0');
  alias control_vector16_alias is control_vector16;
  alias buried_control_vector16_alias is << signal .alias_extname_driving_signal_tb.uut.buried_control_vector16 : std_logic_vector(15 downto 0) >>;
  signal vector16 : std_logic_vector(15 downto 0);

begin

  clk <= not clk after 10 ns;

  control_vector16 <= std_logic_vector(unsigned(control_vector16) + 1) when rising_edge(clk);

  uut : entity work.alias_extname_driving_signal
  port map(
    clk => clk
  );

  -- vector16 <= << signal .alias_extname_driving_signal_tb.uut.buried_control_vector16 : std_logic_vector(15 downto 0) >>; -- this statement works
  -- vector16 <= control_vector16_alias; -- this statement works
  -- vector16 <= buried_control_vector16_alias; -- vector16 remains perpetually undefined with this statement

end architecture primary;

As you can see, I'm able to drive a signal with an external name, an alias of a local signal, but not an alias of an external name. Is there any way I can use an alias of an external name to drive a signal in vhdl-2008?

Thanks in advance for your help.

  • 1
    You are never updating the external name, you are always reading from it. You need to use a *forced signal assignment*: `buried_control_vector16_alias <= force X"1234";` – Paebbels Jan 19 '18 at 19:02
  • 1
    Btw, I think your code is not valid VHDL code. The alias needs to be declared after the referenced external name was elaborated. Have you analysed and run your example in eg. GHDL? – Paebbels Jan 19 '18 at 19:05
  • Hmmm your code let's GHDL crash, am I allowed to report your code as a bug? – Paebbels Jan 19 '18 at 19:12
  • Your force statement is in the wrong direction. I'm not trying to control the buried_control_vector16_alias signal. I'm trying to set vector16 to buried_control_vector16_alias. I tried what you suggested, though, in the opposite direction, and vector16 still didn't update. Also, regarding the force statement, I don't think it's necessary. I can instantiate another component in the testbench, connect the alias of the external name to one of its input ports, and that input port will update just fine in simulation. – Michael Grover Jan 19 '18 at 21:03
  • 1
    Regarding your elaboration statement, I'm a little confused. I can't declare a statement after something is elaborated. Do you mean I need to declare my alias somewhere else in the code? Could you please not report this code as a bug? I copied and pasted this code verbatim into a blank file then compiled it with Questasim 10.6c and simulated just fine. Thanks! – Michael Grover Jan 19 '18 at 21:04
  • He wants to use your code for a bug report for GHDL, not questasim. – JHBonarius Jan 20 '18 at 13:51
  • OK, if you are only reading, you don't need a **force** - I misunderstood your question. [I reported the bug for GHDL](https://github.com/ghdl/ghdl/issues/520). See that issue for the declaration of an alias to an external name – Paebbels Jan 20 '18 at 15:16
  • Thanks for the clarification on the bug report and for reporting it. – Michael Grover Jan 21 '18 at 17:28
  • I've been thinking about this, and either it's a bug, or it's that you assign the alias in the declarative region: that is only evaluated once. I.e. is the buried signal changes, the local signal is not updated any more. – JHBonarius Jan 21 '18 at 19:04
  • Your code as it is should not compile as it currently is written. Referencing an alias to an external name before the referenced object is elaborated is an error. – Jim Lewis Jan 22 '18 at 17:30

1 Answers1

2

External names can only be declared AFTER the object being referenced is elaborated.

VHDL starts elaborating from the testbench. First it elaborates the declaration region. Then it elaborates the code region in order. If it finds a component, it elaborates it and any subcomponents. When it finishes elaborating the component (and any subcomponents) it picks up elaborating int the testbench where it left off.

Hence, you need to move your alias declaration to either a block statement or a process. The code for the block statement is as follows. Note the label with the block statement is required.

architecture primary of alias_extname_driving_signal_tb is

  signal clk : std_logic := '0';
  signal control_vector16 : std_logic_vector(15 downto 0) := (others => '0');
  alias control_vector16_alias is control_vector16;
  signal vector16 : std_logic_vector(15 downto 0);

begin

  clk <= not clk after 10 ns;

  control_vector16 <= std_logic_vector(unsigned(control_vector16) + 1) when rising_edge(clk);

  uut : entity work.alias_extname_driving_signal
  port map(
    clk => clk
  );

  myblock : block 
    alias buried_control_vector16_alias is << signal .alias_extname_driving_signal_tb.uut.buried_control_vector16 : std_logic_vector(15 downto 0) >>;
  begin
     vector16 <= << signal .alias_extname_driving_signal_tb.uut.buried_control_vector16 : std_logic_vector(15 downto 0) >>; -- this statement works
     vector16 <= control_vector16_alias; -- this statement works
     vector16 <= buried_control_vector16_alias; -- vector16 remains perpetually undefined with this statement
  end block myblock ; 

end architecture primary;
Jim Lewis
  • 3,601
  • 10
  • 20
  • 'created' is imprecise. Note the examples found in IEEE Std 1076-2008 14.2 Elaboration of a design hierarchy, page 202 wherein the first example use of an external name (`alias DONE_SIG <>; -- legal` is marked as the legal use of an external name and matches the OP's usage. Also the last paragraph before the examples gives the two criteria for when an object denoted by an external name is required to be previously elaborated. The OP's usage meets neither of these two criteria. (The value is not read and the external name is not an actual in an association list). –  Jan 22 '18 at 18:13
  • WRT 14.2, the statement that says "legal" should say "illegal" and was corrected in ISAC issue 05 in LRM that is being revised. See: http://www.eda-twiki.org/cgi-bin/view.cgi/P1076/LCS2016_I05 – Jim Lewis Jan 22 '18 at 18:30
  • WRT "created" many apologies for thinking in English synonyms. – Jim Lewis Jan 22 '18 at 18:32
  • Is there any possible way for me to declare an alias of an external name in the declarative region of the architecture or at least in a way that I can use that alias anywhere in the architecture statement part? – Michael Grover Jan 23 '18 at 00:04
  • @MichaelGrover For a simple testbench where you have uut instance and code, you can wrap everything except the uut in a block statement - or put the alias in a process (but it will only be seen by that process). For a higher level structured testbench where the stimulus is in a sequencer component, instance the sequencer component last in the testbench architecture and instance the uut first. This way the test sequencer can have an external name reference into either the uut or the verification components. For more, see our blog and website. http://www.synthworks.com – Jim Lewis Jan 24 '18 at 22:17