Verilog实现流水线CPU实验报告

合集下载

verilog任务报告

verilog任务报告

1.PWM学会了模块间参数的调用,了解了pwm的原理,可以根据需求对不同的div进行设定从而获得一个条件限制从而获得一些不同的效果。

2. 8位桶形移位器波形这里用了一个case来表示移动的位数同时也能表示几种不同的情况。

每变换一个数或者位数便重新进行判断,从而得到准确的结果。

移位在之后的任务中显得比较重要。

所以使用快速准确的移位器可以较多地节省时间。

3.FIFO4.流水线加法器波形这里采用的是两级流水。

并在其中添加了拼接从而使得结果更加准确。

这里有一个问题。

我本来设定的firsta,b是两位的,但是相加的时候发生了溢出。

所以,把它设定为三位,这样进位就可以保存在多余出的那一位中。

做完这道题让我对流水线有了更深的理解。

5.除法器I波形这是个整数除法器,用的是辗转相减,这里用了case来实现循环,这样就使得原本比较棘手的while循环更加简便。

也可以较为条理的顺序执行。

但是,这种方法似乎不是很高效,因为,结果的出现有明显的延迟,而且,随着被除数和除数的改变,延迟也会有所改变。

所以,我采用了以下方法。

6.除法器II波形这个除法器是通过移位来实现的,逻辑较为复杂,尤其是,for循环块中的逻辑,想了很长时间。

但是,它更为高效,因为是通过按位实现。

所以,我在下面的流水线除法器中,使用了这个方法。

7.流水线除法器这是流水线除法器,采用九级流水,其实,是把上面的循环,分成了九个步骤。

但是,这其中的参数处理起来比较棘手,所以我使用了很多寄存器。

九级流水也使得吞吐量大幅提高。

7个操作数由原来的9个周期变为现在的2.285个周期。

8.阵列除法器波形;。

Verilog HDL 实验报告

Verilog HDL 实验报告

Verilog实验报告班级:学号:姓名:实验1 :用 Verilog HDL 程序实现直通线1 实验要求:(1) 编写一位直通线的 Veirlog HDL 程序.(2) 编写配套的测试基准.(3) 通过 QuartusII 编译下载到目标 FPGA器件中进行验证.(4) 建议用模式 52 试验程序:module wl(in,out);input in;output out;wire out;assign out=in;endmodule3 测试基准:`include “wl.v”module wl_tb;reg in_tb;wire out_tb;initialbeginin_tb =0;#100 in_tb =1;#130 in_tb =0;endendmodule4 仿真图形:实验2 :用 Verilog HDL 程序实现一位四选一多路选择器1实验要求:(1) 编写一位四选一多路选择器的 Veirlog HDL 程序.(2) 编写配套的测试基准.(3) 通过 QuartusII 编译下载到目标 FPGA器件中进行验证.(4)建议用模式 52 试验程序:module mux4_to_1 (out,i0,i1,i2,i3,s1,s0);output out;input i0,i1,i2,i3;input s1, s0;reg out;always @ (s1 or s0 or i0 or i1 or i2 or i3)begincase ({s1, s0})2'b00: out=i0;2'b01: out=i1;2'b10: out=i2;2'b11: out=i3;default: out=1'bx;endcaseendendmodule3 测试基准:`include "mux4_to_1.v"module mux4_to_1_tb1;reg ain,bin,cin,din;reg[1:0] select;reg clock;wire outw;initialbeginain=0;bin=0;cin=0;din=0;select=2'b00;clock=0;endalways #50 clock=~clock;always @(posedge clock)begin#1 ain={$random} %2;#3 bin={$random} %2;#5 cin={$random} %2;#7 din={$random} %2;endalways #1000 select[0]=!select[0];always #2000 select[1]=!select[1];mux4_to_1 m(.out(outw),.i0(ain),.i1(bin),.i2(cin),.i3(din),.s1(select[1]),.s0(select[0])); endmodule4 仿真图形:实验3:用 Verilog HDL 程序实现十进制计数器1实验要求:(1) 编写十进制计数器的 Veirlog HDL 程序. 有清零端与进位端, 进位端出在输出为 9 时为高电平.(2) 编写配套的测试基准.(3) 通过 QuartusII 编译下载到目标 FPGA器件中进行验证.(4) 自行选择合适的模式2 实验程序:module counter_10c (Q, clock, clear, ov);output [3:0] Q;output ov;input clock, clear;reg [3:0] Q;reg ov;initial Q=4'b0000;always @ (posedge clear or negedge clock)beginif (clear)Q<=4'b0;else if (Q==8)beginQ<=Q+1;ov<=1'b1;endelse if (Q==9)beginQ<=4'b0000;ov<=1'b0;endelsebeginQ<=Q+1;ov<=1'b0;endendendmodule3 测试基准:`include"./counter_10c.v"module counter_10c_tb;wire[3:0] D_out;reg clk,clr;wire c_out;reg[3:0] temp;initialbeginclk=0;clr=0;#100 clr=1;#20 clr=0;endalways #20 clk=~clk;counter_10c m_1(.Q(D_out),.clear(clr),.clock(clk),.ov(c_out)); endmodule4 仿真波形:实验4 :用 Verilog HDL 程序实现序列检测器1 实验要求:、(1) 编写序列检测器的 Veirlog HDL 程序. 检测串行输入的数据序列中是否有目标序列5'b10010, 检测到指定序列后, 用一个端口输出高电平表示.(2) 编写配套的测试基准.(3) 通过 QuartusII 编译下载到目标 FPGA器件中进行验证.(4) 自行选择合适的模式2试验程序:module e15d1_seqdet( x, z, clk, rst);input x,clk, rst;output z;reg [2:0] state;wire z;parameter IDLE = 3 'd0,A = 3'd1,B = 3'd2,C = 3'd3,D = 3'd4,E = 3'd5,F = 3'd6,G = 3'd7;assign z =(state==D && x==0)?1:0;always @(posedge clk or negedge rst)if(!rst)beginstate<=IDLE;endelsecasex(state)IDLE: if(x==1)state<=A;else state<=IDLE;A: if (x==0)state<=B;else state<=A;B: if (x==0)state<=C;else state<=F;C: if(x==1)state<=D;else state<=G;D: if(x==0)state<=E;else state<=A;E: if(x==0)state<=C;else state<=A;F: if(x==1)state<=A;else state<=B;G: if(x==1)state<=F;else state <=G;default: state<=IDLE;endcaseendmodule3测试基准:`include"e15d1_seqdet.v"`timescale 1ns/1ns`define halfperiod 20module e15d1_seqdet_tb;reg clk, rst;reg [23:0] data;wire z;reg x;initialbeginclk =0;rst =1;#2 rst =0;#30 rst =1;data= 20 'b1100_1001_0000_1001_0100;#(`halfperiod*1000) $stop;endalways #(`halfperiod) clk=~clk;always @ (posedge clk)begin#2 data={data[22:0],data[23]};x=data[23];ende15d1_seqdet m(.x(x),.z(z),.clk(clk),.rst(rst)); endmodule4仿真波形:。

流水线实验报告

流水线实验报告

流水线实验报告一、实验目的本次实验旨在探究流水线技术在计算机体系结构中的应用,并了解流水线的工作原理与效果。

通过对流水线的实验,掌握流水线操作的过程和相关概念,并通过实践了解其对计算机性能的提升作用。

二、实验器材与软件环境实验使用的器材为一台配有Intel Core i7处理器的计算机。

软件环境为Windows 10操作系统,使用C语言编译器进行代码编写和实验运行。

三、实验内容1. 流水线概述流水线是一种用于提高计算机处理器效率的技术。

它将任务划分为多个阶段,使得每个阶段都能并行地处理不同的任务。

通过将多个任务拆分并在不同的阶段同时进行,可以显著提高计算机处理速度。

2. 流水线原理流水线工作原理如下:1) 将任务划分为多个子任务,并在不同的阶段上并行执行。

2) 每个阶段的任务之间通过专门的寄存器传递数据。

3) 每个阶段的任务完成后,将结果写入寄存器,供下一个阶段使用。

4) 流水线的效果取决于各个阶段的任务执行时间,如果存在某个阶段的任务耗时较长,则可能导致整个流水线效率下降。

3. 流水线的实现实验中我们使用C语言编写一段简单的代码来模拟流水线的实现过程。

我们通过将输入的整数加1后输出,来模拟流水线的工作状态。

cinclude <stdio.h>int main() {int input[5] = {1, 2, 3, 4, 5};int output[5];int i;for (i = 0; i < 5; i++) {output[i] = input[i] + 1;}for (i = 0; i < 5; i++) {printf("%d\n", output[i]);}return 0;}上述代码将输入数组中的每个元素加1后,输出到屏幕上。

在这个过程中,我们可以将输入和输出视为流水线中的阶段,每个阶段都有固定的任务。

4. 实验结果与分析在实验中,我们输入数组为{1, 2, 3, 4, 5},运行结果如下:23456可以看到,实验结果符合我们的预期,每个输入元素都成功地加1后输出。

verilog实验报告

verilog实验报告

verilog实验报告Verilog实验报告引言:Verilog是一种硬件描述语言(HDL),用于设计和模拟数字电路。

它是一种高级语言,能够描述电路的行为和结构,方便工程师进行数字电路设计和验证。

本实验报告将介绍我在学习Verilog过程中进行的实验内容和所获得的结果。

实验一:基本门电路设计在这个实验中,我使用Verilog设计了基本的逻辑门电路,包括与门、或门和非门。

通过使用Verilog的模块化设计,我能够轻松地创建和组合这些门电路,以实现更复杂的功能。

我首先创建了一个与门电路的模块,定义了输入和输出端口,并使用逻辑运算符和条件语句实现了与门的功能。

然后,我创建了一个测试模块,用于验证与门的正确性。

通过输入不同的组合,我能够验证与门的输出是否符合预期。

接下来,我按照同样的方法设计了或门和非门电路,并进行了相应的测试。

