Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] How can I resolve this multi-driven net problem in Verilog?

Status
Not open for further replies.

hobbskw

Junior Member level 3
Junior Member level 3
Joined
Oct 19, 2021
Messages
25
Helped
1
Reputation
2
Reaction score
1
Trophy points
3
Activity points
197
Hello,
I implemented a program that outputs SPWM signals with deadtime. The deadtime works like this:

On every negative edge of 1P, set deadtimer1N = deadtime On every positive clk edge, if deadtimer1N != 0 then set deadtimer1N = deadtimer1N - 1

This works perfectly in simulation, as I show here:
1649700562170.png


However, when I try to generate the bitstream, it does not seem to like me assigning a value to deadtimer1N/1P in two different statements (posedge clk and negedge pwm1P) and gives this error:
1649700710765.png


Here you can see there are so many because it does it for every element in deadtimer1P, as well as for the other deadtimers. Line 131 is in the always@(posedge clk) statement, and line 183 is in the always@(negedge pwm1N) statement.
1649700798885.png


Here is the block diagram:
1649701106816.png


And here is the RTL code:
Code:
`timescale 1ns / 1ps

module sine_LUT(
        input clk,
        input rst_n,
        output pwm1P,
        output pwm2P,
        output pwm3P,
        output pwm1N,
        output pwm2N,
        output pwm3N
    );

reg [12:0] sineLUT[0:49];
integer addr=0;
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

integer active = 1;

localparam  D = 1250;
integer triangle = D;
integer sinewave = D;
integer updown = 1;
integer sineCount1 = 0;
integer sineCount2 = 0;

integer sinewave1 = D;
integer sinewave2 = D;
integer sinewave3 = D;
integer addr1 = 32;
integer addr2 = 16;
integer addr3 = 0;

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
        sineCount1 = 0;
        sineCount2 = sineCount2 + 1;
    end
    sineCount1 = sineCount1 + 1;
    if(sineCount2 == 333)
    begin
        sineCount2 = 0;
        addr = addr + 1;
        addr1 = addr1 + 1;
        addr2 = addr2 + 1;
        addr3 = addr3 + 1;
    end
   
    if (addr == 50)
    begin
        addr <= 0;
    end
   
    if (addr1 == 50)
    begin
        addr1 <= 0;
    end
   
    if (addr2 == 50)
    begin
        addr2 <= 0;
    end
   
    if (addr3 == 50)
    begin
        addr3 <= 0;
    end
   
    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
               
    sinewave = sineLUT[addr];
    sinewave1 = sineLUT[addr1];
    sinewave2 = sineLUT[addr2];
    sinewave3 = sineLUT[addr3];
   
    if (triangle == 2*D)
        begin
            updown <= -1;
        end
    if (triangle == 1)
        begin
            updown <= 1;
        end
    triangle <= triangle + updown;
   
end

always@(negedge pwm1P) begin
    deadtimer1N = deadtime;
end
always@(negedge pwm2P) begin
    deadtimer2N = deadtime;
end
always@(negedge pwm3P) begin
    deadtimer3N = deadtime;
end
always@(negedge pwm1N) begin
    deadtimer1P = deadtime;
end
always@(negedge pwm2N) begin
    deadtimer2P = deadtime;
end
always@(negedge pwm3N) begin
    deadtimer3P = deadtime;
end


assign pwm1P = ((deadtimer1P == 0)&&(sinewave1 > triangle))?1:0;
assign pwm2P = ((deadtimer2P == 0)&&(sinewave2 > triangle))?1:0;
assign pwm3P = ((deadtimer3P == 0)&&(sinewave3 > triangle))?1:0;
assign pwm1N = ((deadtimer1N == 0)&&(sinewave1 < triangle))?1:0;
assign pwm2N = ((deadtimer2N == 0)&&(sinewave2 < triangle))?1:0;
assign pwm3N = ((deadtimer3N == 0)&&(sinewave3 < triangle))?1:0;
endmodule

Here's the constraints:
Code:
set_property -dict { PACKAGE_PIN F16 IOSTANDARD LVCMOS33} [get_ports pwm1P];
set_property -dict { PACKAGE_PIN F17 IOSTANDARD LVCMOS33} [get_ports pwm2P];
set_property -dict { PACKAGE_PIN E18 IOSTANDARD LVCMOS33} [get_ports pwm3P];
set_property -dict { PACKAGE_PIN E19 IOSTANDARD LVCMOS33} [get_ports pwm1N];
set_property -dict { PACKAGE_PIN D19 IOSTANDARD LVCMOS33} [get_ports pwm2N];
set_property -dict { PACKAGE_PIN D20 IOSTANDARD LVCMOS33} [get_ports pwm3N];

Does anyone know how to resolve this issue? I cannot think of another way of implementing deadtime with SPWM. I would greatly appreciate any help!
 

Notice that all pwmxy edges occur at posedge clk. Instead of using the signals as separate clocks, they can be processed synchronously in the posedge clk always block.

Besides the obvious multiple driver problem created by your design method, the combinational pwmxy clocks will most likely have glitches and not work reliably.
 
Last edited:

Notice that all pwmxy edges occur at posedge clk. Instead of using the signals as separate clocks, they can be processed synchronously in the posedge clk always block.

Besides the obvious multiple driver problem created by your design method, the combinational pwmxy clocks will most likely have glitches and not work reliably.
Thank you for the helpful reply! Like you said, I had to change it to trigger the deadtime timers in the clk's posedge. Had to sleep on it, but today I thought up a way of doing it. Now it generates the bitstream successfully.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top