Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
10 years ago

Deforming of 60Hz sine wave wrt time based on 20KHz SPWM

Hello everyone!

I am using altera ep2c5t144c8 mini development board to get the output of 60Hz sine wave with the carrier frequency of 20KHz. I,ve got the results of SPWM but with spikes in it and these spikes are increasing with time due to which the shape of sine wave is deforming and the wave is shifting towards right while I am giving the sine table of 1000 values in my vhdl code.

Vhdl code is here....

library IEEE;use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity pwm is
	port (
			clk        : in std_logic;
			reset      : in std_logic;
			driv1_out  : out std_logic;
			driv2_out  : out std_logic;
			driv3_out  : out std_logic;
			driv4_out  : out std_logic;
			pwm_out    : out std_logic
	);
	end pwm;
	
	architecture behavioral of pwm is
	signal driv1_out_sig, driv4_out_sig : std_logic := '0';
	signal driv2_out_sig, driv3_out_sig : std_logic := '1';
	signal pwm_out_sig : std_logic := '0';
	signal i : integer range 0 to 999:=0;
	type memory_type is array (0 to 999) of integer range 0 to 2450;
	signal sine : memory_type :=(0, 4, 8, 12, 15, 19, 23, 27, 31, 35, 38, 42, 46, 50, 54, 58, 62, 65, 69,
	73, 77, 81, 85, 88, 92, 96, 100, 104, 108, 112, 115, 119, 123, 127, 131, 135, 138, 142, 146, 150, 154,
	158, 162, 165, 169, 173, 177, 181, 185, 188, 192, 196, 200, 204, 208, 211, 215, 219, 223, 227, 231, 234,
	238, 242, 246, 250, 254, 257, 261, 265, 269, 273, 276, 280, 284, 288, 292, 296, 299, 303, 307, 311, 315,
	319, 322, 326, 330, 334, 338, 341, 345, 349, 353, 357, 360, 364, 368, 372, 376, 379, 383, 387, 391, 395,
	398, 402, 406, 410, 414, 417, 421, 425, 429, 433, 436, 440, 444, 448, 452, 455, 459, 463, 467, 470, 474,
	478, 482, 486, 489, 493, 497, 501, 504, 508, 512, 516, 519, 523, 527, 531, 534, 538, 542, 546, 549, 553,
	557, 561, 564, 568, 572, 576, 579, 583, 587, 591, 594, 598, 602, 606, 609, 613, 617, 620, 624, 628, 632,
	635, 639, 643, 646, 650, 654, 658, 661, 665, 669, 672, 676, 680, 684, 687, 691, 695, 698, 702, 706, 709,
	713, 717, 720, 724, 728, 731, 735, 739, 742, 746, 750, 753, 757, 761, 764, 768, 772, 775, 779, 783, 786,
	790, 794, 797, 801, 805, 808, 812, 815, 819, 823, 826, 830, 834, 837, 841, 844, 848, 852, 855, 859, 862,
	866, 870, 873, 877, 880, 884, 888, 891, 895, 898, 902, 905, 909, 913, 916, 920, 923, 927, 930, 934, 938,
	941, 945, 948, 952, 955, 959, 962, 966, 969, 973, 977, 980, 984, 987, 991, 994, 998, 1001, 1005, 1008,
	1012, 1015, 1019, 1022, 1026, 1029, 1033, 1036, 1040, 1043, 1047, 1050, 1054, 1057, 1061, 1064, 1067, 
	1071, 1074, 1078, 1081, 1085, 1088, 1092, 1095, 1099, 1102, 1105, 1109, 1112, 1116, 1119, 1123, 1126,
	1129, 1133, 1136, 1140, 1143, 1146, 1150, 1153, 1157, 1160, 1163, 1167, 1170, 1174, 1177, 1180, 1184,
	1187, 1190, 1194, 1197, 1200, 1204, 1207, 1211, 1214, 1217, 1221, 1224, 1227, 1231, 1234, 1237, 1241,
	1244, 1247, 1250, 1254, 1257, 1260, 1264, 1267, 1270, 1274, 1277, 1280, 1283, 1287, 1290, 1293, 1296,
	1300, 1303, 1306, 1310, 1313, 1316, 1319, 1323, 1326, 1329, 1332, 1335, 1339, 1342, 1345, 1348, 1352,
	1355, 1358, 1361, 1364, 1368, 1371, 1374, 1377, 1380, 1383, 1387, 1390, 1393, 1396, 1399, 1402, 1406,
	1409, 1412, 1415, 1418, 1421, 1424, 1428, 1431, 1434, 1437, 1440, 1443, 1446, 1449, 1452, 1456, 1459,
	1462, 1465, 1468, 1471, 1474, 1477, 1480, 1483, 1486, 1489, 1492, 1496, 1499, 1502, 1505, 1508, 1511,
	1514, 1517, 1520, 1523, 1526, 1529, 1532, 1535, 1538, 1541, 1544, 1547, 1550, 1553, 1556, 1559, 1562,
	1565, 1568, 1571, 1574, 1576, 1579, 1582, 1585, 1588, 1591, 1594, 1597, 1600, 1603, 1606, 1609, 1612,
	1614, 1617, 1620, 1623, 1626, 1629, 1632, 1635, 1637, 1640, 1643, 1646, 1649, 1652, 1655, 1657, 1660,
	1663, 1666, 1669, 1672, 1674, 1677, 1680, 1683, 1686, 1688, 1691, 1694, 1697, 1699, 1702, 1705, 1708,
	1711, 1713, 1716, 1719, 1721, 1724, 1727, 1730, 1732, 1735, 1738, 1741, 1743, 1746, 1749, 1751, 1754,
	1757, 1759, 1762, 1765, 1767, 1770, 1773, 1775, 1778, 1781, 1783, 1786, 1789, 1791, 1794, 1796, 1799, 
	1802, 1804, 1807, 1810, 1812, 1815, 1817, 1820, 1822, 1825, 1828, 1830, 1833, 1835, 1838, 1840, 1843,
	1845, 1848, 1850, 1853, 1855, 1858, 1860, 1863, 1865, 1868, 1870, 1873, 1875, 1878, 1880, 1883, 1885,
	1888, 1890, 1893, 1895, 1898, 1900, 1902, 1905, 1907, 1910, 1912, 1914, 1917, 1919, 1922, 1924, 1926, 
	1929, 1931, 1934, 1936, 1938, 1941, 1943, 1945, 1948, 1950, 1952, 1955, 1957, 1959, 1962, 1964, 1966, 
	1968, 1971, 1973, 1975, 1978, 1980, 1982, 1984, 1987, 1989, 1991, 1993, 1996, 1998, 2000, 2002, 2004, 
	2007, 2009, 2011, 2013, 2015, 2018, 2020, 2022, 2024, 2026, 2029, 2031, 2033, 2035, 2037, 2039, 2041, 
	2043, 2046, 2048, 2050, 2052, 2054, 2056, 2058, 2060, 2062, 2064, 2067, 2069, 2071, 2073, 2075, 2077, 
	2079, 2081, 2083, 2085, 2087, 2089, 2091, 2093, 2095, 2097, 2099, 2101, 2103, 2105, 2107, 2109, 2111, 
	2113, 2115, 2117, 2119, 2120, 2122, 2124, 2126, 2128, 2130, 2132, 2134, 2136, 2138, 2139, 2141, 2143, 
	2145, 2147, 2149, 2151, 2152, 2154, 2156, 2158, 2160, 2162, 2163, 2165, 2167, 2169, 2171, 2172, 2174, 
	2176, 2178, 2179, 2181, 2183, 2185, 2186, 2188, 2190, 2192, 2193, 2195, 2197, 2198, 2200, 2202, 2204, 
	2205, 2207, 2209, 2210, 2212, 2214, 2215, 2217, 2218, 2220, 2222, 2223, 2225, 2227, 2228, 2230, 2231, 
	2233, 2235, 2236, 2238, 2239, 2241, 2242, 2244, 2245, 2247, 2248, 2250, 2252, 2253, 2255, 2256, 2258, 
	2259, 2261, 2262, 2264, 2265, 2266, 2268, 2269, 2271, 2272, 2274, 2275, 2277, 2278, 2279, 2281, 2282, 
	2284, 2285, 2286, 2288, 2289, 2290, 2292, 2293, 2295, 2296, 2297, 2299, 2300, 2301, 2303, 2304, 2305, 
	2306, 2308, 2309, 2310, 2312, 2313, 2314, 2315, 2317, 2318, 2319, 2320, 2322, 2323, 2324, 2325, 2326, 
	2328, 2329, 2330, 2331, 2332, 2334, 2335, 2336, 2337, 2338, 2339, 2341, 2342, 2343, 2344, 2345, 2346, 
	2347, 2348, 2349, 2351, 2352, 2353, 2354, 2355, 2356, 2357, 2358, 2359, 2360, 2361, 2362, 2363, 2364, 
	2365, 2366, 2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379, 2380, 2380, 
	2381, 2382, 2383, 2384, 2385, 2386, 2387, 2388, 2388, 2389, 2390, 2391, 2392, 2393, 2393, 2394, 2395, 
	2396, 2397, 2398, 2398, 2399, 2400, 2401, 2401, 2402, 2403, 2404, 2404, 2405, 2406, 2407, 2407, 2408, 
	2409, 2409, 2410, 2411, 2412, 2412, 2413, 2414, 2414, 2415, 2415, 2416, 2417, 2417, 2418, 2419, 2419, 
	2420, 2420, 2421, 2422, 2422, 2423, 2423, 2424, 2424, 2425, 2426, 2426, 2427, 2427, 2428, 2428, 2429, 
	2429, 2430, 2430, 2431, 2431, 2432, 2432, 2433, 2433, 2433, 2434, 2434, 2435, 2435, 2436, 2436, 2436, 
	2437, 2437, 2438, 2438, 2438, 2439, 2439, 2439, 2440, 2440, 2441, 2441, 2441, 2442, 2442, 2442, 2442, 
	2443, 2443, 2443, 2444, 2444, 2444, 2444, 2445, 2445, 2445, 2445, 2446, 2446, 2446, 2446, 2447, 2447, 
	2447, 2447, 2447, 2447, 2448, 2448, 2448, 2448, 2448, 2448, 2449, 2449, 2449, 2449, 2449, 2449, 2449, 
	2449, 2449, 2449, 2450, 2450, 2450, 2450, 2450, 2450, 2450, 2450, 2450, 2450, 2450, 2450);
	begin
	driv1_out <= driv1_out_sig;
	driv2_out <= driv2_out_sig;
	driv3_out <= driv3_out_sig;
	driv4_out <= driv4_out_sig;
	pwm_out 	 <= pwm_out_sig;
	process(clk)
	variable count : integer  range 0 to 416000;
	variable counter_60hz : integer  range 0 to 416000;
	variable counter_pwm : integer  range 0 to 2510;
	variable pwm_shift_reg : integer  range 0 to 2510;
	variable count_sync : integer range 0 to 209;
	begin
	if(clk'event and clk = '1') then counter_pwm := counter_pwm +1 ; count := count + 1;
	counter_60hz := counter_60hz + 1;
		if(reset = '0') then
			counter_pwm   := 0;
			count_sync    := 0;
			count 		  := 0;
			counter_60hz  := 0;
			pwm_shift_reg := 0;
			i 				  <= 0;
			pwm_out_sig   <= '0';
			driv1_out_sig <= '0';
			driv2_out_sig <= '1';
			driv3_out_sig <= '1';
			driv4_out_sig <= '0';
			else 
			    if (count > 416000) then
				      count := 0 ;
			    end if;
			    if (count < 208000) then count_sync  := count_sync +1;
					   if(count_sync =208) then
						    count_sync :=0;
						    i <= i+ 1;
							 if(i = 999) then
								  i <= 999;
							 end if;
					   end if;
			    else if (count > 208000) then count_sync  := count_sync +1;
						     if(count_sync =208) then
						         count_sync :=0;
						         i <= i- 1;
							  if(i = 0) then
								   i <= 0;
							  end if;
					        end if;
			         end if;
			    end if;			
			if (counter_60hz = 416000) then
					counter_60hz :=0 ; 
					driv1_out_sig <= not (driv1_out_sig);
					driv2_out_sig <= not (driv2_out_sig);
					driv3_out_sig <= not (driv3_out_sig);
					driv4_out_sig <= not (driv4_out_sig);
			end if;
			pwm_shift_reg := sine(i);
			if(counter_pwm = pwm_shift_reg ) then
			    pwm_out_sig <= '0';
			else if(counter_pwm = 2510) then
					   counter_pwm := 0;
					   pwm_out_sig <= '1';	
				  end if;
			end if;	
	end if; --reset
	end if; --clk
	end process;
	end Behavioral;

The screenshots of sine wave output which is shifting with time

http://www.alteraforum.com/forum/attachment.php?attachmentid=11224&stc=1 http://www.alteraforum.com/forum/attachment.php?attachmentid=11225&stc=1 http://www.alteraforum.com/forum/attachment.php?attachmentid=11226&stc=1

How can I fix this problem? I want pure sine wave that should not vary with time which is happening in my case currently.

Everyone's attention will be highly appreciable!:)

5 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    one thing I notice your counters are restrained only if equal to maximum set but they can be over max so they keep adding.

    for example

    if(counter_pwm = 2500) then

    counter_pwm := 0

    end if;

    it should be more than or equal.

    if you are just adding 1 that shouldn't matter but what about count which adds 83 and what is this logic meant to do:

    if (count < 208335) then

    count := 0;
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    first of all thanks for your attention Kaz!

    What I can understand from ur perspective that I should write the condition like this

    if(counter_pwm >= 2500) then

    counter_pwm := 0

    end if;

    secondly in given code the count of 208 is adding instead of 83.

    Now my logic is that the value '208335' is the total time in which 1/4th of the complete cycle completes and

    I am using 1000 values(you can see in code) which I am sending in this total time so I get the equal interval of

    208 counts.

    In short we can say 208 is the time interval between two values of the table of 1000 values.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Let me focus on this issue.

    
    if clk edge...
       count := count + 83;
       if reset...
           count := 0;
       else
          if (count < 208335) then 
              count := 0;
    ...
    

    so count starts as zero and so is always < 208335 and so should be stuck between 83 and zero. Is this really the correct copy of your code? Or am I missing something?

    The second issue what do mean by 60Hz and 20KHz carrier? what is your clock speed?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I am trying to make 60Hz inverter based on 20KHz carrier frequency of pulse width modulation(PWM) and clock speed is 50MHz.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I am done with it Kaz! :)

    I,ve achieved pure sine wave!!!

    Kaz thank you so much for your help and attention towards me :)