待办事项

  • 时钟频率高,取指周期长,远大于执行周期,如何处理?
  • 不可综合逻辑的处理

接上一篇
【计算机系统设计】实践笔记(2)数据通路构建:第一类R型指令分析(1)

8.2 ALU运算器

`timescale 1ns / 1ps
//
// Engineer:jht
// Create Date: 2020/11/14 22:30:23
// Module Name: ALU_1
//module ALU_1(// datainput [31:0] A,input [31:0] B,// controlinput [3:0] ALUop,output reg [31:0] ALUresult);// convert A and B to signed numbers
wire signed [31:0] A_signed = A;
wire signed [31:0] B_signed = B;always @(*)
begincase (ALUop)4'b0000:    // addbeginALUresult <= A + B;end4'b0001:    // addubeginALUresult <= A + B;end4'b0010:    // subbeginALUresult <= A - B;end4'b0011:    // sububeginALUresult <= A - B;end4'b0100:    // andbeginALUresult <= A & B;end4'b0101:    // orbeginALUresult <= A | B;end4'b0110:    // xorbeginALUresult <= A ^ B;end4'b0111:    // norbeginALUresult <= ~(A | B);end4'b1000:    // slt // note:********signed********//beginif(A_signed < B_signed)ALUresult <= 1;elseALUresult <= 0;end4'b1001:    // sltubeginif(A < B)ALUresult <= 1;elseALUresult <= 0;end4'b1010:    // sllvbeginALUresult <= A << B;end4'b1011:    // srlvbeginALUresult <= A >> B;end4'b1100:    // srav // note: ******signed*******//beginALUresult <= A_signed >>> B;enddefault:beginALUresult <= 0;endendcase
endendmodule

测试文件tb_ALU_1.v

`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2020/11/27 10:36:19
// Design Name:
// Module Name: tb_ALU_1
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module tb_ALU_1;// ALU_1 Inputs
reg   [31:0]  A                            = 0 ;
reg   [31:0]  B                            = 0 ;
reg   [3:0]  ALUop                         = 0 ;// ALU_1 Outputs
wire  [31:0]  ALUresult                    ;ALU_1  u_ALU_1 (.A                       ( A          [31:0] ),.B                       ( B          [31:0] ),.ALUop                   ( ALUop      [3:0]  ),.ALUresult               ( ALUresult  [31:0] ));initial
begin#10ALUop = 0;A = 1;B = 4;#10ALUop = 1;A = 1;B = 5;#10ALUop = 2;A = 4;B = 1;#10ALUop = 3;A = 4;B = 2;// and#10ALUop = 4;A = 32'b1001111;B = 32'b1001001;#10ALUop = 5;A = 32'b1001111;B = 32'b1001001;#10ALUop = 6;A = 32'b1001111;B = 32'b1001001;#10ALUop = 7;A = 32'b1001111;B = 32'b1001001;// slt#30ALUop = 8;A = -1;B = 3;#10ALUop = 9;A = -1;B = 3;#10ALUop = 9;A = 1;B = 3;// sllv#30ALUop = 10;A = 32'b1001111;B = 32'd4;#10ALUop = 11;A = 32'hABCDabcd;B = 32'd4;// srav#30ALUop = 12;A = 32'hABCDabcd;B = 32'd4;#40ALUop = 4'b1111;endendmodule

功能仿真成功!

8.2.1 注意事项:有无符号数的运算和比较

主要针对slt sltu srlv srav这几条指令中,涉及到的对有无符号数进行的操作。

原则:Verilog默认都是无符号数,需要显式地声明signed才能进行带符号数运算

  1. 对于slt sltu,前者是带符号数比较,后者是无符号数比较,只有当比较的值显式地声明为signed时候,slt使用比较运算符<才进行带符号比较,否则还是无符号比较。
  2. 对于srlv srav,主要是srav,对于带符号数,使用>>>首位生成1,通用应该显式地声明signed否则会与srlv指令没区别。

注意代码中的

// convert A and B to signed numbers
wire signed [31:0] A_signed = A;
wire signed [31:0] B_signed = B;

这是将无符号数声明为带符号数的方法。

8.3 Register Files 寄存器堆

reg_files.v

