实验练习9
一个简单的数据处理器
Figure 1 显示了一个数字系统,这个数字系统包含了一个16位的数字寄存器,一个多路复用器,一个加减单元,一个计数器和一个控制单元。数据通过一个16位的DIN输入接口输入到这个系统中来。这些数据可以通过16位的多路复用器存储到不同的寄存器中,例如R0……R7和A。这个复用器也允许数据从一个寄存器传输到另一个寄存器中。这个复用器的输出通道在图片中也就是Bus(总线),因为在数据传输期间它允许数据从一个地址传输到另一个地址。
加法(或者减法)的执行是通过复用器将第一个地址的16位数字放到总线上,然后将总线上的数据存储到A寄存器中。当上面的步骤完成后,将第二个地址中的数放到总线上,加法/减法单元会执行相应的运算,然后将计算的结果存储到G寄存器总。最后G寄存器中的数据可以传输到其他指定的寄存器中。
在控制单元的控制下,这个系统可以在不同的时钟周期执行不同的运算。这个控制单元决定了当特定的数据放到总线上去后,哪一个寄存器可以接受到该数据。例如,如果控制单元接收到指令信号R0out和Ain时,复用器将会把R0寄存器中的内容放置到总线上去,然后在下一个时钟信号将信号存储到A寄存器中。
这样的一个系统可以称为是处理器。它将执行不同指令的具体操作。Table 1(表1)列出了该处理器实现的指令。左列显示了指令和操作数。RX[RY]的意思是把RY寄存器中的数据传输到RX寄存器中。mv(move)指令允许数据从一个寄存器复制到另一个寄存器。对于mvi(move immediate)指令RXD意味着将16位的数据D存储到RX寄存器中。
每条指令可以通过9位数据IIIXXXYYY编码存储到IR寄存器当中,III代表指令,XXX代表RX寄存器,YYY代表RY寄存器。虽然只需要2位就可以编码4条指令,但是我们这里使用了3位,这是由于后续可能会有其他的指令添加到这个系统中来。IR寄存器使用16位的DIN输入中的9个位来输入指令,在图1(Figure 1)中已有暗示。对于mvi指令来说YYY三位并没有什么含义,而且立即数#D依靠16位的DIN来输入,并且立即数的输入是在指令存储到IR寄存器之后。
某些指令,例如加法或者减法,需要超过1个时钟周期才能够完成,因为多个转换步骤需要依靠总线。在图1(Figure 1)中显示了控制单元通过2位的计数器来允许指令一步步的运行。当Run信号输入和指令处理完毕的Done信号输出后,处理器开始执行下一个DIN输入的指令。表2(Table2)表明了在执行表1(Table1)中的指令时不同的步骤后可以取得的控制信号。注意在步骤0(即T0)时取得的控制信号是IRin,所以这个步骤没有在列表中显示出来。
第一部分:
根据下面的要求,利用Verilog语言设计并完成图1(Figure1)显示的处理器的功能:
1、为这个练习生成一个QuartusII工程;
2、在你新建的工程文件下,新建要求的Verilog文件,编写整个流程。一个Verilog语言的模板已经在图2a(Figure 2a)中提供了,同时还有一些可以使用的底层的模块在图2b(Figure2b);
3、使用仿真功能来检验你的代码是否正确。一个正确的代码的仿真输出例图已经在图3(Figure3)中提供了。它显示了在30ns时将数据(2000)16存储到IR寄存器中。这个范例在50ns时通过指令mviR0,#D把数据D=5存储到寄存器R0中。仿真在90ns时显示输入指令mvR1,R0,110ns时输入指令addR0,R1,和在190ns时输入指令subR0,R0。注意的是在该仿真中DIN输入是4位的十进制数,IR中的数据是八进制数。
4、生成一个新的Quartus II工程,将完成的代码烧到Altera DE2代码中。这个工程在包含了一个顶层模块和Altera板子上适当的输入输出接口。例如你的处理器在顶层模块
中,可以使用SW15-0作为系统DIN的输入端口和使用SW17来作为Run输入。同时,使用按钮KEY0作为Resetn输入,按钮KEY1作为Clock输入。连接处理器的总线和LEDR15-0,最后连接Done信号输出和LEDR17;
5、为你的工程分配DE2板上适当的引脚。编译完代码后下载到FPGA芯片中去;
6、通过拨动拨码开关和观察LED灯来测试你定义的功能是否实现了。当处理器的时钟可以通过开关来控制的时候,就很容易一步步操作指令和观察代码的功能实现情况。
module proc (DIN, Resetn, Clock, Run, Done, BusWires);
input [15:0] DIN;
input Resetn, Clock, Run;
output Done;
output [15:0] BusWires;
. . . declare variables
wire Clear = . . .
upcount Tstep (Clear, Clock, Tstep_Q);
assign I = IR[1:3];
dec3to8 decX (IR[4:6], 1’b1, Xreg);
dec3to8 decY (IR[7:9], 1’b1, Yreg);
always @(Tstep_Q or I or Xreg or Yreg)
begin
. . . specify initial values
case (Tstep_Q)
2’b00: // store DIN in IR in time step 0
begin
IRin = 1’b1;
end
2’b01: //define signals in time step 1
case (I)
. . .
endcase
2’b10: //define signals in time step 2
case (I)
. . .
endcase
2’b11: //define signals in time step 3
case (I)
. . .
endcase
endcase
end
regn reg_0 (BusWires, Rin[0], Clock, R0);
. . . instantiate other registers and the adder/subtracter unit
. . . define the bus
endmodule
Figure 2a. Skeleton Verilog code for the processor.
module upcount(Clear, Clock, Q);
input Clear, Clock;
output [1:0] Q;
reg [1:0] Q;
always @(posedge Clock)
if (Clear)
Q <= 2’b0;
else
Q <= Q + 1’b1;
endmodule
module dec3to8(W, En, Y);
input [2:0] W;
input En;
output [0:7] Y;
reg [0:7] Y;
always @(W or En)
begin
if (En == 1)
case (W)
3’b000: Y = 8’b10000000;
3’b001: Y = 8’b01000000;
3’b010: Y = 8’b00100000;
3’b011: Y = 8’b00010000;
3’b100: Y = 8’b00001000;
3’b101: Y = 8’b00000100;
3’b110: Y = 8’b00000010;
3’b111: Y = 8’b00000001;
endcase
else
Y = 8’b00000000;
end
endmodule
module regn(R, Rin, Clock, Q);
parameter n = 16;
input [n-1:0] R;
input Rin, Clock;
output [n-1:0] Q;
reg [n-1:0] Q;
always @(posedge Clock)
if (Rin)
Q <= R;
endmodule
Figure 2b. Subcircuit modules for use in the processor.
第二部分
在这个部分中你需要设计图4(Figure4)描绘的电路,其中有和第一部分处理器连接的内存模块和计数器。计数器可以被用来读取内存单元中的逐个地址,这些数据可以提供给处理器作为一串指令。对于处理器和内存,我们可以使用单独的时钟信号,RCClock和MClock信号来仿真我们的设计和测试这个电路。
1、生成一个新的QuartusII工程来测试你的电路;
2、生成一个顶层模块来代替处理器,内存和计数器。使用Quartus II的MegaWizard Plug-In Manager tool来从Altera library of parameterized modules(LPMs)中产生一个内存模块。正确的LPM叫做ALTSYNCRAM并且可以在storage下面找到。通过程序提供的指令可以生成一个16位可读数据接口和32字深的内存单元。程序的第一个画面在图5(Figure5)中显示。当内存只有一个读取接口没有写入接口时,它称为同步只读内存(synchronous ROM)。注意内存为了同步写入地址往往包含一个寄存器。这个寄存器要求使用Cyclone II FPGA来设计;这是地址寄存器记录由你来设计。将处理器的指令放置到内存中,你需要特殊的初始数据,这些初始数据在你的电路烧入FPGA芯片同时写入内存。这个可以通过命令程序使用内存初始文件(MIF)来初始化内存。Mega Wizard
Plug-In Manager tool图面在图6(Figure6)中已有显示。我们要指定命名一个生成包含Quartus II工程的目录文件inst_mem.mif,使用Quartus II的在线帮助来学习使用MIF文件和产生一个拥有足够处理器指令来测试你的电路的文件。
3、使用仿真功能测试电路。确定数据能够从ROM中完全读出并由处理器执行。
4、确定你的工程包含必要的接口名和分配好引脚地址来让DE2板执行你的电路。使用SW17来执行你的处理器的Run输出,对于Resetn输入使用KEY0,对于MClock输入使用KEY1,对于PClock输入使用KEY2。连接处理器的总线和LEDR15-0,连接Done信号和LEDR17。
5、编译电路程序然后烧写到FPGA芯片中。
6、通过拨动拨码开关和观察LED灯来测试你的设计的程序的功能。当电路的时钟信号输入是通过按按钮来控制的时候,一步步执行指令和观察电路的运作就变得很简单了。
扩展处理器的功能
扩展处理器的功能是有可能的,所以在图4(Figure4)中的计数器就可以不用了,并
且处理器可以使用内存或者其他的设备来执行读和写操作。这些扩展功能需要新增指令到处理器和程序中,这样就可以让处理器的执行更加复杂。当这些步骤在逻辑设计的程序中得到世实现,它们将显示在Altera上随之而来的结果。
Copyright c 2006 Altera Corporation.
由于笔者的英语水平和翻译水平有限,如果有不准确的地方,请以英文版为准,或者email:2322695571@qq.com与本人联系指正,谢谢
因篇幅问题不能全部显示,请点此查看更多更全内容