VHDL与数字系统课程设计.docx
《VHDL与数字系统课程设计.docx》由会员分享,可在线阅读,更多相关《VHDL与数字系统课程设计.docx(37页珍藏版)》请在冰豆网上搜索。
VHDL与数字系统课程设计
<
课程设计报告
%
实践课题:
VHDL与数字系统课程设计
学生:
XXX
指导老师:
XXX、XXX
系别:
电子信息与电气工程系
专业:
电子科学与技术
班级:
XXX
学号:
XXX
{
!
一、设计任务
用VHDL设计一个简单的处理器,并完成相关的仿真测试。
.设计要求:
图1是一个处理器的原理图,它包含了一定数量的寄存器、一个复用器、一个加法/减法器(Addsub),一个计数器和一个控制单元。
图1简单处理器的电路图
数据传输实现过程:
16位数据从DIN输入到系统中,可以通过复用器分配给R0~R7和A,复用器也允许数据从一个寄存器传通过Bus送到另外一个寄存器。
》
加法和减法的实现过程:
复用器先将一个数据通过总线放到寄存器A中,然后将另一个数据放到总线上,加法/减法器对这两个数据进行运算,运算结果存入寄存器G中,G中的数据又可根据要求通过复用器转存到其他寄存器中。
下表是该处理所支持的指令。
操作
功能
mvRx,Ry
mviRx,#D
addRx,Ry
subRx,Ry
[
Rx←[Ry]
Rx←Data
Rx←[Rx]+[Ry]
Rx←[Rx]-[Ry]
1)Rx←[Ry]:
将寄存器Ry中的内容复制到Rx;
2)MviRx,#D:
将立即数存入寄存器Rx中去。
所有指令都按9位编码(取自DIN的高9位)存储在指令存储器IR中,编编码规则为IIIXXXYYY,III表示指令,XXX表示Rx寄存器,YYY表示Ry寄存器。
立即数#D是在mvi指令存储到IR中之后,通过16位DIN输入的。
有一些指令,如加法指令和减法指令,需要在总线上多次传输数据,因此需要多个时钟周期才能完成。
控制单元使用了一个两位计数器来区分这些指令执行的每一个阶段。
当Run信号置位时,处理器开始执行DIN输入指令。
当指令执行结束后,Done信号置位,下表列出四个指令在执行过程中每一个时间段置位的控制信号。
(
时间
指令
T0
T1
T2
T3
(mv):
I0
(mvi):
I1
]
(add):
I2
(sub):
I3
IRin
IRin
IRin
IRin
RYout,RXin,Done
DINout,RXin,Done
~
RXout,Ain
RXout,Ain
----
----
RYout,Gin,Addsub
RYout,Gin,Addsub
----
----
【
Gout,RXin,Done
Gout,RXin,Done
二、实现功能说明
mvRx,Ry
实现的功能:
将寄存器Rx的值赋给寄存器Ry(以mvR0,R5为例)
(1)计数器为“00”时,指令寄存器的置位控制信号输入端IRin=1有效,将DIN输入的数据的高9位锁存。
置位的控制信号如图3加粗黑线所示。
~
图3
(2)计数器为“01”时,首先控制单元根据设计器为“00”时输入的指令,向复用器发出选通控制信号,复用器根据该控制信号让R5的值输出到总线上,然后控制单元控制寄存器R0将总线上的值锁存,完成整个寄存器对寄存器的赋值过程。
置位的控制信号和数据流如图4加粗黑线所示。
图4
mviRx,#D
实现的功能:
将的立即数#D赋给寄存器Rx(以mvR0,#D为例)
(1)计数器为“00”时,指令寄存器的置位控制信号输入端IRin=1有效,将DIN输入的数据的高9位锁存。
置位的控制信号如图5加粗黑线所示。
】
图5
(2)计数器为“01”时,首先控制单元根据设计器为“00”时输入的指令,向复用器发出选通控制信号,复用器根据该控制信号让DIN的值输出到总线上,然后控制单元控制寄存器R0将总线上的值锁存,完成整个立即数对寄存器的赋值过程。
置位的控制信号和数据流如图6加粗黑线所示。
图6
addRx,Ry和subRx,Ry
实现的功能:
将寄存器Ry的值加上/减去寄存器Rx的值并赋给寄存器Rx(以add/subR0,R1为例)。
(1)计数器为“00”时,指令寄存器的置位控制信号输入端IRin=1有效,将DIN输入的数据的高9位锁存。
置位的控制信号如图7加粗黑线所示。
[
图7
(2)计数器为“01”时,首先控制单元根据设计器为“00”时输入的指令,向复用器发出选通控制信号,复用器根据该控制信号让R0的值输出到总线上,然后控制单元控制寄存器A将总线上的值锁存。
置位的控制信号和数据流如图8加粗黑线所示。
图8
(3)计数器为“10”时,首先控制单元根据设计器为“00”时输入的指令,向复用器发出选通控制信号,复用器根据该控制信号让R1的值输出到总线上,然后控制单元控制加法/减法器addsub将寄存器A的值和总线上的值相加/相减并输出,接着寄存器G将加法/减法器addsub的计算结果锁存。
置位的控制信号和数据流如图9加粗黑线所示。
(
图9
(4)计数器为“11”时,首先控制单元向复用器发出选通控制信号,复用器根据该控制信号让寄存器G的值输出到总线上,寄存器R0将总线上的值进行锁存,完成整个寄存器与对寄存器见加减法的运算过程。
置位的控制信号和数据流如图10加粗黑线所示。
图10
三、单元模块设计说明
寄存器Registe
(
寄存器R0~R7、寄存器A或寄存器G:
用于数据的存储。
当时钟输入clk的上升沿到来且rin=1时,将数据输入端rxin[15..0]的数据锁存到寄存器中并从数据输出端rxout[15..0]输出;当rin=0时,输出端保持原来的值不变。
寄存器Registe的VHDL代码:
LIBRARYIEEE;
USEregisteis
port(
clk:
instd_logic;
rin:
instd_logic;
】
rxin:
instd_logic_vector(15downto0);
rxout:
outstd_logic_vector(15downto0));
endentityregiste;
architectureoneofregisteis
begin
process(clk)
begin
ifclk'eventandclk='1'then
"
ifrin='1'thenrxout<=rxin;
endif;
endif;
endprocess;
endone;
指令寄存器IR
指令寄存器IR用于对输入的16为指令进行处理,取其高9位。
当时钟输入clk的上升沿到来且rin=1时,取数据输入端rxin[15..0]的高9位将其锁存到寄存器中并从数据输出端rxout[8..0]输出;当rin=0时,输出端保持原来的值不变。
]
指令寄存器IR的VHDL代码:
LIBRARYIEEE;
USEIRis
port(
clk:
instd_logic;
rin:
instd_logic;
rxin:
instd_logic_vector(15downto0);
|
rxout:
outstd_logic_vector(8downto0));
endentityIR;
architectureoneofIRis
begin
process(clk)
begin
ifclk'eventandclk='1'then
ifrin='1'thenrxout<=rxin(15downto7);
…
endif;
endif;
endprocess;
endone;
加/减法器addsub
加/减法器addsub用于处理两个输入的数据datain2[15..0]和datain1[15..0],当控制端Addsub=1时,两个数据输入端datain2[15..0]和datain1[15..0]相加并从数据输出端dataout[15..0]输出;当控制端Addsub=0时,数据输入端datain2[15..0]减去datain1[15..0],结果从数据输出端dataout[15..0]输出。
^
加/减法器addsub的VHDL代码:
LIBRARYIEEE;
USEaddsubis
port(ain:
instd_logic_vector(15downto0);
bin:
instd_logic_vector(15downto0);
adsub:
inbit;
about:
outstd_logic_vector(15downto0));
endentityaddsub;
·
architectureoneofaddsubis
signala,b:
std_logic_vector(15downto0);
begin
process(adsub,ain,bin)
begin
ifadsub='0'thenabout<=ain+bin;
elsifadsub='1'thenabout<=ain-bin;
endif;
<
endprocess;
endone;
计数器counter
计数器counter用于产生控制单元的输入脉冲,对控制单元的工作时序进行控制。
当clear=0时(清零端clear无效),时钟输入clk每来一个上升沿,输出count[1..0]加1,所以输出为00——>01——>10——>11——>00不断循环;当clear=1时(清零端clear有效),对输出Q[1..0]同步清零,与时钟有关。
计数器counter的VHDL代码:
libraryieee;
usecounteris
.
port(
clk:
instd_logic;
clear:
instd_logic;
count:
outstd_logic_vector(1downto0));
endcounter;
architectureoneofcounteris
signalc:
std_logic_vector(1downto0);
begin
;
process(clk,clear)
begin
ifclk'eventandclk='1'then
if(clear='1')thenc<="00";
elsec<=c+1;endif;
endif;
endprocess;
count<=c;
、
endone;
复用器multiplexers
复用器根据控制单元的控制信号将指定的输入数据输出到总线上。
来自控制单元的控制信号为R0out~R7out、Gout、DINout,输入数据位来自寄存器R0~R7、寄存器A、数据输入端DIN,当控制信号的某一位为1时,将其对应的输入数据输出到总线上。
复用器multiplexers的VHDl代码:
libraryieee;
~
usemultiplexersis
port(din:
instd_logic_vector(15downto0);
gin:
instd_logic_vector(15downto0);
r0:
instd_logic_vector(15downto0);
r1:
instd_logic_vector(15downto0);
r2:
instd_logic_vector(15downto0);
r3:
instd_logic_vector(15downto0);
r4:
instd_logic_vector(15downto0);
《
r5:
instd_logic_vector(15downto0);
r6:
instd_logic_vector(15downto0);
r7:
instd_logic_vector(15downto0);
ren:
inbit_vector(7downto0);
gen:
inbit;
dinen:
inbit;
dout:
outstd_logic_vector(15downto0));
endmultiplexers;
…
architecturebhvofmultiplexersis
begin
dout<=ginwhengen='1'else
r0whenren(0)='1'else
r1whenren
(1)='1'else
r2whenren
(2)='1'else
r3whenren(3)='1'else
r4whenren(4)='1'else
】
r5whenren(5)='1'else
r6whenren(6)='1'else
r7whenren(7)='1'else
dinwhendinen='1'else
"0000000000000000";
endbhv;
控制单元control
:
控制单元根据计数器发出的脉冲和DIN输入的操作指令对整个系统的其他模块进行控制,完成指定的操作。
控制单元control的VHDL代码:
libraryieee;
usecontrolis
port(reset:
instd_logic;
run:
instd_logic;
—
clk:
instd_logic_vector(1downto0);
irin:
instd_logic_vector(8downto0);
clear:
outstd_logic;
irout:
outstd_logic;
gout:
outstd_logic;
dinout:
outstd_logic;
rout:
outstd_logic_vector(7downto0);
r0in:
outstd_logic;
、
r1in:
outstd_logic;
r2in:
outstd_logic;
r3in:
outstd_logic;
r4in:
outstd_logic;
r5in:
outstd_logic;
r6in:
outstd_logic;
r7in:
outstd_logic;
ain:
outstd_logic;
·
addsub:
outstd_logic;
gin:
outstd_logic;
done:
outstd_logic);
endcontrol;
architectureoneofcontrolis
begin
process(clk,run,reset,irin)
begin
^
if(reset='0')then
clear<='1';
irout<='0';
gout<='0';
dinout<='0';
rout<="00000000";
r0in<='0';
#
r1in<='0';
r2in<='0';
r3in<='0';
r4in<='0';
r5in<='0';
r6in<='0';
r7in<='0';
ain<='0';
【
addsub<='0';
gin<='0';
done<='0';
else
caseclkis
when"00"=>
clear<='0';
irout<='1';
:
gout<='0';
dinout<='1';
rout<="00000000";
r0in<='0';
r1in<='0';
r2in<='0';
r3in<='0';
r4in<='0';
%
r5in<='0';
r6in<='0';
r7in<='0';
ain<='0';
addsub<='0';
gin<='0';
done<='0';
ifrun='0'thenirout<='1';
|
elseirout<='0';endif;
when"01"=>
if(irin(8downto6)="000")then
clear<='1';
irout<='0';
gout<='0';
dinout<='0';
ain<='0';
|
addsub<='0';
gin<='0';
done<='1';
caseirin(5downto3)is
when"000"=>r0in<='1';r1in<='0';r2in<='0';r3in<='0';r4in<='0';r5in<='0';r6in<='0';r7in<='0';
when"001"=>r1in<='1';r0in<='0';r2in<='0';r3in<='0';r4in<='0';r5in<='0';r6in<='0';r7in<='0';
when"010"=>r2in<='1';r0in<='0';r1in<='0';r3in<='0';r4in<='0';r5in<='0';r6in<='0';r7in<='0';
when"011"=>r3in<='1';r0in<='0';r1in<='0';r2in<='0';r4in<='0';r5in<='0';r6in<='0';r7in<='0';
$
when"100"=>r4in<='1';r0in<='0';r1in<='0';r2in<='0';r3in<='0';r5in<='0';r6in<='0';r7in<='0';
when"101"=>r5in<='1';r0in<='0';r1in<='0';r2in<='0';r3in<='0';r4in<='0';r6in<='0';r7in<='0';
when"110"=>r6in<='1';r0in<='0';r1in<='0';r2in<='0';r3in<='0';r4in<='0';r5in<='0';r7in<='0';
when"111"=>r7in<='1';r0in<='0';r1in<='0';r2in<='0';r3in<='0';r4in<='0';r5in<='0';r6in<='0';
whenothers=>null;
endcase;
caseirin(2downto0)is
when"000"=>rout<="00000001";
|
when"001"=>rout<="00000010";
when"010"=>rout<="00000100";
when"011"=>rout<="00001000";
when"100"=>rout<="00010000";
when"101"=>rout<="00100000";
when"110"=>rout<="01000000";
when"111"=>rout<="";
whenothers=>null;
、
endcase;
elsif(irin(8downto6)="001")then
clear<='1';
irout<='0';
gout<='0';
dinout<='1';
rout<="00000000";
ain<='0';
-
addsub<='0';
gin<='0';
done<='1';
caseirin(5downto3)is
when"000"=>r0in<='1';r1in<='0';r2in<='0';r3in<='0';r4in<='0';r5in<='0';r6in<='0';r7in<='0';
when"001"=>r1in<='1';r0in<='0';r2in<='0';r3in<='0';r4in<='0';r5in<='0';r6in<='0';r7in<='0';
when"010"=>r2in<='1';r0in<='0';r1in<='0';r3in<='0';r4in<='0';r5in<='0';r6in<='0';r7in<='0';
when"011"=>r3in<='1';r0in<='0';r1in<='0';r2in<='0';r4in<='0';r5in<='0';r6in<='0';r7in<='0';
|
when"100"=>r4in<='1';r0in<='0';r1in<='0';r2in<='0';r3in<='0';r5in<='0';r6in<='0';r7in<='0';
when"101"=>r5in<='1';r0in<='0';r1in<='0';r2in<='0';r3in<='0';r4in<='0';r6in<='0';r7in<='0';
when"110"=>r6in<='1';r0in<='0';r1in<='0';r2in<='0';r3in<='0';r4in<='0';r5in<='0';r7in<='0';
when"111"=>r7in<='1';r0in<='0';r1in<='0';r2in<='0';r3in<='0';r4in<='0';r5in<='0';r6in<='0';
whenothers=>null;
endcase;
elsif(irin(8downto6)="010"oririn(8downto6)="011")then
clear<='0';
\
irout<='0';
gout<='0';
dinout<='0';
r0in<='0';
r1in<='0';
r2in<='0';
r3in<='0';
r4in<='0';
…
r5in<='0';
r6in<='0';
r7in<='0';
ain<='1';
addsub<='0';
gin<='0';
done<='0';
caseirin(5downto3)is
:
when"000"=>rout<="00000001";
when"001"=>rout<="00000010";
when"010"=>rout<="00000100";
when"011"=>rout<="00001000";
when"100"=>rout<="00010000";
when"101"=>rout<="00100000";
when"110"=>rout<="01000000";
when"111"=>rout<="";
&
whenothers=>null;
endcase;
else
clear<='1';
irout<='0';
gout<='0';
dinout<='0';
rout<