写在前面:本博客为本人原创,严禁任何形式的转载!本博客只允许放在博客园(.cnblogs.com),如果您在其他网站看到这篇博文,请通过下面这个唯一的合法链接转到原文!

本博客全网唯一合法URL:http://www.cnblogs.com/acm-icpcer/p/9289857.html

(1)shift:

module shift (d,sa,right,arith,sh);
input [:] d;
input [:] sa;
input right,arith;
output [:] sh;
reg [:] sh;
always @* begin
if (!right) begin //shift left
sh = d << sa;
end else if (!arith) begin //shift right logical
sh = d >> sa;
end else begin //shift right arithmetic
sh = $signed(d) >>> sa;
end
end
endmodule

移位器,<<表示向左移,>>表示向右移,>>>表示无符号向右移,sa表示向右移的位数。因为做多移动32位,所以sa用5位寄存器表示。

图一

(2)scinstmem(图一左边蓝圈):

module scinstmem (a,inst);
input [:] a;
output [:] inst;
wire [:] rom [:];
assign rom['h00] = 32'h3c010000; // (00) main: lui r1,0
assign rom['h01] = 32'h34240050; // (04) ori r4,r1,80
assign rom['h02] = 32'h20050004; // (08) addi r5,r0, 4
assign rom['h03] = 32'h0c000018; // (0c) call: jal sum
assign rom['h04] = 32'hac820000; // (10) sw r2,0(r4)
assign rom['h05] = 32'h8c890000; // (14) lw r9, 0(r4)
assign rom['h06] = 32'h01244022; // (18) sub r8, r9. r4
assign rom['h07] = 32'h20050003; // (lc) addi r5, r0. 3
assign rom['h08] = 32'h20a5ffff; // (20) loop2: addi r5, r5, -1
assign rom['h09] = 32'h34a8ffff; // (24) ori r8, r5, 0xffff
assign rom['h0A] = 32'h39085555; // (28) xori r8. r8, 0x5555
assign rom['h0B] = 32'h2009ffff; // (2c) addi r9, rO, -1
assign rom['h0C] = 32'h312affff; // (30) andi rlO, r9, 0xffff
assign rom['h0D] = 32'h01493025; // (34) or r6. rlO, r9
assign rom['h0E] = 32'h01494026; // (38) xor r8, rlO, r9
assign rom['h0F] = 32'h01463824; // (3c) and r7, rlO, r6
assign rom['h10] = 32'h10a00001; // (40) beq r5, r0, shift
assign rom['h11] = 32'h08000008; // (44) j loop2
assign rom['h12] = 32'h2005ffff; // (48) shift: addi r5. r0, -1
assign rom['h13] = 32'h000543c0; // (4c) sll r8. r5. 15
assign rom['h14] = 32'h00084400; // (50) sll r8, r8, 16
assign rom['h15] = 32'h00084403; // (54) sra r8, r8, 16
assign rom['h16] = 32'h000843c2; // (58) srl r8. r8. 15
assign rom['h17] = 32'h08000017; // (5c) finish: j finish
assign rom['h18] = 32'h00004020; // (60) sum: add r8, r0, r0
assign rom['h19] = 32'h8c890000; // (64) loop: lw r9, (r4)
assign rom['h1A] = 32'h20840004; // (68) addi r4, r4, 4
assign rom['h1B] = 32'h01094020; // (6c) add r8, r8, r9
assign rom['h1C] = 32'h20a5ffff; // (70) addi r5, r5, -1
assign rom['h1D] = 32'h14a0fffb; // (74) bne rS, r0, loop
assign rom['h1E] = 32'h00081000; // (78) sll r2f r8f 0
assign rom['h1F] = 32'h03e00008; // (7c) jr r31
assign inst = rom[a[:]]; endmodule

只读指令存储器,用于存放存储的程序,用32个32位寄存器表示,每一个寄存器存储一条指令的机器语言格式(用8位16进制代码表示32位2进制代码,每一条机器指令后面的注释是它的汇编格式)。a用于存放本指令周期内寄存器pc的值,output用于存放即将要执行的寄存器pc所指向的指令所在的寄存器编号。这就是为什么要在最后加上代码:assign   inst = rom[a[6:2]];实际上,a[6:2]所代表的就是pc内容格式所表示的寄存器号码的字段。

(3)scdatamem(图一右边蓝圈):

module scdatamem (clk,dataout,datain,addr,we,inclk,outclk);
input [:] datain;
input [:] addr ;
input clk, we, inclk, outclk;
output [:] dataout;
reg [:] ram [:];
assign dataout =ram[addr[:]];
always @ (posedge clk) begin
if (we) ram[addr[:]] = datain;
end
integer i;
initial begin
for (i = ;i < ;i = i + )
ram[i] = ;
ram['h14] = 32'h000000a3;
ram['h15] = 32'h00000027;
ram['h16] = 32'h00000079;
ram['h17] = 32'h00000115;
end
endmodule

we表示写使能,由图一可知,此项信号由控制器负责译码传输过来,故而if (we) ram[addr[6:2]] = datain;表示当有写使能的,通过输入的addr数据的寄存器字段指定相应的32位寄存器,并将输入的数据datain写入数据存储器内的相应的ram部分。always @ (posedge clk) begin表示始终在上升沿的时候触发写ram。后面的:

initial begin

      for (i = 0;i < 32;i = i + 1)

           ram[i] = 0;

      ram[5'h14] = 32'h000000a3;

      ram[5'h15] = 32'h00000027;

      ram[5'h16] = 32'h00000079;

      ram[5'h17] = 32'h00000115;

end

与存储在指令存储器内的汇编源代码的具体意义相关,先不分析了。

(4)sccu_dataflow(控制器译码模块):

module sccu_dataflow (op,func,z,wmem,wreg,regrt,m2reg,aluc,shift,aluimm,pcsource,jal,sext);
input [:] op,func;
input z;
output wreg,regrt,jal,m2reg,shift,aluimm,sext,wmem;
output [:] aluc;
output [:] pcsource; wire r_type = ~|op; wire i_add = r_type&func[]&~func[]&~func[]&~func[]&~func[]&~func[];
wire i_sub = r_type&func[]&~func[]&~func[]&~func[]&func[]&~func[];
wire i_and = r_type&func[]&~func[]&~func[]&func[]&~func[]&~func[];
wire i_or = r_type&func[]&~func[]&~func[]&func[]&~func[]&func[];
wire i_xor = r_type&func[]&~func[]&~func[]&func[]&func[]&~func[];
wire i_sll = r_type&~func[]&~func[]&~func[]&~func[]&~func[]&~func[];
wire i_srl = r_type&~func[]&~func[]&~func[]&~func[]&func[]&~func[];
wire i_sra = r_type&~func[]&~func[]&~func[]&~func[]&func[]&func[];
wire i_jr = r_type&~func[]&~func[]&func[]&~func[]&~func[]&~func[];
wire i_addi = ~op[]&~op[]&op[]&~op[]&~op[]&~op[];
wire i_andi = ~op[]&~op[]&op[]&op[]&~op[]&~op[];
wire i_ori = ~op[]&~op[]&op[]&op[]&~op[]&op[];
wire i_xori = ~op[]&~op[]&op[]&op[]&op[]&~op[];
wire i_lw = op[]&~op[]&~op[]&~op[]&op[]&op[];
wire i_sw = op[]&~op[]&op[]&~op[]&op[]&op[];
wire i_beq = ~op[]&~op[]&~op[]&op[]&~op[]&~op[];
wire i_bne = ~op[]&~op[]&~op[]&op[]&~op[]&op[];
wire i_lui = ~op[]&~op[]&op[]&op[]&op[]&op[];
wire i_j = ~op[]&~op[]&~op[]&~op[]&op[]&~op[];
wire i_jal = ~op[]&~op[]&~op[]&~op[]&op[]&op[]; assign wreg = i_add|i_sub|i_and|i_or|i_xor|i_sll|i_srl|i_sra|i_addi|i_andi|i_ori|i_xori|i_lw|i_lui|i_jal;
assign regrt= i_addi|i_andi|i_ori|i_xori|i_lw|i_lui;
assign jal= i_jal;
assign m2reg= i_lw;
assign shift=i_sll|i_srl|i_sra;
assign aluimm=i_addi|i_andi|i_ori|i_xori|i_lw|i_lui|i_sw;
assign sext =i_addi|i_lw|i_sw|i_beq|i_bne;
assign aluc[]=i_sra;
assign aluc[]=i_sub|i_or|i_srl|i_sra|i_ori|i_lui;
assign aluc[]=i_xor|i_sll|i_sra|i_xori|i_beq|i_bne|i_lui;
assign aluc[]=i_and|i_or|i_sll|i_srl|i_sra|i_andi|i_ori;
assign wmem = i_sw;
assign pcsource[]=i_jr|i_j|i_jal;
assign pcsource[]=i_beq&z|i_bne&~z|i_j|i_jal;
endmodule

图二

此乃控制器译码部分。前面的20条wire语句对应于前面的mips指令集,其中的前10条是R型指令,其主要是先判断是否是R型,如果是,再通过最后面的function字段判断到底是哪一条R型指令;后面的10条wire语句就可以直接通过op字段判断出是哪一条MIPS指令。判断出是什么指令了就要进行译码,并输出控制信号,代码最后面的一堆assign就是干这个事情的。

图三

现在取出几条代码来说明assign语句如何工作的:

1)

assign wreg = i_add|i_sub|i_and|i_or|i_xor|i_sll|i_srl|i_sra|i_addi|i_andi|i_ori|i_xori|i_lw|i_lui|i_jal;表示当指令类型为等号后面的列出的那些类型中的任意一种时,就必定要输出对寄存器堆进行操作的使能信号。

2)

assign pcsource[1]=i_jr|i_j|i_jal;

assign pcsource[0]=i_beq&z|i_bne&~z|i_j|i_jal;

两条pcsource赋值语句用于告诉四选一选择器判断到底是用哪一条数据来源进行对pc值(下一条待执行的代码段地址)的修改。例如:如果当前指令是跳转指令时,那么就要通过读取寄存器对的内容或者

通过alu的计算来获得下一条指令的地址。

3)

assign aluc[3]=i_sra;

assign aluc[2]=i_sub|i_or|i_srl|i_sra|i_ori|i_lui;

assign aluc[1]=i_xor|i_sll|i_sra|i_xori|i_beq|i_bne|i_lui;

assign aluc[0]=i_and|i_or|i_sll|i_srl|i_sra|i_andi|i_ori;

如果当前的指令是要用到alu的指令时,就要判断具体要让alu进行说明操作,故而要产生一些传递给alu的控制信号。

其余的assign指令不赘述,思想大同小异。

(5)sccpu_dataflow:

module  sccpu_dataflow(clock, resetn, inst,mem,pc, wmem,alu,data);
input [:] inst,mem;
input clock,resetn;
output [:] pc,alu,data; output wmem;
wire [:] p4 , bpc, npc, adr, ra, alua, alub, res, alu_mem;
wire [:] aluc;
wire [:] reg_dest, wn;
wire [:] pcsource;
wire zero, wmem, wreg, regrt, m2reg, shift, aluimm, jal, sext;
wire [:] sa = {'b0,inst[10:6]};
wire [:] offset = {imm[:],inst[:],'b00};
sccu_dataflow cu (inst[:] , inst[:] , zero, wmem,wreg,regrt,m2reg, aluc, shift, aluimm,pcsource, jal, sext);
wire e = sext & inst[];
wire [:] imm = {{e}};
wire [:] immediate = {imm,inst[:]};
dff32 ip (npc,clock,resetn,pc);
cla32 pcplus4 (pc,'h4,1'b0,p4);
cla32 br_adr (p4,offset,'b0, adr);
wire [:] jpc = {p4[:],inst[:],'b00};
mux2x32 alu_b (data, immediate,aluimm, alub) ;
mux2x32 alu_a (ra,sa,shift,alua);
mux2x32 result (alu,mem,m2reg,alu_mem);
mux2x32 link (alu_mem,p4,jal,res);
mux2x5 reg_wn (inst[:], inst[: ] , regrt, reg_dest);
assign wn = reg_dest | {{jal}}; //ja1: r31 <-- p4;
mux4x32 nextpc (p4,adr,ra, jpc,pcsource,npc);
regfile rf (inst[:] ,inst[:] ,res,wn,wreg,clock,resetn,ra,data);
alu al_unit (alua,alub,aluc,alu, zero);
endmodule

这个就是描述图三中所有的部件,以及部件之间如何传递数据的关系的模块调用代码

(6)sccmop_dataflow:

module  sccomp_dataflow(clock, resetn, inst, pc, aluout, memout,mem_clk);
input clock, resetn,mem_clk;
output [:] inst,pc, aluout,memout;
wire [:] data;
wire wmem;
sccpu_dataflow s (clock, resetn, inst,memout,pc, wmem, aluout, data);
scinstmem imem (pc,inst);
scdatamem dmem (clock, memout, data, aluout, wmem, mem_clk, mem_clk);
endmodule

最顶层的控制模块,从代码结构可以看出其主要控制数据通路、存储好的程序和数据存储模块。

(7)regfile:

module regfile  (rna, rnb, d, wn,we, clk, clrn, qa, qb);
input [:] rna,rnb,wn;
input [:] d;
input we, clk, clrn;
output [:] qa,qb;
reg [:] register [:]; // 31 x 32-bit regs // 2 read ports
assign qa = (rna == ) ? : register[rna];
assign qb = (rnb == ) ? : register[rnb]; // 1 write port
always @(posedge clk or negedge clrn)
begin
if (clrn==)
begin
integer i;
for(i=;i<;i=i+)
register[i] <= ;
end
else if((wn!=)&&we)
register[wn] <= d;
end
endmodule

这个就是位于图三中心部分的是寄存器堆,前头部分主要是完成了对寄存器堆的定义,后面就是对寄存器堆读写的分别实现。

比如代码assign qa  =   (rna ==  0) ? 0 : register[rna]; 就表示读出ma所指定的寄存器中的值,并输出到qa输出口。

(8)mux4x32:

module mux4x32 (a0,a1,a2,a3,s,y);
input [:] a0,a1,a2,a3;
input [:] s;
output [:] y;
function [:] select;
input [:] a0,a1,a2,a3;
input [:] s;
case (s)
'b00: select = a0;
'b01: select = a1;
'b10: select = a2;
'b11: select = a3;
endcase
endfunction
assign y = select(a0,a1,a2,a3,s);
endmodule

四选一多路选择器,主要选择从输入的4个口中的具体选择哪一个口子数据输出。因为只有4个来源,所以只要使用两位的s来进行选择就行。代码功能就是从a1,a2,a3,a4中通过s选一个输出到y,s的内容一般由模块(4),也就是控制器译码模块决定。

(9)其余的选择器:

module mux2x5 (a0,a1,s,y);
input [:] a0,a1;
input s;
output [:] y;
assign y = s?a1:a0;
endmodule module mux2x32 (a0,a1,s,y);
input [:] a0,a1;
input s;
output [:] y;
assign y = s?a1:a0;
endmodule

功能与(8)中所述一致,但是比(8)的功能简单多了。一个是32位数据的的二选一选择器,一个是5位数据的二选一选择器。

(10)dff32(32位寄存器):

module dff32(d,clk,clrn,q);
input [:] d;
input clk,clrn;
output [:] q;
reg [:] q;
always @ (negedge clrn or posedge clk)
if (clrn == ) begin
q <= ;
end else begin
q <= d;
end
endmodule

普通32位寄存器的代码描述,当有清零信号来临时就清零,否则寄存器内就存入输入的32位数据q。

图四

(11)并行进位加法器(CLA)的实现:

module cla32 (a,b,ci,s,co);
input [:] a,b;
input ci;
output [:] s;
output co;
wire g_out,p_out;
cla_32 cla (a,b, ci,g_out,p_out, s);
assign co = g_out| p_out & ci;
endmodule module add(a,b,c,g,p,s);
input a,b,c;
output g,p,s;
assign s = a^b^c;
assign g = a & b;
assign p = a | b;
endmodule module g_p (g,p,c_in,g_out,p_out,c_out);
input [:] g,p;
input c_in;
output g_out, p_out, c_out;
assign g_out = g[]|p[] & g[];
assign p_out = p[] & p[];
assign c_out = g[] | p[] & c_in;
endmodule module cla_2 (a,b,c_in,g_out,p_out,s) ;
input [:] a,b;
input c_in;
output g_out, p_out;
output [:] s;
wire [:] g,p;
wire c_out;
add add0 (a[],b[],c_in, g[],p[],s[]);
add add1 (a[],b[],c_out, g[],p[],s[]);
g_p g_p0 (g,p,c_in, g_out,p_out,c_out);
endmodule module cla_4 (a,b, c_in,g_out,p_out,s);
input [:] a,b;
input c_in;
output g_out, p_out;
output [:] s;
wire [:] g,p;
wire c_out;
cla_2 cla0 (a[:],b[:],c_in, g[],p[],s[:]);
cla_2 clal (a[:],b[:],c_out,g[],p[],s[:]);
g_p g_p0 (g,p,c_in, g_out,p_out,c_out);
endmodule module cla_8 (a,b, c_in,g_out,p_out, s);
input [:] a,b;
input c_in;
output g_out, p_out;
output [:] s;
wire [:] g,p;
wire c_out;
cla_4 cla0 (a[:],b[:],c_in, g[],p[],s[:]);
cla_4 c1a1 (a[:],b[:],c_out,g[],p[],s[:]);
g_p g_p0 (g,p,c_in, g_out,p_out,c_out);
endmodule module cla_16 (a,b, c_in,g_out,p_out, s);
input [:] a,b;
input c_in;
output g_out, p_out;
output [:] s;
wire [:] g,p;
wire c_out;
cla_8 cla0 (a[:],b[:],c_in,g[],p[],s[:]);
cla_8 cla1 (a[:],b[:],c_out,g[],p[],s[:]);
g_p g_p0 (g,p,c_in, g_out,p_out,c_out);
endmodule module cla_32 (a,b,c_in,g_out,p_out, s);
input [:] a,b;
input c_in;
output g_out, p_out;
output [:] s;
wire [:] g,p;
wire c_out;
cla_16 c1a0 (a[:],b[:],c_in,g[],p[],s[:]);
cla_16 c1a1 (a[:],b[:],c_out,g[],p[],s[:]);
g_p g_p0 (g,p,c_in, g_out,p_out,c_out);
endmodule

这段代码使用并行进位加法技术,从最基本的加法进位模型add实现全加器cla_2,逐步集成为4位全加器cla_4、8位的全加器cla_8、16位全加器cla_16、32位全加器cla_32(详见南京大学袁春风老师的《计算机组成与系统结构(第二版)》清华出版社P72),其实这段代码逐步集成为32位全加器的过程一看就知道是递归实现的,因为代码结构都是一样的。

(12)alu(运算逻辑单元):

module alu (a,b,aluc,r,z);
input [:] a,b; // aluc[3:0]
input [:] aluc;
output [:] r; // x 0 0 0 ADD
output z; // x1 0 0 SUB
wire [:] d_and = a & b; // x 0 01 WD
wire [:] d_or = a | b; // x1 01 0R
wire [:] d_xor = a ^ b; // x 0 1 0 XOR
wire [:] d_lui = {b[:],'h0}; // x1 1 0 LUI
wire [:] d_and_or = aluc[]?d_or : d_and; // 0 01 1 SLL,
wire [:] d_xor_1ui= aluc[]?d_lui : d_xor; // 0 1 1 1 SRL
wire [:] d_as,d_sh; // 1 1 1 1 SRA
addsub32 as32 (a,b,aluc[],d_as);
shift shifter (b,a[:],aluc[],aluc[],d_sh) ;
mux4x32 se1ect (d_as,d_and_or, d_xor_1ui, d_sh, aluc[:],r);
assign z = ~|r;
endmodule

alu算术逻辑单元提供出来基础计算功能外的包括异或、按位与和按位或等逻辑计算功能。具体执行什么运算由4位aluc决定(最多能提供16种基础计算方式)。具体解释如下:

1)wire  [31:0]  d_and = a & b;这句代码提供按位与运算

2)wire  [31:0] d_or = a | b;这句代码提供按位或运算

3)wire  [31:0] d_xor = a ^ b;这句代码提供按位异或运算

4)wire  [31:0]  d_lui = {b[15:0],16'h0};高16位是所给数据b的低16位,低16位补0,两者拼接成32位数据

5)wire  [31:0]  d_and_or = aluc[2]?d_or : d_and;这句代码选择获取按位与还是按位或运算

6)wire  [31:0]  d_xor_1ui= aluc[2]?d_lui : d_xor; 这句代码与5)一致,目的在于选择运算结果

7)addsub32 as32(a,b,aluc[2],d_as);调用下面的(13)模块进行加或者减运算

8)shift shifter (b,a[4:0],aluc[2],aluc[3],d_sh) ;调用模块(1)进行左移或者右移

9)mux4x32 se1ect (d_as,d_and_or, d_xor_1ui, d_sh, aluc[1:0],r);四选一输出

(13)addsub32(32位加减运算模块):

module addsub32(a,b,sub,s);
input [:] a,b;
input sub;
output [:] s;
cla32 as32 (a,b^{{sub}},sub,s);
endmodule

addsub32模块提供了32位数据的加或者减计算功能。具体是加还是减运算取决于sub的取值。

tz@COI HZAU

2018/7/10

Verilog HDL语言实现的单周期CPU设计(全部代码及其注释)的更多相关文章

  1. 单周期CPU设计的理论基础

    写在前面:本博客内容为本人老师原创,严禁任何形式的转载!本博客只允许放在博客园(.cnblogs.com),如果您在其他网站看到这篇博文,请通过下面这个唯一的合法链接转到原文! 本博客全网唯一合法UR ...

  2. 单周期cpu设计代码解读

    目录 写在前面 单周期cpu设计代码讲解 概念回顾 Verilog代码讲解 写在前面 欢迎转载,转载请说明出处. 单周期cpu设计代码讲解 概念回顾 一.电子计算机的部件 分为:中央处理器(cpu). ...

  3. 单周期CPU设计

    终于有点时间了,恰好多周期的设计也已经完成,其实只想写写多周期的,无奈单周期补上才好,哈哈哈~ —————+—————黄金分割线—————+————— 首先要理解什么叫单周期CPU(与后面多周期CPU ...

  4. 使用Verilog搭建一个单周期CPU

    使用Verilog搭建一个单周期CPU 搭建篇 总体结构 其实跟使用logisim搭建CPU基本一致,甚至更简单,因为完全可以照着logisim的电路图来写,各个模块和模块间的连接在logisim中非 ...

  5. Verilog单周期CPU(未完待续)

    单周期CPU:指令周期=CPU周期 Top模块作为数据通路 运算器中有ALU,通路寄存器(R1.R2.R3.R4),数据缓冲寄存器(鉴于书上的运算器只有R0)........... 此为ALU和通用寄 ...

  6. P4-verilog实现mips单周期CPU

    最近对学习的掌控可能出现了问题,左支右绌,p2挂了,p2.p3.p4.p5每周在计组花的连续时间少了很多,学习到的东西也少了很多,流水线都还没真正开始写,和别人比落后了一大截,随笔自然就荒废了,我得尽 ...

  7. Vivado实战—单周期CPU指令分析

    引言   不知道你是否和我有过同样的感受,<计算机组成原理>这门学科学起来如此的艰难:一节课下来,教室黑板上留下了满满的 "足迹",看上去也挺简单的,不就是 0 和 1 ...

  8. 关于初次使用Verilog HDL语言需要懂的基本语法

    关于初次使用Verilog HDL语言需要懂的基本语法 1.常量 数字表达式全面的描述方式为:<位宽><进制><数字> 8’b10101100,表示位宽为8的二进制 ...

  9. 为什么现在使用多周期CPU,而单周期CPU被弃用?

    最初设计的CPU结构简单,内部不复杂.之所以制造它是为了让机器自动跑程序,算数. 早期CPU都是单周期的,人们没考虑那么多,性能啥的.就让CPU每个时钟周期跑一个指令,这些时钟周期等长.这样下来,有的 ...

随机推荐

  1. 老司机在zabbix上的一次翻车

    [前言] 自以为是zabbix的老司机了,没有想到今天翻车了! 一般人出错了都可以找到一个借口.我就不一样啦,我感觉我可以找两个1): 针对官方文档 给出的操作步骤没有经过深入的思考 2): 今天没有 ...

  2. input框触发回车事件

    window.event只能在IE下运行,不能在firefox下运行,这是因为firefox的event只能在事件发生的现场使用.   在firefox里直接调用event对象会报undefined. ...

  3. [svc]通过bridge连接单机的多个网络namespace

    ip操作物理网卡 参考: http://www.cnblogs.com/iiiiher/p/8056930.html - 查看mac/操作物理网卡 ip link - 查看ip/mac ip a - ...

  4. 【Netty】通俗地讲,Netty 能做什么?

    作者:郭无心链接:https://www.zhihu.com/question/24322387/answer/78947405来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...

  5. [Big Data - Kafka] Kafka设计解析(五):Kafka Benchmark

    性能测试及集群监控工具 Kafka提供了非常多有用的工具,如Kafka设计解析(三)- Kafka High Availability (下)中提到的运维类工具——Partition Reassign ...

  6. 15款基于 jQuery模态对话框

    在数字世界的竞争已大大增加.这就是为什么要确保网络设计的各个方面都是一流的,这是很重要的.从布局到一些非常小的东西,比如对话框,每一件都需要设计得很好.对话框通常被忽视,但它们可能对访问者有很大的影响 ...

  7. mxnet:基础知识和一个简单的示例

    NDArray与NumPy的多维数组类似,但NDArray提供了更多的功能:GPU和CPU的异步计算:自动求导.这使得NDArray能更好地支持机器学习. 初始化 from mxnet import ...

  8. ArcGIS Runtime SDK for iOS之符号和渲染

    符号定义了图形外观的非地理方面.它包括了图形的颜色.线宽.透明度等等.ArcGIS Runtime SDK for iOS包含了许多符号类,其中的每个类可以让你以独特的方式指定符号.每个符号的类型也是 ...

  9. 【九天教您南方cass 9.1】 14 坐标数据的纠正

    同学们大家好,欢迎收看由老王测量上班记出品的cass9.1视频课程 我是本节课主讲老师九天. 我们讲课的教程附件也是共享的,请注意索取 在测量空间中. 九天老师的联系方式  点击直接请教九天老师吧! ...

  10. windows server r2 安装vs2017 更新补丁Windows8.1-KB2919355-x6

    方法一: 点击vs2017安装包后提示需要更新Windows8.1-KB2919355-x64补丁 点击链接进入全部下载后查看官方安装顺序为 注意 必须按照以下顺序安装更新:clearcompress ...