实验四:多周期CPU实验要求

  • 源代码
  1. 实验类型
    本实验为设计型实验。
  2. 实验目的
    ① 了解指令执行的周期划分。
    ② 具有多周期CPU的设计能力。
    ③ 熟悉Vivado的设计流程,具备电路的设计仿真和硬件测试能力。
    ④ 能编写测试程序,测试多周期CPU的功能。
  3. 实验原理
    1)多周期CPU实现的指令集
    要求在20条MIPS整数指令的基础上,由读者自主增加1条指令,共实现21条指令。请参考附录E,填写多周期CPU新增指令的功能表。
    指令名称 指令类型 汇编指令 指令码 源操作数1 源操作数2 源操作数3 目的寄存器 功能描述
    ADDU R型 ADDU rd,rs,rt 000000|rs|rt|rd|00000|100001 rs rt rd rs=rs+ rt
    ADD R型 ADD rd,rs,rt 000000|rs|rt|rd|00000|100000 rs rt rd rd=rs+rt
    SUB R型 SUB rd,rs,rt 000000|rs|rt|rd|00000|100010 rs rt rd rd=rs-rt
    AND R型 AND rd,rs,rt 000000|rs|rt|rd|00000|100100 rs rt rd rd=rs&rt
    OR R型 OR rd,rs,rt 000000|rs|rt|rd|00000|100101 rs rt rd rd=rs | rt
    XOR R型 XOR rd,rs,rt 000000|rs|rt|rd|00000|100110 rs rt rd rd=rs ^ rt
    SLL R型 SLL rd,rt,shf 000000|00000|rt|rd|shf|000000 rt shf rd rd=rt<<shf
    SRL R型 SRL rd,rt,shf 000000|00000|rt|rd|shf|000010 rt shf rd rd=rt>>shf
    SRA R型 SRA rd,rt,shf 000000|00000|rt|rd|shf|000011 rt shf rd rd=rt>>shf
    JR R型 JR rs 000000|rs|0000000000|00000|001000|000000 rs PC PC=rs
    ADDI I型 ADDI rt,rs,imm 001000|rs|rt|imm rs sign_ext(imm) rt rd=rs+imm
    ANDI I型 ANDI rt,rs,imm 001100|rs|rt|imm rs zero_ext(imm) rt rd=rs&imm
    ORI I型 ORI rt,rs,imm 001101|rs|rt|imm rs zero_ext(imm) rt rd=rs|imm
    XORI I型 XORI rt,rs,imm 001110|rs|rt|imm rs zero_ext(imm) rt rd=rs^imm
    LW I型 LW rt,offset(base) 100011|base|rt|offset base sign_ext(offset) rt rt=mem[base+offset]
    SW I型 SW rt,offset(base) 101011|base|rt|offset base sign_ext(offset) rt mem[base+offset]=rt
    BEQ I型 BEQ rs,rt,offset 000100|rs|rt|offset rs rt sign_ext(offset) PC PC=(rs==rt)?B_PC+sign_ext(offset)<<2:PC
    BNE I型 BNE rs,rt,offset 000101|rs|rt|offset rs rt sign_ext(offset) PC PC=(rs!=rt)?B_PC+sign_ext(offset)<<2:PC
    LUI I型 LUI rt,imm 001111|00000|rt|imm imm rt rt={imm,16’d0}
    J J型 J target 000010|target target PC PC={B_PC[31:28],target<<2}
    JAL J型 JAL target 000011|target target $31,PC $31=B_PC+4;PC={B_PC[31:28],target<<2}
    2)多周期CPU 的指令执行过程
    多周期CPU把指令执行分成多个阶段,每个阶段在一个时钟周期内完成,如取指、译码、执行、访存、写回。此时,不同指令所用周期数可以不同,每个周期只做一部分操作。
    取指(IF)状态:将程序计数器PC的值作为存储器的地址,从存储器取出指令,并把PC+4。当取指结束后锁存取指阶段产生的结果—当前PC值和指令。
    译码(ID)状态:主要完成指令译码、读寄存器、判断跳转等。控制器可以区分各条指令并产生用于译码、执行、访存、写回的控制信号。当译码结束后,锁存译码阶段产生的结果用于下一状态执行,包括用于执行、访存、写回的控制信号、用于执行阶段的两个源操作数、用于访存阶段的写入内存数据、用于写回阶段的写寄存器地址等。
    执行(EXE)状态:由ALU模块完成指令操作。当执行结束后锁存执行阶段产生的结果及前级传递的结果,包括用于访存、写回的控制信号、ALU结果、内存写入数据、寄存器写地址等。
    访存(MEM)状态:完成对数据存储器的读写,并选择将要写回寄存器的值。当访存结束后,锁存访存阶段产生的结果及前级传递的结果,包括用于写回的控制信号、数据和地址。
    写回(WB)状态:完成对寄存器的写入。CPU复位结束,状态机进入取指状态,其后在每次上一状态结束时进入下一状态,写回状态结束后返回取指状态。不同指令所用周期数不一样,如跳转指令只需2个周期,在译码状态后直接返回到下一指令的取指状态,不需要经过执行等后续状态。
    3)多周期计算机的总体设计
    实现20条MIPS整数指令的多周期计算机的总体电路设计如下图所示,包含多周期控制器CU、运算器ALU、寄存器和存储器等功能模块。实现21条指令的多周期CPU设计图可在此基础上修改完成。

    利用多周期CPU 实现的21 条指令,读者可以编写一段汇编程序,用于测试多周期CPU的功能是否正确。请根据前2 行指令的填写示例,将测试程序完整填写到下表中。

