以下是我的顶级模块:
module spwm(clk, p1, sine_a, tri_out);
input clk; //16MHz
reg tick = 0;
reg [7:0] theta_a = 8'd0;
reg [7:0] theta_tri = 8'd0;
output [8:0] sine_a;
output [9:0] tri_out;
integer div = 42;
integer r = 0;
output p1;
reg p1;
always@(posedge clk) begin
if(r == div) begin
tick = ~tick;
r = 1;
end
else begin
r = r + 1;
end
end
always@(tick) begin
theta_a = (theta_a + 8'b1) % 8'd255;
end
always@(posedge clk) begin
theta_tri = (theta_tri + 8'b1) % 8'd255;
end
//generate spwm
always@(clk) begin
if ($signed(sine_a) > $signed(tri_out))
p1 = 1'b1;
else if ($signed(sine_a) < $signed(tri_out))
p1 = 1'b0;
end
SINE_LUT lut_a(theta_a, sine_a);
TRI_LUT lut_tri(theta_tri, tri_out);
endmodule
我的正弦波查找表:
module SINE_LUT (THETA, SINE_OUT);
input [7:0] THETA; //Input THETA
output [8:0] SINE_OUT; //Output SINE_OUT
reg [5:0] THETA_TMP; //Lower bits of THETA (counting up or counting down)
reg [6:0] THETA_HLP; //Helper for reversing lower bits of counting direction for theta
reg [8:0] SINE_TMP; //Temporary holder for output (two's compliment)
reg [8:0] SINE_OUT; //Output Sine in two's compliment
always @ (THETA) begin //Combinatorial Logic Look Up Table
if (THETA[6:0] == 7'd64) begin //At 90 degrees and 270 degrees
SINE_TMP = 9'd255;
end
else begin
if (THETA[6]) begin //If counting down should begin reverse counting order
THETA_HLP = 7'd64 - {1'd0, THETA[5:0]};
THETA_TMP = {THETA_HLP[5:0]};
end
else begin //Continue counting up by default
THETA_TMP = {THETA[5:0]};
end
case (THETA_TMP) //Look Up Table (quarter wave)
6'd0: SINE_TMP = 9'd0;
6'd1: SINE_TMP = 9'd6;
6'd2: SINE_TMP = 9'd13;
6'd3: SINE_TMP = 9'd19;
6'd4: SINE_TMP = 9'd25;
6'd5: SINE_TMP = 9'd31;
6'd6: SINE_TMP = 9'd37;
6'd7: SINE_TMP = 9'd44;
6'd8: SINE_TMP = 9'd50;
6'd9: SINE_TMP = 9'd56;
6'd10: SINE_TMP = 9'd62;
6'd11: SINE_TMP = 9'd68;
6'd12: SINE_TMP = 9'd74;
6'd13: SINE_TMP = 9'd80;
6'd14: SINE_TMP = 9'd86;
6'd15: SINE_TMP = 9'd92;
6'd16: SINE_TMP = 9'd98;
6'd17: SINE_TMP = 9'd103;
6'd18: SINE_TMP = 9'd109;
6'd19: SINE_TMP = 9'd115;
6'd20: SINE_TMP = 9'd120;
6'd21: SINE_TMP = 9'd126;
6'd22: SINE_TMP = 9'd131;
6'd23: SINE_TMP = 9'd136;
6'd24: SINE_TMP = 9'd142;
6'd25: SINE_TMP = 9'd147;
6'd26: SINE_TMP = 9'd152;
6'd27: SINE_TMP = 9'd157;
6'd28: SINE_TMP = 9'd162;
6'd29: SINE_TMP = 9'd167;
6'd30: SINE_TMP = 9'd171;
6'd31: SINE_TMP = 9'd176;
6'd32: SINE_TMP = 9'd180;
6'd33: SINE_TMP = 9'd185;
6'd34: SINE_TMP = 9'd189;
6'd35: SINE_TMP = 9'd193;
6'd36: SINE_TMP = 9'd197;
6'd37: SINE_TMP = 9'd201;
6'd38: SINE_TMP = 9'd205;
6'd39: SINE_TMP = 9'd208;
6'd40: SINE_TMP = 9'd212;
6'd41: SINE_TMP = 9'd215;
6'd42: SINE_TMP = 9'd219;
6'd43: SINE_TMP = 9'd222;
6'd44: SINE_TMP = 9'd225;
6'd45: SINE_TMP = 9'd228;
6'd46: SINE_TMP = 9'd231;
6'd47: SINE_TMP = 9'd233;
6'd48: SINE_TMP = 9'd236;
6'd49: SINE_TMP = 9'd238;
6'd50: SINE_TMP = 9'd240;
6'd51: SINE_TMP = 9'd242;
6'd52: SINE_TMP = 9'd244;
6'd53: SINE_TMP = 9'd246;
6'd54: SINE_TMP = 9'd247;
6'd55: SINE_TMP = 9'd249;
6'd56: SINE_TMP = 9'd250;
6'd57: SINE_TMP = 9'd251;
6'd58: SINE_TMP = 9'd252;
6'd59: SINE_TMP = 9'd253;
6'd60: SINE_TMP = 9'd254;
6'd61: SINE_TMP = 9'd254;
6'd62: SINE_TMP = 9'd255;
6'd63: SINE_TMP = 9'd255;
endcase
end
if (THETA > 8'd128) begin //Any theta between 180 and 360 degrees should be negative
SINE_OUT = (~SINE_TMP) + 1'd1; //Create negative value in two's compliment
end
else begin //Any theta between 0 and 180 degrees should be positive
SINE_OUT = SINE_TMP;
end
end
endmodule
我还使用三角波查找表:
module TRI_LUT (THETA, TRI_OUT);
input [7:0] THETA;
output [9:0] TRI_OUT;
reg [5:0] THETA_TMP;
reg [6:0] THETA_HLP;
reg [9:0] TRI_TMP;
reg [9:0] TRI_OUT;
always @ (THETA) begin
if (THETA[6:0] == 7'd64) begin
TRI_TMP = 10'd364;
end
else begin
if (THETA[6]) begin
THETA_HLP = 7'd64 - {1'd0, THETA[5:0]};
THETA_TMP = {THETA_HLP[5:0]};
end
else begin
THETA_TMP = {THETA[5:0]};
end
case (THETA_TMP)
6'd0: TRI_TMP = 10'd0;
6'd1: TRI_TMP = 10'd6;
6'd2: TRI_TMP = 10'd12;
6'd3: TRI_TMP = 10'd17;
6'd4: TRI_TMP = 10'd23;
6'd5: TRI_TMP = 10'd29;
6'd6: TRI_TMP = 10'd35;
6'd7: TRI_TMP = 10'd40;
6'd8: TRI_TMP = 10'd46;
6'd9: TRI_TMP = 10'd52;
6'd10: TRI_TMP = 10'd58;
6'd11: TRI_TMP = 10'd64;
6'd12: TRI_TMP = 10'd69;
6'd13: TRI_TMP = 10'd75;
6'd14: TRI_TMP = 10'd81;
6'd15: TRI_TMP = 10'd87;
6'd16: TRI_TMP = 10'd92;
6'd17: TRI_TMP = 10'd98;
6'd18: TRI_TMP = 10'd104;
6'd19: TRI_TMP = 10'd110;
6'd20: TRI_TMP = 10'd116;
6'd21: TRI_TMP = 10'd121;
6'd22: TRI_TMP = 10'd127;
6'd23: TRI_TMP = 10'd133;
6'd24: TRI_TMP = 10'd139;
6'd25: TRI_TMP = 10'd144;
6'd26: TRI_TMP = 10'd150;
6'd27: TRI_TMP = 10'd156;
6'd28: TRI_TMP = 10'd162;
6'd29: TRI_TMP = 10'd168;
6'd30: TRI_TMP = 10'd173;
6'd31: TRI_TMP = 10'd179;
6'd32: TRI_TMP = 10'd185;
6'd33: TRI_TMP = 10'd191;
6'd34: TRI_TMP = 10'd196;
6'd35: TRI_TMP = 10'd202;
6'd36: TRI_TMP = 10'd208;
6'd37: TRI_TMP = 10'd214;
6'd38: TRI_TMP = 10'd220;
6'd39: TRI_TMP = 10'd225;
6'd40: TRI_TMP = 10'd231;
6'd41: TRI_TMP = 10'd237;
6'd42: TRI_TMP = 10'd243;
6'd43: TRI_TMP = 10'd248;
6'd44: TRI_TMP = 10'd254;
6'd45: TRI_TMP = 10'd260;
6'd46: TRI_TMP = 10'd266;
6'd47: TRI_TMP = 10'd272;
6'd48: TRI_TMP = 10'd277;
6'd49: TRI_TMP = 10'd283;
6'd50: TRI_TMP = 10'd289;
6'd51: TRI_TMP = 10'd295;
6'd52: TRI_TMP = 10'd300;
6'd53: TRI_TMP = 10'd306;
6'd54: TRI_TMP = 10'd312;
6'd55: TRI_TMP = 10'd318;
6'd56: TRI_TMP = 10'd324;
6'd57: TRI_TMP = 10'd329;
6'd58: TRI_TMP = 10'd335;
6'd59: TRI_TMP = 10'd341;
6'd60: TRI_TMP = 10'd347;
6'd61: TRI_TMP = 10'd352;
6'd62: TRI_TMP = 10'd358;
6'd63: TRI_TMP = 10'd364;
endcase
end
if (THETA > 8'd128) begin
TRI_OUT = (~TRI_TMP) + 1'd1;
end
else begin
TRI_OUT = TRI_TMP;
end
end
endmodule
上述 SPWM 在 ModelSim PE Student Edition 10.3 中有效。
当加载到 GFEC Max II 入门套件中时,信号 p1 未被调制。任何帮助。谢谢...