I want to create Led PWM controller and I tought it is easy but one line in my code generates more warnings than all my previous little projects. Here is the code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity pwmLed is
generic( N : integer := 4
);
port( pwm : in std_logic_vector(N-1 downto 0);
clk : in std_logic;
leds : out std_logic_vector(7 downto 0)
);
end pwmLed;
architecture Behavioral of pwmLed is
constant CLOCK_CYCLES : integer := 1000;
signal counter : integer ;
begin
process(clk)
begin
if counter > CLOCK_CYCLES then
counter <= 0;
elsif (clk'event and clk = '1') then
counter <= counter + 1;
end if;
end process;
leds <= "11111111" when counter < (to_integer(unsigned(pwm))/(2**N) * CLOCK_CYCLES) else "00000000";
end Behavioral;
The problematic line is :
leds <= "11111111" when counter < (to_integer(unsigned(pwm))/(2**N) * CLOCK_CYCLES) else "00000000";
All the warnings:
WARNING:HDLCompiler:92 – "E:\Xilinx\Projects\PWM_LED\pwmLed.vhd" Line 48: counter should be on the sensitivity list of the process
WARNING:Xst:647 – Input is never used. This port will be preserved and left unconnected if it belongs to a top-level block or it belongs to a sub-block and the hierarchy of this sub-block is preserved.
WARNING:Xst:3002 – This design contains one or more registers/latches that are directly
incompatible with the Spartan6 architecture. The two primary causes of this is
either a register or latch described with both an asynchronous set and
asynchronous reset, or a register or latch described with an asynchronous
set or reset which however has an initialization value of the opposite
polarity (i.e. asynchronous reset with an initialization value of 1).
WARNING:Xst:1426 – The value init of the FF/Latch counter_31_LD hinder the constant cleaning in the block pwmLed.
You should achieve better results by setting this init to 0.
WARNING:Par:288 – The signal pwm<0>_IBUF has no load. PAR will not attempt to route this signal.
WARNING:Par:288 – The signal pwm<1>_IBUF has no load. PAR will not attempt to route this signal.
WARNING:Par:288 – The signal pwm<2>_IBUF has no load. PAR will not attempt to route this signal.
WARNING:Par:288 – The signal pwm<3>_IBUF has no load. PAR will not attempt to route this signal.
WARNING:Par:283 – There are 4 loadless signals in this design. This design will cause Bitgen to issue DRC warnings.
WARNING:PhysDesignRules:372 – Gated clock. Clock net
counter[31]_GND_4_o_LessThan_1_o is sourced by a combinatorial pin. This is
not good design practice. Use the CE pin to control the loading of data into
the flip-flop.
I understand them but I got no idea why they occur. I use pwm explicitly so why the warning that this input is never used.
Best Answer
You are performing a division and a multiplication operation on a signal. At least the multiplication is mapped to a hardware multiplication circuit on your FPGA.
Your module provides the generic parameter N, which could also be called PWM_RESOLUTION. Beside this, I miss two additional parameters or constants in your module:
One easy way to build a pwm generator is to use two counters:
Here some calculations for the frequency counter:
Some hints on the compact code above:
Example 1:
If N=4 the pwm signal can have 16 duty cycle steps. Counter 1 is running at 400 kHz. This equals a period of 2.5 us, which need 250 cycles at 100 MHz to achieve this timing. A 8 bit signal is needed for counter 1.
The output is then a simple comparison:
This code does not prohibit the input of PWMIn=0 to produce a flat-line output, which would not be a correct pwm signal (100% low, 0% high, no edges -> no frequency)
Example 2:
If PWMIn is 3 ("0011") then PWMOut is '1' for counter values 0,1,2 else '0'.