`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2020/11/14 22:31:09
// Design Name:
// Module Name: reg_files_1
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module reg_files_1(input clk,input rst_n,/*** read port 1 ***/input [4:0] rA,      // rs fieldoutput reg [31:0] A,/*** read port 2 ***/input [4:0] rB,      // rtoutput reg [31:0] B,/*** write port ***/input [4:0] rW,          // rd or rtinput [31:0] writeData,  // datainput RegWrite           // if RegWrite == 1,you can write data to reg files);// reg files
reg [31:0] register [0:31];
integer i;
initial
beginfor (i = 0;i < 32;i = i + 1)beginregister[i] <= 0;end
end/******* write operation *******/always @(posedge clk) // sequential logic
beginif(rst_n == 0)  // reset is invalidbeginif((RegWrite == 1'b1) && (rW != 5'b0))  // write is valid and address is not equal zerobeginregister[rW] <= writeData;endelse;endelse;
end/******* rA read operation *******/
always @(*) // combinational logic
beginif(rst_n == 1)beginA <= 32'b0;endelse if(rA == 5'b0)beginA <= 32'b0;endelsebeginA <= register[rA];end
end/******* rB read operation *******/
always @(*) // combinational logic
beginif(rst_n == 1)beginB <= 32'b0;endelse if(rB == 5'b0) // $zerobeginB <= 32'b0;endelsebeginB <= register[rB];end
endendmodule

测试文件tb_reg_files_1.v

`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2020/11/27 10:11:14
// Design Name:
// Module Name: tb_reg_files_1
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module tb_reg_files_1;// reg_files_1 Parameters
parameter PERIOD  = 10;// reg_files_1 Inputs
reg   clk                                  = 0 ;
reg   rst_n                                = 1 ;
reg   [4:0]  rA                            = 0 ;
reg   [4:0]  rB                            = 0 ;
reg   [4:0]  rW                            = 0 ;
reg   [31:0]  writeData                    = 0 ;
reg   RegWrite                             = 0 ;// reg_files_1 Outputs
wire  [31:0]  A                            ;
wire  [31:0]  B                            ;initial
beginforever#(PERIOD/2)  clk=~clk;
endinitial
begin#(PERIOD*2) rst_n  =  0;
endreg_files_1  u_reg_files_1 (.clk                     ( clk               ),.rst_n                   ( rst_n             ),.rA                      ( rA         [4:0]  ),.rB                      ( rB         [4:0]  ),.rW                      ( rW         [4:0]  ),.writeData               ( writeData  [31:0] ),.RegWrite                ( RegWrite          ),.A                       ( A          [31:0] ),.B                       ( B          [31:0] ));initial
begin#20RegWrite = 1;rW = 0;writeData = 32'hff;#10rW = 1;writeData = 32'hff;#10rA = 1;#10rB = 1;#10rA = 0;rB = 0;
endendmodule

初步功能仿真成功!

9 连接已有器件

9.1 增加ROM

使用IP核,参考东南大学计算机系统设计MOOC9.1节的做法。

9.2 将已有部件连接起来!

