Using generic for a type in a port entity in VHDL 93 - vhdl

I have a type declared in a package which I use in the port entity:
Package:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
package ports_type is
constant N: positive := 3;
type t_ports_types is array(0 to N-1) of std_logic_vector (N-1 downto 0);
end package ports_type;
Module:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.ports_type.all;
entity ports is
generic (
N : positive := 3
);
port(
inp : in t_ports_types;
outp : out std_logic_vector(N-1 downto 0)
);
end ports;
architecture Behavioral of ports is
begin
process(inp)
variable result : std_logic;
begin
for y in 0 to N-1 loop
result := '0';
for x in 0 to N-1 loop
result := result or inp(x)(y);
end loop;
outp(y) <= result;
end loop;
end process;
end Behavioral;
The problem is that I have to manually change the value of Nin the package, which is a problem if I want to instantiate the ports entity in another module, like:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.ports_type.all;
entity ports_top is
generic (
N : positive := 3
);
Port (
A : in std_logic_vector(N-1 downto 0);
B : in std_logic_vector(N-1 downto 0);
C : in std_logic_vector(N-1 downto 0);
Outp : out std_logic_vector(N-1 downto 0)
);
end ports_top;
architecture Behavioral of ports_top is
signal s_ports : t_ports_types;
begin
s_ports(0) <= A;
s_ports(1) <= B;
s_ports(2) <= C;
ports_0: entity work.ports(Behavioral)
generic map (
N => N
)
port map(
inp => s_ports,
outp => Outp
);
end Behavioral;
The goal would be to only change N in the top module and not in the package as well. Is that possible with vhdl'93?
Thanks for the help.

Related

How to declare an array of arrays in the test bench of a VHDL code?

I have an array of arrays defined as the input to my entity. I used a package to define the array of arrays. In the test bench, I included that package and declared the component in the architecture but there is an error saying "formal port x does not exist in entity average. Please compare the definition of block average to its component declaration and its instantion to detect the mismatch."
Attaching the declarations below. Please help.
-- the code
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
package vpkg is
type m_array is array(1 downto 0, 1 downto 0) of std_logic_vector(7 downto 0);
end package;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.vpkg.all;
entity average is
Port (x : in m_array;
clk : in std_logic;
y : out std_logic_vector(7 downto 0)
);
end average;
architecture avg_arch of average is
signal sum : std_logic_vector(8 downto 0) := (others => '0');
begin
process(x):
for I in 0 to 1 loop
for J in 0 to 1 loop
sum <= sum + ('0' + x(I,J));
end loop;
end loop;
end process;
y <= std_logic_vector(to_signed(to_integer(signed(sum) / 4),8));
end avg_arch;
--the test bench
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.vpkg.all;
entity tb_average is
-- Port ( );
end tb_average;
architecture tb_average_arch of tb_average is
component average
Port (x : in m_array;
clk : in std_logic;
y : out std_logic_vector(7 downto 0)
);
end component;
signal x : m_array;
signal clk : std_logic := '0';
signal y : std_logic_vector(7 downto 0);
begin
average_1 : average Port Map (x => x,clk => clk,y=>y);
input_proc : process
begin
wait for 100ns;
x(0,0) <= "00001001";
x(0,1) <= "00000110";
x(1,0) <= "00000011";
x(1,1) <= "00000001";
wait;
end process;
clk_proc : process
begin
wait for 100ns;
loop
clk <= '1';
wait for 10ns;
clk <= '0';
wait for 10ns;
end loop;
end process;
end tb_average_arch;

Implementing Overflow Checking in 4-bit Adder/Subtractor (VHDL)

