PARWANCPU状态机设计.docx
《PARWANCPU状态机设计.docx》由会员分享,可在线阅读,更多相关《PARWANCPU状态机设计.docx(16页珍藏版)》请在冰豆网上搜索。
PARWANCPU状态机设计
基于FPGA的数字系统设计
大作业
学号:
13091378
:
邢武天
班级:
130914
题目一:
设计Parwan的controlsection部状态机s1\s2\..\s9\,并给出功能仿真?
题目二:
利用分层结构设计ParwanCPU,并给出功能仿真?
(利用在实验课中所给出的TESTBENCH)
实验原理图
ControlSectionStructure:
s1…s9(如下图所示)
InputsandoutputsofPARWANcontrolsections:
–Appliedto,categories,signalname,functions
实验过程
1.1创建工程
(1)打开ISE13.x软件,选择File->NewProject在弹出的对话框中输入工程名和路径。
(2)单击下一步选择所使用的芯片。
Spartan3E开发板的芯片型号为Spartan3EXC3S500E芯片,FG320封装。
(3)单击Next,进入工程信息页面,确认无误后,点击Finish完成工程的创建。
1.2测试文件
(1)选择菜单栏中的Project->NewSource。
(2)在SelectSourceType窗口中,选择左侧的VHDLTestBench,在右侧FileName栏中输入文件名par_control_unit_tb
(3)单击Next按钮,选择关联文件。
1.3实验截图
实验代码
在实现过程中,除了定义CPU的信号接口外,还设置了一个输出类型的接口,名字叫present_state_value,主要是用来在调试或仿真的过程中输出CPU所处的状态,便于调试分析。
整个状态机的实现过程主要使用了case…IS…when逻辑结构。
用了present_state和next_state两个状态变量。
详细的实现代码如下所示:
LIBRARYIEEE;
USEIEEE.std_logic_1164.ALL;
USEwork.synthesis_utilities.ALL;
--
ENTITYpar_control_unitIS
PORT(clk:
INstd_logic;
--registercontrolsignals:
load_ac,zero_ac,
load_ir,
increment_pc,load_page_pc,load_offset_pc,reset_pc,
load_page_mar,load_offset_mar,
load_sr,cm_carry_sr,
--busconnectioncontrolsignals:
pc_on_mar_page_bus,ir_on_mar_page_bus,
pc_on_mar_offset_bus,dbus_on_mar_offset_bus,
pc_offset_on_dbus,obus_on_dbus,databus_on_dbus,
mar_on_adbus,
dbus_on_databus,
--logicunitfunctioncontroloutputs:
arith_shift_left,arith_shift_right:
OUTstd_logic;
alu_and,alu_not,alu_a,alu_add,alu_b,alu_sub:
outstd_logic;
--inputsfromthedatasection:
ir_lines:
INstd_logic_vector(7DOWNTO0);
status:
INstd_logic_vector(3DOWNTO0);
--memorycontrolandotherexternalsignals:
read_mem,write_mem:
OUTstd_logic;interrupt:
INstd_logic;
--test
present_state_value:
outstd_logic_vector(3DOWNTO0)
);
ENDpar_control_unit;
--
ARCHITECTUREdataflow_synthesizableOFpar_control_unitIS
TYPEcpu_statesIS(s1,s2,s3,s4,s5,s6,s7,s8,s9);
SIGNALpresent_state,next_state:
cpu_states;
SIGNALnext_state_value:
std_logic_vector(3DOWNTO0);
BEGIN
clocking:
PROCESS(clk,interrupt)
BEGIN
IF(interrupt='1')THEN
present_state<=s1;
present_state_value<="0001";
ELSIFclk'EVENTANDclk='0'THEN
present_state<=next_state;
present_state_value<=next_state_value;
ENDIF;
ENDPROCESSclocking;
--
sequencing:
PROCESS(present_state,ir_lines,status,
interrupt)
BEGIN
load_ac<='0';zero_ac<='0';load_ir<='0';
increment_pc<='0';
load_page_pc<='0';load_offset_pc<='0';reset_pc
<='0';
load_page_mar<='0';load_offset_mar<='0';
load_sr<='0';cm_carry_sr<='0';
--busconnectioncontrolsignals:
pc_on_mar_page_bus<='0';ir_on_mar_page_bus<='0';
pc_on_mar_offset_bus<='0';dbus_on_mar_offset_bus<=
'0';
pc_offset_on_dbus<='0';obus_on_dbus<='0';
databus_on_dbus<='0';
mar_on_adbus<='0';dbus_on_databus<='0';
--logicunitfunctioncontroloutputs:
arith_shift_left<='0';arith_shift_right<='0';
alu_and<='0';alu_not<='0';alu_a<='0';alu_add<='0';alu_b<='0';alu_sub<='0';
--memorycontrolandotherexternalsignals:
read_mem<='0';write_mem<='0';
CASEpresent_stateIS
WHENs1=>
-------------------------------------------1
IF(interrupt='1')THEN
reset_pc<='1';
next_state<=s1;
next_state_value<="0001";
ELSE
pc_on_mar_page_bus<='1';
pc_on_mar_offset_bus<='1';
load_page_mar<='1';
load_offset_mar<='1';
next_state<=s2;
next_state_value<="0010";
ENDIF;
WHENs2=>
---------------------------------------2
--readmemoryintoir
mar_on_adbus<='1';
read_mem<='1';
databus_on_dbus<='1';
alu_a<='1';
load_ir<='1';
increment_pc<='1';
next_state<=s3;
next_state_value<="0011";
WHENs3=>
--------------------------------------3
pc_on_mar_page_bus<='1';
pc_on_mar_offset_bus<='1';
load_page_mar<='1';
load_offset_mar<='1';
IF(ir_lines(7DOWNTO4)/="1110")THEN
next_state<=s4;
next_state_value<="0100";
ELSE
CASEir_lines(3DOWNTO0)IS
WHEN"0001"=>--cla
zero_ac<='1';
load_ac<='1';
WHEN"0100"=>--cmc
cm_carry_sr<='1';
WHEN"1000"=>--asl
alu_b<='1';
arith_shift_left<='1';
load_sr<='1';
load_ac<='1';
WHEN"1001"=>--asr
alu_b<='1';
arith_shift_right<='1';
load_sr<='1';
load_ac<='1';
WHENOTHERS=>NULL;
ENDCASE;
next_state<=s2;
next_state_value<="0010";
ENDIF;
WHENs4=>
----------------------------------------4
--readmemoryintomaroffset
mar_on_adbus<='1';
read_mem<='1';
databus_on_dbus<='1';
dbus_on_mar_offset_bus<='1';
load_offset_mar<='1';
IF(ir_lines(7DOWNTO6)/="11")THEN
ir_on_mar_page_bus<='1';
load_page_mar<='1';
IF(ir_lines(4)='1')
THEN
next_state<=s5;
next_state_value<="0101";
ELSE
next_state<=s6;
next_state_value<="0110";
ENDIF;
ELSE--jsrorbra,donotaltermar
--page
IF(ir_lines(5)='0')THEN
--jsr
next_state<=s7;
next_state_value<="0111";
ELSE
next_state<=s9;
next_state_value<="1001";
ENDIF;
ENDIF;
increment_pc<='1';
WHENs5=>
---------------------------------------5
--readactualoperandfrommemoryintomar
--offset
mar_on_adbus<='1';
read_mem<='1';
databus_on_dbus<='1';
dbus_on_mar_offset_bus<='1';
load_offset_mar<='1';
next_state<=s6;
next_state_value<="0110";
WHENs6=>
--------------------------------------6
IF(ir_lines(7DOWNTO5)="100")THEN--jmp
load_page_pc<='1';
load_offset_pc<='1';
next_state<=s2;
next_state_value<="0010";
ELSIF(ir_lines(7DOWNTO5)="101")THEN
--maronadbus,acondatabus,write
--tomemory
mar_on_adbus<='1';
alu_b<='1';
obus_on_dbus<='1';
dbus_on_databus<='1';
write_mem<='1';
next_state<=s1;
next_state_value<="0001";
ELSIF(ir_lines(7)='0')THEN------
--lda,and,add,sub
--maronadbus,readmemoryfor
--operand,performoperation
mar_on_adbus<='1';
read_mem<='1';
databus_on_dbus<='1';
IF(ir_lines(6)='0')THEN
----lda,and
IF(ir_lines(5)='0')
THEN--lda
alu_a<='1';
ELSE--and
alu_and<='1';
ENDIF;
ELSE----add,sub
IF(ir_lines(5)='0')
THEN--add
alu_add<='1';
ELSE--sub
alu_sub<='1';
ENDIF;
ENDIF;
load_sr<='1';
load_ac<='1';
next_state<=s1;
next_state_value<="0001";
ENDIF;
WHENs7=>
--------------------------------------------7
--writepcoffsettotopofsubroutine
mar_on_adbus<='1';
pc_offset_on_dbus<='1';
dbus_on_databus<='1';
write_mem<='1';
load_offset_pc<='1';
next_state<=s8;
next_state_value<="1000";
WHENs8=>
--------------------------------------8
increment_pc<='1';
next_state<=s1;
next_state_value<="0001";
WHENs9=>
-----------------------------------------9
IF(all_or(statusANDir_lines(3DOWNTO0))='1')THEN
load_offset_pc<='1';
ENDIF;
next_state<=s1;
next_state_value<="0001";
实验原理
实验过程
2.1创建工程
(1)打开ISE13.x软件,选择File->NewProject在弹出的对话框中输入工程名和路径。
(2)单击下一步选择所使用的芯片。
Spartan3E开发板的芯片型号为Spartan3EXC3S500E芯片,FG320封装。
(3)单击Next,进入工程信息页面,确认无误后,点击Finish完成工程的创建。
2.2设计输入
选择Project->Addcopyofsource,将实验的源代码添加到工程中。
2.3综合实现
(1)编写汇编测试代码
(2)用文本编辑器打开实验源代码中的simple.asm文件。
(3)将测试代码转换为存文件
(4)编译并执行程序
2.4设计仿真
2.5结果截图
编写testbench代码对以上的状态机进行功能仿真。
Testbench的核心代码如下:
stim_proc:
process
begin
--holdresetstatefor100ns.
waitfor10ns;
ir_lines<="01101111";--SUBloc
waitforclk_period*10;
ir_lines<="10001111";--JMPloc
waitforclk_period*10;
ir_lines<="10101111";--STAloc
waitforclk_period*10;
ir_lines<="11111000";--BRA_V_addr
waitforclk_period*10;
ir_lines<="11100001";--CLA
waitforclk_period*10;
endprocess;
由上代码可见,在测试波形中,选取了4种ir_line的可能值来测试。
下面选择两处仿真波形进行分析:
图5.1“STAloc”仿真波形图
从“STAloc”仿真波形图中,连续的时钟周期里,ir_line的值都为“10101111”,可知该指令是“STA1111”。
结合parwan的状态转换关系来看,一开始CPU处于s1状态,由于interrupt=‘0’,转到s2状态,再转到s3状态,由于ir_line(7to4)!
=”1110”,转到s4状态,由于ir_line(7to4)=”11X0”转到s6状态,最后由于ir_line(7to5)=”1010”转回s1,完成一次循环周期。
还可以看到在相应的状态,相应的信号会被设为“1”,如s1中,信号load_page_mar、load_offset_mar、pc_on_mar_page_bus和pc_on_mar_offset_bus等信号为“1”,状态机的设计相符。
图5.2“CLA”仿真波形图
从“CLA”仿真波形图中,我们主要从黄线部分开始往后看,在这的一个时钟周期后ir_line的值都为“11100001”,parwan的指令集可知指令是“CLA”。
结合parwan的状态设计来看,一开始CPU处于s1状态,由于interrupt=‘0’,转到s2状态,再转到s3状态,由于ir_line(7to4)=”1110”,转到s2状态,最后在s2和s3中循环。
验证了程序的正确性。
实验总结:
本次作业以以前四次上机为基础,通过利用上机所得的实验能力和部分实验代码,进行本次的ParwanCPU设计,基本上来说,本次作业要比上机更有难度,首先,进行的一次综合性实验,其次,上机时均给出了实验步骤。
但不可否认的是,本次实验更能提高我们对ParwanCPU的理解,对提高我们的实验能力更有帮助。