-
Notifications
You must be signed in to change notification settings - Fork 179
/
tb_clark_park_tr.v
108 lines (88 loc) · 4.49 KB
/
tb_clark_park_tr.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//--------------------------------------------------------------------------------------------------------
// Module : tb_clark_park_tr
// Type : simulation, top
// Standard: Verilog 2001 (IEEE1364-2001)
// Function: testbench for sincos.sv , clark_tr.sv , park_tr.sv
//--------------------------------------------------------------------------------------------------------
module tb_clark_park_tr();
initial $dumpvars(1, tb_clark_park_tr);
reg rstn = 1'b0;
reg clk = 1'b1;
always #(13563) clk = ~clk; // 36.864MHz
initial begin repeat(4) @(posedge clk); rstn<=1'b1; end
reg en_theta = 0;
reg [11:0] theta = 0; // 当前电角度(简记为 ψ)。取值范围0~4095。0对应0°;1024对应90°;2048对应180°;3072对应270°。
localparam [11:0] PI_M2_D3 = (2*4096/3); // (2/3)*π
localparam [11:0] PI_D3 = ( 4096/3); // (1/3)*π
wire en_iabc;
wire signed [15:0] ia, ib, ic;
wire en_ialphabeta;
wire signed [15:0] ialpha, ibeta;
wire en_idq;
wire signed [15:0] id;
wire signed [15:0] iq;
// 这里只是刚好借助了 sincos 模块来生成正弦波给 clark_tr ,只是为了仿真。在 FOC 设计中 sincos 模块并不是用来给 clark_tr 提供输入数据的,而是被 park_tr 调用。
sincos u1_sincos (
.rstn ( rstn ),
.clk ( clk ),
.i_en ( en_theta ),
.i_theta ( theta + PI_M2_D3 ), // input : θ + (2/3)*π
.o_en ( en_iabc ),
.o_sin ( ia ), // output: Ia, 振幅为±16384,初相位为 (4/3)*π 的正弦波
.o_cos ( )
);
sincos u2_sincos (
.rstn ( rstn ),
.clk ( clk ),
.i_en ( en_theta ),
.i_theta ( theta + PI_D3 ), // input : θ + (1/3)*π
.o_en ( ),
.o_sin ( ib ), // output: Ib, 振幅为±16384,初相位为 (2/3)*π 的正弦波
.o_cos ( )
);
sincos u3_sincos (
.rstn ( rstn ),
.clk ( clk ),
.i_en ( en_theta ),
.i_theta ( theta ), // input : θ
.o_en ( ),
.o_sin ( ic ), // output: Ic, 振幅为±16384,初相位为 0 的正弦波
.o_cos ( )
);
// clark 变换
clark_tr u_clark_tr (
.rstn ( rstn ),
.clk ( clk ),
.i_en ( en_iabc ),
.i_ia ( ia / 16'sd2 ), // input : 振幅为±8192,初相位为 (4/3)*π 的正弦波
.i_ib ( ib / 16'sd2 ), // input : 振幅为±8192,初相位为 (2/3)*π 的正弦波
.i_ic ( ic / 16'sd2 ), // input : 振幅为±8192,初相位为 0 的正弦波
.o_en ( en_ialphabeta ),
.o_ialpha ( ialpha ), // output: Iα ,应该为初相位为 (4/3)*π 的正弦波
.o_ibeta ( ibeta ) // output: Iβ ,相位应该比 Iα 滞后 (1/2)*π ,也就是与 Iα 正交
);
// park 变换
park_tr u_park_tr (
.rstn ( rstn ),
.clk ( clk ),
.psi ( theta + 12'd512 ), // input : θ + (1/4)*π
.i_en ( en_ialphabeta ),
.i_ialpha ( ialpha ), // input : Iα
.i_ibeta ( ibeta ), // input : Iβ
.o_en ( en_idq ),
.o_id ( id ), // output: Id ,应该变为一个定值,因为 park 变换把转子又变回定子了
.o_iq ( iq ) // output: Iq ,应该变为一个定值,因为 park 变换把转子又变回定子了
);
integer i;
initial begin
while(~rstn) @ (posedge clk);
for (i=0; i<1000; i=i+1) @ (posedge clk) begin
en_theta <= 1'b1;
theta <= theta + 12'd10;
@ (posedge clk);
en_theta <= 1'b0;
repeat (9) @ (posedge clk);
end
$finish;
end
endmodule