写在前面

欢迎转载,转载请说明出处。

单周期cpu设计代码讲解

概念回顾

一、电子计算机的部件

分为:中央处理器(cpu)、内部存储器(Memory)、输入/输出(I/O)设备,以及连接它们的总线(Bus)。下图为图示,注意色块的区分。

二、cpu

又包括控制器(Controller)和数据通路(Data Path)。下图为图示,注意色块区分。

三、控制器

分为主控(Main Control)和局控(Local Control或ALU Control)。将二进制指令输入控制器,生成控制信号,该过程称为译码。控制信号控制数据通路工作。且不同的指定对应不同的控制信号。

下图为在控制器中译码的逻辑示意图:

下图为在控制器中译码的物理示意图:

讲解一下从逻辑图到物理图的转换:

  1. 首先由主控解析op指令,如果发现该指令为“000000”则表示该指令是R指令,输出中间信号R-Type为1,否则为0;如果发现该指令是其他值,则按照逻辑图,为RegDst等信号赋相应的值;
  2. 中间信号R-Type起到二路选择的作用,如图。
  3. 中间信号ALUop,在R-Type为0(选择0路)时,直接通过局控,输出成为ALUctr信号,对应上面逻辑图的最后一行后5列;在R-Type为1时,局控起作用。
  4. 局控解析R指令的func部分,输出对应指令的ALUctr信号。

四、数据通路:

是包括运算器、寄存器组、存储器(高速缓存)、多路选择器等等在内的元件的有结构的组合。如下图所示:

【数据通路各部分的讲解将结合代码完成】

Verilog代码讲解

在代码讲解之前有必要放几张图:

shift.v

/*移位*/
/*输入一个数,返回移位之后的结果*/
/*输入d(待移的数)、sa(移动的位数)、right(移动方向)、arith(空位补全方式)*/
/*输出sh(移位后的结果)*/
module shift (d,sa,right,arith,sh);
input [31:0] d;
input [4:0] sa;
input right,arith;
output [31:0] sh;
reg [31:0] sh; // 组合逻辑
always @* begin
if (!right) begin // right为逻辑0时,左移
sh = d << sa;
end else if (!arith) begin // right为逻辑1,且arith为逻辑0时,右移、0补空
sh = d >> sa;
end else begin // 右移、1补空
sh = $signed(d) >>> sa;
end
end
endmodule

scinstmem.v