指令地址 汇编指令 功能描述 机器指令的机器码
十六进制 二进制
00H lui r1, 0 GPR[r1]{0,16’d0} 3c010000 0011110000000001
0000000000000000
04H ori r4, r1,80 GPR[r4] GPR[r1] & zero_ext(80) 34240080 0011010000100100
0000000010000000
08H addi r5, r0, 4 GPR[r5] GPR[r0] +sign_ext(4) 20050004 0010000000000101
0000000000000100
0CH call: jal sum 调用sum并返回 0c000018 0000110000000000
0000000000011000
10H sw r2,0(r4)
Mem[GPR[r4]+sign_ext(0)]←GPR[r2] ac820000 1010110010000010
0000000000000000
14H lw r9, 0(r4) GPR[r9] ←Mem[GPR[r4]+sign_ext(0)] 8c890000 1000110010001001
0000000000000000
18H sub r8, r9, r4 GPR[r8] GPR[r9] -GPR[r4] 01244022 1001001000100000
000100010
1CH addi r5, r0, 3 GPR[r5] GPR[r0] +sign_ext(3) 20050003 1000000000010100
00000000000011
20H loop2: addi r5, r5, -1 GPR[r5] GPR[r5] +sign_ext(-1) 20a5ffff 1000001010010111
11111111111111
24H ori r8, r5, 0xffff r5与0xffff相或,存储到r8 34a8ffff 1101001010100011
11111111111111
28H xori r8, r8, 0x5555 r8与0x5555相异或,存储到r8 39085555 1110010000100001
01010101010101
2CH addi r9, r0, -1
GPR[r9] GPR[r0] +sign_ext(-1) 2009ffff 1000000000100111
11111111111111
30H andi r10, r9, 0xffff GPR[r10] GPR[r9] +sign_ext(0xffff) 312affff 1100010010101011
11111111111111
34H or r6, r10, r9 GPR[r6] GPR[r10] | GPR[r9] 01493025 1010010010011000
000100101
38H xor r8, r10, r9 GPR[r8] GPR[r10] ^GPR[r9] 01494026 1010010010100000
000100110
3CH and r7, r10, r6 GPR[r7] GPR[r10] &GPR[r6] 01463824 1010001100011100
000100100
40H beq r5, r0, shift If GPR[r5]= GPR[r0] then PC←B_PC+sign_ext(shift)<<2 10a00001 1000010100000000
0000000000001
44H loop2 循环 08000008 1000000000000000
000000001000
48H shift: addi r5, r0, -1 转换到GPR[r5] GPR[r0] +sign_ext(-1) 2005ffff 1000000000010111
11111111111111
4CH sll r8, r5, 15 GPR[r8] zeroGPR[r5] <<15 000543c0 1010100001111000000
50H sll r8, r8, 16 GPR[r8] zeroGPR[r8] <<16 00084400 10000100010000000000
54H sra r8, r8, 16
GPR[r8] signGPR[r8] >>16 00084403 10000100010000000011
58H srl r8, r8, 15 GPR[r8] zeroGPR[r8] >>15 000843c2 10000100001111000010
5CH finish: j finish 完成任务 08000017 1000000000000000000000010111
60H sum: add r8, r0, r0 GPR[r8] ←GPR[r0]+ GPR[r0] 00004020 100000000100000
64H loop: lw r9, 0(r4) 循环GPR[r9] ←Mem[GPR[r4]+sign_ext(0)] 8c890000 10001100100010010000000000000000
68H addi r4, r4, 4 GPR[r4] GPR[r4] +sign_ext(4) 20840004 100000100001000000000000000100
6CH add r8, r8, r9 GPR[r8] ←GPR[r8]+ GPR[r9] 01094020 1000010010100000000100000
70H addi r5, r5, -1 GPR[r5] GPR[r5] +sign_ext(-1) 20a5ffff 100000101001011111111111111111
74H bne r5, r0, loop If GPR[r5]!= GPR[r0] then PC←B_PC+sign_ext(loop)<<2 14a0fffb 10100101000001111111111111011
78H sll r2, r8, 0 GPR[r2] zeroGPR[r8] <<0 00081000 10000001000000000000
7CH jr r31 PC←GPR[r31] 03e00008 11111000000000000000001000
4. 实验内容和要求
① 本实验需要用到之前实验的结果,如ALU模块、存储器模块和控制器模块。其中,RAM建议使用调用库IP实例化的同步存储器,因为存储器在实际应用中基本都是同步读写的,为更贴近真实情况,此处建议使用同步RAM。
② 在实验中生成的同步RAM,是在发送地址后的下一拍才能获得对应数据。故在使用同步存储器时,从存储器中读取数据就需要等待一个时钟周期,即取指令需要两个时钟周期,LOAD 操作也需要两个时钟周期。在真实的处理器系统中,取指令和访存其实都需要多个时钟周期。
③ 根据设计的实验方案,使用Verilog HDL编写相应代码。
④ 对编写的代码进行仿真,得到正确的波形图。
⑤ 将以上设计作为一个单独模块,设计一个外围模块去调用它,如下图所示。