`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2020/11/27 11:41:34
// Design Name:
// Module Name: datapath_1
// Project Name:
// Target Devices:
// Tool Versions:
// Description: 仅仅实现了几个简单的R类指令的最简单的数据通路,不与外界交互
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module datapath_1(input clk,input rst_n);/******** PC ********/// pc_1 Outputs
wire  [31:0]  pcOld;pc_1  u_pc_1 (.clk                     ( clk     ),.rst_n                   ( rst_n   ),.pcNew                   ( pcOld   ), // pcNew = pcOld + 4; no selection.pcOld                   ( pcOld   ));/******** Instruction ROM ********/// blk_mem_gen_0 Inputs
wire  [13:0]  addra  = pcOld[15:2];// blk_mem_gen_0 Outputs // instructions
wire  [31:0]  instruction;blk_mem_gen_0  u_blk_mem_gen_0 (.clka                    ( clk    ),.addra                   ( addra   ),.douta                   ( instruction   ));/******** Reg Files ********/// reg_files_1 Inputs
wire   [4:0]  rA = instruction[25:21];
wire   [4:0]  rB = instruction[20:16];
wire   [4:0]  rW = instruction[15:11];
wire   [31:0]  writeData;
wire   RegWrite;// reg_files_1 Outputs
wire  [31:0]  A;
wire  [31:0]  B;reg_files_1  u_reg_files_1 (.clk                     ( clk         ),.rst_n                   ( rst_n       ),.rA                      ( rA          ),.rB                      ( rB          ),.rW                      ( rW          ),.writeData               ( writeData   ),.RegWrite                ( RegWrite    ),.A                       ( A           ),.B                       ( B           )
);/******** ALU ********/// ALU_1 Inputs
// wire   [31:0]  A;
// wire   [31:0]  B;
wire   [3:0]  ALUop;// ALU_1 Outputs
wire  [31:0]  ALUresult = writeData;ALU_1  u_ALU_1 (.A                       ( A           ),.B                       ( B           ),.ALUop                   ( ALUop       ),.ALUresult               ( ALUresult   )
);/******** controler ********/// control_1 Inputs
wire   [5:0]  op = instruction[31:26];
wire   [5:0]  func = instruction[5:0];// control_1 Outputs
// wire  RegWrite
// wire  [3:0]  ALUop;control_1  u_control_1 (.op                      ( op         ),.func                    ( func       ),.RegWrite                ( RegWrite   ),.ALUop                   ( ALUop      )
);endmodule

9.3 测试我们的数据通路

  1. 由于寄存器堆初始全是0,最开始又没有写入的指令,因此修改下以方便测试
// reg files
reg [31:0] register [0:31];
integer i;
initial
beginfor (i = 0;i < 32;i = i + 1)begin// 为了方便初步测试 ///register[i] <= i; end
end

注意赋值的是i而不是0了。

  1. 写入一些指令,测试我们的数据通路

测试文件如下

`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2020/11/27 12:12:14
// Design Name:
// Module Name: tb_datapath_1
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module tb_datapath_1;// datapath_1 Parameters
parameter PERIOD  = 10;// datapath_1 Inputs
reg   clk                                  = 0 ;
reg   rst_n                                = 1 ;// datapath_1 Outputsinitial
beginforever #(PERIOD/2)  clk=~clk;
endinitial
begin#(PERIOD*2) rst_n  =  0;
enddatapath_1  u_datapath_1 (.clk                     ( clk     ),.rst_n                   ( rst_n   )
);endmodule

RTL优化

测试指令如下


以上错误!因为一次性连接了太多器件,不符合单元测试原则,重新开始,重要的是,ROM的IP核没有测试!

9.4 构建取值模块

我们先把PC和ROM连接起来测试。

然后发现……很诡异,PC似乎对ROM不起作用?


这个IP核……居然有延迟??不是瞬间取得指令……需要等一个周期后,再等待上升沿,才能取指。也就是说,ROM的取指需要等待一个额外的时钟周期,这才是真实世界

9.5 插叙:带延迟的ROM

实际上,访存时间更长,取指比较慢,这个事实我们都知道,现在,我们真地面临这个问题了。

理想取指的时序图,与带一个时钟周期延迟的时序图,是不一样的!

在单周期CPU中

  • 理想瞬间取指,那么更新PC值需要是下降沿,而写寄存器堆需要是上升沿
  • 带一个时钟周期延迟的,就可以都是上升沿,因为取下一条指令的过程占一个时钟周期,此时CPU就讲当前指令执行完了,也就是取下一条指令和CPU执行当前指令,同步进行。

特别注意:默认值0的指令会比较诡异

在我们的设计中,pc默认是0,因此……0号地址的指令会被直接取出来,但是如果没有复位也是不能指令的,这个情况下,其实可以用nop指令(全是0)作为0号地址的指令。

9.6 完整数据通路的实现与测试

让我们返回看看。

datapath_1.v

