1,归纳抽象
我们上述分析归纳了实际上只需要三类操作
1,执行命令操作。包含三个操作 RESET 转换D1 转换D2。
2,读出6个16位校准字。
3,读出D1 D2.
其中第一条是阻塞的,也就是要等SDO为高后才能认为执行完毕并返回。
上述三个操作我们都分别命名为ISSUE_CMD,RD_U16,RD_U24。
2,有限状态机FSM是使用HDL在并行的硬件里面实现类似C语言那样串行执行指令的一种很好方式。
我们考虑在C语言中函数实现的特点:
A,要有一个函数名,实际对应函数地址。
B,可以有一个输入参数。有一定方式传递这个参数。
C,可以有一个返回结果。有一定的方式传递这个结果。
D,无论是否有输入参数和返回结果,必须要做一些事情。
E,要有返回地址。
3,上述C函数的实现方式是最基本的我们考虑在HDL写的FSM里面如何实现。
直接上代码:
ISSUE_CMD + 0 : begin CSN<=0; SCK<=0;MO<=A[7];st<=st+1;end
ISSUE_CMD + 1 : begin CSN<=0; SCK<=1;MO<=A[7];st<=st+1;end
ISSUE_CMD + 2 : begin CSN<=0; SCK<=0;MO<=A[6];st<=st+1;end
ISSUE_CMD + 3 : begin CSN<=0; SCK<=1;MO<=A[6];st<=st+1;end
ISSUE_CMD + 4 : begin CSN<=0; SCK<=0;MO<=A[5];st<=st+1;end
ISSUE_CMD + 5 : begin CSN<=0; SCK<=1;MO<=A[5];st<=st+1;end
ISSUE_CMD + 6 : begin CSN<=0; SCK<=0;MO<=A[4];st<=st+1;end
ISSUE_CMD + 7 : begin CSN<=0; SCK<=1;MO<=A[4];st<=st+1;end
ISSUE_CMD + 8 : begin CSN<=0; SCK<=0;MO<=A[3];st<=st+1;end
ISSUE_CMD + 9 : begin CSN<=0; SCK<=1;MO<=A[3];st<=st+1;end
ISSUE_CMD + 10 : begin CSN<=0; SCK<=0;MO<=A[2];st<=st+1;end
ISSUE_CMD + 11 : begin CSN<=0; SCK<=1;MO<=A[2];st<=st+1;end
ISSUE_CMD + 12 : begin CSN<=0; SCK<=0;MO<=A[1];st<=st+1;end
ISSUE_CMD + 13 : begin CSN<=0; SCK<=1;MO<=A[1];st<=st+1;end
ISSUE_CMD + 14 : begin CSN<=0; SCK<=0;MO<=A[0];st<=st+1;end
ISSUE_CMD + 15 : begin CSN<=0; SCK<=1;MO<=A[0];st<=st+1;end
ISSUE_CMD + 16 : begin CSN<=0; SCK<=0;if (MIr)st<=st+1;end
ISSUE_CMD + 17 : st<=st+1;
ISSUE_CMD + 18 : st<=st+1;
ISSUE_CMD + 19 : begin CSN<=1; st<=st+1;end
ISSUE_CMD + 20 : st<=st+1;
ISSUE_CMD + 21 : st <= RET_ST;
我们暂且说这是FSM实现的ISSUE_CMD函数,下面是调用这个函数的代码:
0: st<=1;
1: begin CSN <=1 ;SCK<=0; st<=10;end
10: begin A[7:0]<='H1E; RET_ST<=st+1;st<= ISSUE_CMD ;end
11: st<=st+1; ///reset
31: begin A[7:0]<=CNVT_D1r; RET_ST<=st+1;st<= ISSUE_CMD ;end
32: st<=st+1;
33: begin RET_ST<=st+1; st<=RD_U24;end
34: begin q <= {8'h0,R[23:0]} ;q_valid<=1; st<=st+1 ;end
35: begin q_valid<=0; st<=st+1 ;end
这里我们我们通过寄存器A传递过去要发送的命令,设置RET_ST记录返回地址是当前状态的下一个状态,之后转跳到ISSUE_CMD这个地址依次一条条执行,将A寄存器的7为都传输出去。发出去之后,再转跳回去原来的地址。另外我们看到RD_U24的返回的结果保存在R寄存器里,这就实现了类似函数的返回。
全部的代码我贴在下面:
/*
ms5611_man ms5611_man(
.clk( ) ,
.rst( ) ,
.CSN( ) ,
.SCK( ) ,
.MO( ) ,
.MIr( ) ,
.CNVT_D1( ) ,
.CNVT_D2( ) ,
.Q( ) ,
.Q_WR( ) ,
.start_rd_u24( )
);
*/
module ms5611_man(
input clk,rst,
output reg CSN,SCK,MO,
input MI,
input [7:0] CNVT_D1,
input [7:0] CNVT_D2,
output reg [31:0] Q,
output reg Q_WR ,
input start_rd_u24
);
reg [15:0] st = 0 ;
reg [7:0] A;
reg [15:0] RET_ST ;
reg [23:0] R;
reg q_valid , q_validr ;
reg [31:0] q ;
reg [7:0] CNVT_D2r;
reg [7:0] CNVT_D1r;
reg MIr ;always@(posedge clk)MIr <= MI ;
always@(posedge clk)if (start_rd_u24==1 && st == 30) begin
CNVT_D2r <= CNVT_D2 ;
CNVT_D1r <= CNVT_D1 ;
end
//parameter CVT_D1 = 'H48 ;
//parameter CVT_D2 = 'H58 ;
localparam ISSUE_CMD = 100 ;
localparam RD_U16 = 200 ;
localparam RD_U24 = 300 ;
always @(posedge clk ) q_validr <= q_valid ;
always @(posedge clk ) Q_WR <= {q_validr,q_valid} == 2'b01 ;
always @(posedge clk ) Q <= q ;
reg [8:0] d = 0 ; always @(posedge clk )d<=d+1;
always @ (posedge clk) if (rst) st<=0; else if (d==0)
case (st)
0: st<=1;
1: begin CSN <=1 ;SCK<=0; st<=10;end
10: begin A[7:0]<='H1E; RET_ST<=st+1;st<= ISSUE_CMD ;end
11: st<=st+1; ///reset
12: begin A[7:0] <= 'HA2+'h0 ; RET_ST<=st+1;st<= RD_U16 ; end
13: begin q <= {8'h0,R[15:0]} ;q_valid<=1; st<=st+1 ;end
14: begin q_valid<=0; st<=st+1 ;end //read c0
15: begin A[7:0] <= 'HA2+'h2 ; RET_ST<=st+1;st<= RD_U16 ; end
16: begin q <= {8'h0,R[15:0]} ;q_valid<=1; st<=st+1 ;end
17: begin q_valid<=0; st<=st+1;end //read c1
18: begin A[7:0] <= 'HA2+'h4 ; RET_ST<=st+1;st<= RD_U16 ; end
19: begin q <= {8'h0,R[15:0]} ;q_valid<=1; st<=st+1 ;end
20: begin q_valid<=0; st<=st+1; end //read c2
21: begin A[7:0] <= 'HA2+'h6 ; RET_ST<=st+1;st<= RD_U16 ; end
22: begin q <= {8'h0,R[15:0]} ;q_valid<=1; st<=st+1 ;end
23: begin q_valid<=0; st<=st+1; end //read c3
24: begin A[7:0] <= 'HA2+'h8 ; RET_ST<=st+1;st<= RD_U16 ; end
25: begin q <= {8'h0,R[15:0]} ;q_valid<=1; st<=st+1 ;end
26: begin q_valid<=0; st<=st+1; end //read c4
27: begin A[7:0] <= 'HA2+'ha; RET_ST<=st+1;st<= RD_U16 ; end
28: begin q <= {8'h0,R[15:0]} ;q_valid<=1; st<=st+1 ;end
29: begin q_valid<=0; st<=st+1; end //read c5
30: if (start_rd_u24) st<=31;
31: begin A[7:0]<=CNVT_D1r; RET_ST<=st+1;st<= ISSUE_CMD ;end
32: st<=st+1;
33: begin RET_ST<=st+1; st<=RD_U24;end
34: begin q <= {8'h0,R[23:0]} ;q_valid<=1; st<=st+1 ;end
35: begin q_valid<=0; st<=st+1 ;end
36: begin A[7:0]<=CNVT_D2r; RET_ST<=st+1;st<= ISSUE_CMD ;end
37: st<=st+1;
38: begin RET_ST<=st+1; st<=RD_U24;end
39: begin q <= {8'h0,R[23:0]} ;q_valid<=1; st<=st+1 ;end
40: begin q_valid<=0; st<=st+1 ;end
41: begin st<= 30; end
ISSUE_CMD + 0 : begin CSN<=0; SCK<=0;MO<=A[7];st<=st+1;end
ISSUE_CMD + 1 : begin CSN<=0; SCK<=1;MO<=A[7];st<=st+1;end
ISSUE_CMD + 2 : begin CSN<=0; SCK<=0;MO<=A[6];st<=st+1;end
ISSUE_CMD + 3 : begin CSN<=0; SCK<=1;MO<=A[6];st<=st+1;end
ISSUE_CMD + 4 : begin CSN<=0; SCK<=0;MO<=A[5];st<=st+1;end
ISSUE_CMD + 5 : begin CSN<=0; SCK<=1;MO<=A[5];st<=st+1;end
ISSUE_CMD + 6 : begin CSN<=0; SCK<=0;MO<=A[4];st<=st+1;end
ISSUE_CMD + 7 : begin CSN<=0; SCK<=1;MO<=A[4];st<=st+1;end
ISSUE_CMD + 8 : begin CSN<=0; SCK<=0;MO<=A[3];st<=st+1;end
ISSUE_CMD + 9 : begin CSN<=0; SCK<=1;MO<=A[3];st<=st+1;end
ISSUE_CMD + 10 : begin CSN<=0; SCK<=0;MO<=A[2];st<=st+1;end
ISSUE_CMD + 11 : begin CSN<=0; SCK<=1;MO<=A[2];st<=st+1;end
ISSUE_CMD + 12 : begin CSN<=0; SCK<=0;MO<=A[1];st<=st+1;end
ISSUE_CMD + 13 : begin CSN<=0; SCK<=1;MO<=A[1];st<=st+1;end
ISSUE_CMD + 14 : begin CSN<=0; SCK<=0;MO<=A[0];st<=st+1;end
ISSUE_CMD + 15 : begin CSN<=0; SCK<=1;MO<=A[0];st<=st+1;end
ISSUE_CMD + 16 : begin CSN<=0; SCK<=0;if (MIr)st<=st+1;end
ISSUE_CMD + 17 : st<=st+1;
ISSUE_CMD + 18 : st<=st+1;
ISSUE_CMD + 19 : begin CSN<=1; st<=st+1;end
ISSUE_CMD + 20 : st<=st+1;
ISSUE_CMD + 21 : st <= RET_ST;
RD_U16 + 0 : begin CSN<=0; SCK<=0;MO<=A[7];st<=st+1;end
RD_U16 + 1 : begin CSN<=0; SCK<=1;MO<=A[7];st<=st+1;end
RD_U16 + 2 : begin CSN<=0; SCK<=0;MO<=A[6];st<=st+1;end
RD_U16 + 3 : begin CSN<=0; SCK<=1;MO<=A[6];st<=st+1;end
RD_U16 + 4 : begin CSN<=0; SCK<=0;MO<=A[5];st<=st+1;end
RD_U16 + 5 : begin CSN<=0; SCK<=1;MO<=A[5];st<=st+1;end
RD_U16 + 6 : begin CSN<=0; SCK<=0;MO<=A[4];st<=st+1;end
RD_U16 + 7 : begin CSN<=0; SCK<=1;MO<=A[4];st<=st+1;end
RD_U16 + 8 : begin CSN<=0; SCK<=0;MO<=A[3];st<=st+1;end
RD_U16 + 9 : begin CSN<=0; SCK<=1;MO<=A[3];st<=st+1;end
RD_U16 + 10 : begin CSN<=0; SCK<=0;MO<=A[2];st<=st+1;end
RD_U16 + 11 : begin CSN<=0; SCK<=1;MO<=A[2];st<=st+1;end
RD_U16 + 12 : begin CSN<=0; SCK<=0;MO<=A[1];st<=st+1;end
RD_U16 + 13 : begin CSN<=0; SCK<=1;MO<=A[1];st<=st+1;end
RD_U16 + 14 : begin CSN<=0; SCK<=0;MO<=A[0];st<=st+1;end
RD_U16 + 15 : begin CSN<=0; SCK<=1;MO<=A[0];st<=st+1;end
RD_U16 + 16 : begin CSN<=0; SCK<=0;R[7+8]<=MIr; st<=st+1;MO<=0;end
RD_U16 + 17 : begin CSN<=0; SCK<=1;R[7+8]<=MIr; st<=st+1;end
RD_U16 + 18 : begin CSN<=0; SCK<=0;R[6+8]<=MIr; st<=st+1;end
RD_U16 + 19 : begin CSN<=0; SCK<=1;R[6+8]<=MIr; st<=st+1;end
RD_U16 + 20 : begin CSN<=0; SCK<=0;R[5+8]<=MIr; st<=st+1;end
RD_U16 + 21 : begin CSN<=0; SCK<=1;R[5+8]<=MIr; st<=st+1;end
RD_U16 + 22 : begin CSN<=0; SCK<=0;R[4+8]<=MIr; st<=st+1;end
RD_U16 + 23 : begin CSN<=0; SCK<=1;R[4+8]<=MIr; st<=st+1;end
RD_U16 + 24 : begin CSN<=0; SCK<=0;R[3+8]<=MIr; st<=st+1;end
RD_U16 + 25 : begin CSN<=0; SCK<=1;R[3+8]<=MIr; st<=st+1;end
RD_U16 + 26 : begin CSN<=0; SCK<=0;R[2+8]<=MIr; st<=st+1;end
RD_U16 + 27 : begin CSN<=0; SCK<=1;R[2+8]<=MIr; st<=st+1;end
RD_U16 + 28 : begin CSN<=0; SCK<=0;R[1+8]<=MIr; st<=st+1;end
RD_U16 + 29 : begin CSN<=0; SCK<=1;R[1+8]<=MIr; st<=st+1;end
RD_U16 + 30 : begin CSN<=0; SCK<=0;R[0+8]<=MIr; st<=st+1;end
RD_U16 + 31 : begin CSN<=0; SCK<=1;R[0+8]<=MIr; st<=st+1;end
RD_U16 + 32 : begin CSN<=0; SCK<=0;R[7]<=MIr; st<=st+1;end
RD_U16 + 33 : begin CSN<=0; SCK<=1;R[7]<=MIr; st<=st+1;end
RD_U16 + 34 : begin CSN<=0; SCK<=0;R[6]<=MIr; st<=st+1;end
RD_U16 + 35 : begin CSN<=0; SCK<=1;R[6]<=MIr; st<=st+1;end
RD_U16 + 36 : begin CSN<=0; SCK<=0;R[5]<=MIr; st<=st+1;end
RD_U16 + 37 : begin CSN<=0; SCK<=1;R[5]<=MIr; st<=st+1;end
RD_U16 + 38 : begin CSN<=0; SCK<=0;R[4]<=MIr; st<=st+1;end
RD_U16 + 39 : begin CSN<=0; SCK<=1;R[4]<=MIr; st<=st+1;end
RD_U16 + 40 : begin CSN<=0; SCK<=0;R[3]<=MIr; st<=st+1;end
RD_U16 + 41 : begin CSN<=0; SCK<=1;R[3]<=MIr; st<=st+1;end
RD_U16 + 42 : begin CSN<=0; SCK<=0;R[2]<=MIr; st<=st+1;end
RD_U16 + 43 : begin CSN<=0; SCK<=1;R[2]<=MIr; st<=st+1;end
RD_U16 + 44 : begin CSN<=0; SCK<=0;R[1]<=MIr; st<=st+1;end
RD_U16 + 45 : begin CSN<=0; SCK<=1;R[1]<=MIr; st<=st+1;end
RD_U16 + 46 : begin CSN<=0; SCK<=0;R[0]<=MIr; st<=st+1;end
RD_U16 + 47 : begin CSN<=0; SCK<=1;R[0]<=MIr; st<=st+1;end
RD_U16 + 48 : begin SCK<=0;st<=st+1;end
RD_U16 + 49 : st<=st+1;
RD_U16 + 50 : begin CSN<=1;st<=st+1;end
RD_U16 + 51 : st<=st+1;
RD_U16 + 52 : st <= RET_ST;
RD_U24 + 0 : begin CSN<=0; SCK<=0;MO<=0;st<=st+1;end
RD_U24 + 1 : begin CSN<=0; SCK<=1;MO<=0;st<=st+1;end
RD_U24 + 2 : begin CSN<=0; SCK<=0;MO<=0;st<=st+1;end
RD_U24 + 3 : begin CSN<=0; SCK<=1;MO<=0;st<=st+1;end
RD_U24 + 4 : begin CSN<=0; SCK<=0;MO<=0;st<=st+1;end
RD_U24 + 5 : begin CSN<=0; SCK<=1;MO<=0;st<=st+1;end
RD_U24 + 6 : begin CSN<=0; SCK<=0;MO<=0;st<=st+1;end
RD_U24 + 7 : begin CSN<=0; SCK<=1;MO<=0;st<=st+1;end
RD_U24 + 8 : begin CSN<=0; SCK<=0;MO<=0;st<=st+1;end
RD_U24 + 9 : begin CSN<=0; SCK<=1;MO<=0;st<=st+1;end
RD_U24 + 10 : begin CSN<=0; SCK<=0;MO<=0;st<=st+1;end
RD_U24 + 11 : begin CSN<=0; SCK<=1;MO<=0;st<=st+1;end
RD_U24 + 12 : begin CSN<=0; SCK<=0;MO<=0;st<=st+1;end
RD_U24 + 13 : begin CSN<=0; SCK<=1;MO<=0;st<=st+1;end
RD_U24 + 14 : begin CSN<=0; SCK<=0;MO<=0;st<=st+1;end
RD_U24 + 15 : begin CSN<=0; SCK<=1;MO<=0;st<=st+1;end
RD_U24 + 16 : begin CSN<=0; SCK<=0;R[7+8+8]<=MIr; st<=st+1;end
RD_U24 + 17 : begin CSN<=0; SCK<=1;R[7+8+8]<=MIr; st<=st+1;end
RD_U24 + 18 : begin CSN<=0; SCK<=0;R[6+8+8]<=MIr; st<=st+1;end
RD_U24 + 19 : begin CSN<=0; SCK<=1;R[6+8+8]<=MIr; st<=st+1;end
RD_U24 + 20 : begin CSN<=0; SCK<=0;R[5+8+8]<=MIr; st<=st+1;end
RD_U24 + 21 : begin CSN<=0; SCK<=1;R[5+8+8]<=MIr; st<=st+1;end
RD_U24 + 22 : begin CSN<=0; SCK<=0;R[4+8+8]<=MIr; st<=st+1;end
RD_U24 + 23 : begin CSN<=0; SCK<=1;R[4+8+8]<=MIr; st<=st+1;end
RD_U24 + 24 : begin CSN<=0; SCK<=0;R[3+8+8]<=MIr; st<=st+1;end
RD_U24 + 25 : begin CSN<=0; SCK<=1;R[3+8+8]<=MIr; st<=st+1;end
RD_U24 + 26 : begin CSN<=0; SCK<=0;R[2+8+8]<=MIr; st<=st+1;end
RD_U24 + 27 : begin CSN<=0; SCK<=1;R[2+8+8]<=MIr; st<=st+1;end
RD_U24 + 28 : begin CSN<=0; SCK<=0;R[1+8+8]<=MIr; st<=st+1;end
RD_U24 + 29 : begin CSN<=0; SCK<=1;R[1+8+8]<=MIr; st<=st+1;end
RD_U24 + 30 : begin CSN<=0; SCK<=0;R[0+8+8]<=MIr; st<=st+1;end
RD_U24 + 31 : begin CSN<=0; SCK<=1;R[0+8+8]<=MIr; st<=st+1;end
RD_U24 + 32 : begin CSN<=0; SCK<=0;R[7+8]<=MIr; st<=st+1;end
RD_U24 + 33 : begin CSN<=0; SCK<=1;R[7+8]<=MIr; st<=st+1;end
RD_U24 + 34 : begin CSN<=0; SCK<=0;R[6+8]<=MIr; st<=st+1;end
RD_U24 + 35 : begin CSN<=0; SCK<=1;R[6+8]<=MIr; st<=st+1;end
RD_U24 + 36 : begin CSN<=0; SCK<=0;R[5+8]<=MIr; st<=st+1;end
RD_U24 + 37 : begin CSN<=0; SCK<=1;R[5+8]<=MIr; st<=st+1;end
RD_U24 + 38 : begin CSN<=0; SCK<=0;R[4+8]<=MIr; st<=st+1;end
RD_U24 + 39 : begin CSN<=0; SCK<=1;R[4+8]<=MIr; st<=st+1;end
RD_U24 + 40 : begin CSN<=0; SCK<=0;R[3+8]<=MIr; st<=st+1;end
RD_U24 + 41 : begin CSN<=0; SCK<=1;R[3+8]<=MIr; st<=st+1;end
RD_U24 + 42 : begin CSN<=0; SCK<=0;R[2+8]<=MIr; st<=st+1;end
RD_U24 + 43 : begin CSN<=0; SCK<=1;R[2+8]<=MIr; st<=st+1;end
RD_U24 + 44 : begin CSN<=0; SCK<=0;R[1+8]<=MIr; st<=st+1;end
RD_U24 + 45 : begin CSN<=0; SCK<=1;R[1+8]<=MIr; st<=st+1;end
RD_U24 + 46 : begin CSN<=0; SCK<=0;R[0+8]<=MIr; st<=st+1;end
RD_U24 + 47 : begin CSN<=0; SCK<=1;R[0+8]<=MIr; st<=st+1;end
RD_U24 + 48 : begin CSN<=0; SCK<=0;R[7]<=MIr; st <= st + 1;end
RD_U24 + 49 : begin CSN<=0; SCK<=1;R[7]<=MIr; st <= st + 1;end
RD_U24 + 50 : begin CSN<=0; SCK<=0;R[6]<=MIr; st <= st + 1;end
RD_U24 + 51 : begin CSN<=0; SCK<=1;R[6]<=MIr; st <= st + 1;end
RD_U24 + 52 : begin CSN<=0; SCK<=0;R[5]<=MIr; st <= st + 1;end
RD_U24 + 53 : begin CSN<=0; SCK<=1;R[5]<=MIr; st <= st + 1;end
RD_U24 + 54 : begin CSN<=0; SCK<=0;R[4]<=MIr; st <= st + 1;end
RD_U24 + 55 : begin CSN<=0; SCK<=1;R[4]<=MIr; st <= st + 1;end
RD_U24 + 56 : begin CSN<=0; SCK<=0;R[3]<=MIr; st <= st + 1;end
RD_U24 + 57 : begin CSN<=0; SCK<=1;R[3]<=MIr; st <= st + 1;end
RD_U24 + 58 : begin CSN<=0; SCK<=0;R[2]<=MIr; st <= st + 1;end
RD_U24 + 59 : begin CSN<=0; SCK<=1;R[2]<=MIr; st <= st + 1;end
RD_U24 + 60 : begin CSN<=0; SCK<=0;R[1]<=MIr; st <= st + 1;end
RD_U24 + 61 : begin CSN<=0; SCK<=1;R[1]<=MIr; st <= st + 1;end
RD_U24 + 62 : begin CSN<=0; SCK<=0;R[0]<=MIr; st <= st + 1;end
RD_U24 + 63 : begin CSN<=0; SCK<=1;R[0]<=MIr; st <= st + 1;end
RD_U24 + 64 : begin SCK<=0;st<=st+1;end
RD_U24 + 65 : st<=st+1;
RD_U24 + 66 : begin CSN<=1;st<=st+1;end
RD_U24 + 67 : st<=st+1;
RD_U24 + 68 : st <= RET_ST;
default st<=0;
endcase
endmodule
我们看到这个控制器在开始运行后发送一个复位命令,之后从PROM里面读出6个16位校准字传输出去(Q是数据输出,Q_WR是Q有效写的指示,可以接在一个队列里面),再之后就检测strat_rd u24信号,如果此信号有效则
1,启动转换D1命令并等待执行完毕,
2,读出D1并通过Q和Q_WR传输出去。
3,启动转换D2命令并等待执行完毕,
4,读出D2并通过Q和Q_WR传输出去。
这四个操作中1,3调用了ISSUE_CMD“函数”,2,4调用了RD_U24“函数“,这就实现了很好的复用性,函数优势体现出来了。
下一个BLOG我 写一下这个控制器如何连接FIFO队列,以及如何接入AXI_LITE外设核。再下一篇我简单写一下在PS里面如何控制这个核,最后写写如何实现温度气压的运算。