外围模块需调用封装好的LCD触摸屏模块,观察多周期CPU的状态和PC等输出信号的值,利用触摸屏实时观察输出信号变化的效果,可以在实验箱上充分验证CPU 的功能。
⑥ 将编写的代码进行综合布局布线,并下载到FPGA实验箱进行硬件测试,做好实验记录,验证此设计的功能。
注意:控制CPU运转的时钟一般是由FPGA实验箱的时钟输出提供的,但为了方便演示,需在每个时钟周期中查看一条指令的运算结果,故实验的时钟是手动输入的,可以使用FPGA实验箱的脉冲开关代替时钟。
⑦ 参考附录C的格式撰写实验报告,实验报告内容包括:程序设计、仿真分析、硬件测试和实验操作步骤,以及源程序代码、仿真波形图、数据记录和实验结果分析等。

源代码

mccomp.v:
module mccomp(clock,resetn,q,a,b,alu,adr,tom,fromm,pc,ir,mem_clk);input clock,resetn,mem_clk;output [31:0] a,b,alu,adr,tom,fromm,pc,ir;output [2:0] q;wire      wmem;mccpu mc_cpu(clock,resetn,fromm,pc,ir,a,b,alu,wmem,adr,tom,q);mcmem memory(clock,fromm,tom,adr,wmem,mem_clk,mem_clk);
endmodule
alu.v:
module alu(a,b,aluc,r,z);input [31:0] a,b;input [3:0] aluc;output [31:0] r;output z;assign r = cal (a,b,aluc);assign z = ~|r;function [31:0] cal;input [31:0] a,n;input [3:0] aluc;casex (aluc)4'bx000: cal = a+b;4'bx100: cal = a-b;4'bx001: cal = a&b;4'bx101: cal = a|b;4'bx010: cal = a^b;4'bx110: cal = {b[15:0],16'h0};4'bx011: cal = b<<a[4:0];4'b0111: cal = b>>a[4:0];4'b1111: cal = $signed(b) >>> a[4:0];endcaseendfunction
endmodule
dff32.v:
module dff32 (d,clk,clrn,q); // dff with asynchronous reset.input [31:0]d,clk,clrn;output [31:0]q;reg      [31:0]q;always   @  (posedge clk or negedge clrn) beginif (clrn == 0)  q <= 0;else              q <= d;end
endmoduledffe32.v:
module dffe32 (d,clk,clrn,e,q);input [31:0]d;input clk, clrn,e;output  [31:0]q;reg     [31:0]  q;always  @  (negedge clrn or posedge clk)if (clrn == 0)  q<= 0;else if (e)      q<= d;
endmodule
mccpu.v
module mccpu (clock,resetn,frommem,pc,inst,alua,alub,alu,wmem,madr,tomem,state
);input [31:0]   frommem;input clock,resetn;output[31:0]pc,inst,alua,alub,alu,madr,tomem;output[2:0]state;output wmem;wire[3:0] aluc;wire[4:0] reg_dest;wire z,wpc,wir,wmem,wreg,iord,regrt,m2reg,shift,selpc,jal,sext;wire[31:0] npc,rega,regb,regc,mem,qa,qb,res,opa,bra,alua,alu_mem;wire[1:0] alusrcb,pcsource;wire[31:0] sa={27'b0,inst[10:6]};wire[31:0]jpc={pc[31:28],inst[5:0],1'b0,1'b0};mccu control_unit(inst[31:26],inst[5:0],z,clock,resetn,wpc,wir,wmem,wreg,iord,regrt,m2reg,aluc,shift,selpc,alusrcb,pcsource,jal,sext,state);wire e=sext&inst[15];wire[15:0] imm={16{e}};wire[31:0] immediate={imm,inst[15:0]};wire[31:0] offset={imm[13:0],inst[15:0],1'b0,1'b0};
dffe32 ip(npc,clock,resetn,wpc,pc);
dffe32 ir(frommem,clock,resetn,wir,inst);
dff32 dr(frommem,clock,resetn,mem);
dff32 ra(qa,clock,resetn,rega);
dff32 rb(qb,clock,resetn,regb);
dff32 rc(qc,clock,resetn,regc);
assign tomem=regb;
mux2x32 reg_wn(inst[15:11],inst[20:16],regrt,reg_dest);
wire[4:0]wu=reg_dest|{5{jal}};
mux2x32 mem_addres(pc,regc,iord,madr);
mux2x32 result(regc,mem,m2reg,alu_mem);
mux2x32 link(alu_mem,pc,jal,res);
mux2x32 oprand_a(rega,sa,shift,opa);
mux2x32 alu_a(opa,pc,selpc,alua);
mux4x32 alu_b(regb,32'h4,immediate,offset,alusrcb,alub);
mux4x32 nextpc(alu,regc,qa,jpc,pcsource,npc);
regfile rf(inst[25:21],inst[20:16],res,wn,wreg,clock,resetn,qa,qb);
alu alunit(alua,alub,aluc,alu,z);
endmodule 
mccu.v
module mccu (op,func,z,clock,resetn,wpc,wir,wmem,wreg,iord,regrt,m2reg,aluc,shift
,alusrca,alusrcb,pcsource,jal,sext,state); input [5:0] op,func; input z,clock,resetn; output reg wpc,wir,wmem,wreg,iord,regrt,m2reg; output reg [3:0] aluc; output reg [1:0] alusrcb,pcsource; output reg shift,alusrca,jal,sext; output reg [2:0] state; reg [2:0] next_state; parameter [2:0] sif = 3'b000, sid = 3'b001, sexe = 3'b010, smem = 3'b011, swb = 3'b100; wire r_type,i_add,i_sub,i_and,i_or,i_xor,i_sll,i_srl,i_sra,i_jr; wire i_addi,i_andi,i_ori,i_xori,i_lw,i_sw,i_beq,i_bne,i_lui,i_j,i_jal; //and(r_type,~op[5],~op[4],~op[3],~op[2],~op) ;and(r_type,~op[5],~op[4],~op[3],~op[2],~op[1],~op[0]); and(i_add,r_type,func[5],~func[4],~func[3],~func[2],~func[1],~func[0]); and(i_sub,r_type,func[5],~func[4],~func[3],~func[2],func[1],~func[0]); and(i_and,r_type,func[5],~func[4],~func[3],func[2],~func[1],~func[0]); and(i_or,r_type,func[5],~func[4],~func[3],func[2],~func[1],func[0]); and(i_xor,r_type,func[5],~func[4],~func[3],func[2],func[1],~func[0]); and(i_sll,r_type,~func[5],~func[4],~func[3],~func[2],~func[1],~func[0]); and(i_srl,r_type,~func[5],~func[4],~func[3],~func[2],func[1],~func[0]); and(i_sra,r_type,~func[5],~func[4],~func[3],~func[2],func[1],func[0]); and(i_jr,r_type,~func[5],~func[4],func[3],~func[2],~func[1],~func[0]); and(i_addi,~op[5],~op[4],op[3],~op[2],~op[1],~op[0]); and(i_andi,~op[5],~op[4],op[3],op[2],~op[1],~op[0]); and(i_ori,~op[5],~op[4],op[3],op[2],~op[1],op[0]); and(i_xori,~op[5],~op[4],op[3],op[2],op[1],~op[0]); and(i_lw,op[5],~op[4],~op[3],~op[2],op[1],op[0]); and(i_sw,op[5],~op[4],op[3],~op[2],op[1],op[0]); and(i_beq,~op[5],~op[4],~op[3],op[2],~op[1],~op[0]); and(i_bne,~op[5],~op[4],~op[3],op[2],~op[1],op[0]); and(i_lui,~op[5],~op[4],~op[3],op[2],op[1],op[0]); and(i_j,~op[5],~op[4],~op[3],~op[2],op[1],~op[0]); and(i_jal,~op[5],~op[4],~op[3],~op[2],op[1],op[0]); and(i_bgezal,op[5],~op[4],~op[3],~op[2],~op[1],op[0]);wire i_shift; or (i_shift,i_sll,i_srl,i_sra); always @ * begin wpc = 0; wir = 0; wmem = 0; wreg = 0; iord = 0; aluc = 4'bx000; alusrca = 0; alusrcb = 2'h0; regrt = 0; m2reg = 0; shift = 0; pcsource = 2'h0; jal = 0; sext = 1; case (state) sif:begin wpc = 1; wir = 1; alusrca = 1; alusrcb = 2'h1; next_state = sid; end sid:begin if(i_j)begin pcsource = 2'h3; wpc = 1; next_state = sif; end else if(i_jal)begin pcsource = 2'h3; wpc = 1; jal = 1; wreg = 1; next_state = sif; end else if(i_jr)begin pcsource = 2'h2; wpc = 1; next_state = sif; end else begin aluc = 4'bx000; alusrca = 1; alusrcb = 2'h3; next_state = sexe; end end sexe:begin  aluc[3] = i_sra; aluc[2] = i_sub | i_or | i_srl | i_sra | i_ori | i_lui; aluc[1] = i_xor | i_sll| i_srl | i_sra | i_xori| i_beq | i_bne
| i_lui; aluc[0] = i_and | i_or | i_sll | i_srl | i_sra | i_andi| i_ori; if(i_beq || i_bne) begin  pcsource = 2'h1; wpc = i_beq & z | i_bne & ~z; next_state =  sif; end else begin  if(i_lw || i_sw) begin alusrcb = 2'h2; next_state = smem; end  else begin if(i_shift) shift = 1; if(i_addi || i_andi || i_ori || i_xori ||i_lui) alusrcb = 2'h2; if(i_andi || i_ori || i_xori) sext=0;next_state = swb; end end end   smem:begin  iord = 1; if(i_lw) begin  next_state = swb; end else begin  wmem = 1; next_state = sif; end end swb:begin if(i_lw) m2reg = 1; if(i_lw || i_addi || i_andi || i_ori || i_xori ||i_lui)  regrt = 1; wreg = 1; next_state = sif; end default:begin  next_state = sif; end endcase end always @ (posedge clock or negedge resetn)begin  if(resetn == 0) begin  state <= sif; end  else begin  state <= next_state; end end
endmodule 
mcmen.v:
module mcmem(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:63];
assign dataout = ram[addr[8:2]];
always @ (posedge clk) beginif (we) ram[addr] = datain;
end
integer i;
initial beginfor (i = 0; i < 32; i = i + 1)ram[i] = 0;
ram[5'h0] = 32'h00011083;//00011083     3c010000
/*ram[5'h1] = 32'h34240080;
ram[5'h2] = 32'h20050004;
ram[5'h3] = 32'h0c000018;
ram[5'h4] = 32'hac820000;
ram[5'h5] = 32'h8c890000;
ram[5'h6] = 32'h01244022;
ram[5'h7] = 32'h20050003;
ram[5'h8] = 32'h20a5ffff;
ram[5'h9] = 32'h34a8ffff;
ram[5'hA] = 32'h39085555;
ram[5'hB] = 32'h2009ffff;
ram[5'hC] = 32'h312affff;
ram[5'hD] = 32'h01493025;
ram[5'hE] = 32'h01494026;
ram[5'hF] = 32'h01463824;
ram[5'h10] = 32'h10a00001;
ram[5'h11] = 32'h08000008;
ram[5'h12] = 32'h2005ffff;
ram[5'h13] = 32'h000543c0;
ram[5'h14] = 32'h00084400;
ram[5'h15] = 32'h00084403;
ram[5'h16] = 32'h000843c2;
ram[5'h17] = 32'h08000017;
ram[5'h18] = 32'h00004020;
ram[5'h19] = 32'h8c890000;
ram[5'h1A] = 32'h20840004;
ram[5'h1B] = 32'h01094020;
ram[5'h1C] = 32'h20a5ffff;
ram[5'h1D] = 32'h14a0fffb;
ram[5'h1E] = 32'h00081000;
ram[5'h1F] = 32'h03e00008;
ram[5'h20] = 32'h000000A3;
ram[5'h21] = 32'h00000027;
ram[5'h22] = 32'h00000079;
ram[5'h23] = 32'h00000115;
ram[5'h24] = 32'h00000000;*/
end
endmodule
mux2x5.v:
module mux2x5 (a0, a1,s,y);input [4:0] a0, a1;input s;output [4:0] y;assign y =s ? a1 : a0;
endmodulemux2x32.v:
module mux2x32 (a0, a1,s,y);input [31:0] a0, a1;input s;output [31:0] y;assign y =s ? a1 : a0;
endmodule
mu4x32.v:
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;2'b01: select = a1;2'b10: select = a2;2'b11: select = a3;endcaseendfunctionassign y=select(a0,a1,a2,a3,s);
endmoduleregfile.v:
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]; // 31 x 32-bit regs
integer i;
// 2 read ports
assign qa = (rna == 0) ? 0 : register[rna];
assign qb = (rnb == 0) ? 0 : register[rnb];
// 1 write port
always @(posedge clk or negedge clrn)
if(clrn==0) begin
for (i=1; i<32; i=i+1)
register[i]<=0;
end else if ( (wn != 0)&& we)
register[wn]<= d;
endmodule
mccomp_tb.v:
//********************************************************************
// > 鏂囦欢鍚?: mccomp_tb.v
// > 鎻忚堪 锛歮ccomp 浠跨湡娴嬭瘯妯″潡
//********************************************************************
`timescale 1ns/1ns
`include "mccomp.v"
module mccomp_tb;
//--------------Input Ports-----------------------
reg clock,resetn,mem_clk; //resetn=1,姝e父宸ヤ綔;resetn=0,澶嶄綅
//--------------Output Ports-----------------------
//-----{姝ゅ鐪佺暐锛岃鑷繁缂栧啓}
wire [31:0] a,b,alu,adr,tom,fromm,pc,ir;
wire [2:0] q;
initial begin clock=1;resetn=0;mem_clk=0;
#0 $display("time\tclock\tresetn\tq\tir\tpc\ta\tb\talu\tfromem\ttomem");
#1 resetn=1;
end
always #2 mem_clk=~mem_clk;
always #4 clock=~clock;//-----{姝ゅ鐪佺暐锛岃鑷繁缂栧啓}
mccomp m(clock,resetn,q,a,b,alu,adr,tom,fromm,pc,ir,mem_clk); //-----{姝ゅ鐪佺暐锛岃鑷繁缂栧啓});
initial begin
$dumpfile("test.vcd"); //缁? gtkwave 浣跨敤
$dumpvars;
$monitor("%g\t %b %b %b %b %b %b %b %b %b %b %b %b",$time,clock,resetn,q,a,b,alu,adr,
tom,fromm,pc,ir,mem_clk);//灞忓箷鏄剧ず
#1200 $finish;
end
endmodule
mccomp_display.v:
`timescale 1ns / 1ps
//********************************************************************
// > 鏂囦欢鍚?: mccomp_display.v
// > 鎻忚堪 :澶氬懆鏈? COMP 鏄剧ず妯″潡锛岃皟鐢? FPGA 鏉夸笂鐨? IO 鎺ュ彛鍜岃Е鎽稿睆
//********************************************************************
module mccomp_display( // 澶氬懆鏈? cpu
//鏃堕挓涓庡浣嶄俊鍙?
input clk,
input resetn, //鍚庣紑"n"浠h〃浣庣數骞虫湁鏁?
//鑴夊啿寮?鍏筹紝鐢ㄤ簬浜х敓鑴夊啿 clk锛屽疄鐜板崟姝ユ墽琛?
input btn_clk,
//瑙︽懜灞忕浉鍏虫帴鍙o紝涓嶉渶瑕佹洿鏀?
output lcd_rst,
output lcd_cs,
output lcd_rs,
output lcd_wr,
output lcd_rd,
inout[15:0] lcd_data_io,
output lcd_bl_ctr,
inout ct_int,
inout ct_sda,
output ct_scl,
output ct_rstn
);
//-----{鏃堕挓鍜屽浣嶄俊鍙穧begin
//涓嶉渶瑕佹洿鏀癸紝鐢ㄤ簬鍗曟璋冭瘯
wire cpu_clk; //澶氬懆鏈? CPU 閲屼娇鐢ㄨ剦鍐插紑鍏充綔涓烘椂閽燂紝浠ュ疄鐜板崟姝ユ墽琛?
reg btn_clk_r1;
reg btn_clk_r2;
always @(posedge clk)
begin
if (!resetn)
begin
btn_clk_r1<= 1'b0;
end
else
begin
btn_clk_r1 <= ~btn_clk;
end
btn_clk_r2 <= btn_clk_r1;
end
wire clk_en;
assign clk_en = !resetn || (!btn_clk_r1 && btn_clk_r2);
BUFGCE cpu_clk_cg(.I(clk),.CE(clk_en),.O(cpu_clk));
//-----{鏃堕挓鍜屽浣嶄俊鍙穧end
//-----{璋冪敤澶氬懆鏈? COMP 妯″潡}begin
//鐢ㄤ簬鍦? FPGA 鏉夸笂鏄剧ず缁撴灉
wire [ 2:0] q; //灞曠ず CPU 褰撳墠鐘舵??
wire [31:0]  a,b,alu,adr,tom,fromm,pc,ir;//-----{姝ゅ鐪佺暐锛岃鑷繁缂栧啓}
mccomp cpu(
.clock (cpu_clk ),
.resetn (resetn ),
.q (q),
.a(a),
.b(b),
.alu(alu),
.adr(adr),
.tom(tom),
.fromm(fromm),
.pc(pc),
.ir(ir),
.mem_clk(clk)
//-----{姝ゅ鐪佺暐锛岃鑷繁缂栧啓}
);
//-----{璋冪敤澶氬懆鏈? COMP 妯″潡}end
//---------------------{璋冪敤瑙︽懜灞忔ā鍧梷begin--------------------//
//-----{瀹炰緥鍖栬Е鎽稿睆}begin
//姝ゅ皬鑺備笉闇?瑕佹洿鏀?
reg display_valid;
reg [39:0] display_name;
reg [31:0] display_value;
wire [5 :0] display_number;wire input_valid;
wire [31:0] input_value;
lcd_module lcd_module(
.clk (clk ), //10Mhz
.resetn (resetn ),
//璋冪敤瑙︽懜灞忕殑鎺ュ彛
.display_valid (display_valid ),
.display_name (display_name ),
.display_value (display_value ),
.display_number (display_number),
.input_valid (input_valid ),
.input_value (input_value ),
//lcd 瑙︽懜灞忕浉鍏虫帴鍙o紝涓嶉渶瑕佹洿鏀?
.lcd_rst (lcd_rst ),
.lcd_cs (lcd_cs ),
.lcd_rs (lcd_rs ),
.lcd_wr (lcd_wr ),
.lcd_rd (lcd_rd ),
.lcd_data_io (lcd_data_io ),
.lcd_bl_ctr (lcd_bl_ctr ),
.ct_int (ct_int ),
.ct_sda (ct_sda ),
.ct_scl (ct_scl ),
.ct_rstn (ct_rstn )
);
//-----{瀹炰緥鍖栬Е鎽稿睆}end
//-----{杈撳嚭鍒拌Е鎽稿睆鏄剧ず}begin
//鏍规嵁闇?瑕佹樉绀虹殑鏁颁慨鏀规灏忚妭锛?
//瑙︽懜灞忎笂鍏辨湁 44 鍧楁樉绀哄尯鍩燂紝鍙樉绀? 44 缁? 32 浣嶆暟鎹?
//44 鍧楁樉绀哄尯鍩熶粠 1 寮?濮嬬紪鍙凤紝缂栧彿涓? 1~44锛?
always @(posedge clk)
begin
case(display_number)6'd1 : //鏄剧ず IF 妯″潡鐨? PC
begin
display_valid <= 1'b1;
display_name <= "Q";
display_value <= q;
end
6'd2 :
begin
display_valid <= 1'b1;
display_name <= "A";
display_value <= a;
end
6'd3 :
begin
display_valid <= 1'b1;
display_name <= "B";
display_value <= b;
end
6'd4 :
begin
display_valid <= 1'b1;
display_name <= "ALU";
display_value <= alu;
end
6'd5 :
begin
display_valid <= 1'b1;
display_name <= "ADR";
display_value <= adr;
end
6'd6 :
begin
display_valid <= 1'b1;
display_name <= "TOM";
display_value <= tom;
end
6'd7 :
begin
display_valid <= 1'b1;
display_name <= "FROMM";
display_value <= fromm;
end
6'd8 :
begin
display_valid <= 1'b1;
display_name <= "PC";
display_value <= pc;
end
6'd9 :
begin
display_valid <= 1'b1;
display_name <= "IR";
display_value <= ir;
end
//-----{姝ゅ鐪佺暐锛岃鑷繁缂栧啓}
default :
begin
display_valid <= 1'b0;
display_name <= 40'd0;
display_value <= 32'd0;
end
endcase
end
//-----{杈撳嚭鍒拌Е鎽稿睆鏄剧ず}end
//----------------------{璋冪敤瑙︽懜灞忔ā鍧梷end---------------------//
endmodule
mcmen.xdc:
#时钟信号连接
set_property PACKAGE_PIN AC19 [get_ports clk]#脉冲开关,用于输入作为复位信号,低电平有效
set_property PACKAGE_PIN Y3 [get_ports resetn]#脉冲开关,用于输入作为单步执行的clk
set_property PACKAGE_PIN Y5 [get_ports btn_clk]set_property IOSTANDARD LVCMOS33 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports resetn]
set_property IOSTANDARD LVCMOS33 [get_ports btn_clk]#触摸屏引脚连接
set_property PACKAGE_PIN J25 [get_ports lcd_rst]
set_property PACKAGE_PIN H18 [get_ports lcd_cs]
set_property PACKAGE_PIN K16 [get_ports lcd_rs]
set_property PACKAGE_PIN L8 [get_ports lcd_wr]
set_property PACKAGE_PIN K8 [get_ports lcd_rd]
set_property PACKAGE_PIN J15 [get_ports lcd_bl_ctr]
set_property PACKAGE_PIN H9 [get_ports {lcd_data_io[0]}]
set_property PACKAGE_PIN K17 [get_ports {lcd_data_io[1]}]
set_property PACKAGE_PIN J20 [get_ports {lcd_data_io[2]}]
set_property PACKAGE_PIN M17 [get_ports {lcd_data_io[3]}]
set_property PACKAGE_PIN L17 [get_ports {lcd_data_io[4]}]
set_property PACKAGE_PIN L18 [get_ports {lcd_data_io[5]}]
set_property PACKAGE_PIN L15 [get_ports {lcd_data_io[6]}]
set_property PACKAGE_PIN M15 [get_ports {lcd_data_io[7]}]
set_property PACKAGE_PIN M16 [get_ports {lcd_data_io[8]}]
set_property PACKAGE_PIN L14 [get_ports {lcd_data_io[9]}]
set_property PACKAGE_PIN M14 [get_ports {lcd_data_io[10]}]
set_property PACKAGE_PIN F22 [get_ports {lcd_data_io[11]}]
set_property PACKAGE_PIN G22 [get_ports {lcd_data_io[12]}]
set_property PACKAGE_PIN G21 [get_ports {lcd_data_io[13]}]
set_property PACKAGE_PIN H24 [get_ports {lcd_data_io[14]}]
set_property PACKAGE_PIN J16 [get_ports {lcd_data_io[15]}]
set_property PACKAGE_PIN L19 [get_ports ct_int]
set_property PACKAGE_PIN J24 [get_ports ct_sda]
set_property PACKAGE_PIN H21 [get_ports ct_scl]
set_property PACKAGE_PIN G24 [get_ports ct_rstn]set_property IOSTANDARD LVCMOS33 [get_ports lcd_rst]
set_property IOSTANDARD LVCMOS33 [get_ports lcd_cs]
set_property IOSTANDARD LVCMOS33 [get_ports lcd_rs]
set_property IOSTANDARD LVCMOS33 [get_ports lcd_wr]
set_property IOSTANDARD LVCMOS33 [get_ports lcd_rd]
set_property IOSTANDARD LVCMOS33 [get_ports lcd_bl_ctr]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[8]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[9]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[10]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[11]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[12]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[13]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[14]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[15]}]
set_property IOSTANDARD LVCMOS33 [get_ports ct_int]
set_property IOSTANDARD LVCMOS33 [get_ports ct_sda]
set_property IOSTANDARD LVCMOS33 [get_ports ct_scl]
set_property IOSTANDARD LVCMOS33 [get_ports ct_rstn]set_property IOSTANDARD LVCMOS33 [get_ports btn_clk]

计算机组成原理实验 实验四:多周期CPU实验要求(源代码全)相关推荐

  1. 计算机公共基础知识实验报告,MIPS单周期CPU实验报告总结.doc

    <计算机组成原理实验> 实验报告 (实验二) 学 院 名 称 : 专业(班级) : 学 生 姓 名 : 学号 : 时间:2017年11月25日 成 绩 : 实 验 二 : 单周期 CPU设 ...

  2. 【计算机组成原理】中央处理器(一)—— CPU 的功能与基本结构

    [计算机组成原理]中央处理器(一)-- CPU 的功能与基本结构 一.现代计算机的结构 1. 运算器的基本组成 2. 控制器的基本组成 二.CPU 的功能 1. 运算器的基本结构 2. 控制器的基本结 ...

  3. 计算机组成原理--基于Logisim的4位并行加法器实验的应用(超详细/设计/实验/作业/练习)

    目录 课程名:计算机组成原理 内容/作用:设计/实验/作业/练习 学习:基于Logisim的4位并行加法器实验 一.前言 二.环境与设备 三.内容 四.结果与分析 课程名:计算机组成原理 内容/作用: ...

  4. 计算机组成原理VHDL语言实现16位ALU实验

    计算机组成原理实验第二个,VHDL语言,ISE设计环境设计一个16位的ALU. 资源下载: 链接:https://pan.baidu.com/s/1cyhJ2ZynUMMFnYi2YOIMmA 提取码 ...

  5. 计算机组成原理论文逻辑控制电路,计算机组成原理课程设计――设计逻辑控制电路cpu..doc...

    文档介绍: 计算机组成原理课程设计报告书题目:设计逻辑电路控制器CPU(含至少3条指令院系:计算机科学与工程学院专业班级:学号:学生姓名:指导教师:2015年12月15日安徽理工大学课程设计(论文任务 ...

  6. 华中科技大学计算机组成原理慕课第四章 存储系统(一) 单元测验(习题+答案+详细解析)

    第四章 存储系统(一) 单元测验 ★有诗云:纸上得来终觉浅,绝知此事要躬行.--陆游(宋) 本篇内容整理及解析:Code_流苏(CSDN) 观前提示:以下解析来自自己思考以及笔记记录的综合,可能并不官 ...

  7. 北京理工大学大学计算机实验报告四,北京理工大学汇编实验报告实验四.doc

    文档介绍: 本科实验报告实验名称:分支和循环实验课程名称:CPU与汇编语言和选修实验实验时间:.10.24任课教师:高平实验地点:10-102实验教师:高平实验类型:█原理验证□综合设计□自主创新学生 ...

  8. 单周期CPU实验之学习之旅

    初接触到CPU(处理器)的实现,有很多东西需要先学习一下,才能了解其中的原理,更好地实现它.首先,你需要深入了解MIPS指令集,理解其各个指令的执行过程:其次,你需要掌握Verilog语言的使用,理解 ...

  9. 计算机组成原理学习笔记(第三部分 CPU部分)

    学习视频 随看随记 MAR(主存地址寄存器)和MDR(主存数据寄存器)不是CPU的组件,但是常常把他们两个集成到CPU中. ()中保存的是地址,或者寄存器,表示地址或寄存器中的内容.例如AD(IR): ...

  10. 计算机组成原理(第四版)课后答案 第一章

    1.比较数字计算机和模拟计算机的特点 模拟计算机的特点:数值由连续量来表示,运算过程也是连续的. 数字计算机的特点:数值由数字量(离散量)来表示,运算按位进行,并且不连续地跳动计算. 2.数字计算机如 ...

最新文章

  1. AAAI 独家 | 腾讯AI Lab 现场陈述论文:使众包配对排名聚合信息最大化的 HodgeRank
  2. Angular input控件的click事件响应处理的调用上下文
  3. .NET静态代码织入——肉夹馍(Rougamo)
  4. RS485串口光端机产品功能特点介绍
  5. UISwitch 添加 标签
  6. https p12证书请求解决问题过程
  7. 一人网站所有的 ip地址_咸宁网站建设-网站的主要特征
  8. android 字体切换快捷键,Android stdio 字体设置及快捷键
  9. sql载取最后出现字符前的字符
  10. Spring→事务、隔离级别、事务传播行为、编程式事务控制、XML配置声明式事务(原始方式)、XML配置声明式事务(基于tx/aop)、@注解配置声明式事务、优势总结
  11. KeyMob聚合致力于为广大开发者及广告聚合服务
  12. Pycharm设置默认UTF8编码格式
  13. 机器学习标准教科书PRML的Python实现:最佳读书伴侣
  14. Python教学视频(七)分支结构
  15. 【机器学习】网格搜索、随机搜索和贝叶斯搜索实用教程
  16. linux导入表dmp文件命令,linux下导入.dmp文件
  17. java100道逻辑题及答案_100道Java面试题收集整理及参考答案
  18. Linux /usr、/usr/share、/etc介绍
  19. HTML+CSS模仿百度首页(gird+flex布局)
  20. opencv图像识别训练实例

热门文章

  1. win10 python安装以及编辑器pycharm安装
  2. iproxy工具的作用
  3. VMware安装最新版CentOS7图文教程
  4. Linux下wine最新版源码编译
  5. 初探flask debug生成pin码
  6. 蜂鸣器音乐代码 天空之城_歌单 | 音乐拥有魔力
  7. 适合客厅的挂画 山水画让家活色生香
  8. vue 解决跨域问题(开发环境)
  9. MFC + MDI文件拖拽功能
  10. Android NDK SO库隐藏内部符号表