`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2020/11/27 11:41:34
// Design Name:
// Module Name: datapath_1
// Project Name:
// Target Devices:
// Tool Versions:
// Description: 仅仅实现了几个简单的R类指令的最简单的数据通路,不与外界交互
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module datapath_1(input clk,input rst_n);/******** PC ********/// pc_1 Outputs
wire  [31:0]  pcOld;pc_1  u_pc_1 (.clk                     ( clk     ),.rst_n                   ( rst_n   ),.pcNew                   ( pcOld   ), // pcNew = pcOld + 4; no selection.pcOld                   ( pcOld   ));/******** Instruction ROM ********/// blk_mem_gen_0 Inputs
wire  [13:0]  addra  = pcOld[15:2];// blk_mem_gen_0 Outputs // instructions
wire  [31:0]  instruction;blk_mem_gen_0  u_blk_mem_gen_0 (.clka                    ( clk    ),.addra                   ( addra   ),.douta                   ( instruction   ));/******** Reg Files ********/// reg_files_1 Inputs
wire   [4:0]  rA = instruction[25:21];
wire   [4:0]  rB = instruction[20:16];
wire   [4:0]  rW = instruction[15:11];
wire   [31:0]  writeData;
wire   RegWrite;// reg_files_1 Outputs
wire  [31:0]  A;
wire  [31:0]  B;reg_files_1  u_reg_files_1 (.clk                     ( clk         ),.rst_n                   ( rst_n       ),.rA                      ( rA          ),.rB                      ( rB          ),.rW                      ( rW          ),.writeData               ( writeData   ),.RegWrite                ( RegWrite    ),.A                       ( A           ),.B                       ( B           ));/******** ALU ********/// ALU_1 Inputs
// wire   [31:0]  A;
// wire   [31:0]  B;
wire   [3:0]  ALUop;// ALU_1 Outputs
// wire  [31:0]  ALUresult = writeData;【】【为什么不能用?】ALU_1  u_ALU_1 (.A                       ( A           ),.B                       ( B           ),.ALUop                   ( ALUop       ),.ALUresult               ( writeData   ));/******** controler ********/// control_1 Inputs
wire   [5:0]  op = instruction[31:26];
wire   [5:0]  func = instruction[5:0];// control_1 Outputs
// wire  RegWrite
// wire  [3:0]  ALUop;control_1  u_control_1 (.op                      ( op         ),.func                    ( func       ),.RegWrite                ( RegWrite   ),.ALUop                   ( ALUop      ));endmodule

RTL优化

测试文件 tb_datapath_1.v

`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2020/11/27 12:12:14
// Design Name:
// Module Name: tb_datapath_1
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module tb_datapath_1;// datapath_1 Parameters
parameter PERIOD  = 10;// datapath_1 Inputs
reg   clk                                  = 0 ;
reg   rst_n                                = 1 ;// datapath_1 Outputsinitial
beginforever #(PERIOD/2)  clk=~clk;
endinitial
begin#(PERIOD*2) rst_n  =  0;
enddatapath_1  u_datapath_1 (.clk                     ( clk     ),.rst_n                   ( rst_n   )
);endmodule

仿真结果
测试指令

nop
add $1,$2,$3    # $1 = 2 + 3 = 5
addu $2,$4,$1   # $2 = 4 + 5 = 9
sub $4,$2,$1    # $4 = 9 - 5 = 4
subu $5,$4,$3   # $5 = 4 - 3 = 1and $6,$7,$8  # $6 = 0111 and 1000 = 0
or $7,$6,$8     # $7 = 0 or 1000 = 8
xor $7,$6,$8    # $7 = 0000 xor 1000 = 1000 = 8
nor $8,$7,$6    # $8 = not (1000 or 0) = 11111111111110111slt $10,$11,$12 # $10 = 11 < 12 = 1        # 应该用负数验证,以后再说
sltu $10,$12,$11    # $10 = 12 > 11 = 0sllv $12,$5,$13 # $12 = 1101 << 1 = 1101_0 = 1A    【注意此处的倒置问题! sllv rd,rt,rs】
srlv $12,$5,$13 # $12 = 1101 >> 1 = 110 = 6
srav $14,$5,$15 # $14 = 1111 >>> 1 = 111  = 7 应该用负数验证,以后再说

指令编码

00000000
00430820
00811021
00412022
00832823
00e83024
00c83825
00c83826
00e64027
016c502a
018b502b
01a56004
01a56006
01e57007

注意事项

  1. sllv srlv srav指令的使用方法是sllv rd,rt,rs它们的rs和rt与一般指令顺序不一样,是反着的,使用的时候需要注意
  2. 第一条指令使用nop是因为PC默认地址是0,此时ROM将会读出0号地址的指令,这里其实不写空指令也无妨
  3. 注意ROM指令读取延迟1个周期
  4. 此处有两个负数验证的指令,暂时没有验证,以后再说
  5. 敲重点!writeData与ALUresult的连接问题