通过这个实验,我不仅学会了使用Verilog进行基本门电路的设计,还加深了对逻辑电路的理解。

实验二:时序电路设计在这个实验中,我学习了如何使用Verilog设计时序电路,例如寄存器和计数器。

时序电路是一种具有状态和时钟输入的电路,能够根据时钟信号的变化来改变其输出。

我首先设计了一个简单的寄存器模块,使用触发器和组合逻辑电路实现了数据的存储和传输功能。

然后,我创建了一个测试模块,用于验证寄存器的正确性。

通过输入不同的数据和时钟信号,我能够观察到寄存器的输出是否正确。

接下来,我设计了一个计数器模块,使用寄存器和加法电路实现了计数功能。

我还添加了一个复位输入,用于将计数器的值重置为初始状态。

通过测试模块,我能够验证计数器在不同的时钟周期内是否正确地进行计数。

通过这个实验,我不仅学会了使用Verilog设计时序电路,还加深了对触发器、寄存器和计数器的理解。

实验三:组合电路设计在这个实验中,我学习了如何使用Verilog设计组合电路,例如多路选择器和加法器。

组合电路是一种没有状态和时钟输入的电路,其输出只取决于当前的输入。

Verilog十大基本功1(流水线设计PipelineDesign)

Verilog十大基本功1(流水线设计PipelineDesign)

Verilog十大基本功1(流水线设计PipelineDesign)需求说明:Verilog设计基础内容:流水线设计来自:时间的诗流水线设计前言:本文从四部分对流水线设计进行分析,具体如下:第一部分什么是流水线第二部分什么时候用流水线设计第三部分使用流水线的优缺点第四部分流水线加法器举例第一什么是流水线流水线设计就是将组合逻辑系统地分割,并在各个部分(分级)之间插入寄存器,并暂存中间数据的方法。

目的是将一个大操作分解成若干的小操作,每一步小操作的时间较小,所以能提高频率,各小操作能并行执行,所以能提高数据吞吐率(提高处理速度)。

第二什么时候用流水线设计使用流水线一般是时序比较紧张,对电路工作频率较高的时候。

典型情况如下:1)功能模块之间的流水线,用乒乓buffer 来交互数据。

代价是增加了 memory 的数量,但是和获得的巨大性能提升相比,可以忽略不计。

2) I/O 瓶颈,比如某个运算需要输入 8 个数据,而 memroy 只能同时提供 2 个数据,如果通过适当划分运算步骤,使用流水线反而会减少面积。

3)片内 sram 的读操作,因为 sram 的读操作本身就是两极流水线,除非下一步操作依赖读结果,否则使用流水线是自然而然的事情。

4)组合逻辑太长,比如(a+b)*c,那么在加法和乘法之间插入寄存器是比较稳妥的做法。

第三使用流水线的优缺点1)优点:流水线缩短了在一个时钟周期内给的那个信号必须通过的通路长度,增加了数据吞吐量,从而可以提高时钟频率,但也导致了数据的延时。

举例如下:例如:一个 2 级组合逻辑,假定每级延迟相同为 Tpd,1.无流水线的总延迟就是2Tpd,可以在一个时钟周期完成,但是时钟周期受限制在 2Tpd;2.流水线:每一级加入寄存器(延迟为T co)后,单级的延迟为Tpd+Tco,每级消耗一个时钟周期,流水线需要 2 个时钟周期来获得第一个计算结果,称为首次延迟,它要2*(Tpd+Tco),但是执行重复操作时,只要一个时钟周期来获得最后的计算结果,称为吞吐延迟( Tpd+Tco)。

Verilog流水灯实验报告.pptx