I am rather new (3 weeks) to VHDL, and I am having a problem in my latest assignment, which involves implementing overflow checking in a simple 4-bit adder:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity add_sub_4bit is
Port ( a : in STD_LOGIC_VECTOR(3 downto 0);
b : inout STD_LOGIC_VECTOR(3 downto 0);
sel: in STD_LOGIC );
--sum : inout STD_LOGIC_VECTOR(3 downto 0)
end add_sub_4bit;
architecture Behavioral of add_sub_4bit is
signal localflow : STD_LOGIC;
signal localsum : STD_LOGIC_VECTOR (3 downto 0);
begin
localsum <= a + b when sel = '1'
else
a - b;
process(a,b,localsum) begin
if a(3) = '0' AND b(3) = '0' AND localsum(3) = '1' then
localflow <= '1';
elsif a(3) = '1' AND b(3) = '1' AND localsum(3) = '0' then
localflow <='1';
else
localflow <='0';
end if;
end process;
end Behavioral;
Now, the test cases are as such:
A=5, B=-3, giving 0 to sel adds them, 1 subtracts.
A=6, B=2, working much the same.
Now, given that the numbers are signed, of course, they are two's complement numbers, so is the result. However, I can only detect overflow in a case of adding 6 (0110) and 2 (0010), giving out -8 (1000), which is obviously an overflow case in 4-bit. But, when doing 5 -(-3), the result is much the same, 1000, but since I have given numbers of two different signs, I cannot detect overflow using my method.
My teacher has suggested that we change the sign of B depending on the value of sel - I tried something like making b <= b+"1000" based on that but that didn't help, and I don't know of other ways, being very new to the language. What can I do to get a proper program? Thank you.
Firstly:
use IEEE.STD_LOGIC_UNSIGNED.ALL;
Don't do that. Especially if you want the numbers to be signed. Normal to use is:
use IEEE.numeric_std.all;
After that, you should cast the std_logic_vector to the wanted data type, e.g. 'signed', for the correct arithmetic.
Secondly, don't use inout. VHDL is not so good with bidirectional assignments. Either use in or out.
So combining the above, you could do (n.b. not the best code):
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
entity add_sub_4bit is
Port (
a : in STD_LOGIC_VECTOR(3 downto 0);
b : in STD_LOGIC_VECTOR(3 downto 0);
sel: in STD_LOGIC;
sum : out STD_LOGIC_VECTOR(3 downto 0);
overflow : out std_logic
);
end add_sub_4bit;
architecture Behavioral of add_sub_4bit is
signal localflow : STD_LOGIC;
signal locala, localb, localsum : signed(4 downto 0); -- one bit more then input
signal sumout : std_logic_vector(4 downto 0);
begin
locala <= resize(signed(a), 5);
localb <= resize(signed(b), 5);
localsum <= locala + localb when sel = '1' else locala - localb;
-- overflow occurs when bit 3 is not equal to the sign bit(4)
localflow <= '1' when localsum(3) /= localsum(4) else '0';
-- convert outputs
sumout <= std_logic_vector(localsum);
--outputs
sum <= sumout(4)&sumout(2 downto 0);
overflow <= localflow;
end Behavioral;
You can test this using a testbench:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
entity add_sub_4bit_tb is
end add_sub_4bit_tb;
architecture Behavioral of add_sub_4bit_tb is
signal sel : std_logic_vector(0 downto 0);
signal a, b, sum : std_logic_vector(3 downto 0);
begin
uut: entity work.add_sub_4bit
port map (a, b, sel(0), sum);
test: process
begin
for sel_o in 0 to 1 loop
sel <= std_logic_vector(to_signed(sel_o, 1));
for a_o in -8 to 7 loop
a <= std_logic_vector(to_signed(a_o, 4));
for b_o in -8 to 7 loop
b <= std_logic_vector(to_signed(b_o, 4));
wait for 1 ns;
end loop;
end loop;
end loop;
wait;
end process;
end Behavioral;

VHDL Counter ones errors

