【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验二十:SDRAM模块③ — 页读写 α
实验二十:SDRAM模块③ — 页读写 α
完成单字读写与多字读写以后,接下来我们要实验页读写。丑话当前,实验二十的页读写只是实验性质的东西,其中不存在任何实用价值,笔者希望读者可以把它当成页读写的热身运动。
表示20.1 Mode Register的内容。
|
Mode Register |
||||||||||||
|
A12 |
A11 |
A10 |
A9 |
A8 |
A7 |
A6 |
A5 |
A4 |
A3 |
A2 |
A1 |
A0 |
|
0 |
0 |
OP Code |
0 |
0 |
CAS Latency |
BT |
Burst Length |
|
|
||||||||||||||||||||||||||||||||||||||
|
|
所谓页读写就是全列读写,而且表20.1告诉我们,页读写必须将 A2~A0设置为3’b111。然而,Verilog的描述结果如代码20.1所示:
7: // Send LMR Cmd. Burst Read & Write, 3'b010 mean CAS latecy = 3, Sequential,Full Page
begin rCMD <= _LMR; rBA <= 2'b11; rA <= { 3'd0, 1'b0, 2'd0, 3'b011, 1'b0, 3'b111 }; i <= i + 1'b1; end
代码20.1
如果我们一页一页的叫,基本上“一页”的定义是非常暧昧的,因为“一页”所指定的范围会随着该存储器的容量而有所改变。举例HY57V2562GTR 这只SDRAM,地址的指定范围有 BA1~BA0,R12~R0,C8~C0,其中“一页”是全列,亦即C8~C0。根据计算,C8~C0等价29 = 512,或者说页读写有512的地址偏移量。
页写操作:

图20.1 页写操作的理想时序图。
图20.1是笔者自定义的页写操作的理想时序图,其中C1是为了控制读写的次数。页读写相较字读写,前者好比一只不会停下冲锋的山猪。一旦读写开始,SDRAM内部的计数器就会从0开始计数,计数结果为511又会从0重新计数。因为如此,页读写需要利用BSTP命令禁止山猪继续冲锋。
此外,自动预充对页读写来说是无效的东西,因此A10拉不拉高都没有关系,而且页写操作也不需要满足 TWR/TDPL与TPR。图20.1大致的时序过程如下:
l T1,发送ACT命令,BANK地址与行地址;
l T1半周期,SDRAM读取;
l T2,满足TRCD;
l T3,发送WR命令,BANK地址与列地址,还有第0数据;
l T3半周期,SDRAM读取
l T4,发送第1~511数据,然后发送BSTP命令结束页写。
Verilog则可以这样描述,结果如代码20.2所示:
1. 1: // Send Active Command with Bank and Row address
2. begin rCMD <= _ACT; rBA <= iAddr[23:22]; rA <= iAddr[21:9]; i <= i + 1'b1; end
3.
4. 2: // wait TRCD 20ns
5. if( C1 == TRCD -1 ) begin C1 <= 14'd0; i <= i + 1'b1; end
6. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; end
7.
8. 3: // Send Write command with row address
9. begin rCMD <= _WR; rBA <= iAddr[23:22]; rA <= { 4'b0010, iAddr[8:0] }; D1 <= iData; i <= i + 1'b1; end
10.
11. 4: // continue write until end and send BSTP
12. if( C1 == 512 -1 ) begin rCMD <= _BSTP; C1 <= 14'd0; i <= i + 1'b1 ;end
13. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; D1 <= D1 + 1'b1; end
代码20.2
如代码20.2所示,步骤3写第0数据,步骤4则写入第1~511数据并且发送 BSTP命令。
页读操作:

图20.2 页读操作的理想时序图。
图20.2也是笔者自定义的理想时序图。同样,页读操也是一只不断冲锋的山猪,因此它需要BSTP这支停下的告示牌。除此之外,页读也没有自行预充电的必要,而且TPR也不用满足。实验二十要实验的页读比较单纯,我们读取第0数据以后立即发送BSTP命令来结束也操作。图20.2大致的时序过程如下:
l T1,发送ACT命令,BANK地址与行地址;
l T1半周期,SDRAM读取;
l T2,满足TRCD;
l T3,发送RD命令,BANK地址与列地址;
l T3半周期,SDRAM读取命令。
l T4,满足 CAS Latency。
l T5,读取第0数据,然后发送BSTP命令。
Verilog则可以这样描述,结果如代码20.3所示:
1. 1: // Send Active command with Bank and Row address
2. begin rCMD <= _ACT; rBA <= iAddr[23:22]; rA <= iAddr[21:9]; i <= i + 1'b1; end
3.
4. 2: // wait TRCD 20ns
5. if( C1 == TRCD -1 ) begin C1 <= 14'd0; i <= i + 1'b1; end
6. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; end
7.
8. 3: // Send Read command and column address
9. begin rCMD <= _RD; rBA <= iAddr[23:22]; rA <= { 4'b0010, iAddr[8:0]}; i <= i + 1'b1; end
10.
11. 4: // wait CL 3 clock
12. if( C1 == CL -1 ) begin C1 <= 14'd0; i <= i + 1'b1; end
13. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; end
14.
15. 5: // Read Data
16. begin D1 <= S_DQ; rCMD <= _BSTP; i <= i + 1'b1; end
代码20.3
如代码20.3所示,步骤5读取数据以后立即发送 BSTP命令以示结束页读操作。理解完毕以后我们便可以开始建模了。

图20.3 SDRAM基础模块的建模图。
图20.3是SDRAM基础模块的建模图,外表上和实验十八差不多,不过SDRAM功能模块的内容却有一些改变。
sdram_funcmod.v
1. module sdram_funcmod
2. (
3. input CLOCK,
4. input RESET,
5.
6. output S_CKE, S_NCS, S_NRAS, S_NCAS, S_NWE,
7. output [1:0]S_BA,
8. output [12:0]S_A,
9. output [1:0]S_DQM,
10. inout [15:0]S_DQ,
11.
12. input [3:0]iCall,
13. output oDone,
14. input [23:0]iAddr, // [23:22]BA,[21:9]Row,[8:0]Column
15. input [15:0]iData,
16. output [15:0]oData
17. );
第3~16行是相关的输入端声明。
18. parameter T100US = 14'd13300;
19. // tRP 20ns, tRRC 63ns, tRCD 20ns, tMRD 2CLK, tWR/tDPL 2CLK, CAS Latency 3CLK
20. parameter TRP = 14'd3, TRRC = 14'd9, TMRD = 14'd2, TRCD = 14'd3, TWR = 14'd2, CL = 14'd3;
21. parameter _INIT = 5'b01111, _NOP = 5'b10111, _ACT = 5'b10011, _RD = 5'b10101, _WR = 5'b10100,
22. _BSTP = 5'b10110, _PR = 5'b10010, _AR = 5'b10001, _LMR = 5'b10000;
23.
第18~22行是相关的常量声明。
24. reg [4:0]i;
25. reg [13:0]C1;
26. reg [15:0]D1;
27. reg [4:0]rCMD;
28. reg [1:0]rBA;
29. reg [12:0]rA;
30. reg [1:0]rDQM;
31. reg isOut;
32. reg isDone;
33.
34. always @ ( posedge CLOCK or negedge RESET )
35. if( !RESET )
36. begin
37. i <= 4'd0;
38. C1 <= 14'd0;
39. D1 <= 16'd0;
40. rCMD <= _NOP;
41. rBA <= 2'b11;
42. rA <= 13'h1fff;
43. rDQM <= 2'b00;
44. isOut <= 1'b1;
45. isDone <= 1'b0;
46. end
第24~46行是相关的寄存器声明与复位操作。
47. else if( iCall[3] )
48. case( i )
49.
50. 0: // Set IO to output State
51. begin isOut <= 1'b1; i <= i + 1'b1; end
52.
53. 1: // Send Active Command with Bank and Row address
54. begin rCMD <= _ACT; rBA <= iAddr[23:22]; rA <= iAddr[21:9]; i <= i + 1'b1; end
55.
56. 2: // wait TRCD 20ns
57. if( C1 == TRCD -1 ) begin C1 <= 14'd0; i <= i + 1'b1; end
58. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; end
59.
60. /*********************************************/
61.
62. 3: // Send Write command with row address
63. begin rCMD <= _WR; rBA <= iAddr[23:22]; rA <= { 4'b0010, iAddr[8:0] }; D1 <= iData; i <= i + 1'b1; end
64.
65. 4: // continue write until end and send BSTP
66. if( C1 == 512 -1 ) begin rCMD <= _BSTP; C1 <= 14'd0; i <= i + 1'b1 ;end
67. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; D1 <= D1 + 1'b1; end
68.
69. /**********************************************/
70.
71. 5: // Generate done signal
72. begin rCMD <= _NOP; isDone <= 1'b1; i <= i + 1'b1; end
73.
74. 6:
75. begin isDone <= 1'b0; i <= 4'd0; end
76.
77. endcase
以上内容为页写操作,注意步骤3写入第0数据,步骤4则写入第1~511数据并且发送BSTP命令。
78. else if( iCall[2] )
79. case( i )
80.
81. 0:
82. begin isOut <= 1'b0; D1 <= 16'd0; i <= i + 1'b1; end
83.
84. 1: // Send Active command with Bank and Row address
85. begin rCMD <= _ACT; rBA <= iAddr[23:22]; rA <= iAddr[21:9]; i <= i + 1'b1; end
86.
87. 2: // wait TRCD 20ns
88. if( C1 == TRCD -1 ) begin C1 <= 14'd0; i <= i + 1'b1; end
89. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; end
90.
91. /********************/
92.
93. 3: // Send Read command and column address
94. begin rCMD <= _RD; rBA <= iAddr[23:22]; rA <= { 4'b0010, iAddr[8:0]}; i <= i + 1'b1; end
95.
96. 4: // wait CL 3 clock
97. if( C1 == CL -1 ) begin C1 <= 14'd0; i <= i + 1'b1; end
98. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; end
99.
100. /********************/
101.
102. 5: // Read Data
103. begin D1 <= S_DQ; rCMD <= _BSTP; i <= i + 1'b1; end
104.
105. /********************/
106.
107. 6: // Generate done signal
108. begin rCMD <= _NOP; isDone <= 1'b1; i <= i + 1'b1; end
109.
110. 7:
111. begin isDone <= 1'b0; i <= 4'd0; end
112.
113. endcase
以上内容为页读操作,注意步骤5是读取第0数据并且发送 BSTP命令。
114. else if( iCall[1] )
115. case( i )
116.
117. 0: // Send Precharge Command
118. begin rCMD <= _PR; i <= i + 1'b1; end
119.
120. 1: // wait TRP 20ns
121. if( C1 == TRP -1 ) begin C1 <= 14'd0; i <= i + 1'b1; end
122. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; end
123.
124. 2: // Send Auto Refresh Command
125. begin rCMD <= _AR; i <= i + 1'b1; end
126.
127. 3: // wait TRRC 63ns
128. if( C1 == TRRC -1 ) begin C1 <= 14'd0; i <= i + 1'b1; end
129. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; end
130.
131. 4: // Send Auto Refresh Command
132. begin rCMD <= _AR; i <= i + 1'b1; end
133.
134. 5: // wait TRRC 63ns
135. if( C1 == TRRC -1 ) begin C1 <= 14'd0; i <= i + 1'b1; end
136. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; end
137.
138. /********************/
139.
140. 6: // Generate done signal
141. begin isDone <= 1'b1; i <= i + 1'b1; end
142.
143. 7:
144. begin isDone <= 1'b0; i <= 4'd0; end
145.
146. endcase
以上内容是刷新操作。
147. else if( iCall[0] )
148. case( i )
149.
150. 0: // delay 100us
151. if( C1 == T100US -1 ) begin C1 <= 14'd0; i <= i + 1'b1; end
152. else begin C1 <= C1 + 1'b1; end
153.
154. /********************/
155.
156. 1: // Send Precharge Command
157. begin rCMD <= _PR; { rBA, rA } <= 15'h3fff; i <= i + 1'b1; end
158.
159. 2: // wait TRP 20ns
160. if( C1 == TRP -1 ) begin C1 <= 14'd0; i <= i + 1'b1; end
161. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; end
162.
163. 3: // Send Auto Refresh Command
164. begin rCMD <= _AR; i <= i + 1'b1; end
165.
166. 4: // wait TRRC 63ns
167. if( C1 == TRRC -1 ) begin C1 <= 14'd0; i <= i + 1'b1; end
168. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; end
169.
170. 5: // Send Auto Refresh Command
171. begin rCMD <= _AR; i <= i + 1'b1; end
172.
173. 6: // wait TRRC 63ns
174. if( C1 == TRRC -1 ) begin C1 <= 14'd0; i <= i + 1'b1; end
175. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; end
176.
177. /********************/
178.
179. 7: // Send LMR Cmd. Burst Read & Write, 3'b010 mean CAS latecy = 3, Sequential,Full Page
180. begin rCMD <= _LMR; rBA <= 2'b11; rA <= { 3'd0, 1'b0, 2'd0, 3'b011, 1'b0, 3'b111 }; i <= i + 1'b1; end
181.
182. 8: // Send 2 nop CLK for tMRD
183. if( C1 == TMRD -1 ) begin C1 <= 14'd0; i <= i + 1'b1; end
184. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; end
185.
186. /********************/
187.
188. 9: // Generate done signal
189. begin isDone <= 1'b1; i <= i + 1'b1; end
190.
191. 10:
192. begin isDone <= 1'b0; i <= 4'd0; end
193.
194. endcase
195.
以上内容是初始化,注意步骤7的Mode Register 内容,Busrt Length 为 3’b111。
196. assign { S_CKE, S_NCS, S_NRAS, S_NCAS, S_NWE } = rCMD;
197. assign { S_BA, S_A } = { rBA, rA };
198. assign S_DQM = rDQM;
199. assign S_DQ = isOut ? D1 : 16'hzzzz;
200. assign oDone = isDone;
201. assign oData = D1;
202.
203. endmodule
第196~201行是相关的输出驱动。
sdram_ctrlmod.v
该控制模块的内容与实验十八一致。
sdram_basemod.v
该组合模块的内容也与实验十八一致
sdram_demo.v

图20.4 实验二十的建模图。
图20.4是实验二十的建模图,外观上与实验十八一样,不过核心操作的内容却有所不同,具体内容我们还是来看代码吧。
1. module sdram_demo
2. (
3. input CLOCK,
4. input RESET,
5. output S_CLK,
6. output S_CKE, S_NCS, S_NRAS, S_NCAS, S_NWE,
7. output [12:0]S_A,
8. output [1:0]S_BA,
9. output [1:0]S_DQM,
10. inout [15:0]S_DQ,
11. output TXD
12. );
以上内容为相关的出入端声明。
13. wire CLOCK1,CLOCK2;
14.
15. pll_module U1
16. (
17. .inclk0 ( CLOCK ), // 50Mhz
18. .c0 ( CLOCK1 ), // 133Mhz -210 degree phase
19. .c1 ( CLOCK2 ) // 133Mhz
20. );
21.
以上内容为PLL模块的实例化。
22. wire [1:0]DoneU2;
23. wire [15:0]DataU2;
24.
25. sdram_basemod U2
26. (
27. .CLOCK( CLOCK1 ),
28. .RESET( RESET ),
29. .S_CKE( S_CKE ),
30. .S_NCS( S_NCS ),
31. .S_NRAS( S_NRAS ),
32. .S_NCAS( S_NCAS ),
33. .S_NWE( S_NWE ),
34. .S_A( S_A ),
35. .S_BA( S_BA ),
36. .S_DQM( S_DQM ),
37. .S_DQ( S_DQ ),
38. .iCall( isCall ),
39. .oDone( DoneU2 ),
40. .iAddr( D1 ),
41. .iData( D2 ),
42. .oData( DataU2 )
43. );
44.
以上内容为SDRAM基础模块的实例化。
45. parameter B115K2 = 11'd1157, TXFUNC = 6'd16;
46.
47. reg [5:0]i,Go;
48. reg [10:0]C1;
49. reg [23:0]D1;
50. reg [15:0]D2,D3;
51. reg [10:0]T;
52. reg [1:0]isCall;
53. reg rTXD;
54.
55. always @ ( posedge CLOCK1 or negedge RESET )
56. if( !RESET )
57. begin
58. i <= 6'd0;
59. Go <= 6'd0;
60. C1 <= 11'd0;
61. D1 <= 24'd0;
62. D2 <= 16'd0;
63. D3 <= 16'd0;
64. T <= 11'd0;
65. isCall <= 2'b00;
66. rTXD <= 1'b1;
67. end
68. else
以上内容为相关的寄存器声明还有复位操作。第45行是波特率还有伪函数入口的常量声明。
69. case( i )
70.
71. 0:
72. if( DoneU2[1] ) begin isCall[1] <= 1'b0; i <= i + 1'b1; end
73. else begin isCall[1] <= 1'b1; D1 <= 24'd0; D2 <= 16'hA000; end
74.
75. 1:
76. if( DoneU2[0] ) begin D3 <= DataU2; isCall[0] <= 1'b0; i <= i + 1'b1; end
77. else begin isCall[0] <= 1'b1; end
78.
79. 2:
80. begin T <= { 2'b11, D3[15:8], 1'b0 }; i <= TXFUNC; Go <= i + 1'b1; end
81.
82. 3:
83. begin T <= { 2'b11, D3[7:0], 1'b0 }; i <= TXFUNC; Go <= i + 1'b1; end
84.
85. 4:
86. if( D1 == 24'd511 ) i <= i + 1'b1;
87. else begin D1 <= D1 + 1'b1; i <= 6'd1; end
88.
89. 5:
90. i <= i;
91.
92. /******************************/
93.
以上内容为部分核心操作。步骤0将数据 16’hA×××从地址0写至地址511,其中×××会经由页写而自行递增。换句话说,数据16’hA000~16’hA1FF从地址0写至地址511。
步骤1则用来读取数据,步骤2~3将读出的数据一一发送出去。步骤4用来递增地址,从0~511,然后返回步骤1,直至人为页读结束。
94. 16,17,18,19,20,21,22,23,24,25,26:
95. if( C1 == B115K2 -1 ) begin C1 <= 11'd0; i <= i + 1'b1; end
96. else begin rTXD <= T[i - 16]; C1 <= C1 + 1'b1; end
97.
98. 27:
99. i <= Go;
100.
101. endcase
102.
103. assign S_CLK = CLOCK2;
104. assign TXD = rTXD;
105.
106. endmodule
以上内容为部分核心操作。步骤16~27是发送一帧数据的伪函数。第103~104行则是相关的输出驱动。综合完毕并且下载程序,如果串口调试软件出现数据 A000~A1FF表示实验成功。
【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验二十:SDRAM模块③ — 页读写 α的更多相关文章
- [黑金原创教程] FPGA那些事儿《设计篇 III》- 图像处理前夕·再续
简介 一本为入门图像处理的入门书,另外还教你徒手搭建平台(片上系统),内容请看目录. 注意 为了达到最好的实验的结果,请准备以下硬件. AX301开发板, OV7670摄像模块, VGA接口显示器, ...
- [黑金原创教程] FPGA那些事儿《设计篇 II》- 图像处理前夕·续
简介 一本为入门图像处理的入门书,另外还教你徒手搭建平台(片上系统),内容请看目录. 注意 为了达到最好的实验的结果,请准备以下硬件. AX301开发板, OV7670摄像模块, VGA接口显示器, ...
- [黑金原创教程] FPGA那些事儿《设计篇 I》- 图像处理前夕
简介 一本为入门图像处理的入门书,另外还教你徒手搭建平台(片上系统),内容请看目录. 注意 为了达到最好的实验的结果,请准备以下硬件. AX301开发板, OV7670摄像模块, VGA接口显示器, ...
- [黑金原创教程] FPGA那些事儿《数学篇》- CORDIC 算法
简介 一本为完善<设计篇>的书,教你CORDIC算法以及定点数等,内容请看目录. 贴士 这本教程难度略高,请先用<时序篇>垫底. 目录 Experiment 01:认识CORD ...
- 【黑金原创教程】【FPGA那些事儿-驱动篇I 】原创教程连载导读【连载完成,共二十九章】
前言: 无数昼夜的来回轮替以后,这本<驱动篇I>终于编辑完毕了,笔者真的感动到连鼻涕也流下来.所谓驱动就是认识硬件,还有前期建模.虽然<驱动篇I>的硬件都是我们熟悉的老友记,例 ...
- 【黑金原创教程】【FPGA那些事儿-驱动篇I 】连载导读
前言: 无数昼夜的来回轮替以后,这本<驱动篇I>终于编辑完毕了,笔者真的感动到连鼻涕也流下来.所谓驱动就是认识硬件,还有前期建模.虽然<驱动篇I>的硬件都是我们熟悉的老友记,例 ...
- 【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验二:按键模块① - 消抖
实验二:按键模块① - 消抖 按键消抖实验可谓是经典中的经典,按键消抖实验虽曾在<建模篇>出现过,而且还惹来一堆麻烦.事实上,笔者这是在刁难各位同学,好让对方的惯性思维短路一下,但是惨遭口 ...
- 【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验十八:SDRAM模块① — 单字读写
实验十八:SDRAM模块① — 单字读写 笔者与SDRAM有段不短的孽缘,它作为冤魂日夜不断纠缠笔者.笔者尝试过许多方法将其退散,不过屡试屡败的笔者,最终心情像橘子一样橙.<整合篇>之际, ...
- 【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验七:PS/2模块① — 键盘
实验七:PS/2模块① — 键盘 实验七依然也是熟烂的PS/2键盘.相较<建模篇>的PS/2键盘实验,实验七实除了实现基本的驱动以外,我们还要深入解PS/2时序,还有PS/2键盘的行为.不 ...
随机推荐
- jmm 和线程安全
Java的内存模型JMM Java的内存模型JMM(Java Memory Model)JMM主要是为了规定了线程和内存之间的一些关系.根据JMM的设计,系统存在一个主内存(Main Memory), ...
- 五步整理你的css文件
鉴于实在无法忍受那种写一句就换一行的css写法,有个项目中的一个css文件竟然高达6000多行,看着实在蛋疼,无实今天下定决心整理一下,在DW里可以用正则很好的进行替换,步骤如下: 一:\r => ...
- mysql 连接字符串 CONCAT
以前用SQL Server 连接字符串是用“+”,现在数据库用mysql,写个累加两个字段值SQL语句居然不支持"+",郁闷了半天在网上查下,才知道mysql里的+是数字相加的操作 ...
- mysql中,通过json_insert函数向json字段插入键值?json_insert函数的使用?
需求描述: 通过json_insert向json字段中插入值,在此进行实验,记录下. 操作过程: 1.查看已经有的包含json数据类型的表 mysql> select * from tab_js ...
- 从Python学习中得到的一点启发 - Java逆向索引ArrayList
看了几天Python,感觉记忆力不行了,很多东西记不住了.但是终归是得到了一点知识:重写一个ArrayList,允许从负值的索引得到指定的项.然后写一个得到斐波拉契数组的方法,这种方法要比递归调用的方 ...
- Spring踩坑记录
1. Spring properties配置项不能解析问题 本地部分配置文件迁到disconf,希望disconf的配置文件交由spring托管.这样的话,原有代码中引用配置的地方就不用变(还是用${ ...
- easyui datagrid 单元格编辑(cell editing)
demo中有row editing 项目中发现个cell editing,但是有bug,修改好了 主要实现功能:单击数据表格单元格,编辑单元格数据 js代码如下: $.extend($.fn.data ...
- 项目管理PMP输入输出ITTO联系记忆
综述九大领域 项目管理的输入输出非常难记,原因在于理解起来也经不去推敲,故整理一个联想记忆版本,通过联想把输入输出都串起来达到记忆的目的,既然是联想,里面的内容逻辑只是为了好记,并无正确与否,请大家原 ...
- MongoDB副本集的工作原理
在MongoDB副本集中,主节点负责处理客户端的读写请求,备份节点则负责映射主节点的数据. 备份节点的工作原理过程可以大致描述为,备份节点定期轮询主节点上的数据操作,然后对自己的数据副本进行这些操作, ...
- linux 端口占用情况
1,查看8010端口是否被占用 [root@cloud ~]# netstat -an|grep 8010 tcp 0 0 0.0.0.0:8010 0.0.0.0:* LISTEN 2,查看8010 ...