Verilog流水灯实验报告.pptx
reg rst_n; reg cnt; wire led;
initial begin clk = 0; rst_n = 0; #100 rst_n = 1; end
always #5 clk=~clk;
LSD LSD_inst( .clk(clk), .rst_n(rst_n),
学海无 涯
流水灯实验报告
实验二 流水灯
一、 实验目的
学会编写一个简单的流水灯程序并掌握分频的方法。熟悉 Modelsim 仿真软件的使用。
二、 实验要求
用 Quartus 编写流水灯程序,在 Modelsim 软件中进行仿真。
三、 实验仪器和设备
1、 硬件:计算机 2、 软件:Quartus、Modelsim、(UE)
四、 实验内容
1、 将时钟周期进行分频。 2、 编写 Verilog 程序实现 LED 等依次亮灭,用 Modelsim 进行仿真,绘制波形图。
五、 实验设计
(一)分频原理 已知时钟周期f 为 50MHz,周期 T 为 1/f,即 20ns。若想得到四分频计数器,即周期为 80ns 的时钟,需要把时钟进行分频。即每四个时钟周期合并为一个周期。原理图如图 1 所示。
1
学海无 涯
clk LED
LED
FPGA
cnt
图 2 设计基本框图
(四)位拼接的用法 若输入 a=4'b1010,b=3'b101,c=4'b0101,想要使输出 d=5'b10001 用位拼接,符号“{ }”:d<={b[2:1],c[1],a[2:1]} 即把 b 的低 1~2 位 10,c 的低 1 位 0,a 的低 1~2 位 01 拼接起来,得到 10 0 01。 流水灯

计算机组成CPU数据通路verilog实验报告.doc

计算机组成CPU数据通路verilog实验报告.doc

计算机组成与系统结构实验报告院(系):计算机科学与技术学院专业班级:学号:姓名:同组者:指导教师:实验时间: 2012 年 5 月 23 日实验目的:完成处理器的单周期cpu的设计。

实验仪器:PC机(安装Altebra 公司的开发软件 QuartusII)一台实验原理:控制器分为主控制器和局部ALU控制器两部分。

主控制器的输入为指令操作码op,输出各种控制信号,并根据指令所涉及的ALU运算类型产生ALUop,同时,生成一个R-型指令的控制信号R-type,用它来控制选择将ALUop输出作为ALUctr信号,还是根据R-型指令中的func字段来产生ALUctr信号。

实验过程及实验记录:1.设计过程:第一步:分析每条指令的功能,并用RTL来表示。

第二步:根据指令的功能给出所需的元件,并考虑如何将它们互连。

第三步:确定每个元件所需控制信号的取值。

第四步:汇总各指令涉及的控制信号,生成所反映指令与控制信号之间的关系图。

第五步:根据关系表,得到每个控制信号的逻辑表达式,据此设计控制电路。

2.完成代码的编写,并调试运行。

1)controlmoduleControl(op,func,Branch,Jump,RegDst,ALUSrc,ALUctr,MemtoReg, RegWr,MemWr,ExtOp);input [5:0] op,func;output regBranch,Jump,RegDst,ALUSrc,MemtoReg,RegWr,MemWr,ExtOp; output reg [2:0] ALUctr;always @(op)case(op)6'b000000:beginBranch=0;Jump=0;RegDst=1;ALUSrc=0;MemtoReg=0;RegWr=1;MemWr =0;case(func)6'b100000:ALUctr=3'b001;6'b100010:ALUctr=3'b101;6'b100011:ALUctr=3'b100;6'b101010:ALUctr=3'b111;6'b101011:ALUctr=3'b110;endcaseend6'b001101:beginBranch=0;Jump=0;RegDst=0;ALUSrc=1;MemtoReg=0;RegWr=1;MemWr =0;ExtOp=0;ALUctr=3'b010;end6'b001001:beginBranch=0;Jump=0;RegDst=0;ALUSrc=1;MemtoReg=0;RegWr=1;MemWr =0;ExtOp=1;ALUctr=3'b000;end6'b100011:beginBranch=0;Jump=0;RegDst=0;ALUSrc=1;MemtoReg=1;RegWr=1;MemWr =0;ExtOp=1;ALUctr=3'b000;end6'b101011:beginBranch=0;Jump=0;ALUSrc=1;RegWr=0;MemWr=1;ExtOp=1;ALUctr=3' b000;end6'b000100:beginBranch=1;Jump=0;ALUSrc=0;RegWr=0;MemWr=0;ALUctr=3'b100; end6'b000010:beginBranch=0;Jump=1;RegWr=0;MemWr=0;endendcaseendmodule2)数据通路DataRoadmoduleDataRoad(Run,Clk,RegWr,MemWr,MemtoReg,RegDst,Branch,Jump,E xtOp,ALUctr,ALUSrc,busA,busB,busW,Instruction,Reg0,Reg1,Re g2,Reg3,Reg4,Mem1,Mem2,Mem3,Result,Im);inputRun,Clk,RegWr,MemWr,MemtoReg,RegDst,Branch,Jump,ExtOp,ALUS rc;input [2:0] ALUctr;output [31:0]Instruction,busA,busB,busW,Reg0,Reg1,Reg2,Reg3,Reg4,Mem1,M em2,Mem3,Result,Im;wire [31:0] busC,DataOut;wire [15:0] im;wire [4:0] Rs,Rd,Rt;wire Overflow,Zero;QZL qzl(Clk,Branch,Jump,Zero,Instruction,Run);assign Rs=Instruction[25:21];assign Rt=Instruction[20:16];assign Rd=Instruction[15:11];assign im=Instruction[15:0];Registerregister(Run,RegWr,Overflow,RegDst,Rd,Rs,Rt,busW,busA,busB ,Clk,Reg0,Reg1,Reg2,Reg3,Reg4);ALU alu(busA,busC,ALUctr,Zero,Overflow,Result);DataMem(Run,MemWr,Clk,busB,DataOut,Result,Mem1,Mem2,Mem3); MUX mux1(ALUSrc,busB,Im,busC);MUX mux2(MemtoReg,Result,DataOut,busW);Extender ext(im,Im,ExtOp);endmodule3)取指令module QZL(Clk,Branch,Jump,Zero,Instruction,Run);input Clk,Branch,Jump,Zero,Run;output [31:0] Instruction;wire [4:0] addmem;reg [29:0] PC;wire [29:0] Newpc,pc_1,pc_2,pc_3,pc_12,imm30;wire Branch_Zero;assign addmem={PC[2:0],2'b00};InsMem GetIns(addmem,Instruction);always @(negedge Clk)if(Run==1)beginPC<=Newpc;endelsebeginPC<=0;endassign pc_1=PC+1;assign imm30={{14{Instruction[15]}},Instruction[15:0]}; assign pc_2=pc_1+imm30;assign pc_3={PC[29:26],Instruction[25:0]};assign Branch_Zero=Branch&Zero;MUX m1(Branch_Zero,pc_1,pc_2,pc_12);MUX m2(Jump,pc_12,pc_3,Newpc);endmodulemodule InsMem(addmem,Instruction);input [4:0] addmem;output reg[31:0] Instruction;reg [31:0] Mem[31:0];always @(*)beginMem[0]<={6'b100011,5'b00000,5'b00001,5'b00000,5'b00000,6'b 000001};Mem[4]<={6'b100011,5'b00000,5'b00010,5'b00000,5'b00000,6'b 000010};Mem[8]<={6'b000000,5'b00001,5'b00010,5'b00011,5'b00000,6'b 100000};Mem[12]<={6'b101011,5'b00000,5'b00011,5'b00000,5'b00000,6' b000010};Mem[16]<={6'b001101,5'b00100,5'b00100,5'b11111,5'b11111,6' b111111};Mem[20]<={6'b000000,5'b00011,5'b00010,5'b00010,5'b00000,6' b100010};Mem[24]<={6'b000100,5'b00010,5'b00001,5'b00000,5'b00000,6' b001000};Mem[28]<={6'b000010,5'b00000,5'b00000,5'b00000,5'b00000,6' b000000};endalways @(*)。

verilog实验报告流水灯数码管秒表交通灯

verilog实验报告流水灯数码管秒表交通灯

流水灯实验目的:在basys2开发板上实现LED灯的花样流水的显示,如隔位显示,依次向左移位显示,依次向右移位显示,两边同时靠中间显示。

实验仪器:FPGA开发板一块,计算机一台。

实验原理:当一个正向的电流通过LED时,LED就会发光。

当阳极的电压高于阴极的电压时,LED就会有电流通过。

当在LED上增添一个典型值为1.5V—2.0V之间的电压时,LED就会有电流通过并发光。

实验内容:顶层模块:输入信号:clk_50MHz(主时钟信号),rst(重置信号),输出信号:[7:0] led(LED灯控制信号)。

module led_top(clkin,rst,led_out);input clkin, rst;output [7:0] led_out;wire clk_1hz;divider_1hz d0(clkin, rst, clk_1hz);led l0(clk_1hz, rst, led_out);endmodule分频模块:module divider_1hz(clkin,rst,clkout);input clkin,rst;output reg clkout;reg [24:0] cnt;always@(posedge clkin, posedge rst)beginif(rst) begincnt<=0;clkout<=0; endelse if(cnt==24999999) begincnt<=0;clkout=!clkout; endelse cnt<=cnt+1;endendmodule亮灯信号模块:module led(clkin,rst,led_out);input clkin,rst;output [7:0] led_out;reg [2:0] state;always@(posedge clkin, posedge rst)if(rst) state<=0;else state<=state+1;always@(state)case(state)3'b000:ledout<=8'b0000_0001;3'b001:ledout<=8'b0000_0010;3'b010:ledout<=8'b0000_0100;3'b011:ledout<=8'b0000_1000;3'b100:ledout<=8'b0001_0000;3'b101:ledout<=8'b0010_0000;3'b110:ledout<=8'b0100_0000;3'b111:ledout<=8'b1000_0000;endcaseendmodule实验中存在的问题:1 芯片选择问题automotive spartan3EXA3S100E XA3S250E CPG132spartan3EXC3S100E XC3S250E CP1322 时序逻辑部分,阻塞赋值和非阻塞赋值混用always@(posedge clk)begina=b+c;d<=e+f;end3 UCF文件格式错误NET “CLK” LOC = “B8”;NET “a” LOC = “N11”;NET “b” LOC = “G13”;NET “c[0]”LOC =“K11;数码管实验目的:设计一个数码管动态扫描程序,实现在四位数码管上动态循环显示“1”、“2”“3”“4”;实验仪器:FPGA开发板一块,计算机一台。

计算机组成原理实验教程

计算机组成原理实验教程

计算机组成原理实验教程计算机组成原理实验是计算机科学与技术专业中非常重要的一门实践课程。

通过实验,学生可以深入了解计算机的基本构成和工作原理,并且培养实际操作的能力。

本教程旨在提供一系列详细的实验指导,帮助学生顺利完成计算机组成原理实验。

序言计算机组成原理是计算机科学与技术专业的一门核心课程,作为理论和实践相结合的实验教程,对于学生深入了解计算机的内部结构和工作原理至关重要。

本教程将介绍计算机组成原理实验的基本内容和实验报告的撰写要求,帮助学生更好地掌握实验技巧和理论知识。

实验一:数字逻辑电路设计与仿真本实验旨在让学生学会使用Verilog HDL设计数字逻辑电路,并通过仿真验证电路的正确性。

首先,学生需要了解Verilog HDL的基本语法和仿真工具的使用方法。

然后,根据实验要求,设计并仿真一个简单的数字逻辑电路,如全加器或比较器。

最后,学生需要撰写实验报告,详细介绍电路设计的过程、仿真结果和分析。

实验二:单周期CPU设计与实现本实验要求学生设计并实现一个单周期的CPU。

在实验过程中,学生需要了解指令的执行过程和控制信号的生成原理,设计CPU的数据通路和控制逻辑,并编写Verilog HDL代码进行实现。

实验完成后,学生需要进行功能仿真和时序仿真,验证CPU的正确性和性能。

实验报告应包括CPU设计的思路、关键问题的解决方法和仿真结果的分析。

实验三:多周期CPU设计与实现本实验要求学生进一步完善CPU的设计,实现一个多周期的CPU。

在实验过程中,学生需要改进单周期CPU的设计,引入时序控制信号和状态机,实现指令的多周期执行。

实验完成后,学生需要进行功能仿真和时序仿真,验证CPU的正确性和性能提升。

实验报告应包括多周期CPU设计的过程、关键问题的解决方法和仿真结果的分析。

实验四:流水线CPU设计与实现本实验要求学生设计并实现一个流水线CPU。

在实验过程中,学生需要了解流水线技术的基本原理和数据冒险的处理方法,设计流水线CPU的数据通路和控制逻辑。

Verilog实现流水线CPU实验报告

Verilog实现流水线CPU实验报告

实验报告课程名称:__ 数字系统设计实验Ⅱ__指导老师:成绩:_______实验名称:流水线MIPS微处理器设计实验类型:____设计型__ __一、实验目的和要求(必填)二、实验内容和原理(必填)三、主要仪器设备(必填)四、操作方法和实验步骤五、实验数据记录和处理六、实验结果与分析(必填)七、讨论、心得一、实验目的1.了解提高CPU性能的方法。

2.掌握流水线MIPS微处理器的工作原理。

3.理解数据冒险、控制冒险的概念以及流水线冲突的解决方法。

4.掌握流水线MIPS微处理器的测试方法。

二、实验任务设计一个32位流水线MIPS微处理器,具体要求如下:1.至少运行下列MIPS32指令。

(1)算术运算指令:ADD、ADDU、SUB、SUBU、ADDI、ADDIU。

(2)逻辑运算指令:AND、OR、NOR、XOR、ANDI、ORI、XORI、SLT、SLTU、SLTI、SLTIU。

(3)移位指令:SLL、SLLV、SRL、SRLV、SRA。

(4)条件分支指令:BEQ、BNE、BGEZ、BGTZ、BLEZ、BLTZ。

(5)无条件跳转指令:J、JR。

(6)数据传送指令:LW、SW。

(7)空指令:NOP。

2.采用5级流水线技术,对数据冒险实现转发或阻塞功能。

3.在XUP Virtex-Ⅱ Pro 开发系统中实现MIPS微处理器,要求CPU的运行速度大于25MHz。

三、实验原理1.总体设计流水线是数字系统中一种提高系统稳定性和工作速度的方法,广泛应用于高档CPU的架构中。

根据MIPS处理器的特点,将整体的处理过程分为取指令(IF)、指令译码(ID)、执行(EX)、存储器访问(MEM)和寄存器会写(WB)五级,对应多周期的五个处理阶段。

如图3.1所示,一个指令的执行需要5个时钟周期,每个时钟周期的上升沿来临时,此指令所代表的一系列数据和控制信息将转移到下一级处理。

图3.1 流水线流水作业示意图由于在流水线中,数据和控制信息将在时钟周期的上升沿转移到下一级,所以规定流水线转移变量命名遵守如下格式:名称_流水线级名称例如:在ID级指令译码电路(Decode)产生的寄存器写允许信号RegWrite在ID级、EX级、MEM级和WB级上的命名分别为RegWrite_id、RegWrite_ex、RegWrite_mem和RegWrite_wb。

cpu设计实验报告

cpu设计实验报告

cpu设计实验报告CPU设计实验报告摘要:本实验旨在设计一个基本的中央处理器(CPU),并通过实验验证其性能和功能。

在设计过程中,我们使用了Verilog硬件描述语言和ModelSim仿真工具。

通过对CPU的设计和仿真实验,我们验证了CPU的正确性和性能,并对其进行了性能分析和优化。

1. 引言CPU是计算机系统中最核心的部件之一,它负责执行计算机指令和控制数据流动。

因此,设计一个高效、稳定的CPU对于计算机系统的性能至关重要。

本实验旨在通过Verilog硬件描述语言和ModelSim仿真工具,设计一个基本的CPU,并验证其性能和功能。

2. 设计过程我们首先对CPU的功能和性能进行了分析和规划,确定了CPU的基本架构和指令集。

然后,我们使用Verilog语言编写了CPU的硬件描述,并通过ModelSim进行了仿真验证。

在设计过程中,我们重点关注了CPU的时序逻辑、数据通路和控制逻辑,确保CPU能够正确地执行指令并保持稳定的性能。

3. 实验结果通过对CPU的设计和仿真实验,我们验证了CPU的正确性和性能。

我们使用了一系列的测试用例对CPU进行了功能和性能测试,并对其进行了性能分析和优化。

实验结果表明,我们设计的CPU能够正确地执行各种指令,并在性能上达到了预期的目标。

4. 总结和展望本实验通过Verilog硬件描述语言和ModelSim仿真工具,设计并验证了一个基本的CPU。

通过实验,我们对CPU的设计和性能有了更深入的了解,并对其进行了性能分析和优化。

未来,我们将进一步完善CPU的设计,提高其性能和功能,以满足计算机系统的需求。

综上所述,本实验为我们提供了一个宝贵的机会,通过实际设计和验证,深入了解了CPU的工作原理和性能特点,为我们今后的学习和研究打下了坚实的基础。

希望通过不懈的努力,我们能够设计出更加高效、稳定的CPU,为计算机系统的发展做出更大的贡献。

VerilogXilinx五级流水CPU代码

VerilogXilinx五级流水CPU代码

Verilog/Xilinx五级流水CPU代码,WebUploader的java后端上传代码(支持分片上传),WIN32贪食蛇改进版,新增计分、等级及暂停功能,Windows下用SDL2实现一个简单的五子棋windows编程c/c++获取域名的IP地址,安装brew[Shell/批处理],安卓找图有什么好的算法安卓图片异步加载工具类,安卓自定义PagerAdapter类,按状态统计tcp连接数量&sort使用,把ByteArrayOutputStream直接作为输入流,百度前端技术学院学习:三行自适应布局[代码] [Flash/ActionScript/Flex]代码var startTime:uint = getTimer();var t:Array = new Array(12515,123232,1515);t[0] = 1232323;t[0] = new Array(1, 2, 3, 4, [1987, 1988, 1989, [19901, 19902, 19903, [199031, 199032, 199033] ] ]);t = [10, [5425, 156,], 10000, 'PHP', true, 0.52455, -15, '-132213656565', null, undefined];t['P'] = 'PPPPPPP';t['obj'] = -15455555;t['list'] = [5,56556,2656,565,665,656,59,[5656565656,656556,4999],5625623,2656,222,[212122,656 56,999,998956,22633,22666,1484223,[10,20,30,40,50,60,[70, 71, 72, 73, 74, 75, 76,[771, 772, 773, 774, 775, [7761, 7762, 7763, 7764, [77641, 77642, 77643, 77644]]]]]]];var obj = {a:'A',b:'B',c:{c1:'C1',c2:'C2'},d:'D'};//C#隐式转换/显式转换(implicit/explicit)//trace(typeof Array);//trace(typeof Object);//c#代码样例-S05GK接口发送短信function printArray(array:Object, indent = ''){for (var i in array){if (array[i] is Array){trace(indent, i+' => Array ('); //数组printArray(array[i], indent+' '); //递归循环trace(indent, ')');}else{if (array[i] is Number){if (array[i] is int){if (array[i] is uint){trace(indent, i+' => (Unit)'+array[i]);//无符号整数}else{trace(indent, i+' => (Int)'+array[i]);//有符号整数}}else{trace(indent, i+' => (Number)'+array[i]);//浮点数}}else if (array[i] is String){trace(indent, i+' => (String) '+array[i]);//字符串}else if (array[i] is Boolean){trace(indent, i+' => (Boolean) '+array[i]);//布尔值}else if (array[i] == null){trace(indent, i+' => (Null) '+array[i]);//空值 }else{trace(indent, i+' => (?) '+array[i]);//未知类型 }}}}//Boolean(布尔)、int(有符整型)、Number(浮点)、String(字符串)、uint(无符整型)printArray(t);//printArray(obj);var endTime:uint = getTimer();trace('运行需时:', endTime - startTime, '毫秒'); [代码] [Flash/ActionScript/Flex]代码/*//运行输出结果:0 => Array (0 => (Unit) 11 => (Unit) 22 => (Unit) 33 => (Unit) 44 => Array (0 => (Unit) 19871 => (Unit) 19882 => (Unit) 19893 => Array (0 => (Unit) 199011 => (Unit) 199022 => (Unit) 199033 => Array (0 => (Unit) 1990311 => (Unit) 1990322 => (Unit) 199033))))1 => (Unit) 1232322 => (Unit) 15153 => Array (0 => (Unit) 101 => Array (0 => (Unit) 54251 => (Unit) 156)2 => (Unit) 100003 => (String) PHP4 => (Boolean) true5 => (Number) 0.524556 => (Int) -157 => (String) -1322136565658 => (Null) null9 => (Null) undefined)P => (String) PPPPPPPobj => (Int) -15455555list => Array (0 => (Unit) 51 => (Unit) 565562 => (Unit) 26563 => (Unit) 5654 => (Unit) 6655 => (Unit) 6566 => (Unit) 597 => Array (0 => (Number) 56565656561 => (Unit) 6565562 => (Unit) 4999)8 => (Unit) 56256239 => (Unit) 265610 => (Unit) 22211 => Array (0 => (Unit) 2121221 => (Unit) 656562 => (Unit) 9993 => (Unit) 9989564 => (Unit) 226335 => (Unit) 226666 => (Unit) 14842237 => Array (0 => (Unit) 101 => (Unit) 202 => (Unit) 303 => (Unit) 404 => (Unit) 505 => (Unit) 606 => Array (0 => (Unit) 701 => (Unit) 712 => (Unit) 723 => (Unit) 734 => (Unit) 745 => (Unit) 756 => (Unit) 767 => Array (0 => (Unit) 7711 => (Unit) 7722 => (Unit) 7733 => (Unit) 7744 => (Unit) 7755 => Array (0 => (Unit) 77611 => (Unit) 77622 => (Unit) 77633 => (Unit) 77644 => Array (0 => (Unit) 776411 => (Unit) 776422 => (Unit) 776433 => (Unit) 77644)))))))运行需时: 63 毫秒*/[代码] 获取百度的热词/*** 获取百度的热词* @user 小杰* @from isharey/?p=354* @return array 返回百度的热词数据(数组返回)*/function getBaiduHotKeyWord(){$templateRss = file_get_contents('top.baidu/rss_xml.php?p=top10');If (preg_match('/<table>(.*)<\/table>/is', $templateRss, $_description)) { $templateRss = $_description [0];$templateRss = str_replace("&", "&amp;", $templateRss);}$templateRss = "<?xml version=\"1.0\" encoding=\"GBK\"?>" . $templateRss; $xml = simplexml_load_String($templateRss);foreach ($xml->tbody->tr as $temp) {if (!empty ($temp->td->a)) {$keyArray [] = trim(($temp->td->a));}}return $keyArray;}[代码] [Java]代码import javax.media.*;public class StateHelper implements ControllerListener{public StateHelper (Player p) {player = p;p.addControllerListener(this);}public boolean configure (int timeOutMillis) {long startTime = System.currentTimeMillis();synchronized (this) {if (player instanceof Processor)((Processor)player).configure();elsereturn false;while(!configured && !failed) {try {wait(timeOutMillis);} catch (InterruptedException e) {// TODO: handle exception}if(System.currentTimeMillis() - startTime > timeOutMillis)break;}}return configured;}public boolean prefetch(int timeOutMillis) {long startTime = System.currentTimeMillis();synchronized (this) {player.prefetch();while(!prefetched && !failed) {try {wait(timeOutMillis);} catch (InterruptedException e) {// TODO: handle exception}if(System.currentTimeMillis() - startTime > timeOutMillis)break;}}return prefetched && !failed;}public boolean realize(int timeOutMillis) {long startTime = System.currentTimeMillis();synchronized (this) {player.realize();while(!realized && !failed) {try {wait(timeOutMillis);} catch (InterruptedException e) {// TODO: handle exception}if(System.currentTimeMillis() - startTime > timeOutMillis)break;}}return realized;}public boolean playToEndOfMedia(int timeOutMillis) {long startTime = System.currentTimeMillis();eom = false;synchronized (this) {player.start();while(!eom && !failed) {try {wait(timeOutMillis);} catch (InterruptedException e) {// TODO: handle exception}if(System.currentTimeMillis() - startTime > timeOutMillis)break;}}return eom && !failed;}public void close() {synchronized (this) {player.close();while(!closed) {try {wait(100);} catch (InterruptedException e) {// TODO: handle exception}}}player.removeControllerListener(this);}@Overridepublic synchronized void controllerUpdate(ControllerEvent e) { if(e instanceof RealizeCompleteEvent) {realized = true;} else if(e instanceof ConfigureCompleteEvent) {configured = true;} else if(e instanceof PrefetchCompleteEvent) {prefetched = true;} else if(e instanceof EndOfMediaEvent) {eom = true;} else if(e instanceof ControllerErrorEvent) {failed = true;} else if(e instanceof ControllerClosedEvent) {closed = true;} else {return;}notifyAll();}boolean configured = false;boolean realized = false;boolean prefetched = false;boolean closed = false;boolean failed = false;boolean eom = false;Player player = null;}[文件] Sender.java ~ 7KB (556)package rtp_test;import java.awt.Dimension;import java.io.IOException;import java.InetAddress;import java.UnknownHostException;import javax.media.CaptureDeviceInfo;import javax.media.CaptureDeviceManager;import javax.media.Codec;import javax.media.Control;import javax.media.Format;import javax.media.Manager;import javax.media.NoProcessorException;import javax.media.Owned;import javax.media.Processor;import javax.media.control.FormatControl;import javax.media.control.QualityControl;import javax.media.control.TrackControl;import javax.media.format.AudioFormat;import javax.media.format.UnsupportedFormatException;import javax.media.format.VideoFormat;import javax.media.protocol.ContentDescriptor;import javax.media.protocol.DataSource;import javax.media.protocol.PushBufferDataSource;import javax.media.protocol.PushBufferStream;import javax.media.rtp.InvalidSessionAddressException;import javax.media.rtp.RTPManager;import javax.media.rtp.SendStream;import javax.media.rtp.SessionAddress;public class Sender {public static void main(String[] args) {try {//设置本地地址和远端地址都为本机地址,自己传给自己,试验用 SessionAddress local = newSessionAddress(InetAddress.getLocalHost(),50000);SessionAddress target = newSessionAddress(InetAddress.getLocalHost(),60000);new Sender(local,target);} catch (UnknownHostException e) {e.printStackTrace();}}public Sender(SessionAddress local,SessionAddress target) {CaptureDeviceInfo info = (CaptureDeviceInfo) CaptureDeviceManager.getDeviceList(new VideoFormat(null)).get(0);// CaptureDeviceInfo info = (CaptureDeviceInfo) CaptureDeviceManager.getDeviceList(new AudioFormat(null)).get(0);用这一句替换上一句可改成音频传输Processor p = null;try {p = Manager.createProcessor(info.getLocator());} catch (NoProcessorException | IOException e) {e.printStackTrace();}StateHelper sh = new StateHelper(p);doSomeVideoProcess(p,sh);// doSomeAudioProcess(p,sh);用这一句替换上一句可改成音频传输RTPManager mgr = RTPManager.newInstance();try {mgr.initialize(local);mgr.addTarget(target);} catch (InvalidSessionAddressException | IOException e) {e.printStackTrace();}DataSource ds = p.getDataOutput();PushBufferDataSource pbds = (PushBufferDataSource)ds;PushBufferStream pbss[] = pbds.getStreams();for(int i=0;i<pbss.length;i++) {try {SendStream ss = mgr.createSendStream(ds, i); ss.start();} catch (UnsupportedFormatException | IOException e) { e.printStackTrace();}}p.start();try {Thread.sleep(60000);//传送一分钟后关闭} catch (InterruptedException e) {e.printStackTrace();}if(p!=null) {p.stop();p.close();}if(mgr!=null) {mgr.removeTargets("client disconnnected");mgr.dispose();mgr = null;}}private static void doSomeVideoProcess(Processor p,StateHelper sh) {sh.configure(5000);p.setContentDescriptor(newContentDescriptor(ContentDescriptor.RAW_RTP));setVideoTrackFormat(p.getTrackControls());sh.realize(5000);setJPEGQuality(p, 0.5f);}private static void doSomeAudioProcess(Processor p,StateHelper sh) {sh.configure(5000);p.setContentDescriptor(newContentDescriptor(ContentDescriptor.RAW));setAudioTrackFormat(p.getTrackControls());sh.realize(5000);}private static Format checkForVideoSizes(Format original, Format supported) {int width, height;Dimension size = ((VideoFormat)original).getSize();Format jpegFmt = new Format(VideoFormat.JPEG_RTP);Format h263Fmt = new Format(VideoFormat.H263_RTP);if (supported.matches(jpegFmt)) {// For JPEG, make sure width and height are divisible by 8.width = (size.width % 8 == 0 ? size.width :(int)(size.width / 8) * 8);height = (size.height % 8 == 0 ? size.height :(int)(size.height / 8) * 8);} else if (supported.matches(h263Fmt)) {// For H.263, we only support some specific sizes.if (size.width < 128) {width = 128;height = 96;} else if (size.width < 176) {width = 176;height = 144;} else {width = 352;height = 288;}} else {// We don't know this particular format. We'll just// leave it alone then.return supported;}return (new VideoFormat(null,new Dimension(width, height),Format.NOT_SPECIFIED,null,Format.NOT_SPECIFIED)).intersects(supported);}private static void setAudioTrackFormat(TrackControl[] trackControls) { boolean ok = false;for(TrackControl t:trackControls){if(!ok && t instanceof FormatControl) {if(((FormatControl)t).setFormat(newAudioFormat(AudioFormat.ULAW_RTP,8000,8,1))==null)t.setEnabled(false);elseok = true;} else {t.setEnabled(false);}}}private static boolean setVideoTrackFormat(TrackControl[] tracks) {if(tracks==null || tracks.length<1)return false;boolean atLeastOneTrack = false;for(TrackControl t:tracks) {if(t.isEnabled()) {Format[] supported = t.getSupportedFormats(); Format chosen = null;if(supported.length>0) {if(supported[0] instanceof VideoFormat) chosen =checkForVideoSizes(t.getFormat(),supported[0]);elsechosen = supported[0]; t.setFormat(chosen);atLeastOneTrack = true;} else {t.setEnabled(false);}} else {t.setEnabled(false);}}return atLeastOneTrack;}private static void setJPEGQuality(Processor p, float val) {Control cs[] = p.getControls();QualityControl qc = null;VideoFormat jpegFmt = new VideoFormat(VideoFormat.JPEG);// Loop through the controls to find the Quality control for// the JPEG encoder.for (int i = 0; i < cs.length; i++) {if (cs[i] instanceof QualityControl && cs[i] instanceof Owned) {Object owner = ((Owned)cs[i]).getOwner();// Check to see if the owner is a Codec.// Then check for the output format.if (owner instanceof Codec) {Format fmts[] =((Codec)owner).getSupportedOutputFormats(null);for (int j = 0; j < fmts.length; j++) {if (fmts[j].matches(jpegFmt)) {qc = (QualityControl)cs[i];qc.setQuality(val);break;}}}if (qc != null)break;}}}}[文件] Receiver.java ~ 3KB (471)package rtp_test;import java.awt.BorderLayout;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import java.io.IOException;import java.InetAddress;import java.UnknownHostException;import javax.media.ControllerEvent;import javax.media.ControllerListener;import javax.media.Manager;import javax.media.NoPlayerException;import javax.media.Player;import javax.media.RealizeCompleteEvent;import javax.media.control.BufferControl;import javax.media.protocol.DataSource;import javax.media.rtp.InvalidSessionAddressException;import javax.media.rtp.RTPManager;import javax.media.rtp.ReceiveStream;import javax.media.rtp.ReceiveStreamListener;import javax.media.rtp.SessionAddress;import javax.media.rtp.event.ByeEvent;import javax.media.rtp.event.NewReceiveStreamEvent;import javax.media.rtp.event.ReceiveStreamEvent;import javax.swing.JFrame;public class Receiver extends JFrame implements ReceiveStreamListener,ControllerListener{public static void main(String[] args) {try {SessionAddress local = newSessionAddress(InetAddress.getLocalHost(),60000);SessionAddress target = newSessionAddress(InetAddress.getLocalHost(),50000);new Receiver(local,target);} catch (UnknownHostException e) {e.printStackTrace();}}public Receiver(SessionAddress local, SessionAddress target) { mgr = RTPManager.newInstance();mgr.addReceiveStreamListener(this);try {mgr.initialize(local);mgr.addTarget(target);} catch (InvalidSessionAddressException | IOException e) { e.printStackTrace();}BufferControl bc =(BufferControl)mgr.getControl("javax.media.control.BufferControl");if (bc != null)bc.setBufferLength(350);addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {disconnect();}});setDefaultCloseOperation(EXIT_ON_CLOSE);setVisible(true);}@Overridepublic void update(ReceiveStreamEvent e) {if(e instanceof NewReceiveStreamEvent) {ReceiveStream rs =((NewReceiveStreamEvent)e).getReceiveStream();DataSource ds = rs.getDataSource();try {player = Manager.createPlayer(ds);} catch (NoPlayerException | IOException e1) {e1.printStackTrace();}player.addControllerListener(this);player.start();} else if(e instanceof ByeEvent) {disconnect();}}public void disconnect() {if(player!=null) {player.stop();player.close();}if(mgr!=null) {mgr.removeTargets("closing session");mgr.dispose();mgr = null;}}@Override public void controllerUpdate(ControllerEvent e) {if(e instanceof RealizeCompleteEvent) {if(player.getVisualComponent()!=null)add(player.getVisualComponent());if(player.getControlPanelComponent()!=null)add(player.getControlPanelComponent(),BorderLayout.SOUTH);pack();}}Player player;RTPManager mgr;}<html><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><title>无标题文档</title></head><BODY STYLE="FONT-SIZE: 10pt; FONT-FAMILY: Verdana, Arial, Helvetica"><SCRIPT LANGUAGE="JScript">var NUMBER_OF_REPETITIONS = 40;var nRepetitions = 0;var g_oTimer = null;function startLongProcess(){divProgressDialog.style.display = "";resizeModal();btnCancel.focus();// Add a resize handler for the windowwindow.onresize = resizeModal;// Add a warning in case anyone tries to navigate away or refresh the page window.onbeforeunload = showWarning;//// Here's where you would normally kick off a long asynchronous process // like a file download or a remote database operation. Here, we use// our "long process" to simulate this process.//continueLongProcess();}function updateProgress(nNewPercent){// Update our pseudo progress bardivProgressInner.style.width = (parseInt(divProgressOuter.style.width) * nNewPercent / 100)+ "px";}function stopLongProcess(){if (g_oTimer != null){// Clear the timer so we don't get called back an extra timewindow.clearTimeout(g_oTimer);g_oTimer = null;}// Hide the fake modal DIVdivModal.style.width = "0px";divModal.style.height = "0px";divProgressDialog.style.display = "none";// Remove our event handlerswindow.onresize = null;window.onbeforeunload = null;nRepetitions = 0;}function continueLongProcess(){if (nRepetitions < NUMBER_OF_REPETITIONS){// Set the timeout somewhere between 0 and .25 secondsvar nTimeoutLength = Math.random() * 250;updateProgress(100 * nRepetitions / NUMBER_OF_REPETITIONS);g_oTimer = window.setTimeout("continueLongProcess();", nTimeoutLength); nRepetitions++;}else{stopLongProcess();}}function showWarning(){//Warn users before they refresh the page or navigate awayreturn "Navigating to a different page or refreshing the window could cause you to lose precious data.\n\nAre you*absolutely* certain you want to do this?";}function resizeModal(){// Resize the DIV which fakes the modality of the dialog DIVdivModal.style.width = document.body.scrollWidth;divModal.style.height = document.body.scrollHeight;// Re-center the dialog DIVdivProgressDialog.style.left = ((document.body.offsetWidth - divProgressDialog.offsetWidth) / 2);divProgressDialog.style.top = ((document.body.offsetHeight - divProgressDialog.offsetHeight) / 2);}</SCRIPT><INPUT TYPE="BUTTON" VALUE="Click Me!" onclick="startLongProcess();"><!-- BEGIN PROGRESS DIALOG --><DIV STYLE="BORDER: buttonhighlight 2px outset; FONT-SIZE: 8pt; Z-INDEX:4; FONT-FAMILY: Tahoma; POSITION: absolute; BACKGROUND-COLOR: buttonface; DISPLAY: none; WIDTH: 350px; CURSOR: default" ID="divProgressDialog" onselectstart="window.event.returnValue=false;"><DIV STYLE="PADDING: 3px; FONT-WEIGHT: bolder; COLOR: captiontext;BORDER-BOTTOM: white 2px groove; BACKGROUND-COLOR: activecaption">Downloading Requested Document</DIV><DIV STYLE="PADDING: 5px">Please wait while I download the document you requested.</DIV><DIV STYLE="PADDING: 5px">This may take several seconds.</DIV><DIV STYLE="PADDING: 5px"><DIV ID="divProgressOuter" STYLE="BORDER: 1px solid threedshadow;WIDTH: 336px; HEIGHT: 15px"><DIV ID="divProgressInner" STYLE="COLOR: white; TEXT-ALIGN:center; BACKGROUND-COLOR: infobackground; MARGIN: 0px; WIDTH: 0px; HEIGHT:13px;"></DIV></DIV></DIV><DIV STYLE="BORDER-TOP: white 2px groove; PADDING-BOTTOM: 5px; PADDING-TOP: 3px; BACKGROUND-COLOR: buttonface; TEXT-ALIGN: center"><INPUT STYLE="FONT-FAMILY: Tahoma; FONT-SIZE: 8pt" TYPE="button"ID="btnCancel" onclick="stopLongProcess();" VALUE="Cancel"></DIV></DIV><!-- END PROGRESS DIALOG --><!-- BEGIN FAKE MODAL DIV--><DIV ID="divModal"STYLE="BACKGROUND-COLOR: white; FILTER: alpha(opacity=75); LEFT: 0px; POSITION: absolute; TOP: 0px; Z-INDEX: 3"onclick="window.event.cancelBubble=true; window.event.returnValue=false;"></DIV><!-- END FAKE MODAL DIV --></body></html>第八:<html><head><title>进度条测试</title><script>function loadBar(fl)//fl is show/hide flag{var x,y;if (self.innerHeight){// all except Explorerx = self.innerWidth;y = self.innerHeight;}elseif (document.documentElement && document.documentElement.clientHeight){// Explorer 6 Strict Modex = document.documentElement.clientWidth;y = document.documentElement.clientHeight;}elseif (document.body){// other Explorersx = document.body.clientWidth;y = document.body.clientHeight;}var el=document.getElementById('loader');if(null!=el){var top = (y/2) - 50;var left = (x/2) - 150;if( left<=0 ) left = 10;el.style.position="absolute";el.style.visibility = (fl==1)?'visible':'hidden';el.style.display = (fl==1)?'block':'none';el.style.left = left + "px"el.style.top = top + "px";el.style.zIndex = 88;}}</script></head><body onload="loadBar(0)"><div id="loader"><table style="FILTER: Alpha(opacity=90);" class="loader" summary="Loader Layout" border="0" cellpadding="5" cellspacing="1"bgcolor="#bbbbb"><tr><td bgcolor="#FFFFFF" align="left"><p><img src="/edit/UploadFile/0612160917132358.gif" align="left" style="margin:3px" alt="请等待" width="94" height="17"/><strong>数据载入中...</strong><br /><span style="font-size:8pt;">Please wait until this screen is completelyloaded.</span></p></td></tr></table></div><script type="text/javascript" language="javascript">loadBar(1);</script><IFRAME name="login" scrolling="no" SRC="/"WIDTH="100%" HEIGHT="100%" MARGINWIDTH="0" MARGINHEIGHT="0"HSPACE="0" VSPACE="0" FRAMEBORDER="0" SCROLLING="no"></IFRAME> </body></html>[代码] [C/C++]代码// c 程序段static PyObject *gc_before_extract = NULL;/// 设置回调static PyObject *SetBeforeCallbackFn(PyObject *dummy, PyObject *args){PyObject *temp = NULL;if (PyArg_ParseTuple(args, "O:set_callback", &temp)) {if (!PyCallable_Check(temp)) {PyErr_SetString(PyExc_TypeError, "parameter must be callable");}Py_XINCREF(temp); /* Add a reference to new callback */Py_XDECREF(gc_before_extract); /* Dispose of previous callback */gc_before_extract = temp; /* Remember new callback */}return Py_BuildValue("l", (gc_before_extract == NULL) ? 0 : 1);}/// 调用上面函数设置的python脚本函数int BeforeExt(char *pBeforeExtract){PyObject* pArgs = NULL;PyObject* pRetVal = NULL;int nRetVal = 0;pArgs = Py_BuildValue("(s)", pFileName);pRetVal = PyEval_CallObject(gc_before_extract, pArgs);if (pRetVal){fprintf(stderr, "PyEval_CallObject : ok \r\n");nRetVal = PyInt_AsLong(pRetVal);fprintf(stderr, "PyEval_CallObject : return : %d \r\n", nRetVal); }Py_DECREF(pArgs);Py_DECREF(pRetVal);return nRetVal;}/// 测试函数staticPyObject* my_test_callback(PyObject *self, PyObject *args){PyObject * arglist;PyObject * result = NULL;BeforeExt("good");result = PyEval_CallObject(gc_before_extract, args);if (result){Py_DECREF(result);}Py_INCREF(Py_None);return Py_None;}[代码] [Python]代码/////// python 脚本from pyArchive import *from ctypes import *# 回调函数必须有一个int型的返回值def set_callback_fn(abc) :print "t_callback_fn say : {0}".format(abc)return 11CMPFUNC = CFUNCTYPE(c_int, c_char_p)_callback = CMPFUNC(set_callback_fn)if SetBeforeCallbackFn(_callback):print "set call back ok"my_test_callback("script call : good luck")else :print "set call back fail"[代码] [C/C++]代码#include <iostream>using namespace std;long pow2[20];int N,M;int ans[1000];void solve( int n , int m , int Min ){if(n == N && m == M){for(int i=0;i<M;i++){cout<<ans[i]<<"";}cout<<endl;return ;}else if( n + (M-m)*Min > N || N > pow2[M-m]*n + pow2[M-m]-1) return ;else{for(int i = Min; i <= n+1; i++){ans[m] = i;solve(n+i,m+1,i);}}}int main(){pow2[0] = 1;for(int i=1;i<20;i++){pow2[i] = pow2[i-1]<<1;}cin>>N>>M;if( M > N || pow2[M]-1 < N){cout<<"没有有效解"<<endl; }solve( 0 , 0 , 1 );system("pause");return 0;}[代码] [C/C++]代码#include <iostream>using namespace std;int Partition(int *L,int low,int high){int pivotkey=L[low];int i = low, j = high+1;while(i<j){while (L[++i]<pivotkey && i<=high);while (L[--j]>pivotkey);if (i<j){int temp = L[i];L[i] = L[j];L[j] = temp;}}L[low] = L[j];L[j]=pivotkey;return j;}。

verilog课程设计实验报告

verilog课程设计实验报告

verilog课程设计实验报告一、教学目标本课程旨在通过Verilog硬件描述语言的学习,让学生掌握数字电路设计的自动化工具,理解并实践硬件描述语言在数字系统设计中的应用。

通过本课程的学习,学生应达到以下目标:1.知识目标:–理解Verilog的基本语法和结构。

–掌握Verilog中的模块化设计方法。

–学习常用的Verilog描述技巧,包括逻辑门级建模、行为级建模和结构级建模。

2.技能目标:–能够运用Verilog语言进行简单的数字电路设计。

–学会使用至少一种Verilog仿真工具进行电路功能验证。

–能够阅读和理解Verilog代码,进行简单的代码优化。

3.情感态度价值观目标:–培养学生的团队合作意识,在实验报告中能够体现分工合作的精神。

–培养学生的问题解决能力,鼓励学生在遇到问题时积极寻找解决方案。

–培养学生对新技术的好奇心和学习兴趣,激发他们对电子工程领域的热爱。

二、教学内容依据教学目标,本课程的教学内容将围绕Verilog语言的基础知识、实践应用和项目设计展开。

教学大纲安排如下:1.第一部分:Verilog基础知识(2周)–介绍Verilog的背景和基本概念。

–详细讲解Verilog的数据类型、运算符和语句。

2.第二部分:模块化设计(2周)–讲解模块的定义和封装。

–实践模块的端口声明和模块实例化。

3.第三部分:数字电路的Verilog描述(2周)–通过实例教学,掌握逻辑门、触发器等基本组件的Verilog建模。

–学习组合逻辑和时序逻辑的设计方法。

4.第四部分:仿真与测试(1周)–学习使用仿真工具进行电路功能验证。

–理解并实践测试台(testbench)的编写。

5.第五部分:项目设计(3周)–小组合作完成一个较为复杂的数字系统设计项目。

–包括系统模块的划分、编码、仿真和测试。

三、教学方法为了提高学生的学习效果,将采用多种教学方法相结合的方式进行授课:1.讲授法:用于讲解Verilog的基本概念和语法。

流水灯基于Verilog语言实现及测试代码

流水灯基于Verilog语言实现及测试代码

流水灯实验的Testbench报告一、设计源码(顺序方法)module led(input clk,input rstn,output reg[3:0]led);parameter T1s = 4'd10;reg[3:0]cnt_1s;always@(posedge clk or negedge rstn)if(!rstn)begincnt_1s <= 0;endelse if(cnt_1s == T1s)begincnt_1s <= 0;endelse begincnt_1s <= cnt_1s + 1'b1;endalways@(posedge clk or negedge rstn)if(!rstn)beginled <= 4'hf;endelse if(led == 4'hf) beginled <= 4'he;endelse if(cnt_1s == T1s)beginled <= {led[2:0],1'b1};endendmodule二、测试代码`timescale 1 ns/1 nsmodule led_tb();reg clk ;reg rstn;wire[3:0] led;parameter CYCLE = 20;parameter RST_TIME = 3 ;led u( .clk (clk ),.rstn (rstn ),.led (led ));initial beginclk = 0;forever#(CYCLE/2)clk=~clk;endinitial beginrstn = 1;#CYCLE;rstn = 0;#(CYCLE*RST_TIME);rstn = 1;endendmoduleTestbench设计的几个步骤:1、设定时间标尺、timescale;2、定义信号类型,与输入对接的reg,与输出对接的wire;3、对待测设计的顶层模块进行例化,即将testbench与待测设计接口对接;4、给输入接口产生激励。

开放性实验FPGA实现流水线式CPU文档-大连理工大学

开放性实验FPGA实现流水线式CPU文档-大连理工大学

大连理工大学计算机系统设计开放实验结课论文4位原型计算机的设计与实现学院:软件学院专业:软件工程(日语强化)姓名与学号:班级:软日1101完成时间:2013.12.25大连理工大学Dalian University of Technology摘要我们之所以选择了这门计算机系统设计开放实验课,是因为感到在计算机组成原理的实验课上对FPGA的学习和理解都远远不够,同时也想通过自己设计计算机系统来加深对计算机系统的理解和认识。

本次实验是基于TEC-XP实验计算机系统的,采用的是spartan-II型号的FPGA 芯片,使用的是VHDL语言。

在本篇结课论文中分析了采用FPGA芯片实现一个支持指令流水的实验计算机系统的方法,主要介绍各个模块的设计以及。

在实际设计过程中,每实现一个模块都需要进行仿真验证,通过观察仿真波形来确定程序设计的正确性。

,最终得到了一个完成了基本功能并实现了指令流水的4位原型计算机。

目录摘要 (2)1引言1.1 TEC-XP教学计算机系统……………………………………………….错误!未定义书签。

1.2 课程目标 (5)2流水线CPU的实现2.1指令集系统 (6)2.2变量的定义 (7)2.3指令的设计实现2.3.1预处理 (8)2.3.2指令集实现 (8)2.4流水线的设计实现2.4.1取指 (13)2.4.2译指 (13)2.4.3执行 (13)2.4.4流水实现 (14)3仿真3.1仿真流程 (14)3.2仿真波形 (15)4结论 (15)参考文献 (16)致谢 (16)1引言1.1 TEC-XP教学计算机系统TEC-XP是16位的教学实验系统,由清华大学科教仪器厂、清华大学计算机系联合研制。

适用于本科、硕士研究生的计算机组成原理和计算机系统结构课程的教学实验。

该系统有自己的指令系统和监控程序,能够与终端或PC机相连(可以通过键盘输入程序执行,结果可以通过终端或者显示器显示),可以进行联机操作和执行比较完整的程序。

Verilog流水灯实验报告

Verilog流水灯实验报告

流水灯实验报告实验二 流水灯一、 实验目的学会编写一个简单的流水灯程序并掌握分频的方法。

熟悉Modelsim 仿真软件的使用。

二、 实验要求用Quartus 编写流水灯程序,在Modelsim 软件中进行仿真。

三、 实验仪器和设备1、 硬件:计算机2、 软件:Quartus 、Modelsim 、(UE )四、 实验内容1、 将时钟周期进行分频。

2、 编写Verilog 程序实现LED 等依次亮灭,用Modelsim 进行仿真,绘制波形图。

五、 实验设计(一)分频原理已知时钟周期f 为50MHz ,周期T 为1/f ,即20ns 。

若想得到四分频计数器,即周期为80ns 的时钟,需要把时钟进行分频。

即每四个时钟周期合并为一个周期。

原理图如图1所示。

rst_nclkclk_4图1 四分频原理图 (二)流水灯设计思路1、实现4盏LED灯依次隔1s亮灭,即周期为1s;2、计算出频率f为1/T=1Hz;3、设置计数器cnt,当检测到clk上升沿时开始计数,当cnt计数到24_999_999时,clk_4跳变为1,LED灯亮起,当cnt计数49_999_999时,clk_4置0,LED灯熄灭。

4、给LED赋初值4’b0001,第一盏灯亮。

5、利用位拼接,实现循环。

(三)设计框图图2 设计基本框图(四)位拼接的用法若输入a=4'b1010,b=3'b101,c=4'b0101,想要使输出d=5'b10001用位拼接,符号“{ }”:d<={b[2:1],c[1],a[2:1]}即把b的低1~2位10,c的低1位0,a的低1~2位01拼接起来,得到10 0 01。

流水灯4'b00014'b00104'b01004'b1000相当于把低三位左移,并最高位放在最低位。

用位拼接可写为:led<={led[2:0], led[3]};低三位最高位六、实验方法和步骤(一)时钟分频1、编写分频程序。

MIPS流水实现Verilog,无中断异常的处理

MIPS流水实现Verilog,无中断异常的处理

MIPS流水实现(Verilog,无中断异常的处理)经过一周的努力,终于将流水部分的Verilog代码给写出,并给出了自己的MIPS汇编测试代码,过了,可能里面还有一些小细节没处理好,但这不影响我的总体的框架,总的框架已将架构起来没什么问题,后面的工作就是,加入异常中断的处理,最好能下板子,这样才是有始有终。

虽然前面做过多周期的异常中断的处理,但是我知道流水部分的异常中断处理和多周期的是不一样的,其实,多周期和单周期对指令的并行是为零的,它们都是一条一条的串行执行的,做中断只是为了,了解指令的切分,和MIPS的中断异常处理机制。

关键是对CPU有深入的了解。

正如&ldquo;纸上得来终觉浅,觉知此事要躬行!&rdquo;这句话可以说是我这是科创项目的核心感想。

以前只是对计算机的底层有一种不懂,神秘的感觉。

随着项目的不断往前推,对底层的认识也加深了,不像以前那样浮于表面了。

结合这学期的OS课程,受益匪浅,最好有时间能摸透Linux OS 的代码,给我的CPU上OS,这样就完美了。

这次的流水实现比较紧,主要是指导老师追的紧(不过还得感谢冯老师的严格要求,我才能如此,当然我的努力也是很重要的。

关于这一点我得吃几句:老师的严格只是外因,主要还是靠自己,努力的孩子,是不需要别人的管束,我应该是输入半自觉的学生,。

还好有冯老师的督促。

),与多周期相比,我对多周期的深入了解是在做中断异常处理的时候,那是,几乎一个月都在看书,《see MIPS run in Linux》的3-6章节快被我方便了,那是的感觉就是,它(中断异常)明明就在眼前,可就是捉不住,最后在曾学长的指点下,我是醍醐灌顶,一下只就顿悟了。

接下来时顺畅的编程,往往后期的测试也是关键,也是能力提升和对你系统的更深更全面的掌握,所以有了问题,一定自己弄(在条件允许),反正多周期我是了解的挺多了,流水由于上的快,有些还没消化,细节部分。

下面是,部分仿真结果的波形图和DM,RF中的值:经过三周的努力终于将多周期的异常和中断(Exception and Interruption)个解决了,经过此次的实现,对MIPS的中断有了即中断的整个流程有了更深的了解。

用Verilog HDL实现CPU基本流水线

用Verilog HDL实现CPU基本流水线

用Verilog HDL实现CPU基本流水线
李文;魏凤歧;武健刚
【期刊名称】《内蒙古大学学报:自然科学版》
【年(卷),期】2004(35)3
【摘要】用硬件描述语言VerilogHDL实现了CPU基本流水线,在寄存器级显示了CPU流水线的内部结构,指令的动态流水执行情况可以通过前仿真形成波形图进行观察.
【总页数】7页(P325-331)
【关键词】流水线;定向技术;数据相关;控制相关
【作者】李文;魏凤歧;武健刚
【作者单位】内蒙古大学计算机学院
【正文语种】中文
【中图分类】TP302
【相关文献】
1.基于Verilog HDL的流水线模型机的设计与实现 [J], 易小琳;彭一凡
2.Verilog-HDL讲座第三讲 Verilog-HDL的基本概念 [J], 常晓明
3.基于Verilog HDL的多周期CPU设计与实现 [J], 严浦洲
4.Verilog-HDL讲座第四讲 Verilog-HDL仿真软件的基本操作 [J], 常晓明
5.Verilog-HDL讲座第五讲典型基本逻辑路的Verilog-HDL描述 [J], 常晓明;李媛媛
因版权原因,仅展示原文概要,查看原文内容请购买。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验报告课程名称:__ 数字系统设计实验Ⅱ__指导老师:成绩:_______实验名称:流水线MIPS微处理器设计实验类型:____设计型__ __一、实验目的和要求(必填)二、实验内容和原理(必填)三、主要仪器设备(必填)四、操作方法和实验步骤五、实验数据记录和处理六、实验结果与分析(必填)七、讨论、心得一、实验目的1.了解提高CPU性能的方法。

2.掌握流水线MIPS微处理器的工作原理。

3.理解数据冒险、控制冒险的概念以及流水线冲突的解决方法。

4.掌握流水线MIPS微处理器的测试方法。

二、实验任务设计一个32位流水线MIPS微处理器,具体要求如下:1.至少运行下列MIPS32指令。

(1)算术运算指令:ADD、ADDU、SUB、SUBU、ADDI、ADDIU。

(2)逻辑运算指令:AND、OR、NOR、XOR、ANDI、ORI、XORI、SLT、SLTU、SLTI、SLTIU。

(3)移位指令:SLL、SLLV、SRL、SRLV、SRA。

(4)条件分支指令:BEQ、BNE、BGEZ、BGTZ、BLEZ、BLTZ。

(5)无条件跳转指令:J、JR。

(6)数据传送指令:LW、SW。

(7)空指令:NOP。

2.采用5级流水线技术,对数据冒险实现转发或阻塞功能。

3.在XUP Virtex-Ⅱ Pro 开发系统中实现MIPS微处理器,要求CPU的运行速度大于25MHz。

三、实验原理1.总体设计流水线是数字系统中一种提高系统稳定性和工作速度的方法,广泛应用于高档CPU的架构中。

根据MIPS处理器的特点,将整体的处理过程分为取指令(IF)、指令译码(ID)、执行(EX)、存储器访问(MEM)和寄存器会写(WB)五级,对应多周期的五个处理阶段。

如图3.1所示,一个指令的执行需要5个时钟周期,每个时钟周期的上升沿来临时,此指令所代表的一系列数据和控制信息将转移到下一级处理。

图3.1 流水线流水作业示意图由于在流水线中,数据和控制信息将在时钟周期的上升沿转移到下一级,所以规定流水线转移变量命名遵守如下格式:名称_流水线级名称例如:在ID级指令译码电路(Decode)产生的寄存器写允许信号RegWrite在ID级、EX级、MEM级和WB级上的命名分别为RegWrite_id、RegWrite_ex、RegWrite_mem和RegWrite_wb。

在顶层文件中,类似的变量名称有近百个,这样的命名方式起到了很好的识别作用。

1)流水线中的控制信号(1)IF级:取指令级。

从ROM中读取指令,并在下一个时钟沿到来时把指令送到ID 级的指令缓冲器中。

该级控制信号决定下一个指令指针的PCSource信号、阻塞流水线的PC_IFwrite信号、清空流水线的IF_flush信号。

(2)ID级:指令译码器。

对IF级来的指令进行译码,并产生相应的控制信号。

整个CPU的控制信号基本都是在这级上产生。

该级自身不需任何控制信号。

流水线冒险检测也在该级进行,冒险检测电路需要上一条指令的MemRead,即在检测到冒险条件成立时,冒险检测电路产生stall信号清空ID/EX寄存器,插入一个流水线气泡。

(3)EX级:执行级。

该级进行算术或逻辑操作。

此外LW、SW指令所用的RAM访问地址也是在本级上实现。

控制信号有ALUCode、ALUSrcA、ALUScrB和RegDst,根据这些信号确定ALU操作、选择两个ALU操作数A、B,并确定目标寄存器。

另外,数据转发也在该级完成。

数据转发控制电路产生ForwardA和ForwardB两组控制信号。

(4)MEM级:存储器访问级。

只有在执行LW、SW指令时才对存储器进行读写,对其他指令只起到一个周期的作用。

该级只需存储器写操作允许信号MemWrite。

(5)WB级:写回级。

该级把指令执行的结果回写到寄存器文件中。

该级设置信号MemtoReg和寄存器写操作允许信号RegWrite,其中MemtoReg决定写入寄存器的数据来自于MEM级上的缓冲值或来自于MEM级上的存储器。

2)流水线冒险在流水线CPU中,多条指令通知执行,由于各种各样的原因,在下一个时钟周期中下一条指令不能执行,这种情况称为冒险。

冒险分为三类:①结构冒险:硬件不支持多条指令在同一个时钟周期内执行。

MIPS指令集专为流水线设计,因此在MIPS CPU中不存在此类冒险。

②数据冒险:在一个操作必须等待另一操作完成后才能进行时,流水线必须停顿,这种情况称为数据冒险。

数据冒险分为两类:ⅰ数据相关:流水线内部其中任何一条指令要用到任何其他指令的计算结果时,将导致数据冒险。

通常可以用数据转发(数据定向)来解决此类冒险。

ⅱ数据冒险:此类冒险发生在当定向的目标阶段在时序上早于定向的源阶段时,数据转发无效。

通常是引入流水线阻塞,即气泡(bubble)来解决。

③控制冒险:CPU需要根据分支指令的结果做出决策,而此时其他指令可能还在执行中,这时会出现控制冒险,也称为分支冒险。

解决此类冒险的常用方法是延迟分支。

2.1)数据相关与转发下面通过具体例子来阐述数据相关。

见图3.2图3.2 数据相关性问题实例图可见,后4条指令都依赖于第一条指令得到寄存器$2的结果,但sub指令要在第五周期才写回寄存器$2,但在第三、四、五个时钟周期$2分别要被and、or和add三个指令用到,所以这三个指令得到的是错误的未更新的数据,会引起错误的结果;而第六个时钟周期$2要被sw指令用到,此时得到的才是正确的已更新的数据。

这种数据之间的互相关联引起的冒险就是数据相关。

可以看出,当一条依赖关系的方向与时间轴的方向相反时,就会产生数据冒险。

(1)一阶数据相关与转发(EX冒险)首先讨论指令sub与and之间的相关问题。

sub指令在第五周期写回寄存器$2,而and指令在第四周期就对sub指令的结果$2提出申请,显然将得到错误的未更新的数据。

像这类第I条指令的源操作寄存器与第I-1条指令(即上一条指令)的目标寄存器相重,导致的数据相关称为一阶数据相关。

见图3.3中实线所示。

图3.3 一阶数据相关实例图可以发现,sub指令的结果其实在EX级结尾,即第三周期末就产生了;而and指令在第四时钟周期向sub指令结果发出请求,请求时间晚于结果产生时间,所以只需要sub指令结果产生之后直接将其转发给and指令就可以避免一阶数据相关。

如图3.3虚线所示。

转发数据为ALUResult_mem数据转发由Forwarding unit单元控制,判断转发条件是否成立。

转发机制硬件实现见图3.4图3.4 转发机制的硬件实现转发条件ForwardA、ForwardB作为数据选择器的地址信号,转发条件不成立时,ALU 操作数从ID/EX流水线寄存器中读取;转发条件成立时,ALU操作数取自数据旁路。

转发条件:①MEM级指令是写操作,即RegWrite_mem=1;②MEM级指令写回的目标寄存器不是$0,即RegWriteAddr_mem≠0;③MEM级指令写回的目标寄存器与在EX级指令的源寄存器是同一寄存器,即RegWriteAddr_mem=RsAddr_ex 或RegWriteAddr_mem=RtAddr_ex。

(2)二阶数据相关与转发(MEM冒险)接下来讨论sub指令与or指令之间的相关问题。

sub指令在第5时钟周期写回寄存器,而or指令也在第5时钟周期对sub指令的结果提出了请求,很显然or指令读取的数据是未被更新的错误内容。

这类第I条指令的源操作寄存器与第I-2条指令(即之上第二条指令)的目标寄存器相重,导致的数据相关称为二阶数据相关。

见图3.5中实线所示。

图3.5 一阶数据相关实例图如前所述,or指令在第五时钟周期向sub指令结果发出请求时,sub指令的结果已经产生。

所以,我们同样采用“转发”,即通过MEM/WB流水线寄存器,将sub指令结果转发给or指令,而不需要先写回寄存器堆。

如图3.5中虚线所示。

转发数据为RegWriteData_wb 转发条件:①WB级指令是写操作,即RegWrite_wb=1;②WB级指令写回的目标寄存器不是$0,即RegWriteAddr_wb≠0;③WB级指令写回的目标寄存器与在EX级指令的源寄存器是同一寄存器,即RegWriteAddr_wb=RsAddr_ex 或RegWriteAddr_wb=RtAddr_ex;④EX冒险不成立,即RegWriteAddr_mem≠RsAddr_ex 或RegWriteAddr_mem=RtAddr_ex。

(3)三阶数据相关与转发最后讨论sub指令与add指令之间的相关问题。

sub指令与add指令在第五时钟周期内同时读写同一个寄存器。

这类同一周期内同时读写同一个寄存器的数据相关称之为三阶数据相关。

如图3.6中实线所示。

图3.6 三阶数据相关实例图假设寄存器的写操作发生在时钟周期的上升沿,而读操作发生在时钟周期的下降沿,那么读操作将读取到最新写入的内容。

在这种假设条件下将不会发生数据冒险。

这就要求流水线中的寄存器具有“先写后读(Read After Write)”的特性。

这类“写操作发生在时钟周期的上升沿,读操作发生在时钟周期的下降沿”的寄存器虽然在理论上是可实现的,但是不适合应用于同步系统,因为它不但影响系统的运行速度,而且影响系统的稳定性,是不可取的。

因此,我们采用“转发”机制来解决三阶数据相关冒险。

该部分转发电路我们放在寄存器堆的设计中完成。

如图3.6中虚线所示。

转发数据为RegWriteData_wb。

转发条件为:①WB级指令是写操作,即RegWrite_wb=1;②WB级指令写回的目标寄存器不是$0,即RegWriteAddr_wb≠0;③WB级指令写回的目标寄存器与在ID级指令的源寄存器是同一寄存器,即RegWriteAddr_wb=RsAddr_id 或RegWriteAddr_wb=RtAddr_id。

2.2)数据冒险与阻塞当一条指令试图读取一个寄存器,而它前一条指令是lw指令,并且该lw指令写入的是同一个寄存器时,定向转发的方法就无法解决问题。

如图3.7所示注意到lw指令只能在第四时钟周期从内存中读出数据,因此它和紧随其后的and指令之间的依赖关系与时序方向是相反的,这种冒险是无法通过转发来实现的。

图3.7 数据冒险与阻塞实例图这类冒险不同于数据相关冒险,需要单独一个“冒险检测单元(Hazard Detector)”,它在ID级完成。

冒险成立的条件为:①上一条指令是lw指令,即MemRead_ex=1;②在EX级的lw指令与在ID级的指令读写的是同一个寄存器,即RegWriteAddr_ex=RsAddr_id 或RegWriteAddr_ex=RtAddr_id。

冒险的解决:为解决数据冒险,我们引入流水线阻塞。

相关文档
最新文档