Reputation: 23
I have written a VHDL code which implements the functionality of a PWM Controller. I have simulated it successfully and the results are as expected. I also checked the syntax for synthesis but it dint showed any error. When I went for synthesizing it using XILINX ISE 12.4 it's not synthesizing and the error states
"ERROR:Xst:827 - line 67: Signal tmp_PC cannot be synthesized, bad synchronous description. The description style you are using to describe a synchronous element (register, memory, etc.) is not supported in the current software release."
--library UNISIM;
--use UNISIM.VComponents.all;
entity CONTROLLER is
PORT(
CLK: IN STD_LOGIC;
VOUT: IN STD_LOGIC;
M1: OUT STD_LOGIC:='0';
M2: OUT STD_LOGIC:='0'
);
end CONTROLLER;
architecture Behavioral of CONTROLLER is
SIGNAL VREF: STD_LOGIC_VECTOR(7 DOWNTO 0):="01000000";
SIGNAL V_ERR: STD_LOGIC_VECTOR(7 DOWNTO 0):="00000000";
SIGNAL PWM: STD_LOGIC_VECTOR(7 DOWNTO 0):="00000000";
SIGNAL PWM_NEW: STD_LOGIC_VECTOR(7 DOWNTO 0):="00000000";
SIGNAL COUNT: STD_LOGIC_VECTOR(7 DOWNTO 0):="00000000";
SIGNAL COUNT2: STD_LOGIC_VECTOR(7 DOWNTO 0):="00000000";
SIGNAL TEMP1: STD_LOGIC_VECTOR(7 DOWNTO 0):="00000000";
SIGNAL TEMP2: STD_LOGIC_VECTOR(7 DOWNTO 0):="00000000";
SIGNAL TEMP3: STD_LOGIC_VECTOR(7 DOWNTO 0):="00000000";
SIGNAL FEED_BACK: STD_LOGIC_VECTOR(7 DOWNTO 0):="00000000";
SIGNAL REG: STD_LOGIC_VECTOR(7 DOWNTO 0):="00000000";
SIGNAL PWM_COUNT: STD_LOGIC_VECTOR(7 DOWNTO 0):="10000000";
BEGIN
PROCESS(CLK)
BEGIN
IF(RISING_EDGE(CLK) AND COUNT2<"10000000")THEN
COUNT <= COUNT+'1';
END IF;
IF(RISING_EDGE(CLK) AND COUNT2>="10000000")THEN
COUNT <= COUNT+'1';
END IF;
IF (COUNT>"00000101" AND COUNT<"01111000") THEN
IF(RISING_EDGE(CLK))THEN
IF (VOUT='0') THEN
FEED_BACK<= FEED_BACK+'1';
END IF;
END IF;
END IF;
IF (COUNT>"01111000" AND COUNT<"01111100")THEN
REG<=FEED_BACK;
TEMP1<=VREF-REG;
IF(TEMP1>"01000000") THEN
TEMP2<=TEMP1+"11111111";
V_ERR<=TEMP2+'1';
END IF;
IF (TEMP1<"01000000") THEN
V_ERR<=TEMP1;
END IF;
PWM<=V_ERR+VREF;
IF (PWM>"11000000")THEN
PWM<="11000000";
IF(PWM<"00001010")THEN
PWM<="00001010";
END IF;
END IF;
END IF;
PWM_NEW<= PWM;
IF (RISING_EDGE(CLK))THEN
IF(COUNT="01111111")THEN
COUNT<="00000000";
FEED_BACK<="00000000";
END IF;
END IF;
IF(RISING_EDGE(CLK))THEN
COUNT2 <= COUNT2+ '1';
END IF;
IF(COUNT>"00000000" AND COUNT<("00000010"))THEN
IF(RISING_EDGE(CLK)) THEN
M1<='0';
M2<='0';
END IF;
END IF;
IF(COUNT>("00000010") AND COUNT<("00000010"+PWM_NEW))THEN
IF(RISING_EDGE(CLK)) THEN
M1<='1';
M2<='0';
END IF;
END IF;
IF(COUNT>("00000010"+PWM_NEW) AND COUNT<("00000100"+PWM_NEW))THEN
IF ( RISING_EDGE(CLK)) THEN
M1<='0';
M2<='0';
END IF;
END IF;
IF(COUNT>("00000100"+PWM_NEW) AND COUNT<("10000000"))THEN
IF (RISING_EDGE(CLK)) THEN
M1<='0';
M2<='1';
END IF;
END IF;
IF (COUNT=("10000000"))THEN
IF (RISING_EDGE(CLK)) THEN
COUNT2<="10000001";
END IF;
END IF;
END PROCESS;
end Behavioral;`
I tried looking up the error message and got different answers. The possible reasons appear to 1: Improper "IF" nesting which is not according to the synthesis template. 2: The use of "risisng_edge(clk)" instead of usual "(clk'event and clk='1')".
I am still not totally sure what could be the exact problem. It would be really helpful if someone could suggest the possible errors I am overlooking.
Upvotes: 1
Views: 1071
Reputation: 155
looks like you can do you code complete synchron
process(clk)
begin
-- put your asyncron code here if needed
if(rising_edge(clk)) then
if(reset = '1') then
-- if you like to implement a synchron reset
else
-- all your synchron code e.g.
if (COUNT2 >= "10000000") then
COUNT <= COUNT+'1';
end if;
if (COUNT > ("00000100"+PWM_NEW)) AND (COUNT < "10000000") then
M1 <= '0';
M2 <= '1';
end if;
.
.
.
end if;
end if;
-- put your asyncron code here if needed
end process;
don't use the unisim Library ... you can do everything with these both
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.NUMERIC_STD.all;
there are standardized.
To make it a little bit clearer you can you hex writing
if (COUNT2 >= x"80") then -- 80 hex = 124 dec
COUNT <= COUNT+'1';
end if;
or you can use unsigned signals
SIGNAL COUNT: unsigned (7 DOWNTO 0) := (others => '0'); -- same as "000000000" but looks better
if (COUNT2 >= 128) then
COUNT <= COUNT + '1';
end if;
calculating is not a problem e.g.
if (COUNT > ("00000100"+PWM_NEW)) AND (COUNT < "10000000") then
M1 <= '0';
M2 <= '1';
end if;
would be
if (COUNT > (unsigned(PWM_NEW) + 4)) AND (COUNT < 128) then
M1 <= '0';
M2 <= '1';
end if;
Upvotes: 0
Reputation: 2290
In order to be recognized by synthesis tools, your process must have a single if rising_edge(clk)
block.
It should be easy to adapt your code, except for the block with reg <= feed_back;
If this specific section models an asynchronous behavior, then move it to a combinational process.
Regarding the possible causes 1. and 2. you listed, your code is ok with respect to both : the nesting is ok (syntactically) and your usage of rising_edge
is ok.
Upvotes: 2