I'm a student learning VHDL and have a pretty basic question.
I've read that signal assignments don't take place immediately. So the following would not work as expected:
x <= y;
z <= not x;
So I understand that assignments are not immediate / don't happen sequentially, but I have a question about passing signals to entities. Supposed I have the following code:
architecture struct of mips is
begin
controller: entity work.controller port map(opD => instrD(31 downto 26),
functD => instrD(5 downto 0));
datapath: entity work.dataPath port map(opD => instrD(31 downto 26),
functD => instrD(5 downto 0));
end;
I'm used to trying to avoid code duplication and hard coding things in other languages, so hard coding the opD
and functD
values in the above code bothers me.
What I'm wondering is if I can assign those values to an internal signal, like this:
architecture struct of mips is
signal opD: STD_LOGIC;
signal functD: STD_LOGIC;
begin
signal opD <= instrD(31 downto 26);
signal functD <= instrD(5 downto 0);
controller: entity work.controller port map(opD => opD,
functD => functD);
datapath: entity work.dataPath port map(opD => opD,
functD => functD);
end;
Would that work as expected (i.e. work exactly the same as the above code block), or would there be some sort of "delay" caused by the use of the signals that would make the two code blocks function differently?
I've read that signal assignments don't take place immediately.
This is true, but I think you miss an important point, which is to know when they take place. Signals are updated when the process that generates them encounter a wait statement, or end (since there is an implicit wait on the process sensitivity list at the end of processes).
So your example wouldn't work like you expect if you put it in a clocked process, but is perfectly valid in a combinational process with correct sensitivity list.
architecture rtl of example is
signal y_r : std_logic;
signal z_r : std_logic;
signal y : std_logic;
signal z : std_logic;
begin
y <= x; -- immediately updated when x changes
z <= not y; -- immediately updated when y changes, equivalent to z <= not x
process(clk)
begin
if rising_edge(clk) then
y_r <= x; -- y is updated when the clock rise, once this process finishes
z_r <= not y_r; -- y still have the value it had when the process started executing
end if;
end process;
end architecture rtl;
So your final example, apart from the syntax errors, would work as you intend. There is a neat syntax that is better IMHO for that though:
architecture struct of mips is
alias opD is instrD(31 downto 26);
alias functD is instrD(5 downto 0);
begin
controller: entity work.controller port map(opD => opD,
functD => functD
datapath: entity work.dataPath port map(opD => opD,
functD => functD;
end;