4 bit magnitude comparator VHDL - vhdl

I have to make a 4bit magnitude comparator in VHDL with only concurrent statements (no if/else or case/when).
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Exercise is
port ( A : in std_logic_vector (3 downto 0);
B : in std_logic_vector (3 downto 0);
Ag : out std_logic;
Bg : out std_logic;
AeqB: out std_logic
);
end Exercise;
architecture Comparator of Exercise is
begin
Ag <= '1'when (A>B) else '0';
Bg <= '1' when (B>A) else '0'; --Problem: Here if i sumulate B="ZZZZ", Bg is 1, asi if B>A
AeqB<= '1' when (A=B) else '0';
end Comparator;
The problem is that i need to take in count all the other values of std_logic (U,X,Z,W,L,H,-), i know there is the others but cant figure it out how to make the comparator with with/select statement.
Thanks

In general you can 'convert' the various values that std_logic can take into either 0 or 1 using the to_01 function. I think it's in package numeric_std.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity comp_4 is
port ( A:IN STD_LOGIC_VECTOR(0 to 3);
B:IN STD_LOGIC_VECTOR(0 to 3);
ET:OUT STD_LOGIC;
GT:OUT STD_LOGIC;
LT:OUT STD_LOGIC);
end comp_4;
architecture dataflow of comp_4 is
begin
with A-B(0 to 3) select
ET <= '1' when "0000",
'0' when others;
with A > B select
GT <= '1' when true,
'0' when others;
with A < B select
LT <= '1' when true,
'0' when others;
end dataflow;

Related

10028 Can't solve multiple constant drivers for net "D[x]"

Hi pleople this is my code, and the only error is Error (10028): Can't resolve multiple constant drivers for net "D[22]" at bonus2.vhd(26). I<m new at this and I don't understant this error.
Here is my code
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity bonus2 is
port (
B,C : in unsigned(15 downto 0);
clear, clk : in std_logic;
Q : out unsigned(31 downto 0)
);
end entity bonus2;
architecture arch_bonus2 of bonus2 is
signal mult : unsigned(31 downto 0); --signal d'addition
signal D: unsigned(31 downto 0); --signal d'addition
begin
mult <= B * C;
process(clear)
begin
if clear = '1' then
D <= x"00000000";
end if;
end process;
process(clk)
begin
if rising_edge(clk) then
D <= mult + D;
end if;
end process;
Q <= D;
end architecture arch_bonus2;
Your code shows that you might be unfamiliar with some concepts of hardware design, so I suggest you catch up on combinational/sequential logic and how to describe them with VHDL. Also, a good rule of thumb is that you should be able to draw some parts of your design, and if you do you'll see that the D wire is driven by multiple nets.
What I believe you want to do, based on your code, is to be able to reset/initialize your output register. However, the way you have coded it suggests you want an asynchronous reset.
Please check here to know more about synch vs asynch logic and then I suggest you to explore further to understand the implications.
Here is a modified version of your code with an asynchronous reset, because it seems what you want.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity bonus2 is
port (
B,C : in unsigned(15 downto 0);
clear, clk : in std_logic;
Q : out unsigned(31 downto 0)
);
end entity bonus2;
architecture arch_bonus2 of bonus2 is
signal mult : unsigned(31 downto 0); --signal d'addition
signal D: unsigned(31 downto 0); --signal d'addition
begin
mult <= B * C;
process(clk,clear)
if clear == '1' then
D <= x"00000000";
elsif rising_edge(clk) then
D <= mult + D;
end if;
end process;
Q <= D;
end architecture arch_bonus2;

Error (10448): VHDL error at teste.vhd(33): record type std_ulogic is used but not declared