10 惊人的事实:我们已经构建了完整的数据通路

你可能感到惊讶,但这就是事实,我们已经,构建好了一个CPU,并且它能够执行13条指令

这简直太酷了不是吗!难以想象……你可能会说?这……就完成了?是的没错,如果我们只需要13条指令的CPU,并且不需要与外界交互的话,真的已经完成了,当然……这个CPU没什么价值,不过后续我们会改进它的不是吗?这很有趣的!

我们会一步步地完成一个完整的CPU,最终变成五级流水线CPU,这简直太棒了!让我们一起加油!

来看看示意图,注意,只是示意图,pc的位宽并不是标准的32位而是8位,总之,这就是完整的数据通路了。
只不过这个CPU还不能与外界交互……但是,它的确能够执行指令了不是吗?后续我们慢慢改进就是了。

10.1 构建我们的第一个CPU

在上面我们已经运行测试过了,不再重复。

综合实现看下面:

实践笔记(2)插叙:综合与实现

10.2 值得优化的点

在有些时候,我们的指令没有准备好,但是Reg已经读取出去了,可能有隐患,我们可以给Reg Files加上读使能信号,但是本次不加了。

11 数据流建模传输问题:不止连线

数据流建模传输问题:赋值传输有方向

经验教训,RTL建模看不出来传输方向! 行为仿真很必要呀!

12 取指延迟

我们都知道,访存是很慢的(相比于CPU执行),在本次示例中,ROM取指,需要2个时钟周期,因此,我们的单周期CPU,更新PC和更新寄存器堆,都可以上升沿触发

PC也能够保存下一条指令的地址,在取下一条指令的同时当前指令也在执行,取完下一条指令,当前指令也执行完成了。

我们看时序图,从PC更新,到取得PC对应的指令,需要2个时钟周期


也就是说,向内存发出指令地址之后,需要两个时钟周期,指令才能被取得,在此期间,CPU内的指令还是原来的指令,该指令也已经在一个时钟周期执行完成,执行一条指令需要三个时钟周期

你可能疑惑,那pc每个时钟周期更新一次,两个时钟周期才能够取到指令,不会冲突吗?当然不会。想象一下高速公路的汽车! pc发出的时间不一样,是可以排队的,没关系的,不会超车插队,另外,数据变化需要时间的,暂时浅显理解即可。

13 疑惑点

当取指非常慢的时候,由应该如何处理?此时如果仍然每个周期PC + 4,但是10个周期(假设)才能取指,是否仍然可行?

我们试试,将周期改为2ns,也就是500MHz的时钟频率。

好吧……看起来没有问题,这个问题以后再解决。

500MHz都没问题了,那基本就没事了其实

开发板使用的100MHz,也就是时钟周期是10ns,足够满足本科阶段需求了,这个细节问题目前不需要关注,无伤大雅,应当先抓住主要矛盾。