I already done the code, and it can work, However, when I try to write the test bench, I got some troubles on that. The input x sets up as 8 bits, and x: IN BIT_VECTOR (N -1 DOWNTO 0).
When I write the test bench I connot enter the bits number.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.std_logic_unsigned.all;
ENTITY Count_ones IS
GENERIC (N: INTEGER := 8); -- number of bits
PORT ( x: IN BIT_VECTOR (N -1 DOWNTO 0); y: OUT NATURAL RANGE 0 TO N);
END ENTITY ;
architecture Behavioral of Count_ones is
TYPE count is Array (N DOWNTO 1) OF Natural;
signal a : count;
begin
a(0) <= 1 when (x(0) = '1')
else
0;
gen: FOR i IN N-1 DOWNTO 0
GENERATE
a(i+1) <= (a(i)+1) when (x(i)='0')
else
a(i);
END GENERATE;
y <= a(N-1);
end Behavioral;
The Test Bench:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
ENTITY Count_ones_TB IS
END Count_ones_TB;
ARCHITECTURE behavior OF Count_ones_TB IS
COMPONENT Count_ones
PORT(
x : IN std_logic_vector(7 downto 0);
y : OUT std_logic_vector(0 to 3)
);
END COMPONENT;
--Inputs
signal x : std_logic_vector(7 downto 0) := (others => '0');
--Outputs
signal y : std_logic_vector(0 to 3);
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: Count_ones PORT MAP (
x => x,
y => y
);
stim_proc: process
begin
x <= "00010101";
wait for 100 ns;
x <= "00001001";
wait for 100 ns;
x <= "11111111101"
wait for 100ns;
-- insert stimulus here
wait;
end process;
END;
The error is
Entity port x does not match with type std_logic_vector of component port
Entity port y does not match with type std_logic_vector of component port
Please help me, I real cannot figure out the way to solve that.
The answer to your specific question is that the types of the ports in the entity, the ports in the component and the types of the signals must match. Here is a link to your code with those errors and many more corrected.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.std_logic_unsigned.all;
ENTITY Count_ones IS
GENERIC (N: INTEGER := 8); -- number of bits
PORT ( x: IN BIT_VECTOR (N -1 DOWNTO 0); y: OUT NATURAL RANGE 0 TO N);
END ENTITY ;
architecture Behavioral of Count_ones is
TYPE count is Array (N DOWNTO 0) OF Natural;
signal a : count;
begin
a(0) <= 1 when (x(0) = '1')
else
0;
gen: FOR i IN N-1 DOWNTO 0
GENERATE
a(i+1) <= (a(i)+1) when (x(i)='0')
else
a(i);
END GENERATE;
y <= a(N-1);
end Behavioral;
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
ENTITY Count_ones_TB IS
END Count_ones_TB;
ARCHITECTURE behavior OF Count_ones_TB IS
COMPONENT Count_ones
GENERIC (N: INTEGER := 8); -- number of bits
PORT ( x: IN BIT_VECTOR (N -1 DOWNTO 0);
y: OUT NATURAL RANGE 0 TO N);
END COMPONENT;
--Inputs
signal x : BIT_VECTOR(7 downto 0) := (others => '0');
--Outputs
signal y : natural;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: Count_ones PORT MAP (
x => x,
y => y
);
stim_proc: process
begin
x <= "00010101";
wait for 100 ns;
x <= "00001001";
wait for 100 ns;
x <= "11111101";
wait for 100ns;
-- insert stimulus here
wait;
end process;
END;
However I must point out that you are a long way from achieving your goal of trying to count the number of ones.
Because of that:
My corrections to your code are not the only correct answer. In
fact, my corrections are not even a good answer. I have simply made
the minimum corrections to make your code compile and run. You need
to think very carefully what type all the ports and signals in your
design should be.
My corrections will not make your code work, i.e. count the number of
ones.

Using array of std_logic_vector as a port type, with both ranges using a generic

