verilog实现多周期处理器之——(五)移动操作(通用数据传送)指令的实现
本文参考作者
自己动手写CPU之第六阶段(1)——移动操作指令说明
自己动手写CPU之第六阶段(2)——移动操作指令实现思路
本文会添加笔者自己的思路以及理解在其中。
指令说明
这6条指令都是R类型指令,并且指令码都是6’b000000,即均为SPECIAL类指令,同时,指令第6-10bit都为0,可以依据指令中0-5bit功能码的值判断是哪一种指令。各指令的用法及作用说明如下。
当功能码为6’b001011时,表示是movn指令,不为零移动
指令用法为:movn rd, rs, rt
指令作用为:if rt ≠0 then rd <- rs,判断地址为rt的通用寄存器的值,如果不为零,那么将地址为rs的通用寄存器的值赋给地址为rd的通用寄存器,反之,保持地址为rd的通用寄存器不变。movn是Move Conditional on Not Zero的意思。当功能码为6’b001010时,表示是movz指令,为零移动
指令用法为:movz rd, rs, rt
指令作用为:if rt = 0 then rd <- rs,与上面movn指令的作用正好相反,判断地址为rt的通用寄存器的值,如果为零,那么将地址为rs的通用寄存器的值赋给地址为rd的通用寄存器,反之,保持地址为rd的通用寄存器不变。movz是Move Conditional on Zero的意思。当功能码为6’b010000时,表示是mfhi指令,赋值HI中的值给rd寄存器
指令用法为:mfhi rd
指令作用为:rd <- hi,将特殊寄存器HI的值赋给地址为rd的通用寄存器。当功能码为6’b010010时,表示是mflo
指令用法为:mflo rd
指令作用为:rd <- lo,将特殊寄存器LO的值赋给地址为rd的通用寄存器。当功能码为6’b010001时,表示是mthi指令
指令用法为:mthi rs
指令作用为:hi <- rs,将地址为rs的通用寄存器的值赋给特殊寄存器HI。当功能码为6’b010011时,表示是mtlo指令
指令用法为:mtlo rs
指令作用为:lo <- rs,将地址为rs的通用寄存器的值赋给特殊寄存器LO。
指令实现思路说明
本文牵扯到新的特殊寄存器HI,LO。将在原先的基础上添加。
分为三类,movn,movz第一类是不需要特殊寄存器的,直接类似于之前的指令,新加一个判断的功能决定是否写入寄存器。mflo,mfhi 第二类是需要读寄存器的, 设计在执行阶段
(1)在译码阶段依据指令,给出运算类型alusel_o、运算子类型aluop_o的值,同时因为有要写的目的寄存器,所以wreg_o为WriteEnable,wd_o为指令中rd的值,也就是目的寄存器地址。(2)在执行阶段获取HI或LO寄存器的值,作为要写入目的寄存器的数据,并将这些信息传递到访存阶段。(3)访存阶段将这些信息再传递到回写阶段。(4)回写阶段依据这些信息修改目的寄存器。
mthi、mtlo第三类指令需要写寄存器,他的实现思路如下
这2条指令需要写HI、LO寄存器,与之前实现的通用寄存器一样,对HI、LO寄存器的写操作放在回写阶段进行。(1)在译码阶段依据指令,给出运算类型alusel_o、运算子类型aluop_o的值,同时读出地址为rs的通用寄存器的值。由于mthi、mtlo不写通用寄存器,所以wreg_o为WriteDisable,wd_o为0。(2)在执行阶段确定要写HI、LO寄存器的情况,以及要写入的值,并将这些信息传递到访存阶段。(3)访存阶段将这些信息再传递到回写阶段。(4)回写阶段依据这些信息修改HI、LO寄存器的值。
这里进行的修改其实只是将数据在译码执行等阶段进行处理,根据指令不同,将原先要写入寄存器堆的数据写入新的寄存器即可。而读特殊寄存器的时候,是将寄存器中的数据读出来在写入通用寄存器,其实和从其他通用寄存器中读数据差别不是很大。下面是雷思磊;老师做的数据流图。
依据上边的分析以及图示,有了如下的修改。
增加了HILO寄存器模块,并且该模块放在回写阶段。
将HI、LO寄存器的值传递到执行阶段,在执行阶段增加了一个选择模块,用于选择要参与运算的数据,如果是mfhi、mflo指令,那么就会选择传递过来的HI、LO寄存器的值。
新的数据相关问题
进一步考虑mfhi、mflo指令的处理过程,这2条指令会在流水线执行阶段读取HI、LO寄存器的值,如果直接采用HILO模块给出的HI、LO寄存器的值,可能不是正确的HI、LO寄存器的值,因为此时处于访存、回写阶段的指令有可能会修改HI、LO寄存器,以如下程序为例。
1、 lui $1,0x0000 # $1 = 0x00000000
2、 lui $2,0xffff # $1 = 0xffff0000
3、 mthi $0 # hi = 0x00000000
4、 mthi $1 # hi = 0x00000000
5、 mthi $2 # hi = 0xffff0000
6、 mfhi $4 # $4 = 0xffff0000
指令3、4、5均要修改HI寄存器,当指令6处于执行阶段时,指令5处于访存阶段,指令4处于回写阶段,而此时HI寄存器的值是指令3刚刚写入的0x00000000,HILO模块正是将该值传到执行阶段,如果采用这个值,那么就会出错,偏离程序设想,正确的值应该是当前处于访存阶段的指令5要写的数据,如图所示。
似曾相识,是不是?这就是上一章介绍过的数据相关问题,解决措施还是使用数据前推。将处于访存阶段、回写阶段的指令对HI、LO寄存器的操作信息反馈到执行阶段,执行阶段依据这些信息,确定HI、LO寄存器的正确值。为此,需要修改数据流图如图6-4所示,相比图6-3,主要增加的部分就是将访存阶段、回写阶段的信息反馈到执行阶段,输入到执行阶段的选择模块(图中粗线所示),如果处于执行阶段的是mfhi、mflo指令,那么就会从中选择HI、LO寄存器的正确值。
对系统的修改
修改代码思路与说明
HI,LO寄存器的实现
`timescale 1ns / 1ps
`include "defines.v"
module hilo_reg(input wire clk ,input wire rst , //write portsinput wire we ,input wire [`RegBus] hi_i ,input wire [`RegBus] lo_i ,//read portsoutput reg [`RegBus] hi_o ,output reg [`RegBus] lo_o );
always @ (posedge clk )
beginif(rst == `RstEnable)beginhi_o <= `ZeroWord ;lo_o <= `ZeroWord ;endelse if(we == `WriteEnable)beginhi_o <= hi_i ;lo_o <= lo_i ;end
end
endmodule
译码阶段
添加代码即可,这里只需要进行译码即可
case(op)`EXE_SPECIAL_INST :begincase(op2) 5'b0000_0:begincase(op3)......`EXE_MFHI:beginwreg_o <= `WriteEnable;aluop_o <= `EXE_MFHI_OP;alusel_o <= `EXE_RES_MOVE;reg1_read_o <= 1'b0;reg2_read_o <= 1'b0;instvalid <= `InstValid;end`EXE_MFLO:beginwreg_o <= `WriteEnable;aluop_o <= `EXE_MFLO_OP;alusel_o <= `EXE_RES_MOVE;reg1_read_o <= 1'b0;reg2_read_o <= 1'b0;instvalid <= `InstValid;end`EXE_MTHI:beginwreg_o <= `WriteDisable;aluop_o <= `EXE_MTHI_OP;reg1_read_o <= 1'b1;reg2_read_o <= 1'b0;instvalid <= `InstValid;end`EXE_MTLO:beginwreg_o <= `WriteDisable;aluop_o <= `EXE_MTLO_OP;reg1_read_o <= 1'b1;reg2_read_o <= 1'b0;instvalid <= `InstValid;end`EXE_MOVN:beginaluop_o <= `EXE_MOVN_OP;alusel_o <= `EXE_RES_MOVE;reg1_read_o <= 1'b1;reg2_read_o <= 1'b1;instvalid <= `InstValid;if(reg2_o != `ZeroWord)wreg_o <= `WriteEnable;else wreg_o <= `WriteDisable;end`EXE_MOVZ:beginaluop_o <= `EXE_MOVZ_OP;alusel_o <= `EXE_RES_MOVE;reg1_read_o <= 1'b1;reg2_read_o <= 1'b1;instvalid <= `InstValid;if(reg2_o == `ZeroWord)wreg_o <= `WriteEnable;else wreg_o <= `WriteDisable;enddefault:beginendendcaseenddefault:beginendendcaseend
endcase
执行阶段
这里修改比较大,后期注释
`timescale 1ns / 1ps
`include "defines.v"
module ex(input wire rst ,//译码送至执行阶段的数据信息input wire [`AluOpBus] aluop_i ,input wire [`AluSelBus] alusel_i ,input wire [`RegBus] reg1_i ,input wire [`RegBus] reg2_i ,input wire [`RegAddrBus] wd_i ,input wire wreg_i ,//执行结果output reg [`RegAddrBus] wd_o ,output reg wreg_o ,output reg [`RegBus] wdata_o ,//HILO模块给出的HI,LO寄存器的值input wire [`RegBus] hi_i ,input wire [`RegBus] lo_i ,//回写阶段的指令是否要写HI,LO,用于检测HI,LO寄存器带来的数据相关问题input wire [`RegBus] wb_hi_i ,input wire [`RegBus] wb_lo_i ,input wire wb_whilo_i ,//访存阶段的指令是否要写HI,LO,用于检测HI,LO寄存器带来的数据相关问题input wire [`RegBus] mem_hi_i ,input wire [`RegBus] mem_lo_i ,input wire mem_whilo_i ,//处于执行阶段的指令对HI,LO寄存器的写操作请求output reg [`RegBus] hi_o ,output reg [`RegBus] lo_o ,output reg whilo_o );
//保存逻辑运算的结果
reg [`RegBus] logicout ;//保存位移运算结果
reg [`RegBus] shiftres ;// 移动操作的结果
reg [`RegBus] moveres ;// 保存HI寄存器的最新值
reg [`RegBus] HI ;// 保存LO寄存器的最新值
reg [`RegBus] LO ;
/*********************************************************************************
*************** 依据aluop_i指示的运算子类型进行运算,
*********************************************************************************/always @ (*)
beginif( rst == `RstEnable)logicout <= `ZeroWord;else begincase(aluop_i)`EXE_OR_OP:beginlogicout <= reg1_i | reg2_i;end`EXE_AND_OP:beginlogicout <= reg1_i & reg2_i;end`EXE_NOR_OP: //逻辑或与非beginlogicout <= ~(reg1_i | reg2_i);end`EXE_XOR_OP:beginlogicout <= reg1_i ^ reg2_i;enddefault:logicout <= `ZeroWord;endcaseend
endalways @ (*)
beginif(rst == `RstEnable)shiftres <= `ZeroWord;else case(aluop_i)`EXE_SLL_OP: //逻辑左移shiftres <= reg2_i << reg1_i[4:0];`EXE_SRL_OP:shiftres <= reg2_i >> reg1_i[4:0];`EXE_SRA_OP:shiftres <= ( {32{ reg2_i[31]} } << (6'd32 - {1'b0,reg1_i[4:0] } ) ) | reg2_i >> reg1_i[4:0];default:beginshiftres <= `ZeroWord;end endcase
end/*********************************************************************************
*************** 第一阶段,得到最新的HI,LO寄存器的值,此处要解决数据相关问题
*********************************************************************************/
always @ (*)
beginif(rst == `RstEnable){HI,LO} <= {`ZeroWord,`ZeroWord};else if(mem_whilo_i == `WriteEnable){HI,LO} <= {mem_hi_i,mem_lo_i}; //访存阶段的指令要写入HI,LO寄存器中elseif(wb_whilo_i == `WriteEnable) {HI,LO} <= {wb_hi_i,wb_lo_i}; //回写阶段的指令要写入HI,LO寄存器中else{HI,LO} <= {hi_i,lo_i};
end
/*********************************************************************************
*************** 第二阶段,MFHI,MFLO,MOVE,MOVZ指令
*********************************************************************************/
always @ (*)
beginif(rst == `RstEnable)moveres <= `ZeroWord; else begin moveres <= `ZeroWord;case(aluop_i)`EXE_MFHI_OP:moveres <= HI; //如果是MFHI指令,HI的值就会作为移动操作的结果`EXE_MFLO_OP:moveres <= LO; //如果是MFLO指令,LO的值就会作为移动操作的结果 `EXE_MOVZ_OP:moveres <= reg1_i; //如果是MOVZ指令,reg1_i的值就会作为移动操作的结果 `EXE_MOVN_OP:moveres <= reg1_i; //如果是MOVN指令,reg1_i的值就会作为移动操作的结果 default:;endcaseend
end
/*********************************************************************************
*************** 第三阶段:依据alusel_i指示的运算类型,确定wdata_o的值
*********************************************************************************/always @ (*)
beginwd_o <= wd_i; //wd_o等于wd_i,要写入的寄存器地址wreg_o <= wreg_i; //wreg_o等于wreg_i,表示是否要写入目的寄存器case(alusel_i)`EXE_RES_LOGIC:beginwdata_o <= logicout; //wdata_o中存放逻辑运算运算结果end`EXE_RES_SHIFT:beginwdata_o <= shiftres; //wdata_o中存放位移运算运算结果end`EXE_RES_MOVE:beginwdata_o <= moveres; //指令为EXE_RES_MOVEenddefault:wdata_o <= `ZeroWord;endcase
end
/*********************************************************************************
********* 第四阶段:如果是MTHI,MTLO指令,那么需要给出的whilo_o,hi_o,lo_i的值
*********************************************************************************/
always @ (*)
beginif(rst == `RstEnable)beginwhilo_o <= `WriteDisable;hi_o <= `ZeroWord;lo_o <= `ZeroWord; end else if(aluop_i == `EXE_MTHI_OP) beginwhilo_o <= `WriteEnable;hi_o <= reg1_i;lo_o <= LO;endelse if(aluop_i == `EXE_MTLO_OP) beginwhilo_o <= `WriteEnable ;hi_o <= HI;lo_o <= reg1_i;endelse beginwhilo_o <= `WriteDisable ;hi_o <= `ZeroWord;lo_o <= `ZeroWord;end
end
endmodule
之后就是连线以及顶层了。这里给出顶层。
顶层例化代码
其实这里的例化也是有一定的技巧的,首先笔者发现,这里所有的数据传输,因此数据传输模块需要进行端口声明。具体的写法如下,其次就是组合逻辑之间的特殊联系,这里只有译码阶段与通用寄存器之间的连线。
`timescale 1ns / 1ps
`include "defines.v"
module openmips(input wire clk ,input wire rst , input wire [`RegBus] rom_data_i ,output wire [`RegBus] rom_addr_o ,output wire rom_ce_o );
//连接IF/ID模块间的连线与译码器ID模块之间的变量
wire [`InstAddrBus] pc ;
wire [`InstAddrBus] id_pc_i ;
wire [`InstBus] id_inst_i ;//连接译码阶段ID模块输出与ID/EX模块的输入变量
wire [`AluOpBus] id_aluop_o ;
wire [`AluSelBus] id_alusel_o ;
wire [`RegBus] id_reg1_o ;
wire [`RegBus] id_reg2_o ;
wire [`RegAddrBus] id_wd_o ;
wire id_wreg_o ;//连接EX与EX/MEM之间的连线
wire [`RegAddrBus] ex_wd_o ;
wire ex_wreg_o ;
wire [`RegBus] ex_wdata_o ;
wire [`RegBus] ex_hi_o ;
wire [`RegBus] ex_lo_o ;
wire ex_whilo_o ; //连接EXM与输出之间的连线
wire [`RegAddrBus] mem_wd_i ;
wire mem_wreg_i ;
wire [`RegBus] mem_wdata_i ;
wire [`RegBus] mem_hi_i ;
wire [`RegBus] mem_lo_i ;
wire mem_whilo_i ;//连接MEM_wb与回写阶段(寄存器堆)的输入变量
wire [`RegAddrBus] wb_wd_i ;
wire wb_wreg_i ;
wire [`RegBus] wb_wdata_i ;//连接ID与寄存器regfile之间的连线
wire [`RegBus] reg1_data ;
wire [`RegBus] reg2_data ;
wire reg1_read ;
wire reg2_read ;
wire [`RegAddrBus] reg1_addr ;
wire [`RegAddrBus] reg2_addr ;//ID/EX 与EX之间的联系
wire [`AluOpBus] ex_aluop_i ;
wire [`AluSelBus] ex_alusel_i ;
wire [`RegBus] ex_reg1_i ;
wire [`RegBus] ex_reg2_i ;
wire [`RegAddrBus] ex_wd_i ;
wire ex_wreg_i ;//MEM访存与回写阶段的连线,MEM与MEM_WB
wire [`RegAddrBus] mem_wb_o ;
wire mem_wreg_o ;
wire [`RegBus] mem_wdata_o ;
wire [`RegBus] mem_hi_o ;
wire [`RegBus] mem_lo_o ;
wire mem_whilo_o ;
//lilo模块寄存器的来连线,写寄存器
wire hilo_we ;
wire [`RegBus] hilo_hi_i ;
wire [`RegBus] hilo_lo_i ;
//执行阶段的读寄存器,HILO模块送出去的信息
wire [`RegBus] hilo_hi_o ;
wire [`RegBus] hilo_lo_o ;
pc_reg pc_reg0 (.clk (clk ), .rst (rst ), .pc (pc ), .ce (rom_ce_o ));
assign rom_addr_o = pc ; //指令寄存器的输入地址就是pc的值if_id if_id0 (.clk (clk ), .rst (rst ), .if_pc (pc ), .if_inst (rom_data_i ), .id_pc (id_pc_i ), .id_inst (id_inst_i ));id id0 (.rst (rst ), //与模块if_id之间的连线.pc_i (id_pc_i ), .inst_i (id_inst_i ), //来自regfile模块的输入.reg1_data_i(reg1_data ), .reg2_data_i(reg2_data ), .reg1_read_o(reg1_read ), .reg2_read_o(reg2_read ), .reg1_addr_o(reg1_addr ), .reg2_addr_o(reg2_addr ),// 与ID/EX模块的连线.aluop_o (id_aluop_o ), .alusel_o (id_alusel_o), .reg1_o (id_reg1_o ), .reg2_o (id_reg2_o ), .wd_o (id_wd_o ), .wreg_o (id_wreg_o ),//与执行阶段的连线.ex_wd_i (ex_wd_o ),.ex_wreg_i (ex_wreg_o ),.ex_wdata_i (ex_wdata_o ),//与访存阶段的连线.mem_wd_i (mem_wb_o ),.mem_wreg_i (mem_wreg_o ),.mem_wdata_i(mem_wdata_o));regfile regfile0 (.clk (clk ), .rst (rst ), //与mem_wb之间的连线.we (wb_wreg_i ), .waddr (wb_wd_i ), .wdata (wb_wdata_i ), //与ID之间的连线.re1 (reg1_read ), .re2 (reg2_read ), .raddr1 (reg1_addr ), .rdata1 (reg1_data ), .raddr2 (reg2_addr ), .rdata2 (reg2_data ));id_ex id_ex0 (.clk (clk ), .rst (rst ), //与id之间的连线.id_aluop (id_aluop_o ), .id_alusel (id_alusel_o), .id_reg1 (id_reg1_o ), .id_reg2 (id_reg2_o ), .id_wd (id_wd_o ), .id_wreg (id_wreg_o ), //与ex之间的连线.ex_aluop (ex_aluop_i ), .ex_alusel (ex_alusel_i), .ex_reg1 (ex_reg1_i ), .ex_reg2 (ex_reg2_i ), .ex_wd (ex_wd_i ), .ex_wreg (ex_wreg_i ));ex ex0 (.rst (rst ), //与id_ex之间的连线.aluop_i (ex_aluop_i ), .alusel_i (ex_alusel_i), .reg1_i (ex_reg1_i ), .reg2_i (ex_reg2_i ), .wd_i (ex_wd_i ), .wreg_i (ex_wreg_i ), //与HILO寄存器模块的连线.从HILO读出的数据.hi_i (hilo_hi_o ),.lo_i (hilo_lo_o ),//引入mem_wb的数据.wb_hi_i (hilo_hi_i ),.wb_lo_i (hilo_lo_i ),.wb_whilo_i (hilo_we ),//引入的mem数据.mem_hi_i (mem_hi_i ),.mem_lo_i (mem_lo_i ),.mem_whilo_i(mem_whilo_i),//与ex/mem之间的连线.wd_o (ex_wd_o ), .wreg_o (ex_wreg_o ), .wdata_o (ex_wdata_o ),.hi_o (ex_hi_o ),.lo_o (ex_lo_o ),.whilo_o (ex_whilo_o ));ex_mem ex_mem0 (.clk (clk ), .rst (rst ), //与EX之间的连线.ex_wd (ex_wd_o ), .ex_wreg (ex_wreg_o ), .ex_wdata (ex_wdata_o ),.ex_hi (ex_hi_o ),.ex_lo (ex_lo_o ),.ex_whilo (ex_whilo_o ), //与MEM之间的连线.mem_wd (mem_wd_i ), .mem_wreg (mem_wreg_i ), .mem_wdata (mem_wdata_i),.mem_hi (mem_hi_i ), .mem_lo (mem_lo_i ), .mem_whilo (mem_whilo_i));mem mem0 (.rst (rst ),//与ex_mem之间的连线.wd_i (mem_wd_i ), .wreg_i (mem_wreg_i ), .wdata_i (mem_wdata_i), .hi_i (mem_hi_i ),.lo_i (mem_lo_i ),.whilo_i (mem_whilo_i), //与mem_wb之间的连线.wd_o (mem_wb_o ), //要写入的目的寄存器地址 .wreg_o (mem_wreg_o ), //是否要写入目的寄存器.wdata_o (mem_wdata_o), //要写入的数据.hi_o (mem_hi_o ), .lo_o (mem_lo_o ), .whilo_o (mem_whilo_o) );mem_wb mem_wb (.clk (clk ), .rst (rst ),//与mem之间的连线.mem_wb (mem_wb_o ), .mem_wreg (mem_wreg_o ), .mem_wdata (mem_wdata_o),.mem_hi_i (mem_hi_o ),.mem_lo_i (mem_lo_o ),.mem_whilo_i(mem_whilo_o), //送到回写的信息.wb_wd (wb_wd_i ), .wb_wreg (wb_wreg_i ), .wb_wdata (wb_wdata_i ),//送到Hilo模块的信息数据.wb_hi_o (hilo_hi_i ),.wb_lo_o (hilo_lo_i ),.wb_whilo_o (hilo_we ));hilo_reg hilo_reg0 (.clk (clk ), .rst (rst ), .we (hilo_we ), .hi_i (hilo_hi_i ), .lo_i (hilo_lo_i ), .hi_o (hilo_hi_o ), .lo_o (hilo_lo_o ));endmodule
其余阶段的连线在书中自己参阅,这里不一一给出。至此即可实现移动该操作。
测试验证
下面是笔者的测试,符合预期。验证成功。
verilog实现多周期处理器之——(五)移动操作(通用数据传送)指令的实现相关推荐
- verilog实现多周期处理器之——(三)数据相关问题及其解决
本文于自己动手写CPU之第五阶段--流水线数据相关问题 "相关"问题 流水线中常常有一些被称为"相关"的情况发生,它使得指令序列中下一条指令无法依照设计的时钟周 ...
- verilog实现多周期处理器之——(二)第一条指令ori的实现
本博文希望对于OpenMIPS第一条指令ori加以实现并总结.会加入一些基本的理论以及博主的学习记录. 流水与五级流水 什么是流水:拆分,并行.将多条指令的执行相互重叠起来.就构成了流水,这样充分利用 ...
- verilog实现多周期处理器之——目录及总述
本系列博文将使用verilog语言,实现兼容MIPS32指令集架构的处理器--OpenMIPS,MIPS是典型的RSIC处理器.主要依据雷思磊老师的<自己动手写CPU>,袁春风老师主编的& ...
- verilog实现多周期处理器之——(一)基本概念以及总体框架
本系列博文将使用verilog语言,实现兼容MIPS32指令集架构的处理器--OpenMIPS,MIPS是典型的RSIC处理器.本系列博文参考雷思磊老师的<自己动手写CPU>,袁春风老师主 ...
- verilog实现多周期处理器之——(四)逻辑,移位操作与空指令的添加
逻辑,移位操作与空指令的添加 综述 ID模块的修改 EX模块的修改 仿真验证 I-型指令 lui ori andi xori xor&nor R-型指令 or and 移位类指令 sll sr ...
- verilog实现多周期处理器之——(六)简单算数操作指令的实现
实现的指令说明 这里解释有符号扩展与无符号扩展,有符号数扩展符号位.也就是1,无符号数扩展0.也就是在前面补满零或1 R-型指令 加减比较指令 add.addu.sub.sub.slt.sltu 这6 ...
- verilog实现多周期处理器之——(零)GUN工具链的安装
参考雷思磊老师得<自己动手写CPU> 这里不需要下载书中说的虚拟机,这里笔者用的是VMware.不需要破解,直接安装点击选择仅用于非商业即可使用!! 安装Ubuntu这里笔者不给出步骤. ...
- Docker系列 五.Docker容器数据卷
五.Docker容器数据卷 环境&工具: 阿里云轻量级服务器.CentOS 7系统.FinalShell(其他连接客户端也可以) 是什么 docker的理念将运行的环境打包形成容器运行,运行可 ...
- 实验五 oracle高级数据查询技术
实验五 oracle高级数据查询技术 实验目的: 一.掌握日期型数据的操作技术 二.掌握层次查询技术 三.理解情景查询与翻译查询技术 四.了解统计查询技术 实验内容: 一.日期型数据的操作 ...
最新文章
- 点分治问题 ----------- P2993 [FJOI2014]最短路径树问题 [最短路径树+点分治+采坑]
- 使用jQuery的attr方法来修改onclick值
- Android JNI 报错(signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr )
- centos升级之内核kernel
- 谈谈C#中的三个关键词new , virtual , override(装载 Winner.Net)
- decimalformat精度丢失_php intval 两位小数乘以100后结果少1
- 计算机二级学那个科目,考计算机二级选哪个科目好 哪个科目简单
- leetcode题解191-位1的个数
- vscode中控制台不能输入_vscode调试时如何在控制台输入
- c++构造函数分类说明
- Win10怎么把登录密码去掉
- 联想服务器光驱安装win7系统,联想光盘安装win7系统教程
- [ thanos源码分析系列 ]thanos sidecar组件源码简析
- 力科(Lecroy)示波器专用波形文件(轨迹文件/trace文件/.trc文件)在MATLAB上的解析与回写
- 截止2017年5月19日小虎软考粉丝有798人
- 了解软件工程与计算机科学的联系与区别
- WARNING: You will need re2c 0.13.4 or later if you want to regenerate PHP parsers
- Elasticsearch 搜索条件与聚合结果再进行过滤的多重聚合查询-过滤桶的使用(六)
- python微信交流群,零基础、入门、大牛都可加入!
- 可以把将日文汉字转换成平假名、片假名、罗马音的KaKaSi