【计算机系统设计】实践笔记(2)数据通路构建:第一类R型指令分析(2)相关推荐

  1. 【计算机系统设计】实践笔记(2)数据通路构建:第一类R型指令分析(1)

    0 回顾 上一次实践笔记(0)我们实现了一个最简单的,能够每个上升沿+4的PC. 我们最需要关注的就是器件功能的独立性,避免内外功能混杂,同时一定要注意脑中有电路(RTL级描述的抽象电路而不是实际的门 ...

  2. 【计算机系统设计】实践笔记(3)改进数据通路:移位R型指令分析

    0 回顾 前面的内容中,第一类R型指令分析,我们完成了一类R型指令的设计,完成了其数据通路,构建了相应的部件,并且完成了从ROM中取指,成功进行了基本的功能仿真,进行了综合和实现,但是没有完成综合和实 ...

  3. 【计算机系统设计】实践笔记(4)改进数据通路:第一类I型指令分析与实现

    0 回顾 之前,我们完成了17条R型指令的设计,接下来,我们逐步完成I型指令的设计. 1 核心思想:增量思维 & 复用思维 & 学会选择 & 分治思想 增量思维 我们从无到有, ...

  4. 计算机组成原理r型指令logisim实现_第一章 计算机体系结构

    需要掌握的内容: 存储程序计算机 计算机系统的多级层级结构 计算机体系结构 计算机组成 计算机实现 计算机体系结构.组成与实现三者的关系 存储程序计算机 透明性 Amdahl定律 CPU 性能公式 程 ...

  5. 计算机组成原理r型指令logisim实现_大学本科计算机科学与技术专业知识体系

    写这篇文章是因为今年我又担任了新生班主任,信息学院计算机科学与技术专业19级1班,也是我校今年录取分数最高的一个专业.今年正好是我教书20年,20年前我第一次担任班主任的情景还历历在目,如今9905班 ...

  6. 【Computer Organization笔记16】大实验任务详细说明:支持指令流水的计算机系统设计与实现

    本次笔记内容: P31 计算机组成原理(31) P32 计算机组成原理(32) 我的计组笔记汇总:计算机组原理成笔记 视频地址:计算机组成原理 清华大学刘卫东 全58讲 国家精品课程 1080P 更完 ...

  7. 计算机组成原理学习笔记第5章指令系统 5.6——MIPS指令详解

    有诗云:苔花如米小,也学牡丹开.--袁枚 本篇笔记整理:Code_流苏(CSDN) Last(在此处点击使用,直达文末) First (在文末点击使用,返回文章首部) 目录 0.思维导图 1.R型指令 ...

  8. 计算机组成原理——复习笔记

    计算机组成原理---复习笔记 第一章 系统结构中的8个伟大思想 面向摩尔定律的设计 使用抽象简化设计 加速大概率事件 通过并行提高性能 通过流水线提高性能 通过预测提高性能 存储器层次 通过冗余提高可 ...

  9. 南邮 计算机组成考试笔记

    一.计算机组成与性能的相关知识与计算 计算机五大组成部件 冯诺依曼体系 控制器,运算器,存储器,输入设备,输出设备 9个影响性能的指标 吞吐量: 表征一台计算机在某一时间间隔内能够处理的信息量,单位是 ...

最新文章

  1. 微信小程序换行,空格的写法
  2. 远程办公指南 | 齐心守护健康,共倡远程协同
  3. Android逆向分析工具ded的使用
  4. 人类首次商业太空行走敲定!马斯克SpaceX宣布新一轮太空旅行计划,美国富豪成回头客...
  5. PowerDesigner显示mysql数据表注释
  6. c#获取父类_C#——父类中的this的指向,及用反射获取当前类所在的Type | 学步园...
  7. python对笔记本电脑的要求-Python的用法笔记本
  8. 夏日清凉小风扇网站源码 抖音引流神器
  9. 动态分区分配算法代码_【代码】巩敦卫等TEVC论文:基于区间相似度分析的协同动态区间多目标进化优化算法...
  10. InfoPath: Passing Command Line parameters to a new form
  11. VS 2013 Chrome PPAPI 开发环境
  12. 如何写一个Linux精灵进程
  13. HDU5763 another meaning -(KMP+DP)
  14. JSOUP爬虫常见问题解决方法
  15. Windows10最常用的软件推荐V1.7
  16. 互联网晚报 | 1月10日 星期一 | 天猫年货节正式开启;哪吒汽车第10万台量产车下线;三星永久关闭Tizen应用商店...
  17. HashMap的put过程
  18. 一天、一个月、一年时间戳分别是多少?
  19. PHP 对银行卡,手机号,真实姓名,身份证进行掩码加星号处理
  20. 3D pose estimation 综述

热门文章

  1. Gson解析Json格式数据
  2. 如何利用C#编写网页投票器程序 如何使用代理来投票 代理IP来投票
  3. 产品经理的职责(转)
  4. 计算机科学研究生规划,2019计算机考研备考:计算机科学与技术研究方向及复习规划...
  5. android病毒下载地址,LINE病毒查杀
  6. logstash 吞吐量优化_1002-谈谈ELK日志分析平台的性能优化理念
  7. linux 自动安装mysql_Linux安装mysql
  8. Linux学习笔记——gzip命令
  9. py脚本:linux系统下定时清理文件
  10. JavaScript中的数组