I was trying to do a work and this error is boring me, i pass to a new project teste.vhdl and this keep happening, i need to have two barriers of clock one for input and another to output, to use timequest with combinational logic.
The 'and' is just a example.
library ieee;
use ieee.std_logic_1164.all;
--use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
ENTITY teste IS
PORT(
clock : in std_logic;
clear : in std_logic;
a : in std_logic_vector(3 downto 0);
b : in std_logic_vector(3 downto 0);
s : out std_logic_vector(3 downto 0)
);
END teste;
ARCHITECTURE comportamento OF teste IS
signal a1,b1,s1 : std_logic_vector(3 downto 0);
begin
FF_in: process(clock.clear)
begin
if clear = '1' then
a1 <= "0000";
b1 <= "0000";
elsif clock'event and clock = '1' then
a1 <= a;
b1 <= b;
end if;
end process;
s1 <= a1 and b1;
FF_out: process(clock.clear)
begin
if clear = '1' then
s <= "0000";
elsif clock'event and clock = '1' then
s <= s1;
end if;
end process;
END comportamento;
You have used a . Rather than , in the process sensitivity list. Using a . Is trying to access a record field.

Creating a 16-bit ALU from 16 1-bit ALUs (Structural code)

i have created the structural and the behavioral code for a 1-bit ALU,as well as a control circuit .The control circuit decides the operation that will be conducted between two variables : a,b .
Here is my behavioral part of the code :
library ieee;
use ieee.std_logic_1164.all;
package erotima2 is
-- AND2 declaration
component myAND2
port (outnotA,outnotB: in std_logic; outAND: out std_logic);
end component;
-- OR2 declaration
component myOR2
port (outnotA,outnotB: in std_logic; outOR: out std_logic);
end component;
-- XOR2 declaration
component myXOR2
port (outnotA,outnotB: in std_logic; outXOR: out std_logic);
end component;
--fulladder declaration
component fulladder
port(CarryIn,outnotA,outnotB: in std_logic; sum,CarryOut: out std_logic);
end component;
--Ainvert declaration
component notA
port(a: in std_logic; signala: std_logic_vector(0 downto 0); outnotA: out std_logic);
end component;
--Binvert declaration
component notB
port(b: in std_logic; signalb: std_logic_vector(0 downto 0); outnotB: out std_logic);
end component;
--ControlCircuit declaration--
component ControlCircuit
port (
opcode : in std_logic_vector (2 downto 0);
signala,signalb : out std_logic_vector(0 downto 0);
operation : out std_logic_vector (1 downto 0);
CarryIn: out std_logic);
end component;
--mux4to1 declaration
component mux4to1
port(outAND, outOR, sum, outXOR: in std_logic; operation: in std_logic_vector(1 downto 0); Result: out std_logic);
end component;
end package erotima2;
--2 input AND gate
library ieee;
use ieee.std_logic_1164.all;
entity myAND2 is
port (outnotA,outnotB: in std_logic; outAND: out std_logic);
end myAND2;
architecture model_conc of myAND2 is
begin
outAND<= outnotA and outnotB;
end model_conc;
-- 2 input OR gate
library ieee;
use ieee.std_logic_1164.all;
entity myOR2 is
port (outnotA,outnotB: in std_logic; outOR: out std_logic);
end myOR2;
architecture model_conc2 of myOR2 is
begin
outOR <= outnotA or outnotB;
end model_conc2;
--2 input XOR gate
library ieee;
use ieee.std_logic_1164.all;
entity myXOR2 is
port(outnotA,outnotB: in std_logic; outXOR: out std_logic);
end myXOR2;
architecture model_conc3 of myXOR2 is
begin
outXOR <= outnotA xor outnotB;
end model_conc3;
--3 input full adder
library ieee;
use ieee.std_logic_1164.all;
entity fulladder is
port(CarryIn,outnotA,outnotB: in std_logic; sum,CarryOut: out std_logic);
end fulladder;
architecture model_conc4 of fulladder is
begin
CarryOut <= (outnotB and CarryIn) or (outnotA and CarryIn) or (outnotA and outnotB);
sum <= (outnotA and not outnotB and not CarryIn) or (not outnotA and outnotB and not CarryIn) or (not outnotA and not outnotB and CarryIn) or (outnotA and outnotB and CarryIn);
end model_conc4;
--1 input notA
library ieee;
use ieee.std_logic_1164.all;
entity notA is
port(a: in std_logic; signala:std_logic_vector(0 downto 0); outnotA: out std_logic);
end notA;
architecture model_conc6 of notA is
begin
with signala select
outnotA <= a when "0",
not a when others;
end model_conc6;
--1 input notB
library ieee;
use ieee.std_logic_1164.all;
entity notB is
port(b: in std_logic; signalb: std_logic_vector(0 downto 0); outnotB: out std_logic);
end notB;
architecture model_conc5 of notB is
begin
with signalb select
outnotB <= b when "0",
not b when others;
end model_conc5;
--4 input MUX
library ieee;
use ieee.std_logic_1164.all;
entity mux4to1 is
port(outAND, outOR, sum, outXOR: in std_logic; operation: in std_logic_vector(1 downto 0); Result: out std_logic);
end mux4to1;
architecture model_conc7 of mux4to1 is
begin
with operation select
Result<= outAND when "00",
outOR when "01",
sum when "10",
outXOR when OTHERS;
end model_conc7 ;
The behavioral part defines the logic gates of AND,OR,XOR, a full adder for numerical addition and substraction. It also contains a 4-to-1 multiplexer that chooses (depending on the value of the "operation" variable) which operation the alu will do. Lastly there is a function that inverts the variables in order to be more efficient with our logic gate usage( using the DeMorgan theorem so we don't have to create a NOR gate). The control unit initializes the variable inputs, as well as the carryIn variable of the full adder, depending on the variable "opcode". A board with every possible combination
Next is the Control Circuit part of the code, which implements the previous board.
`
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity ControlCircuit is
port (
opcode :in std_logic_vector (2 downto 0);
signala, signalb : out std_logic_vector(0 downto 0);
operation : out std_logic_vector(1 downto 0);
CarryIn : out std_logic);
end ControlCircuit;
architecture model_conc9 of ControlCircuit is
--signal outAND,outOR,outXOR,sum,outnotA,outnotB : std_logic;
--signal operation : out std_logic_vector(1 downto 0);
begin
process(opcode)
begin
case opcode is
--AND--
when "000"=>
operation <= "00";
signala <= "0";
signalb <= "0";
CarryIn <= '0';
--OR--
when "001" =>
operation <= "01";
signala <= "0";
signalb <= "0";
CarryIn <= '0';
--ADD--
when "011" =>
operation <= "10";
signala <= "0";
signalb <= "0";
CarryIn <= '0';
--SUB--
when "010" =>
operation <= "10";
signala <= "0";
signalb <="1";
CarryIn <= '1';
--NOR--
when "101"=>
operation <= "00";
signala <= "1";
signalb <= "1";
CarryIn <= '0';
--xor
when "100" =>
operation <= "11";
signala <= "0";
signalb <= "0";
CarryIn <= '0';
--Adiafores times--
when others =>
operation <= "00";
signala <= "0";
signalb <= "0";
CarryIn <= '0';
end case;
end process;
end model_conc9;
`
Lastly here is the code that uses all the previous parts and and an RTL diagram that shows the code's result
library IEEE;
use ieee.std_logic_1164.all;
use work.erotima2.all;
entity structural is
port (a,b: in std_logic;
opcode : in std_logic_vector ( 2 downto 0);
Result,CarryOut : out std_logic);
end structural;
architecture alu of structural is
signal outAND,outOR,outXOR,sum,outnotA,outnotB,CarryIn : std_logic;
signal signala,signalb : std_logic_vector (0 downto 0);
signal operation : std_logic_vector (1 downto 0);
begin
u0 : myAND2 port map (outnotA,outnotB,outAND);
u1 : myOR2 port map (outnotA,outnotB,outOR);
u2 : myXOR2 port map (outnotA,outnotB,outXOR);
u3 : fulladder port map (CarryIn,outnotA,outnotB,sum,CarryOut);
u4 : notA port map (a,signala,outnotA);
u5 : notB port map (b,signalb,outnotB);
u6 : mux4to1 port map (outAND, outOR,sum, outXOR, operation, Result );
u8 : ControlCircuit port map(opcode,signala,signalb,operation,CarryIn);
end alu;
Now for the tough part, i need to use the 1-bit ALU 16 times as a component, to create a 16-bit ALU. It is important to keep the control circuit independent from the rest of the code. I have tried using an std_logic_vector ( 15 downto 0) but it did not work and i would like to use the previous code segments as a component. Can anyone give any tips or ideas that will help connect 16 1-bit ALUs to a complete 16-bit ALU? Thanks in advance for those who read this massive wall of text.
Your recent comment
Yes i understand that my code is weird but we were intsructed to invert the inputs according to this diagram . As for the duplicate post, i checked before posting and they were implemented only structurally, while in my case i need to write the behavioral part too.
Explains the issue, misspellings aside. You'll notice your architecture structural of entity structural doesn't match the signals shown on the above 1 bit alu diagram which doesn't contain an instantiated ControlCircuit.
If you were to provide a design unit that matched the above diagram you can hook up the 1 bit alu carry chain while deriving the carryin for the lsb from the control block which provides a + 1 and inversion for subtraction:
library ieee;
use ieee.std_logic_1164.all;
entity alu_16_bit is
port (
a: in std_logic_vector (15 downto 0);
b: in std_logic_vector (15 downto 0);
opcode: in std_logic_vector (2 downto 0);
result: out std_logic_vector (15 downto 0);
carryout: out std_logic
);
end entity;
architecture foo of alu_16_bit is
component alu_1_bit is
port (
a: in std_logic;
b: in std_logic;
ainvert: in std_logic;
binvert: in std_logic;
carryin: in std_logic;
operation: in std_logic_vector (1 downto 0);
result: out std_logic;
carryout: out std_logic
);
end component;
component controlcircuit is
port (
opcode: in std_logic_vector(2 downto 0);
ainvert: out std_logic;
binvert: out std_logic;
operation: out std_logic_vector(1 downto 0);
carryin: out std_logic -- invert a or b, add + 1 for subtract
);
end component;
signal ainvert: std_logic;
signal binvert: std_logic;
signal operation: std_logic_vector (1 downto 0);
signal carry: std_logic_vector (16 downto 0);
begin
CONTROL_CIRCUIT:
controlcircuit
port map (
opcode => opcode,
ainvert => ainvert,
binvert => binvert,
operation => operation,
carryin => carry(0) -- for + 1 durring subtract
);
GEN_ALU:
for i in 0 to 15 generate
ALU:
alu_1_bit
port map (
a => a(i),
b => b(i),
ainvert => ainvert,
binvert => binvert,
carryin => carry(i),
operation => operation,
result => result(i),
carryout => carry(i + 1)
);
end generate;
carryout <= carry(16) when operation = "10" else '0';
end architecture;
This represents moving ControlCircuit out of structural - only one copy is needed, renaming structural alu_1_bit and making the ports match.
There's a new top level alu_16_bit containing a single instance of ControlCircuit along with sixteen instances of alu_1_bit elaborated from the generate statement using the generate parameter i to index into arrays values for connections.
This design has been behaviorally implemented independently using the Opcode table you provided the link to:
as well as an independent fulladder used in alu_1_bit and appears functional.
This implies your design units haven't been validated.

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;

Can anyone help me with this VHDL code (currently malfunctioning)?

This code should be (and is) very simple, and I don't know what I am doing wrong.
Here is description of what it should do:
It should display a number on one 7-segment display. That number should be increased by one every time someone presses the push button. There is also reset button which sets the number to 0. That's it. Here is VHDL code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity PWM is
Port ( cp_in : in STD_LOGIC;
inc : in STD_LOGIC;
rst: in std_logic;
AN : out STD_LOGIC_VECTOR (3 downto 0);
segments : out STD_LOGIC_VECTOR (6 downto 0));
end PWM;
architecture Behavioral of PWM is
signal cp: std_logic;
signal CurrentPWMState: integer range 0 to 10;
signal inco: std_logic;
signal temp: std_logic_vector (3 downto 0);
begin
--cp = 100 Hz
counter: entity djelitelj generic map (CountTo => 250000) port map (cp_in, cp);
debounce: entity debounce port map (inc, cp, inco);
temp <= conv_std_logic_vector(CurrentPWMState, 4);
ss: entity decoder7seg port map (temp, segments);
process (inco, rst)
begin
if inco = '1' then
CurrentPWMState <= CurrentPWMState + 1;
elsif rst='1' then
CurrentPWMState <= 0;
end if;
end process;
AN <= "1110";
end Behavioral;
Entity djelitelj (the counter used to divide 50MHz clock):
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity PWM is
Port ( cp_in : in STD_LOGIC;
inc : in STD_LOGIC;
rst: in std_logic;
AN : out STD_LOGIC_VECTOR (3 downto 0);
segments : out STD_LOGIC_VECTOR (6 downto 0));
end PWM;
architecture Behavioral of PWM is
signal cp: std_logic;
signal CurrentPWMState: integer range 0 to 10;
signal inco: std_logic;
signal temp: std_logic_vector (3 downto 0);
begin
--cp = 100 Hz
counter: entity djelitelj generic map (CountTo => 250000) port map (cp_in, cp);
debounce: entity debounce port map (inc, cp, inco);
temp <= conv_std_logic_vector(CurrentPWMState, 4);
ss: entity decoder7seg port map (temp, segments);
process (inco, rst)
begin
if inco = '1' then
CurrentPWMState <= CurrentPWMState + 1;
elsif rst='1' then
CurrentPWMState <= 0;
end if;
end process;
AN <= "1110";
end Behavioral;
Debouncing entity:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
ENTITY debounce IS
PORT(pb, clock_100Hz : IN STD_LOGIC;
pb_debounced : OUT STD_LOGIC);
END debounce;
ARCHITECTURE a OF debounce IS
SIGNAL SHIFT_PB : STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
-- Debounce Button: Filters out mechanical switch bounce for around 40Ms.
-- Debounce clock should be approximately 10ms
process
begin
wait until (clock_100Hz'EVENT) AND (clock_100Hz = '1');
SHIFT_PB(2 Downto 0) <= SHIFT_PB(3 Downto 1);
SHIFT_PB(3) <= NOT PB;
If SHIFT_PB(3 Downto 0)="0000" THEN
PB_DEBOUNCED <= '1';
ELSE
PB_DEBOUNCED <= '0';
End if;
end process;
end a;
And here is BCD to 7-segment decoder:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity decoder7seg is
port (
bcd: in std_logic_vector (3 downto 0);
segm: out std_logic_vector (6 downto 0));
end decoder7seg;
architecture Behavioral of decoder7seg is
begin
with bcd select
segm<= "0000001" when "0000", -- 0
"1001111" when "0001", -- 1
"0010010" when "0010", -- 2
"0000110" when "0011", -- 3
"1001100" when "0100", -- 4
"0100100" when "0101", -- 5
"0100000" when "0110", -- 6
"0001111" when "0111", -- 7
"0000000" when "1000", -- 8
"0000100" when "1001", -- 9
"1111110" when others; -- just - character
end Behavioral;
Does anyone see where I made my mistake(s) ?
I've tried that design on Spartan-3 Started board and it isn't working ... Every time I press the push button, I get crazy (random) values. The reset button is working properly.
Thanks !!!!
I guess the problem is here:
process (inco, rst)
begin
if inco = '1' then
CurrentPWMState <= CurrentPWMState + 1;
elsif rst='1' then
CurrentPWMState <= 0;
end if;
end process;
When rst='1' you will reset CurrentPWMState. But when inco='1' the you endlessly add 1 to CurrentPWMState. That's something like an asynchronous feedback loop through a latch. You should do something edge sensitive here. Probably you should capture inco using your clock signal, detect a 0->1 change and then add 1.
Agree with the previous answer.
A code like this should do the trick:
process (inco, ps, rst)
begin
if rst='1' then
CurrentPWMState <= '0';
prev_inco <= inco; -- This signal captures the previous value of inco
elsif ps'event and ps='1' then
if inco='1' and prev_inco='0' then -- Capture the flank rising.
CurrentPWMState <= CurrentPWMState + 1;
end if;
prev_inco <= inco;
end if;
end process;
I recognize I haven't tried the code (just coded in here) but I think it's ok.

Resources