hobbskw
Junior Member level 3
Greetings,
I am trying to generate a bitstream, but it is telling me there is a combinatorial loop occurring with pwm1N, pwm2N, and pwm3N. It does not say where/how/why this happens in the code, so I am at a loss for how to fix this. Is there someone who could help me identify where/how it is happening? I would greatly appreciate your help! I think this happened after adding the "if-else" statements at the beginning of the "posedge clk" statement, though I am not certain whether that is the cause.
I am trying to generate a bitstream, but it is telling me there is a combinatorial loop occurring with pwm1N, pwm2N, and pwm3N. It does not say where/how/why this happens in the code, so I am at a loss for how to fix this. Is there someone who could help me identify where/how it is happening? I would greatly appreciate your help! I think this happened after adding the "if-else" statements at the beginning of the "posedge clk" statement, though I am not certain whether that is the cause.
Code:
`timescale 1ns / 1ps
module sine_LUT(
input clk,
input rst_n,
output pwm1P,
output pwm2P,
output pwm3P,
output pwm1N,
output pwm2N,
output pwm3N
);
// initialize the lookup table
reg [12:0] sineLUT[0:49];
integer addr=0;
// res = number of eleents in the lookup table
localparam res = 49;
always @* begin
case (addr)
0: sineLUT[0] = 1407;
1: sineLUT[1] = 1561;
2: sineLUT[2] = 1710;
3: sineLUT[3] = 1852;
4: sineLUT[4] = 1985;
5: sineLUT[5] = 2106;
6: sineLUT[6] = 2213;
7: sineLUT[7] = 2305;
8: sineLUT[8] = 2381;
9: sineLUT[9] = 2439;
10: sineLUT[10] = 2478;
11: sineLUT[11] = 2498;
12: sineLUT[12] = 2498;
13: sineLUT[13] = 2478;
14: sineLUT[14] = 2439;
15: sineLUT[15] = 2381;
16: sineLUT[16] = 2305;
17: sineLUT[17] = 2213;
18: sineLUT[18] = 2106;
19: sineLUT[19] = 1985;
20: sineLUT[20] = 1852;
21: sineLUT[21] = 1710;
22: sineLUT[22] = 1561;
23: sineLUT[23] = 1407;
24: sineLUT[24] = 1250;
25: sineLUT[25] = 1093;
26: sineLUT[26] = 939;
27: sineLUT[27] = 790;
28: sineLUT[28] = 648;
29: sineLUT[29] = 515;
30: sineLUT[30] = 394;
31: sineLUT[31] = 287;
32: sineLUT[32] = 195;
33: sineLUT[33] = 119;
34: sineLUT[34] = 61;
35: sineLUT[35] = 22;
36: sineLUT[36] = 2;
37: sineLUT[37] = 2;
38: sineLUT[38] = 22;
39: sineLUT[39] = 61;
40: sineLUT[40] = 119;
41: sineLUT[41] = 195;
42: sineLUT[42] = 287;
43: sineLUT[43] = 394;
44: sineLUT[44] = 515;
45: sineLUT[45] = 648;
46: sineLUT[46] = 790;
47: sineLUT[47] = 939;
48: sineLUT[48] = 1093;
49: sineLUT[49] = 1250;
endcase;
end
// when active == 0, the SPWM signals will all be set to 0. This is for implementing safety features (UNFINISHED)
integer active = 1;
// these are used to detect the negative edges of he PWM signals, in order to trigger the deadtime timers
integer T1P = 0;
integer T1N = 0;
integer T2P = 0;
integer T2N = 0;
integer T3P = 0;
integer T3N = 0;
// the Side variable ensures the top and bottom mosfets take turns. One can not turn on twice in a row (UNFINISHED)
integer Side1 = 1;
integer Side2 = 1;
integer Side3 = 1;
// the magnitude of triangle and sinewave is from 0 to 2*D, with the midpoints being equal to D
localparam D = 1250;
integer triangle = D;
integer sinewave = D;
// updown tells what direction the triangle wave counter should be going
integer updown = 1;
// sineCount1 and 2 are counters/timers for the sinewave. There are two: sineCount2 increements when sineCount1 reaches its limit
integer sineCount1 = 0;
integer sineCount2 = 0;
// each sinewave is shifted up by D. Addr1, 2, and 3 effectively phase shift the sinewaves
integer sinewave1 = D;
integer sinewave2 = D;
integer sinewave3 = D;
integer addr1 = 32;
integer addr2 = 16;
integer addr3 = 0;
// each mosfets has their own deadtime timer, which count down from 100
integer deadtime = 100;
integer deadtimer1P = 0;
integer deadtimer1N = 0;
integer deadtimer2P = 0;
integer deadtimer2N = 0;
integer deadtimer3P = 0;
integer deadtimer3N = 0;
always@(posedge clk) begin
if(sineCount1 == 100)
begin // increment sineCount2
sineCount1 = 0;
sineCount2 = sineCount2 + 1;
end
sineCount1 = sineCount1 + 1;
if(sineCount2 == 333)
begin // increment addr values
sineCount2 = 0;
if (addr == res)
begin
addr = 0;
end
else begin
addr = addr + 1;
end
if (addr1 == res)
begin
addr1 = 0;
end
else begin
addr1 = addr1 + 1;
end
if (addr2 == res)
begin
addr2 = 0;
end
else begin
addr2 = addr2 + 1;
end
if (addr3 == res)
begin
addr3 = 0;
end
else begin
addr3 = addr3 + 1;
end
end
// deadtime timer triggers / negative edge detection
if ((pwm1P == 0) && (T1P == 0))
begin
T1P = 1;
deadtimer1N = deadtime;
end
if ((pwm1N == 0) && (T1N == 0))
begin
T1N = 1;
deadtimer1P = deadtime;
end
if ((pwm2P == 0) && (T2P == 0))
begin
T2P = 1;
deadtimer2N = deadtime;
end
if ((pwm2N == 0) && (T2N == 0))
begin
T2N = 1;
deadtimer2P = deadtime;
end
if ((pwm3P == 0) && (T3P == 0))
begin
T3P = 1;
deadtimer3N = deadtime;
end
if ((pwm3N == 0) && (T3N == 0))
begin
T3N = 1;
deadtimer3P = deadtime;
end
// when a PWM signal == 1, its T variable = 0, which allows the above if-statement to trigger when PWM signal == 0 (edge detection)
if (pwm1P == 1)
begin
T1P = 0;
end
if (pwm1N == 1)
begin
T1N = 0;
end
if (pwm2P == 1)
begin
T2P = 0;
end
if (pwm2N == 1)
begin
T2N = 0;
end
if (pwm3P == 1)
begin
T3P = 0;
end
if (pwm3N == 1)
begin
T3N = 0;
end
// decrement the deadtime timers if they are not == 0
if (deadtimer1P != 0)
begin
deadtimer1P <= deadtimer1P - 1;
end
if (deadtimer2P != 0)
begin
deadtimer2P <= deadtimer2P - 1;
end
if (deadtimer3P != 0)
begin
deadtimer3P <= deadtimer3P - 1;
end
if (deadtimer1N != 0)
begin
deadtimer1N <= deadtimer1N - 1;
end
if (deadtimer2N != 0)
begin
deadtimer2N <= deadtimer2N - 1;
end
if (deadtimer3N != 0)
begin
deadtimer3N <= deadtimer3N - 1;
end
// update the values of the sinewaves from the lookup table
sinewave = sineLUT[addr];
sinewave1 = sineLUT[addr1];
sinewave2 = sineLUT[addr2];
sinewave3 = sineLUT[addr3];
// generation of the triangle wave
if (triangle == 2*D)
begin
updown <= -1;
end
if (triangle == 1)
begin
updown <= 1;
end
triangle <= triangle + updown;
end
// generation of PWM signals, as well as interlocks
assign pwm1P = ((deadtimer1P == 0)&&(sinewave1 > triangle)&&(pwm1N==0))?1:0;
assign pwm2P = ((deadtimer2P == 0)&&(sinewave2 > triangle)&&(pwm2N==0))?1:0;
assign pwm3P = ((deadtimer3P == 0)&&(sinewave3 > triangle)&&(pwm3N==0))?1:0;
assign pwm1N = ((deadtimer1N == 0)&&(sinewave1 < triangle)&&(pwm1P==0))?1:0;
assign pwm2N = ((deadtimer2N == 0)&&(sinewave2 < triangle)&&(pwm2P==0))?1:0;
assign pwm3N = ((deadtimer3N == 0)&&(sinewave3 < triangle)&&(pwm3P==0))?1:0;
endmodule