I am facing a confusing problem in my program. I need in my program to port map (calling) a component. Also, inside the component, I need to do another port mapping (calling) which is illegal in VHDL. Do you have an alternative solution to this problem. Here is an example of what I meant.
Here I start my program:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity binary1 is
port( N: in std_logic;
d: out integer);
end binary1 ;
Architecture Behavior1 of binary1 is
Here is a component for example:
component binary_integer_1 is
port ( b1: in std_logic;
int1: out integer);
end component;
The command for calling the component:
begin
s0: binary_integer_1 port map(n,d);
end Behavior1 ;
Also, here is the main program:
library ieee;
use ieee.std_logic_1164.all;
entity binary_integer_1 is
port ( b1: in std_logic;
int1: out integer);
end binary_integer_1;
architecture Behavior4 of binary_integer_1 is
begin
process(b1)
begin
if b1 = '1' then
int1 <= 1;
else
int1 <= 0;
end if;
end process;
end Behavior4;
For example, if I want to do a port map inside the upper entity. I have got an illegal statement.
Please, provide me with another way to do it.
I did a small example of a three level design hierarchy. The entity and architecture pairs are listed from bottom to top.
entity comp1 is
port (
x: in integer;
y: out integer
);
end entity;
architecture foo of comp1 is
begin
y <= x after 2 ns;
end architecture;
entity comp2 is
port (
a: in integer;
b: out integer
);
end entity;
architecture fum of comp2 is
component comp1 is
port (
x: in integer;
y: out integer
);
end component;
begin
INST_COMP1:
comp1 port map (X => A, Y => B);
end architecture;
entity top is
end entity;
architecture fum of top is
component comp2 is
port (
a: in integer;
b: out integer
);
end component;
signal a: integer := 0;
signal b: integer;
begin
INST_COMP2:
comp2 port map (a => a, b => b);
TEST:
process
begin
wait for 5 ns;
a <= 1;
wait for 5 ns;
a <= 2;
wait for 5 ns;
a <= 3;
wait for 5 ns;
wait;
end process;
end architecture;
ghdl -a component.vhdl
ghdl -e top
ghdl -r top --wave=top.ghw
(open top.ghw with gtkwave, setup waveform display), and:
So we have a top level entity top, which happens to be a test bench (no ports), it instantiates component comp2 which contains an instantiated component comp1, which provides a 2 ns delayed assigned to the output from the input.
The maximum negative value for the integer b is the left value for the integer range, and is the default, just like for std_logic the left value is 'U'; The output shows the default value until simulation time advances to an occurrence of x being assigned to y in comp1 (after 2 ns). The transition to 0 happened because of the default value for x in top.
I used integers to avoid context clauses (a library clause and a use clause). I could have used direct entity instantiation, but you showed a component declaration.
Related
I'm looking to implement the functions y = a and b; y = (a or b) and (c or d).
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity task1_tb is
-- Port ( ); end task1_tb;
architecture Behavioral of task1_tb is
--declaring the component component task1
Port ( a : in STD_LOGIC;
b : in STD_LOGIC;
y : out STD_LOGIC); end component;
signal y,a,b: std_logic;
signal counter: unsigned(1 downto 0):="00";
begin
uut: task1 port map(a => a, b => b, y => y );
end Behavioral;
How can I assign a (bit 1) and b (bit 2) so it will test ever possible value and make a 20ns delay between each combination? I've been trying to learn VHDL these past two days for a school project and not even sure if what I have is right.
You're looking to use a wait for <duration> in your stimulus process.
process
begin
for i in 0 to 2**2-1 loop --2**(number of input bits)-1
(a, b) <= to_unsigned(i,2);
wait for 20 ns;
end loop;
wait;
end process;
Credit to user1155120 for refinements.
I have been trying to use a test bench with a configuration unit. I have the following code:
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
ENTITY AND_2 IS
PORT (
a,b : IN std_logic;
x : OUT std_logic
);
END ENTITY AND_2;
ARCHITECTURE EX_1 OF AND_2 IS
BEGIN
x <= a and b;
END ARCHITECTURE EX_1;
ARCHITECTURE EX_2 OF AND_2 IS
SIGNAL ab : std_logic_vector(1 DOWNTO 0);
BEGIN
ab <= (a & b);
WITH ab SELECT
x <= '1' WHEN "11",
'0' WHEN OTHERS;
END ARCHITECTURE EX_2;
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
ENTITY TEST_AND_2 IS
END ENTITY TEST_AND_2;
ARCHITECTURE IO OF TEST_AND_2 IS
SIGNAL a, b, x : std_logic;
BEGIN
G1 : ENTITY work.AND_2(EX_1) PORT MAP ( a => a, b => b, x => x);
a <= '0', '1' AFTER 100 NS;
b <= '0', '1' AFTER 200 NS;
END ARCHITECTURE IO;
CONFIGURATION TESTER1 OF TEST_AND_2 IS
FOR IO
FOR G1 : AND_2
USE ENTITY work.AND_2(EX_1);
END FOR;
END FOR;
END CONFIGURATION TESTER1;
When I compile I kindly receive back the following message:
Error (10482): VHDL error at AND_2.vhd(48): object "AND_2" is used but not declared
The book I am reading from is not to clear in the use of test bench or the configuration unit. Can some one point out the mistake. However obvious it may be.
Many Thanks
D
You cannot use configurations in this way if you are using direct instantiation for your entity. Where you have:
G1 : ENTITY work.AND_2(EX_1) PORT MAP ( a => a, b => b, x => x);
This is direct instantiation, which in general saves typing and duplicated code, but will not allow the architecture to be specified by a configuration. To use configurations, in your declarative region (where the signals are defined), declare a component for your AND_2:
COMPONENT AND_2 IS
PORT (
a,b : IN std_logic;
x : OUT std_logic
);
END COMPONENT;
Then instantiate the AND_2 like this:
G1 : AND_2 PORT MAP ( a => a, b => b, x => x);
Your configuration statement is correct, you should be up and running with these two changes.
I'm trying to learn VHDL through P. Ashenden's book: Designer's Guide to VHDL. Chapter one's exercise 10 asks you to write 2-to-1 (I'm assuming 1 bit wide) MUX in VHDL and simulate it. I apologize in advance for being a complete noob. This is my first VHDL code.
My MUX didn't produce any errors or warnings in synthesis. My test bench doesn't produce errors or warnings, either. However, the simulation comes up completely blank, except for the names of the signals.
I've tried looking at a multitude of other MUX examples online (as well as a bench test example from the book), all of which gave errors when I tried sythesizing them, so I wasn't confident enough to use them as guides and didn't get much out of them. I'm not sure what I'm doing wrong here. I'd include an image of the simulation, but I don't have enough rep points :(
Also, I realize that a good MUX should also have cases for when it receives no select input/high impedance values, ect.. In this case, I'm just trying to get the toy model working.
The MUX code is:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity MUXtop is
Port (a, b, sel: in bit;
z: out bit);
end MUXtop;
architecture behav of MUXtop is
begin
choose: process is
begin
if sel = '0' then
z <= b;
else
z <= a;
end if;
end process choose;
end architecture behav;
The test bench code is:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY MUXtest IS
END MUXtest;
ARCHITECTURE behavior OF MUXtest IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT MUXtop
PORT(
a : IN bit;
b : IN bit;
sel : IN bit;
z : OUT bit
);
END COMPONENT MUXtop;
--Inputs
signal a : bit := '0';
signal b : bit := '0';
signal sel : bit := '0';
--Outputs
signal z : bit;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: MUXtop PORT MAP (
a => a,
b => b,
sel => sel,
z => z
);
-- Stimulus process
stimulus: process
begin
wait for 10 ns;
a <= '1';
wait for 10 ns;
sel <= '1';
wait for 10 ns;
b <= '1';
wait;
end process stimulus;
END architecture behavior;
You don't need a use clause for package std_logic_1164 when using type bit (declared in package standard).
Your process statement choose in MUXtop has no sensitivity clause which cause the process to continually execute in simulation. (It won't do anything until you trip over a delta cycle iteration limit which might be set to infinity).
I added a sensitivity list, commented out the superfluous use clauses in the two design units and added some more stimulus steps as well as a final wait for 10 ns; to allow the last action to be seen in your testbench:
library IEEE;
-- use IEEE.STD_LOGIC_1164.ALL;
entity MUXtop is
Port (a, b, sel: in bit;
z: out bit);
end MUXtop;
architecture behav of MUXtop is
begin
choose: process (a, b, sel) -- is
begin
if sel = '0' then
z <= b;
else
z <= a;
end if;
end process choose;
end architecture behav;
LIBRARY ieee;
-- USE ieee.std_logic_1164.ALL;
ENTITY MUXtest IS
END MUXtest;
ARCHITECTURE behavior OF MUXtest IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT MUXtop
PORT(
a : IN bit;
b : IN bit;
sel : IN bit;
z : OUT bit
);
END COMPONENT MUXtop;
--Inputs
signal a : bit := '0';
signal b : bit := '0';
signal sel : bit := '0';
--Outputs
signal z : bit;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: MUXtop PORT MAP (
a => a,
b => b,
sel => sel,
z => z
);
-- Stimulus process
stimulus: process
begin
wait for 10 ns;
a <= '1';
wait for 10 ns;
sel <= '1';
wait for 10 ns;
sel <= '0'; -- added
wait for 10 ns; -- added
b <= '1';
wait for 10 ns; -- added
wait;
end process stimulus;
END architecture behavior;
And that gives:
(clickable)
So, I have to create a generic N-bit adder with carry in and carry out.
I have made two fully working architectures so far, one using the generate function and one using the rtl description as follows:
entity:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity adder_n is
generic (N: integer:=8);
port (
a,b: in std_logic_vector(0 to N-1);
cin: in std_logic;
s: out std_logic_vector(0 to N-1);
cout: out std_logic);
end adder_n;
architectures 1 and 2:
--STRUCT
architecture struct of adder_n is
component f_adder
port (
a,b,cin: in std_logic;
s,cout: out std_logic);
end component;
signal c: std_logic_vector(0 to N);
begin
c(0)<=cin;
cout<=c(N);
adders: for k in 0 to N-1 generate
A1: f_adder port map(a(k),b(k),c(k),s(k),c(k+1));
end generate adders;
end struct;
--END STRUCT
architecture rtl of adder_n is
signal c: std_logic_vector(1 to N);
begin
s<=(a xor b) xor (cin&c(1 to N-1));
c<=((a or b) and (cin&c(1 to N-1))) or (a and b);
cout<=c(N);
end rtl;
Now, my problem is in the third architecture where I'm trying to infer the adder. Even though the following architecture I created compiles just fine, when I try to simulate it, I get a simulation error (on Modelsim), which I have attached at the end of this post.
I'm guessing there's something wrong with the numeric_std definitions. I am trying to avoid the arith library and I'm still trying to get used to the IEEE standard.
Any ideas are welcomed!! Thank you!
Inference arch:
--INFERENCE
architecture inference of adder_n is
signal tmp: std_logic_vector(0 to N);
signal atmp, btmp, ctmp, add_all : integer :=0;
signal cin_usgn: std_logic_vector(0 downto 0);
signal U: unsigned(0 to N);
begin
atmp <= to_integer(unsigned(a));
btmp <= to_integer(unsigned(b));
cin_usgn(0) <= cin;
ctmp <= to_integer(unsigned(cin_usgn));
add_all <= (atmp + btmp + ctmp);
U <= to_unsigned(add_all,N);
tmp <= std_logic_vector(U);
s <= tmp(0 to N-1);
cout <= tmp(N);
end inference;
-- END
Simulation error:
# Cannot continue because of fatal error.
# HDL call sequence:
# Stopped at C:/altera/14.1/modelsim_ase/test1_simon/adder_inference.vhd 58 Architecture inference
The length of U is N+1 (0 to N)
Changing
U <= to_unsigned(add_all,N);
To
U <= to_unsigned(add_all,N+1);
Will prevent a length mismatch between the left hand side and right hand side of the signal assignment in architecture inference of adder_n.
The passed parameter to to_unsigned specifies the length.
I'm trying to implement VHDL code using Finite state machine and Port mapping to components
Does any one have an idea how to do it, since it isn't allowed to include the port mapping inside the process statement?
------ and_2.vhd (component): ---------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
---------------------------------------
ENTITY and_2 IS
PORT ( a, b: IN STD_LOGIC;
y:OUT STD_LOGIC);
END and_2;
---------------------------------------
ARCHITECTURE and_2 OF and_2 IS
BEGIN
y <= a AND b;
END and_2;
---------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE work.my_data.all;
ENTITY FSM_PORTMAPP IS
PORT(
clk,reset : IN STD_LOGIC;
A,b,c,d: IN STD_LOGIC;
x: out STD_LOGIC
);
END FSM_PORTMAPP;
ARCHITECTURE Flow OF FSM_PORTMAPP IS
-----------------------
COMPONENT and_2 IS
PORT ( a, b: IN STD_LOGIC; y: OUT STD_LOGIC);
END COMPONENT;
-----------------------
TYPE state IS (state0, state1, state2);
SIGNAL pr_state, nx_state: state;
signal y,z :std_logic;
BEGIN
U1:and_2 PORT MAP(a,b ,y);
U2:and_2 PORT MAP(c,d,z);
U3:and_2 PORT MAP(y,z,x);
process(clk,reset)
BEGIN
IF (reset='1') THEN
pr_state <= state0;
ELSIF (clk'EVENT AND clk='1') THEN
pr_state <= nx_state;
END IF;
end process;
process(pr_state)
BEGIN
case pr_state IS
WHEN state0 =>
nx_state <= state1;
WHEN state1=>
nx_state <= state2;
WHEN state2 =>
nx_state <= state0;
END CASE;
end process;
END Flow;
-------------------------------------------------
That is an example for declaration, I want to implement three states, with each state implementing one component.
First of all, think of component instantiation and port mapping as wiring circuit components, not performing operations. The mapping itself does not perform any operation - the logic in the component combined with the signals driven into the component achieve that. This is also why you can't map a component in a process - wiring is a fixed connection, not something that you can perform as a runtime operation. It's not executed code - it's concurrent logic.
In your example code, there are three instances of the component and_2, outside of any process. This mapping is basically what you need (provided you change the component and signal types to your particular function). Then, in your state machine, you can drive the inputs selectively, or read the outputs, or whatever you need. You will probably need some intermediate signals, and you would need to change your wiring around, and what you will most likely get on your first attempt is problematic code with latches where you don't want them and nice things like that. What you can do instead is just register the adder outputs:
U1 : adder_2 port map (a, b, y);
U2 : adder_2 port map (c, d, z);
U3 : adder_2 port map (y_r, z_r, x);
adder_regs : process (clk)
begin
if rising_edge(clk) then
y_r <= y;
z_r <= z;
end if;
end process adder_regs;
Or is there some other reason you're trying to do it the way you are?