/*从ROM(只读存储器)读数据*/
/*输入目标数据在ROM中的地址a*/
/*输出地址对应的数据inst*/
module scinstmem (a,inst);
input [31:0] a;
output [31:0] inst;
wire [31:0] rom [0:31]; // 定义32个32位的存储器ROM // 想ROM中写入一组指令,指令对应的汇编含义见行注释
assign rom[5'h00] = 32'h3c010000; // (00) main: lui r1,0
assign rom[5'h01] = 32'h34240050; // (04) ori r4,r1,80
assign rom[5'h02] = 32'h20050004; // (08) addi r5,r0, 4
assign rom[5'h03] = 32'h0c000018; // (0c)call: jal sum
assign rom[5'h04] = 32'hac820000; // (10) sw r2,0(r4)
assign rom[5'h05] = 32'h8c890000; // (14) lw r9, 0(r4)
assign rom[5'h06] = 32'h01244022; // (18) sub r8, r9. r4
assign rom[5'h07] = 32'h20050003; // (lc) addi r5, r0. 3
assign rom[5'h08] = 32'h20a5ffff; // (20) loop2: addi r5, r5, -1
assign rom[5'h09] = 32'h34a8ffff; // (24) ori r8, r5, 0xffff
assign rom[5'h0A] = 32'h39085555; // (28) xori r8. r8, 0x5555
assign rom[5'h0B] = 32'h2009ffff; // (2c) addi r9, rO, -1
assign rom[5'h0C] = 32'h312affff; // (30) andi rlO, r9, 0xffff
assign rom[5'h0D] = 32'h01493025; // (34) or r6. rlO, r9
assign rom[5'h0E] = 32'h01494026; // (38) xor r8, rlO, r9
assign rom[5'h0F] = 32'h01463824; // (3c) and r7, rlO, r6
assign rom[5'h10] = 32'h10a00001; // (40) beq r5, r0, shift
assign rom[5'h11] = 32'h08000008; // (44) j loop2
assign rom[5'h12] = 32'h2005ffff; // (48) shift: addi r5. r0, -1
assign rom[5'h13] = 32'h000543c0; // (4c) sll r8. r5. 15
assign rom[5'h14] = 32'h00084400; // (50) sll r8, r8, 16
assign rom[5'h15] = 32'h00084403; // (54) sra r8, r8, 16
assign rom[5'h16] = 32'h000843c2; // (58) srl r8. r8. 15
assign rom[5'h17] = 32'h08000017; // (5c) finish: j finish
assign rom[5'h18] = 32'h00004020; // (60) sum: add r8, r0, r0
assign rom[5'h19] = 32'h8c890000; // (64) loop: lw r9, (r4)
assign rom[5'h1A] = 32'h20840004; // (68) addi r4, r4, 4
assign rom[5'h1B] = 32'h01094020; // (6c) add r8, r8, r9
assign rom[5'h1C] = 32'h20a5ffff; // (70) addi r5, r5, -1
assign rom[5'h1D] = 32'h14a0fffb; // (74) bne rS, r0, loop
assign rom[5'h1E] = 32'h00081000; // (78) sll r2f r8f 0
assign rom[5'h1F] = 32'h03e00008; // (7c) jr r31 // 将地址对应的数据放入inst
assign inst = rom[a[6:2]]; endmodule

scdatamem.v

/*将数据写入RAM中(随机存取存储器)的指定位置*/
/*输入待写数据datain、目标地址addr;写使能信号we;时钟信号clk、inclk、outclk*/
/*输出将被覆盖的数据dataout*/
module scdatamem (clk,dataout,datain,addr,we,inclk,outclk);
input [31:0] datain;
input [31:0] addr ;
input clk, we, inclk, outclk;
output [31:0] dataout;
reg [31:0] ram [0:31]; // 定义32个32位RAM
// 把将被覆盖的数据放入dataout
assign dataout =ram[addr[6:2]];
// 时序逻辑,clk的上升沿触发
always @ (posedge clk) begin
if (we) ram[addr[6:2]] = datain; // 如果写使能信号we为1,将数据写入目标地址
end
// 为RAM赋值,这一步不是必要的,只是欲运行的自定义程序的需要。
integer i;
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
endmodule

sccu_dataflow.v

/*基于MIPS指令集的控制器*/
/*输入指令的op字段、func字段、z信号*/
/*输出wreg,regrt,aluc,pcsource等等控制信号*/
module sccu_dataflow (op,func,z,wmem,wreg,regrt,m2reg,aluc,shift,aluimm,pcsource,jal,sext);
input [5:0] op,func;
input z;
output wreg,regrt,jal,m2reg,shift,aluimm,sext,wmem;
output [3:0] aluc;
output [1:0] pcsource; // 确定内部信号r_type的值
wire r_type = ~|op; // 如果r_type为真,根据func,确定是哪一种R型指令
wire i_add = r_type&func[5]&~func[4]&~func[3]&~func[2]&~func[1]&~func[0];
wire i_sub = r_type&func[5]&~func[4]&~func[3]&~func[2]&func[1]&~func[0];
wire i_and = r_type&func[5]&~func[4]&~func[3]&func[2]&~func[1]&~func[0];
wire i_or = r_type&func[5]&~func[4]&~func[3]&func[2]&~func[1]&func[0];
wire i_xor = r_type&func[5]&~func[4]&~func[3]&func[2]&func[1]&~func[0];
wire i_sll = r_type&~func[5]&~func[4]&~func[3]&~func[2]&~func[1]&~func[0];
wire i_srl = r_type&~func[5]&~func[4]&~func[3]&~func[2]&func[1]&~func[0];
wire i_sra = r_type&~func[5]&~func[4]&~func[3]&~func[2]&func[1]&func[0];
wire i_jr = r_type&~func[5]&~func[4]&func[3]&~func[2]&~func[1]&~func[0];
// 如果r_type为假,根据op,确定是哪一种指令
wire i_addi = ~op[5]&~op[4]&op[3]&~op[2]&~op[1]&~op[0];
wire i_andi = ~op[5]&~op[4]&op[3]&op[2]&~op[1]&~op[0];
wire i_ori = ~op[5]&~op[4]&op[3]&op[2]&~op[1]&op[0];
wire i_xori = ~op[5]&~op[4]&op[3]&op[2]&op[1]&~op[0];
wire i_lw = op[5]&~op[4]&~op[3]&~op[2]&op[1]&op[0];
wire i_sw = op[5]&~op[4]&op[3]&~op[2]&op[1]&op[0];
wire i_beq = ~op[5]&~op[4]&~op[3]&op[2]&~op[1]&~op[0];
wire i_bne = ~op[5]&~op[4]&~op[3]&op[2]&~op[1]&op[0];
wire i_lui = ~op[5]&~op[4]&op[3]&op[2]&op[1]&op[0];
wire i_j = ~op[5]&~op[4]&~op[3]&~op[2]&op[1]&~op[0];
wire i_jal = ~op[5]&~op[4]&~op[3]&~op[2]&op[1]&op[0]; // 在确定了指令的情况下,确定控制信号的取值
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[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;
assign wmem = i_sw;
assign pcsource[1]=i_jr|i_j|i_jal;
assign pcsource[0]=i_beq&z|i_bne&~z|i_j|i_jal;
endmodule

mux2x32.v

/*32位二路选择器*/
/*输入决定选择哪一路的控制信号s,输入待选择的信号a0、a1*/
/*输出被选择的信号y*/
module mux2x32 (a0,a1,s,y);
input [31:0] a0,a1;
input s;
output [31:0] y;
assign y = s?a1:a0; // 如果s为1,选择a1,否则选择a0
endmodule

mux2x5.v

/*5位二路选择器*/
/*逻辑同上*/
module mux2x5 (a0,a1,s,y);
input [4:0] a0,a1;
input s;
output [4:0] y;
assign y = s?a1:a0;
endmodule

mux4x32.v

/*32位四路选择器*/
/*待选择的数是a0~a3,控制信号为s,选择结果为y*/
/*s如何控制,由case语句决定*/
module mux4x32 (a0,a1,a2,a3,s,y);
input [31:0] a0,a1,a2,a3;
input [1:0] s;
output [31:0] y;
function [31:0] select;
input [31:0] a0,a1,a2,a3;
input [1:0] s; case (s)
2'b00: select = a0; //s为00时,选择a0
2'b01: select = a1;
2'b10: select = a2;
2'b11: select = a3;
endcase
endfunction
assign y = select(a0,a1,a2,a3,s); // y为选择的结果
endmodule

dff32.v

/*将数据送入指定寄存器*/
/*输入待存数据d,待存寄存器q;时钟clk和clrn*/
/*没有输出*/
module dff32(d,clk,clrn,q);
input [31:0] d;
input clk,clrn;
output [31:0] q;
reg [31:0] q;
/*时序逻辑,clk的上升沿降沿触发、clrn的下降沿触发*/
always @ (negedge clrn or posedge clk)
// clrn是清零时钟
if (clrn == 0) begin // 当清零时钟到来时
q <= 0; // 为q赋值0
end else begin
q <= d; // 否则赋值d
end
endmodule

cla32.v

/*下面所有程序都是为了实现一个东东:32位并行加法器*/
/*从最基本的加法进位模型add实现全加器cla_2,
逐步集成为4位全加器cla_4、8位的全加器cla_8、
16位全加器cla_16、32位全加器cla_32,
最终实现32位并行加法器cla32
*/ /*加数是a、b,和是s*/
/*借位是ci,进位是co*/
module cla32 (a,b,ci,s,co);
input [31:0] a,b;
input ci;
output [31:0] 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 [1:0] g,p;
input c_in;
output g_out, p_out, c_out;
assign g_out = g[1]|p[1] & g[0];
assign p_out = p[1] & p[0];
assign c_out = g[0] | p[0] & c_in;
endmodule module cla_2 (a,b,c_in,g_out,p_out,s) ;
input [1:0] a,b;
input c_in;
output g_out, p_out;
output [1:0] s;
wire [1:0] g,p;
wire c_out;
add add0 (a[0],b[0],c_in, g[0],p[0],s[0]);
add add1 (a[1],b[1],c_out, g[1],p[1],s[1]);
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 [3:0] a,b;
input c_in;
output g_out, p_out;
output [3:0] s;
wire [1:0] g,p;
wire c_out;
cla_2 cla0 (a[1:0],b[1:0],c_in, g[0],p[0],s[1:0]);
cla_2 clal (a[3:2],b[3:2],c_out,g[1],p[1],s[3:2]);
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 [7:0] a,b;
input c_in;
output g_out, p_out;
output [7:0] s;
wire [1:0] g,p;
wire c_out;
cla_4 cla0 (a[3:0],b[3:0],c_in, g[0],p[0],s[3:0]);
cla_4 c1a1 (a[7:4],b[7:4],c_out,g[1],p[1],s[7:4]);
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 [15:0] a,b;
input c_in;
output g_out, p_out;
output [15:0] s;
wire [1:0] g,p;
wire c_out;
cla_8 cla0 (a[7:0],b[7:0],c_in,g[0],p[0],s[7:0]);
cla_8 cla1 (a[15:8],b[15:8],c_out,g[1],p[1],s[15:8]);
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 [31:0] a,b;
input c_in;
output g_out, p_out;
output [31:0] s;
wire [1:0] g,p;
wire c_out;
cla_16 c1a0 (a[15:0],b[15:0],c_in,g[0],p[0],s[15:0]);
cla_16 c1a1 (a[31:16],b[31:16],c_out,g[1],p[1],s[31:16]);
g_p g_p0 (g,p,c_in, g_out,p_out,c_out);
endmodule

addsub32.v

/*32位加减运算模块*/
/*调用32位加法模块*/
/*是加是减,取决于sub的取值*/
module addsub32(a,b,sub,s);
input [31:0] a,b;
input sub;
output [31:0] s;
cla32 as32 (a,b^{32{sub}},sub,s);
endmodule

alu.v

/*alu算数逻辑单元*/
/*输入操作数a、b,操作类型信号aluc*/
/*输出运算结果r;z是?*/
module alu (a,b,aluc,r,z);
input [31:0] a,b;
// aluc是3位的,每一位都有作用,见下
input [3:0] aluc;
output [31:0] r;
output z;
wire [31:0] d_and = a & b; // 求和
wire [31:0] d_or = a | b; // 求或
wire [31:0] d_xor = a ^ b; // 求异或
wire [31:0] d_lui = {b[15:0],16'h0}; // 拼接,低16位补0 wire [31:0] d_and_or = aluc[2]? d_or : d_and; // aluc[2]决定 与/或
wire [31:0] d_xor_1ui= aluc[2]? d_lui : d_xor; // aluc[2]决定 异或/拼接 wire [31:0] d_as,d_sh; // 加减法结果保存到d_as中;移位结果存入d_sh中
// aluc[2]控制加减法
addsub32 as32 (a,b,aluc[2],d_as);
// b为待移的数,a[4:0]为移动位数,aluc[2]决定左右移,aluc[3]决定补全方式,结果保存在d_sh中
shift shifter (b,a[4:0],aluc[2],aluc[3],d_sh) ; // 四路选择,aluc[1:0]控制选择哪一路,r为选择结果
mux4x32 se1ect (d_as,d_and_or, d_xor_1ui, d_sh, aluc[1:0],r);
assign z = ~|r;
endmodule

regfile.v

/*读寄存器堆、写寄存器堆*/
/*输入将要读取哪一个寄存器rna、rnb;输出读出的内容qa、qb*/
/*输入写使能we、待写入的寄存器wn,待写入的数据d*/
/*输入时钟clk、clrn*/
module regfile (rna, rnb, d, wn,we, clk, clrn, qa, qb);
input [4:0] rna,rnb,wn;
input [31:0] d;
input we, clk, clrn;
output [31:0] qa,qb;
reg [31:0] register [1:31]; // 定义32个32位寄存器 // 读寄存器
// 如果指定的是rna,即rna不为0,将rna寄存器中的内容放入qa
assign qa = (rna == 0) ? 0 : register[rna];
// 如果指定的是rnb,即rnb不为0,将rnb寄存器中的内容放入qb
assign qb = (rnb == 0) ? 0 : register[rnb]; // 写寄存器
// 时序逻辑,clk的上升沿或clrn的下降沿触发
always @(posedge clk or negedge clrn)
begin
if (clrn==0) // 当为清空时钟信号时
begin
integer i;
for(i=1;i<32;i=i+1)
register[i] <= 0; // 清空所有寄存器
end
else if((wn!=0)&&we) // 当写使能为逻辑1,且wn不是0时
register[wn] <= d; // 将d写入wn寄存器
end
endmodule

sccpu_dataflow.v

/*cpu*/
/*输入时钟信号clock、是否进行清零的信号resetn*/
/*输入32位指令inst、以及其他值*/
module sccpu_dataflow(clock, resetn, inst, mem, pc, wmem, alu, data);
input [31:0] inst,mem;
input clock, resetn;
output [31:0] pc,alu,data; output wmem;
wire [31:0] p4 , bpc, npc, adr, ra, alua, alub, res, alu_mem;
wire [3:0] aluc;
wire [4:0] reg_dest, wn;
wire [1:0] pcsource;
wire zero, wmem, wreg, regrt, m2reg, shift, aluimm, jal, sext;
wire [31:0] sa = {27'b0,inst[10:6]};
wire [31:0] offset = {imm[13:0],inst[15:0],2'b00}; /*控制器*/
// 输入inst[31:26]即op字段、inst[5:0]即func字段、0标志位zero
// 输出wmem、wreg等控制信号
sccu_dataflow cu (inst[31:26] , inst[5:0] , zero, wmem,wreg,regrt,m2reg, aluc, shift, aluimm,pcsource, jal, sext); /*0拓展或符号拓展*/
wire e = sext & inst[15]; // 取出0或者符号
wire [15:0] imm = {16{e}};
wire [31:0] immediate = {imm,inst[15:0]}; // 拼接、拓展 /*修改PC,使PC指向下一条地址*、
dff32 ip (npc,clock,resetn,pc); // 将npc(即下一条指令的地址)写入寄存器pc /*计算下地址*/
// 四路选择器的0路
cla32 pcplus4 (pc,32'h4,1'b0,p4); // pc和32位十六进制4相加,再加上进位0,结果放入p4
// 四路选择器的1路
cla32 br_adr (p4,offset,1'b0, adr); // p4和拓展后的imm相加,再加上进位0,结果放入adr
// 四路选择器的3路
wire [31:0] jpc = {p4[31:28],inst[25:0],2'b00}; // 如图 /*二路选择器*/
// ③号。在ra即q1、sa之间选择,控制信号是shift,选择结果为alua
mux2x32 alu_a (ra,sa,shift,alua);
// ④号。在data即q2、immediate之间选择,控制信号是aluimm,选择结果为alub
mux2x32 alu_b (data, immediate,aluimm, alub);
// ⑤号。在alu即r、mem即do之间选择,控制信号是m2reg,选择结果为alu_mem
mux2x32 result (alu,mem,m2reg,alu_mem);
// ②号。在alu_mem、p4之间选择,控制信号是jal即call,选择结构是res
mux2x32 link (alu_mem,p4,jal,res);
// ①号。在inst[15:11]即rd,inst[20: 16]即rt之间选择,控制信号是regrt,选择结果是reg_dest
mux2x5 reg_wn (inst[15:11], inst[20: 16] , regrt, reg_dest);
// 对应图中的①号后面的f器件(不知道做什么的...)
assign wn = reg_dest | {5{jal}}; /*四路选择器,计算下地址*/
// 在p4、adr即addr、ra即q1、jpc即p4+immidiate<<2,之间选择,控制信号是pcsource,选择结果是npc
mux4x32 nextpc (p4,adr,ra, jpc,pcsource,npc); /*寄存器组*/
// 定义一个寄存器,输入端口是inst[25:21]即rs(n1)、inst[20:16]即rt(n2)
// 输出端口是data即ra即q1、data即q2
// 输入写使能wreg、待写寄存器wn即n
// 输入时钟clock即clk、清零时钟resetn
regfile rf (inst[25:21] ,inst[20:16] ,res,wn,wreg,clock,resetn,ra,data); /*alu*/
// 操作数是alua、alub,操作结果是aluu空r、标志位zero即z
// 控制信号是aluc
alu al_unit (alua,alub,aluc,alu, zero);
endmodule

sccmop_dataflow.v

/*最顶层的控制模块*/
/*输入时钟clock和resetn*/
/*输出 指令inst、PC的值pc、ALU的运算结果aluout、存储器的输出memout、时钟信号mem_clk*/
module sccomp_dataflow(clock, resetn, inst, pc, aluout, memout,mem_clk);
input clock, resetn,mem_clk;
output [31:0] inst,pc, aluout,memout;
wire [31:0] data;
wire wmem;
// 实例化一个cpu
sccpu_dataflow s (clock, resetn, inst,memout,pc, wmem, aluout, data);
// 实例化一个ROM
scinstmem imem (pc,inst);
// 实例化一个RAM
scdatamem dmem (clock, memout, data, aluout, wmem, mem_clk, mem_clk);
endmodule

单周期cpu设计代码解读的更多相关文章

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

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

  2. 单周期CPU设计

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

  3. Verilog HDL语言实现的单周期CPU设计(全部代码及其注释)

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

  4. 使用logisim搭建单周期CPU与添加指令

    使用logisim搭建单周期CPU与添加指令 搭建 总设计 借用高老板的图,我们只需要分别做出PC.NPC.IM.RF.EXT.ALU.DM.Controller模块即可,再按图连线,最后进行控制信号 ...

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

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

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

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

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

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

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

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

  9. 单周期CPU

    一个时钟周期执行一条指令的过程理解(单周期CPU): https://blog.csdn.net/a201577F0546/article/details/84726912 单周期CPU指的是一条指令 ...

随机推荐

  1. VC++动态链接库(DLL)编程深入浅出(转帖:基础班)

    1.概论 先来阐述一下DLL(Dynamic Linkable Library)的概念,你可以简单的把DLL看成一种仓库,它提供给你一些可以直接拿来用的变量.函数或类.在仓库的发展史上经历了“无库-静 ...

  2. 初识Spacy

    之所以想接触Spacy,是看到其自称为工业级的应用,所以想尝试下 windows下安装Spacy:     直接安装pip install spacy是会报错的     解决方法:     到 htt ...

  3. ORA-21561: OID generation failed

    ORA-21561: OID generation failed 从AIX机器上连Linux上的Oracle数据库时报ORA-21561: OID generation failed错误.不是因为AI ...

  4. inteliji ---idea 如何创建scala程序配置

    首先创建一个新的工程: #####################################################################################

  5. 1080 Graduate Admission (30)(30 分)

    It is said that in 2013, there were about 100 graduate schools ready to proceed over 40,000 applicat ...

  6. Node.js集成支付宝接口注意事项

    目录 签名 发送请求表单 验签 总结 签名 使用node.js自带的加密模块crypto和字符编码模块iconv-lite 根据支付宝接口文档参数格式得到签名之前的字符串beforeSignStr,然 ...

  7. Ubuntu 复制文件,修改文件名

    复制 cp a b   (a为旧的,b为新的) 修改 mv a b (a为旧的,b为新的)

  8. LED接口

    通常我们都听到别人说DVI接口.VGA接口等,可是这些接口是什么意思,led显示屏厂家小编为您解析其含义与不同之处.   1.DVI接口 DVI接口相校于VGA.HDMI.DP等接口来说体积较大,是目 ...

  9. 湖南程序设计竞赛赛题总结 XTU 1237 Magic Triangle(计算几何)

    这个月月初我们一行三人去湖南参加了ccpc湖南程序设计比赛,虽然路途遥远,六月的湘潭天气燥热,不过在一起的努力之下,拿到了一块铜牌,也算没空手而归啦.不过通过比赛,还是发现我们的差距,希望这几个月自己 ...

  10. js css3实现钟表效果

    原理: 利用transform-origin改变旋转的圆心,实现秒数和分钟数的刻度线,利用transfrom translate实现钟表小时刻度的显示 html: <div class=&quo ...