Is it possible to create an entity with a port that is an array of std_logic_vectors, with both the size of the array and the std_logic_vector coming from generics? Ie. is it possible to create eg. a bus multiplexer with both the bus width and bus count configurable?
entity bus_multiplexer is
generic (bus_width : positive := 8;
sel_width : positive := 2);
port ( i : in array(integer range 2**sel_width - 1 downto 0) of std_logic_vector(bus_width - 1 downto 0);
sel : in std_logic_vector(sel_width - 1 downto 0);
o : out std_logic_vector(bus_width - 1 downto 0));
end bus_multiplexer;
architecture dataflow of bus_multiplexer is
begin
o <= i(to_integer(unsigned(sel)));
end dataflow;
The above doesn't seem to work because the array type needs to be defined separately.
Defining the type before the port also does not work, as then it expects the entity definition to end after it. Defining it after the port definition doesn't work since it'd be used before that. Defining it in a package doesn't work because the type definition doesn't seem to like having an unconstrained range in the "base type".
Is it possible to somehow do this in VHDL-93? (What about VHDL-2008?)
Defining the type as array(natural range <>, natural range <>) of std_logic in the package works - as in the port definition doesn't give an error - but actually using it if it's defined that way seems to be quite unwieldy.
Is there some sane way to use it like this? Is there some simple way to map N separate std_logic_vectors to a port defined like that, and likewise for the actual output logic?
I tried the original and o <= i(to_integer(unsigned(sel)), bus_width - 1 downto 0), but neither worked. I know I could do it one bit at a time, but I'd prefer something simpler. And while the bit-by-bit -approach might be okay for the internal implementation, I certainly wouldn't want to have to do that for the port mapping every time I use the component...
Is there some sane(-ish) way to do this?
(Addendum: I know there are some similar questions, but most of them don't deal with the case of both ranges coming from generics, and were solved using a type definition in a package. The one that did talk about two generic dimensions apparently didn't need the input to come from distinct std_logic_vectors and ended up using the "2d-array of std_logic" method, which doesn't work for me (at least without further clarification about how to use it without losing one's sanity))
This works with VHDL2008:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package bus_multiplexer_pkg is
type bus_array is array(natural range <>) of std_logic_vector;
end package;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.bus_multiplexer_pkg.all;
entity bus_multiplexer is
generic (bus_width : positive := 8;
sel_width : positive := 2);
port ( i : in bus_array(2**sel_width - 1 downto 0)(bus_width - 1 downto 0);
sel : in std_logic_vector(sel_width - 1 downto 0);
o : out std_logic_vector(bus_width - 1 downto 0));
end bus_multiplexer;
architecture dataflow of bus_multiplexer is
begin
o <= i(to_integer(unsigned(sel)));
end dataflow;
And it can be used like this:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.all;
use work.bus_multiplexer_pkg.all;
entity bus_multiplexer_4 is
generic (bus_width : positive := 8);
port ( bus0, bus1, bus2, bus3 : in std_logic_vector(bus_width - 1 downto 0);
sel : in std_logic_vector(1 downto 0);
o : out std_logic_vector(bus_width - 1 downto 0));
end bus_multiplexer_4;
architecture structural of bus_multiplexer_4 is
signal i : bus_array(3 downto 0)(bus_width - 1 downto 0);
begin
i <= (0 => bus0, 1 => bus1, 2 => bus2, 3 => bus3);
u: entity bus_multiplexer generic map (bus_width => bus_width, sel_width => 2) port map (i => i, sel => sel, o => o);
end;
It doesn't work with VHDL93, however, because you can't leave the std_logic_vector unconstrained in the type definition, as stated in the question.
Unfortunately, I don't know if there's any way to do anything similar without 2d arrays with VHDL93.
Edit: Paebbels's answer shows how to do this in VHDL93 by using 2d arrays, with custom procedures to make it manageable. Since his example is quite big, here's also a minimal example of the same concept:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package bus_multiplexer_pkg is
type bus_array is array(natural range <>, natural range <>) of std_logic;
procedure slm_row_from_slv(signal slm : out bus_array; constant row : natural; signal slv : in std_logic_vector);
procedure slv_from_slm_row(signal slv : out std_logic_vector; signal slm : in bus_array; constant row : natural);
end package;
package body bus_multiplexer_pkg is
procedure slm_row_from_slv(signal slm : out bus_array; constant row : natural; signal slv : in std_logic_vector) is
begin
for i in slv'range loop
slm(row, i) <= slv(i);
end loop;
end procedure;
procedure slv_from_slm_row(signal slv : out std_logic_vector; signal slm : in bus_array; constant row : natural) is
begin
for i in slv'range loop
slv(i) <= slm(row, i);
end loop;
end procedure;
end package body;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.bus_multiplexer_pkg.all;
entity bus_multiplexer is
generic (bus_width : positive := 8;
sel_width : positive := 2);
port ( i : in bus_array(2**sel_width - 1 downto 0, bus_width - 1 downto 0);
sel : in std_logic_vector(sel_width - 1 downto 0);
o : out std_logic_vector(bus_width - 1 downto 0));
end bus_multiplexer;
architecture dataflow of bus_multiplexer is
begin
slv_from_slm_row(o, i, to_integer(unsigned(sel)));
end dataflow;
And it can be used like this:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.all;
use work.bus_multiplexer_pkg.all;
entity bus_multiplexer_4 is
generic (bus_width : positive := 8);
port ( bus0, bus1, bus2, bus3 : in std_logic_vector(bus_width - 1 downto 0);
sel : in std_logic_vector(1 downto 0);
o : out std_logic_vector(bus_width - 1 downto 0));
end bus_multiplexer_4;
architecture structural of bus_multiplexer_4 is
signal i : bus_array(3 downto 0, bus_width - 1 downto 0);
begin
slm_row_from_slv(i, 0, bus0);
slm_row_from_slv(i, 1, bus1);
slm_row_from_slv(i, 2, bus2);
slm_row_from_slv(i, 3, bus3);
u: entity bus_multiplexer generic map (bus_width => bus_width, sel_width => 2) port map (i => i, sel => sel, o => o);
end;
Yes, it's possible.
Your attempt with a two dimensional array is good, because nested 1 dimensional array need a fixed size in the inner dimensions. So the way to handle such a 2D array is to write some functions and procedures, which convert the 2D array into nested 1D vectors.
I answered a similar question here:
- Fill one row in 2D array outside the process (VHDL) and
- Creating a generic array whose elements have increasing width in VHDL
Here is my vectors package.
And here is an example of an multiplexer for a FIFO interface, which is variable in data width as well as in input count. It uses a round robin arbiter to select the inputs.
Entity 'PoC.bus.Stream.Mux':
-- EMACS settings: -*- tab-width: 2; indent-tabs-mode: t -*-
-- vim: tabstop=2:shiftwidth=2:noexpandtab
-- kate: tab-width 2; replace-tabs off; indent-width 2;
--
-- ============================================================================
-- Authors: Patrick Lehmann
--
-- License:
-- ============================================================================
-- Copyright 2007-2015 Technische Universitaet Dresden - Germany
-- Chair for VLSI-Design, Diagnostics and Architecture
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
-- ============================================================================
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
library PoC;
use PoC.config.all;
use PoC.utils.all;
use PoC.vectors.all;
entity Stream_Mux is
generic (
PORTS : POSITIVE := 2;
DATA_BITS : POSITIVE := 8;
META_BITS : NATURAL := 8;
META_REV_BITS : NATURAL := 2
);
port (
Clock : IN STD_LOGIC;
Reset : IN STD_LOGIC;
-- IN Ports
In_Valid : IN STD_LOGIC_VECTOR(PORTS - 1 downto 0);
In_Data : IN T_SLM(PORTS - 1 downto 0, DATA_BITS - 1 downto 0);
In_Meta : IN T_SLM(PORTS - 1 downto 0, META_BITS - 1 downto 0);
In_Meta_rev : OUT T_SLM(PORTS - 1 downto 0, META_REV_BITS - 1 downto 0);
In_SOF : IN STD_LOGIC_VECTOR(PORTS - 1 downto 0);
In_EOF : IN STD_LOGIC_VECTOR(PORTS - 1 downto 0);
In_Ack : OUT STD_LOGIC_VECTOR(PORTS - 1 downto 0);
-- OUT Port
Out_Valid : OUT STD_LOGIC;
Out_Data : OUT STD_LOGIC_VECTOR(DATA_BITS - 1 downto 0);
Out_Meta : OUT STD_LOGIC_VECTOR(META_BITS - 1 downto 0);
Out_Meta_rev : IN STD_LOGIC_VECTOR(META_REV_BITS - 1 downto 0);
Out_SOF : OUT STD_LOGIC;
Out_EOF : OUT STD_LOGIC;
Out_Ack : IN STD_LOGIC
);
end;
architecture rtl OF Stream_Mux is
attribute KEEP : BOOLEAN;
attribute FSM_ENCODING : STRING;
subtype T_CHANNEL_INDEX is NATURAL range 0 to PORTS - 1;
type T_STATE is (ST_IDLE, ST_DATAFLOW);
signal State : T_STATE := ST_IDLE;
signal NextState : T_STATE;
signal FSM_Dataflow_en : STD_LOGIC;
signal RequestVector : STD_LOGIC_VECTOR(PORTS - 1 downto 0);
signal RequestWithSelf : STD_LOGIC;
signal RequestWithoutSelf : STD_LOGIC;
signal RequestLeft : UNSIGNED(PORTS - 1 downto 0);
signal SelectLeft : UNSIGNED(PORTS - 1 downto 0);
signal SelectRight : UNSIGNED(PORTS - 1 downto 0);
signal ChannelPointer_en : STD_LOGIC;
signal ChannelPointer : STD_LOGIC_VECTOR(PORTS - 1 downto 0);
signal ChannelPointer_d : STD_LOGIC_VECTOR(PORTS - 1 downto 0) := to_slv(2 ** (PORTS - 1), PORTS);
signal ChannelPointer_nxt : STD_LOGIC_VECTOR(PORTS - 1 downto 0);
signal ChannelPointer_bin : UNSIGNED(log2ceilnz(PORTS) - 1 downto 0);
signal idx : T_CHANNEL_INDEX;
signal Out_EOF_i : STD_LOGIC;
begin
RequestVector <= In_Valid AND In_SOF;
RequestWithSelf <= slv_or(RequestVector);
RequestWithoutSelf <= slv_or(RequestVector AND NOT ChannelPointer_d);
process(Clock)
begin
if rising_edge(Clock) then
if (Reset = '1') then
State <= ST_IDLE;
else
State <= NextState;
end if;
end if;
end process;
process(State, RequestWithSelf, RequestWithoutSelf, Out_Ack, Out_EOF_i, ChannelPointer_d, ChannelPointer_nxt)
begin
NextState <= State;
FSM_Dataflow_en <= '0';
ChannelPointer_en <= '0';
ChannelPointer <= ChannelPointer_d;
case State is
when ST_IDLE =>
if (RequestWithSelf = '1') then
ChannelPointer_en <= '1';
NextState <= ST_DATAFLOW;
end if;
when ST_DATAFLOW =>
FSM_Dataflow_en <= '1';
if ((Out_Ack AND Out_EOF_i) = '1') then
if (RequestWithoutSelf = '0') then
NextState <= ST_IDLE;
else
ChannelPointer_en <= '1';
end if;
end if;
end case;
end process;
process(Clock)
begin
if rising_edge(Clock) then
if (Reset = '1') then
ChannelPointer_d <= to_slv(2 ** (PORTS - 1), PORTS);
elsif (ChannelPointer_en = '1') then
ChannelPointer_d <= ChannelPointer_nxt;
end if;
end if;
end process;
RequestLeft <= (NOT ((unsigned(ChannelPointer_d) - 1) OR unsigned(ChannelPointer_d))) AND unsigned(RequestVector);
SelectLeft <= (unsigned(NOT RequestLeft) + 1) AND RequestLeft;
SelectRight <= (unsigned(NOT RequestVector) + 1) AND unsigned(RequestVector);
ChannelPointer_nxt <= std_logic_vector(ite((RequestLeft = (RequestLeft'range => '0')), SelectRight, SelectLeft));
ChannelPointer_bin <= onehot2bin(ChannelPointer);
idx <= to_integer(ChannelPointer_bin);
Out_Data <= get_row(In_Data, idx);
Out_Meta <= get_row(In_Meta, idx);
Out_SOF <= In_SOF(to_integer(ChannelPointer_bin));
Out_EOF_i <= In_EOF(to_integer(ChannelPointer_bin));
Out_Valid <= In_Valid(to_integer(ChannelPointer_bin)) and FSM_Dataflow_en;
Out_EOF <= Out_EOF_i;
In_Ack <= (In_Ack 'range => (Out_Ack and FSM_Dataflow_en)) AND ChannelPointer;
genMetaReverse_0 : if (META_REV_BITS = 0) generate
In_Meta_rev <= (others => (others => '0'));
end generate;
genMetaReverse_1 : if (META_REV_BITS > 0) generate
signal Temp_Meta_rev : T_SLM(PORTS - 1 downto 0, META_REV_BITS - 1 downto 0) := (others => (others => 'Z'));
begin
genAssign : for i in 0 to PORTS - 1 generate
signal row : STD_LOGIC_VECTOR(META_REV_BITS - 1 downto 0);
begin
row <= Out_Meta_rev AND (row'range => ChannelPointer(I));
assign_row(Temp_Meta_rev, row, i);
end generate;
In_Meta_rev <= Temp_Meta_rev;
end generate;
end architecture;

Two's complement VHDL

I am just trying to make a simple two's complement device in VHDL but it is throwing back this really annoying error and I'm unsure what I have done wrong. Probably something very silly...The error is
"Error (10327): VHDL error at twocompliment.vhd(21): can't determine definition of operator ""nand"" -- found 0 possible definitions"
The code is
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity twoscompliment is
generic
(
Nbits : positive := 8
);
port
(
--Inputs
A : in std_logic_vector (Nbits-1 downto 0);
--Outputs
Y : out std_logic_vector (Nbits downto 0)
);
end twoscompliment;
architecture twoscompliment_v1 of twoscompliment is
begin
Y <= std_logic_vector(unsigned(A NAND '1') + '1');
end twoscompliment_v1;
Any help would be awesome!
It seems to me you are trying to negate the input number... Maybe I'm missing something vital, but the other answers give a solution which, whilst achieving the goal, appear to be one step more obfuscated than they need to be.
Barring the ugly conversions, what's wrong with
y <= std_logic_vector(-signed(resize(unsigned(A)), y'length));
Of course, I would argue that if A and Y are supposed to be representing signed numbers (or unsigned numbers), they should be expressed as such:
library ieee;
use ieee.numeric_std.all;
entity twoscomplement is
generic
(
Nbits : positive := 8
);
port
(
A : in unsigned (Nbits-1 downto 0);
Y : out signed (Nbits downto 0)
);
end entity twoscomplement;
architecture a1 of twoscomplement is
begin
Y <= -signed(resize(A, Y'length));
end architecture;
Let's check the results:
entity test_twoscomplement is
end entity;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
architecture test of test_twoscomplement is
signal A : unsigned (7 downto 0);
signal Y : signed(8 downto 0);
begin
dut : entity work.twoscomplement port map (A => A, Y=>Y);
process
begin
for i in 0 to 255 loop
A <= to_unsigned(i, A'length);
wait for 1 ns;
assert to_integer(Y) = -i severity error;
end loop;
report "tests done";
wait;
end process;
end architecture;
Running with GHDL:
$ ghdl -a twoscomp.vhd
$ ghdl --elab-run test_twoscomplement
twoscomp.vhd:40:8:#256ns:(report note): tests done
Success!
Try this:
architecture twoscompliment_v1 of twoscompliment is
signal temp : std_logic_vector(Nbits-1 downto 0);
begin
temp <= not A;
Y <= std_logic_vector(unsigned(temp + 1));
end twoscompliment_v1;
architecture twoscompliment_v1 of twoscompliment is
constant ONE: UNSIGNED(Y'RANGE) := (0 => '1', others => '0');
begin
Y <= std_logic_vector(unsigned (not A) + ONE);
end twoscompliment_v1;
Hi gentleman basically 2's complement is done by inverting the binary bits of a
given no. i.e changing ones to zeroes and zeroes to ones, after that add the
binary bit '1' to the Least significant bit of the given binary number. Now I
have a program
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity twoscomplementconversion is Port (
bin : in STD_LOGIC_VECTOR (3 downto 0);
twos : out STD_LOGIC_VECTOR (3 downto 0)
);
end twoscomplementconversion;
architecture Behavioral of twoscomplementconversion is
component fourbitadder45 Port (
a : in std_logic_vector (3 downto 0);
b : in std_logic_vector(3 downto 0);
cin : in std_logic;
cout : out std_logic;
sum : out std_logic_vector (3 downto 0)
);
end component;
signal onebit : std_logic_vector(3 downto 0):="0001";
signal cin1 : std_logic:='0';
signal notbin : std_logic_vector(3 downto 0);
signal cout1 : std_logic;
begin
notbin <= not(bin);
twos1: fourbitadder45 port map (
a => notbin,
b => onebit,
cin => cin1,
cout => cout1,
sum => twos
);
end Behavioral;
The four bit adder program is given below:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity fourbitadder45 is Port (
a : in std_logic_vector (3 downto 0);
b : in std_logic_vector(3 downto 0);
cin : in std_logic;
cout : out std_logic;
sum : out std_logic_vector (3 downto 0)
);
end fourbitadder45;
architecture Behavioral of fourbitadder45 is
component fulladder2 Port (
a : in std_logic;
b : in std_logic;
cin : in std_logic;
cout : out std_logic;
sum : out std_logic
);
end component;
signal c:std_logic_vector (3 downto 1);
begin
fa1 :fulladder2 port map (a => a(0), b => b(0), cin => cin, cout => c(1), sum => sum(0));
fa2 :fulladder2 port map (a => a(1), b => b(1), cin => c(1), cout => c(2), sum => sum(1));
fa3 :fulladder2 port map (a => a(2), b => b(2), cin => c(2), cout => c(3), sum => sum(2));
fa4 :fulladder2 port map (a => a(3), b => b(3), cin => c(3), cout => cout, sum => sum(3));
end Behavioral;
four bit adder contains 4 full adders so the full adder program is given below:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity fulladder2 is Port (
a : in std_logic;
b : in std_logic;
cin : in std_logic;
cout : out std_logic;
sum : out std_logic
);
end fulladder2;
architecture Behavioral of fulladder2 is
begin
sum <= a xor b xor cin;
cout <= ((a and b) or (b and cin) or (cin and a));
end Behavioral;
I hope that answers the question. This is a method there are many different methods

Resources