0
votes

I am new in VHDL and I want to programm a simple counter for an encoder signal, that counts (duh) to 1000 every 100 cycles. I am programming with a Lattice ispMACH 4000ZE Pico DevKit and with the software ispLEVER Classic Project Navigator.

My code is:

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use IEEE.std_logic_unsigned.all;

entity Counter_10B is 
    port (
       reset        : in  std_ulogic := '0';
       updown       : in  std_ulogic := '0';
       clk          : in  std_ulogic := '0';
       cnt_out      : out std_ulogic_vector(9 downto 0) := (others => '0')

     ); 
 end Counter_10B;

 architecture behavior of Counter_10B is

signal int_cnt : unsigned(9 downto 0)  := (others => '0');

begin              


Counter : process(clk, updown, reset)

variable temp1 : unsigned(4 downto 0) := (others => '0'); 
variable temp2 : unsigned(9 downto 0) := (others => '0'); 

begin
    if (reset = '0') then
        temp2 := (others => '0');
    end if;

    if ((clk'event AND clk='1')) then

        temp1 := temp1 + 1; 

        if(temp1 >= 100) then
            if(updown = '0') then

                if(temp2 >= 1000) then
                    temp2 := (others => '0');
                end if;

                temp2 := temp2 + 1;

            elsif(updown = '1') then

                if(temp2 = 0) then
                    temp2 := (others => '1');
                end if;

                temp2 := temp2 - 1;
            end if ;

            temp1 := 0;
        end if;

        int_cnt <= temp2;

    end if;

end process;
        cnt_out <= std_ulogic_vector(int_cnt);
end behavior;

My problem is that everytime I compile, I don't have any compiling error, but a lot of warnings, like:

All reachable assignments to Counter.temp2(0) assign '0'; register removed by optimization

or

Pruning register bits 9 to 1 of int_cnt(9 downto 0)

but my biggest problem is this:

Input clk/reset/updown is unused

I really need help with the last warning, I don't understand why I have that error. It does not make any sense, doesn't it?

Thank you!

EDIT 30.09

Counter : process(clk, updown, reset)

variable temp1 : natural range 0 to 100 := 0; 

begin
    if (reset = '0') then
        int_cnt <= (others => '0');

    elsif ((clk'event AND clk='1')) then

        temp1 := temp1 + 1; 

        if(temp1 >= 100) then
            if(updown = '0') then

                if(int_cnt >= 1000) then
                    int_cnt <= (others => '0');
                end if;

                int_cnt <= int_cnt + 1;

            elsif(updown = '1') then

                if(int_cnt = 0) then
                    int_cnt <= 1000;
                end if;

                int_cnt <= int_cnt - 1;
            end if ;

            temp1 := 0;
        end if;

    end if;

end process;

cnt_out <= std_ulogic_vector(int_cnt);
2
Note that even after you fix temp2 not having a wide enough range, you'll have logical errors. If you want your rollover boundary to be 1000, counter underflow should end with a value of 1000, not 1023 as (others => '1') will produce. You are also treating variables as if they were signals - every time you roll over you will also subtract or add one meaning that you roll from 1000 to 1, not 1000 to 0 because you assign the variable multiple times. I'd use signals here anyway, but if you use variables you have to bear in mind that they change with every assignment.QuantumRipple

2 Answers

3
votes

Use datatypes better! VHDL has a decent type system : don't ignore it!

Instead of

variable temp1 : unsigned(4 downto 0) := (others => '0');

write

variable temp1 : natural range 0 to 31 := 0;

Simpler and cleaner and equally well supported by most synthesis tools.

And when you then write

if(temp1 >= 100) then

you will probably scratch your head and fix the problem before it happens...

(It should be clear why updown is unused; it's a shame the tool isn't very specific WHICH signal is unused.)

Only compromise if your synth tool is too restrictive to support this, and only compromise enough to satisfy the defective tool, and also report the tool deficiency to the vendor so they can fix it!

0
votes

Your process is not written in a style that is generally valid for synthesis. You need an "else", not two separate if blocks:

if (reset = '0') then
  temp2 := (others => '0');
elsif (clk'event AND clk='1') then
  ...

What you wrote may work in simulation, but whereas a simulation tool generally executes a process literally, as written, a synthesis tool infers physical logic elements, and is more picky about style.

If the synthesis tool optimizes temp2 away, the whole process becomes irrelevant, so the inputs would be unused as a result (since they no longer connect to anything).