问题
I am trying to create a VHDL ALU with structural way that does the following operations: 1)ADDITION 2)SUBSTRACTION 3)LOGIC AND 4)LOGIC OR
I'm running my code in Quartus II and it finds some errors at compilation. Here is my code :
library ieee;
use ieee.std_logic_1164.all;
use work.basic_func.all;
entity askhsh1 is
port
( a : in std_logic_vector(15 downto 0);
b : in std_logic_vector(15 downto 0);
coin : in std_logic;
coout : out std_logic;
s : in std_logic_vector(15 downto 0);
d : in std_logic_vector(15 downto 0);
result : out std_logic;
operator : in std_logic;
binvert : in std_logic;
ainvert : in std_logic);
end askhsh1;
architecture structure of askhsh1 is
signal c : std_logic_vector(1 to 15);
signal result : std_logic_vector(15 downto 0);
component myAND
port (in1, in2: in std_logic; out1: out std_logic);
end component;
component myOR
port (in1, in2: in std_logic; out1: out std_logic);
end component;
component myXOR
port (in1, in2: in std_logic; out1: out std_logic);
end component;
component fullader
port (cin, x, y : in std_logic;
s, cout : out std_logic);
end component;
begin
U1 : myAND port map (a, b, result) when (operator = '0') else T1 : myOR port map (a, b, result) when (operator = '1')
else (stage0 : fullader port map (coin, a(0), b(0), s(0), c(1));
stage1 : fullader port map (c(1), a(1), b(1), s(1), c(2));
stage2 : fullader port map (c(2), a(2), b(2), s(2), c(3));
stage3 : fullader port map (c(3), a(3), b(3), s(3), c(4));
stage4 : fullader port map (c(4), a(4), b(4), s(4), c(5));
stage5 : fullader port map (c(5), a(5), b(5), s(5), c(6));
stage6 : fullader port map (c(6), a(6), b(6), s(6), c(7));
stage7 : fullader port map (c(7), a(7), b(7), s(7), c(8));
stage8 : fullader port map (c(8), a(8), b(8), s(8), c(9));
stage9 : fullader port map (c(9), a(9), b(9), s(9), c(10));
stage10 : fullader port map (c(10), a(10), b(10), s(10), c(11));
stage11 : fullader port map (c(11), a(11), b(11), s(11), c(12));
stage12 : fullader port map (c(12), a(12), b(12), s(12), c(13));
stage13 : fullader port map (c(13), a(13), b(13), s(13), c(14));
stage14 : fullader port map (c(14), a(14), b(14), s(14), c(15));
stage15 : fullader port map (c(15), a(15), b(15), s(15), coout);) when (operator = '2' and binvert = '0' and ainvert = '0')
else (stage0 : fullader port map ('1', a(0), not b(0), s(0), c(1));
stage1 : fullader port map (c(1), a(1), not b(1), s(1), c(2));
stage2 : fullader port map (c(2), a(2), not b(2), s(2), c(3));
stage3 : fullader port map (c(3), a(3), not b(3), s(3), c(4));
stage4 : fullader port map (c(4), a(4), not b(4), s(4), c(5));
stage5 : fullader port map (c(5), a(5), not b(5), s(5), c(6));
stage6 : fullader port map (c(6), a(6), not b(6), s(6), c(7));
stage7 : fullader port map (c(7), a(7), not b(7), s(7), c(8));
stage8 : fullader port map (c(8), a(8), not b(8), s(8), c(9));
stage9 : fullader port map (c(9), a(9), not b(9), s(9), c(10));
stage10 : fullader port map (c(10), a(10), not b(10), s(10), c(11));
stage11 : fullader port map (c(11), a(11), not b(11), s(11), c(12));
stage12 : fullader port map (c(12), a(12), not b(12), s(12), c(13));
stage13 : fullader port map (c(13), a(13), not b(13), s(13), c(14));
stage14 : fullader port map (c(14), a(14), not b(14), s(14), c(15));
stage15 : fullader port map (c(15), a(15), not b(15), s(15), coout);) when (operator = '2' and binvert = '1' and ainvert = '0')
else (stage0 : fullader port map ('1', not a(0), b(0), s(0), c(1));
stage1 : fullader port map (c(1), not a(1), b(1), s(1), c(2));
stage2 : fullader port map (c(2), not a(2), b(2), s(2), c(3));
stage3 : fullader port map (c(3), not a(3), b(3), s(3), c(4));
stage4 : fullader port map (c(4), not a(4), b(4), s(4), c(5));
stage5 : fullader port map (c(5), not a(5), b(5), s(5), c(6));
stage6 : fullader port map (c(6), not a(6), b(6), s(6), c(7));
stage7 : fullader port map (c(7), not a(7), b(7), s(7), c(8));
stage8 : fullader port map (c(8), not a(8), b(8), s(8), c(9));
stage9 : fullader port map (c(9), not a(9), b(9), s(9), c(10));
stage10 : fullader port map (c(10), not a(10), b(10), s(10), c(11));
stage11 : fullader port map (c(11), not a(11), b(11), s(11), c(12));
stage12 : fullader port map (c(12), not a(12), b(12), s(12), c(13));
stage13 : fullader port map (c(13), not a(13), b(13), s(13), c(14));
stage14 : fullader port map (c(14), not a(14), b(14), s(14), c(15));
stage15 : fullader port map (c(15), not a(15), b(15), s(15), coout);) when (operator = '2' and ainvert = '1' and binvert = '0')
else P1 : myXOR port map (a, b, result) when (operator = '3');
end structure;
The package basic_func is here:
library ieee;
use ieee.std_logic_1164.all;
package basic_func is
component myAND
port (in1, in2: in std_logic; out1: out std_logic);
end component;
component myOR
port (in1, in2: in std_logic; out1: out std_logic);
end component;
component myXOR
port (in1, in2: in std_logic; out1: out std_logic);
end component;
component fullader
port (cin, x, y : in std_logic;
s, cout : out std_logic);
end component;
end package basic_func;
library ieee;
use ieee.std_logic_1164.all;
entity myAND is
port (in1, in2: in std_logic; out1: out std_logic);
end myAND;
architecture modeland of myAND is
begin
out1 <= in1 and in2;
end modeland;
library ieee;
use ieee.std_logic_1164.all;
entity myOR is
port (in1, in2: in std_logic; out1: out std_logic);
end myOR;
architecture modelor of myOR is
begin
out1 <= in1 or in2;
end modelor;
library ieee;
use ieee.std_logic_1164.all;
entity myXOR is
port (in1, in2: in std_logic; out1: out std_logic);
end myXOR;
architecture modelxor of myXOR is
begin
out1 <= in1 xor in2;
end modelxor;
library ieee;
use ieee.std_logic_1164.all;
entity myfullader is
port (cin, x, y : in std_logic;
s, cout : out std_logic);
end myfullader;
architecture modelfulla of myfullader is
begin
s <= x xor y xor cin;
cout <= (x and y) or (cin and x) or (cin and y);
end modelfulla;
Any help is appreciated
回答1:
Your approach to the problem of selecting the different outputs of the functional blocks (addition, etc) is not valid:
U1 : myAND port map (a, b, result) when (operator = '0') else T1 : myOR port map (a, b, result) when (operator = '1') -- and so on
Remember that you are describing hardware. What you have attempted to do here is to instantiate different hardware, depending on the operator
, which changes during run time. What you need to do is to instantiate all the functional blocks, then use your operator
to multiplex the output of one of those functional blocks to your output. It's difficult to give an example you can copy exactly, but the general way to select one of the outputs would look something like this (where operator
is an integer range 0 to 2
):
process (operator, adder_output, and_output, or_output)
begin
case (operator) is
when 0 => result <= and_output;
when 1 => result <= or_output;
when 2 => result <= adder_output;
end case;
end process;
There are a few other points to make.
Your
operator
is defined as anstd_logic
, and you are trying to check for it being'2'
. It looks like to implement the number of operators you have, you should define this input to be aninteger
. Having done this, you test this input against an integer literal, which would look like2
, not'2'
. I would make the inputoperator : in integer range 0 to 2
, assuming you have 3 operators.You have
result
defined as anstd_logic
port, and anstd_logic_vector
signal. It is not clear what you actually wanted, but I suspect you should make yourresult
port anstd_logic_vector
, and remove the signal.You are instantiating entities using positional association. this is not generally recommended. Where you have:
stage0 : fullader port map (coin, a(0), b(0), s(0), c(1));
You would instead use named association:
stage0 : fullader port map ( cin => coin, x => a(0), y => b(0), s => s(0), cout => c(1) );
This prevents bugs if somebody alters the port list, and makes the code more readable.
I would suggest making the code more structured, so that you create an entity that creates an 8-bit adder using your
fulladder
entites, then you can much more cleanly instnatiate this one 8-bit adder in your top level. This will make it more clear in your code what is going on.If you did have a need to conditionally instantiate an entity, you would use the
generate
statement:SomeLabel : if (my_condition = true) generate stage0 : fullader port map ( cin => coin, x => a(0), y => b(0), s => s(0), cout => c(1) ); end generate;
Again, I don't think this is what you should be using in this case, as
generate
is a compile-time construct, and you want the behavior to change during run-time.
来源:https://stackoverflow.com/questions/37073331/vhdl-program-doesn-t-compile