华北电力大学
    综合实验报告
    ( 2018— 2019 年度第 2 学期)


    名 称: 计算机组成与结构综合实验
    题 目: 认识性、运算器、存储器、
    控制器设计实验等
    院 系: 计算机系
    班 级: 计科1702班
    学 号: 201709000720
    学生姓名: 杨鼎睿
    实验课序号: 2
    指导教师: 王晓霞、徐伟峰、张铭泉
    设计周数: 1

    成 绩:

    日期: 2019年 7 月 12 日

    《计算机组成与结构》综合实验
    任 务 书
    一、 目的与要求
    1.
    目的
    1.1
    熟悉教学计算机THINPAD指令系统,包括指令功能、指令格式和寻址方式。
    1.2
    熟悉硬件描述语言及开发环境,了解硬件系统开发的基本过程。
    1.3
    掌握ALU基本设计方法和运算器的数据传送通路。
    1.4
    熟悉THINPAD教学计算机内存储器的配置及与总线的连接方式。
    1.5
    掌握教学机内存(RAM)的访问时序和方法。
    1.6
    理解总线数据传输的基本原理。
    2. 要求
    2.1 实验之前,认真写出预习报告,包括实验用的全部数据,实验操作步骤,实验电路图等。
    2.2 实验之后,认真写出实验报告,包括实验过程中遇到的问题,解决的办法等。
    二、 主要内容
    1.
    秒表设计实验
    1.1
    熟悉使用ISE创建工程、调试以及在THINPAD硬件平台上的配置过程。
    1.2
    熟悉硬件描述语言VHDL。
    1.3
    实现时钟分频、秒表计数以及七段数码管显示的功能。
    1.4
    在教学计算机THINPAD上验证所实现功能。
    2.运算器实验
    2.1
    根据实验具体要求,用VHDL语言实现一个简单的ALU。
    (1) 算术逻辑部件ALU的主要功能是对二进制数据进行定点算术运算、逻辑运算和各种移位操作等。算术运算包括定点加减乘除运算;逻辑运算主要有逻辑与、逻辑或、逻辑异或和逻辑非等操作。ALU通常有两个数据输入端A和B输入操作数,一个数据输出端Y以及标志位输出结果,通过输入操作码op来确定所要进行的操作。本实验通过实现一个状态机,根据状态机状态的变化来输入操作数及操作码,并最终实现不同的运算,将结果和标志位呈现出来。
    (2) 实验中ALU要求实现基本的算术运算、逻辑运算、移位运算等,具体功能如下表所示:

    操作码 功能 描述
    ADD A + B 加法
    SUB A – B 减法
    AND A and B
    OR A or B
    XOR A xor B 与或
    NOT not A 取非
    SLL A sll B 逻辑左移B位
    SRL A srl B 逻辑右移B位
    SRA A sra B 算数右移B位
    ROL A rol B 循环左移B位

    要求:ALU的数据输入A、B的长度为16位,操作码op为4位,算术运算时数据用补码表示。
    (3)
    将实验过程中进行的操作与结果数据记录在下表中。

    输入数据 实际输出 与预期一致性
    操作码 操作数A 操作数B 运算结果 标志位

    2.2
    在教学计算机THINPAD上验证实现的ALU的功能。
    2.3
    思考题
    (1) ALU进行算术逻辑运算所使用的电路是组合逻辑电路还是时序逻辑电路?
    (2) 如果给定了A和B的初值,且每次运算完后结果都写入到B中,再进行下次运算。这样一个带暂存功能的ALU要增加一些什么电路来实现?
    3. 存储器实验
    使用教学计算机上的FPGA芯片,设计一个状态机和内存读写逻辑,完成对存储器RAM的访问。
    3.1
    具体要求如下:
    (1)
    写RAM1。将手拨开关上的数据,写入到RAM1的相应存储单元中。首先,在手拨开关上拨入写入地址单元的地址,按CLK键后,再在手拨开关上拨入要写入该单元的数据,再按CLK键后,数据应写入到RAM1的对应单元中。继续按CLK键,则地址和数据各加1后写入,共写10个数据。过程中,应在LED灯上分别显示地址和数据。
    (2)
    读RAM1。RAM1中写入10组数据后,按CLK键后开始读RAM1的内容。按CLK键,逐个将刚写入的10个数据从存储单元中读出,送到LED上显示。
    3.2
    具体步骤如下:
    (1)
    定义输入信号:拨码开关决定读写地址或数据;绑定Ram1的数据线、地址线;绑定LED灯,用来显示从内存中读出的数据。
    (2)
    定义状态机:读写状态控制的状态机:控制当前控制器是处于读状态还是写状态;内存读周期、写周期的状态机:根据时钟进行跳转,控制读写的过程。
    (3)
    验证过程:将编译好的内存控制器烧入实验板;写周期,LED灯显示当前写入的地址;读周期,LED灯最终显示从内存中读出的数据;观察LED上地址和数据的变化,是否符合实验的设计要求;记录实验结果;可以自行设计该实验展示的方式。
    3.3 在实验过程中可以使用七段数码管监测状态机当前状态,发光二极管只有16个,可以只显示地址的低8位和数据的低8位。
    3.4 思考题:静态存储器的读、写时序各有什么特点?
    4. 控制器实验
    4控制器实验
    1. 实验名称:THCO MIPS指令控制器实验
    控制器是计算机的核心,通过对指令的译码获取控制信号,进而控制整个系统的运行。
    2. 实验目的:
    ① 进一步理解和掌握教学计算机THINPAD指令系统,包括指令功能、指令格式等;
    ② 了解控制器的功能,并通过实验加深对多周期CPU的控制器与指令周期的理解;
    3.实验环境:
    ① 硬件环境:PC计算机;win7以上操作系统;ThinPAD教学计算机;
    ② 软件环境:FPGA开发工具软件Xilinx ISE 12.3。
    4. 实验内容:
    (1) 编写VHDL程序,实现具有七条MIPS指令功能的控制器。
    (2)七条指令分别为:ADDU SUBU BEQZ JR XOR LW SW
    (3)电子版《计算机硬件系统实验教程》指导书第23页-32页中除去上述7条指令外的其他指令任选2条。(实验步骤等详见课堂派控制器部分任务)

    三、 进度计划

    ** **设计(实验) ** **
    1 认识性(秒表设计)实验 周一
    2 运算器实验 周二
    3 运算器实验 周三
    4 存储器实验 周四
    5 控制器实验 周五


    四、 设计(实验)成果要求
    1. 秒表设计实验
    1.1
    熟练使用ISE创建工程、调试以及配置的过程。
    1.2
    完成秒表基本功能。
    2. 运算器实验
    2.1 熟练使用VHDL语言设计硬件电路。
    2.2 实现基本ALU,完成表中运行功能,且结果正确。
    2.3 实验拓展,如ADC,SBB;输出标志位等。
    3. 存储器实验
    3.1 完成SRAM写,连续写10个数。
    3.2 完成SRAM读,连续读出刚写入的10个数。
    3.3 LED和数码管正确显示数据及状态的变化。
    4. 控制器实验
    4.1设计扩展指令,包括指令功能、指令格式、指令流程、微码;
    4.2 在原来提供的MACH程序的基础上按照ABEL语言的要求添加新指令的控制信号,编译产生.JED文件并下载到MACH芯片里;并验证其正确性。
    4.3 基本要求完成ADC、SBB和NOT;扩展要求完成RCL、RCR和ASR。

    五、 考核方式
    1.
    总成绩=考勤成绩(占20%)+ 验收成绩(占40%)+ 报告成绩(占40%)
    1.1 考勤成绩
    (1)一周实验共记10次考勤,共20分。
    (2) 缺勤,该次考勤成绩记0分。
    (3) 迟到或早退,该次考勤成绩记1分。
    (4) 考勤成绩大于等于18分,为优秀。
    (5) 考勤成绩少于12分,总成绩为不及格。
    1.2 验收成绩
    (1) 验收成绩少于26分,总成绩为不及格。
    (3) 同组人员合作,独立完成实验内容,严禁抄袭、找人代做,拿他人程序、实验板验收等,一经发现成绩记零分,按考试作弊处理。
    1.3 报告成绩
    (1) 实验报告成绩占40%,分为优、良、中、及格、不及格。
    (2) 实验报告必须符合格式要求,格式不合格的记为零分。
    (3) 实验报告严禁抄袭,一经发现,记为零分。
    (4) 报告成绩不及格,总成绩为不及格。
    2.
    总成绩分为优、良、中、及格和不及格。


    学生姓名: 阙雪琳
    指导教师: 王晓霞、徐伟峰、张铭泉
    2019年5月 24 日

    实验一 认识性实验
    一、目的与要求
    1. 熟悉使用ISE创建工程、调试以及在THINPAD硬件平台上的配置过程。
    2. 熟悉硬件描述语言VHDL。
    3. 实现时钟分频、秒表计数以及七段数码管显示的功能。
    4. 在教学计算机THINPAD上验证所实现功能。
    二、实验正文
    1. 实验内容
    由于秒表实验在上学期数字逻辑实验时做过,所以对照书上的代码很快就成功完成了实验。
    2. 实验步骤
    2.1 创建空白工程
    2.2 添加源文件(代码借鉴参考书)
    2.3 综合与功能仿真
    2.4 添加用户约束
    2.5 实现
    2.6 配置
    三、综合实验总结
    1. 实验难点
    这个实验很顺利实现了。
    2. 心得体会
    对开发环境的熟悉有利于后续实验的顺利完成,比如刚开始的创建空白工程和后面的综合与功能仿真等步骤。


    实验二 运算器实验
    一、目的与要求
    1. 熟悉硬件描述语言及开发环境,了解硬件系统开发的基本过程。
    2. 掌握ALU基本设计方法和简单运算器的数据传送通路。
    3. 验证ALU的功能。
    二、实验正文
    1. 实验内容
    1.1 根据实验具体要求,用VHDL语言实现一个简单的ALU。
    1.2 将实验过程中进行的操作与结果数据记录在任务书的表格中。
    1.3 在教学计算机THINPAD上验证实现的ALU的功能。
    2. 实验步骤
    2.1 用VHDL语言编写ALU功能代码。
    2.2 将代码下载到教学机的FPGA芯片中,并调试完成。
    2.3 在THINPAD教学机上运行时,RST和时钟均用手动开关或按钮。
    2.4 设计状态机,如下:


    2.5 记录实验结果
    3. 关键代码

    1. case opCode is
    2. when "0000" => y<= a + b;
    3. if y="0000000000000000" then zflag<='1';else zflag<='0';end if;
    4. if "1111111111111111"-a>b then cflag<='0';else cflag<='1';end if;
    5. if ((y(15)xor b(15)) and (y(15) xor a(15)))='1' then oflag<='1'; else oflag<='0';end if; sflag<=y(15);
    6. when "0001" => y<= a + (not b) + 1;
    7. if y="0000000000000000" then zflag<='1';else zflag<='0';end if;
    8. if a>=b then cflag<='0';else cflag<='1';end if;
    9. if (a(1

    case opCode is
    when “0000” => y<= a + b;
    if y=”0000000000000000” then zflag<=’1’;else zflag<=’0’;end if;
    if “1111111111111111”-a>b then cflag<=’0’;else cflag<=’1’;end if;
    if ((y(15)xor b(15)) and (y(15) xor a(15)))=’1’ then oflag<=’1’; else oflag<=’0’;end if; sflag<=y(15);
    when “0001” => y<= a + (not b) + 1;
    if y=”0000000000000000” then zflag<=’1’;else zflag<=’0’;end if;
    if a>=b then cflag<=’0’;else cflag<=’1’;end if;
    if (a(15) xor b(15))=’1’ then oflag<=’1’; else oflag<=’0’;end if;
    sflag<=y(15);
    when “0010” => y<= a and b;
    if y=”0000000000000000” then zflag<=’1’;else zflag<=’0’;end if;
    cflag<=’0’;
    oflag<=’0’; sflag<=y(15);
    when “0011” => y<= a or b;
    if y=”0000000000000000” then zflag<=’1’;else zflag<=’0’;end if;
    cflag<=’0’; oflag<=’0’; sflag<=y(15);
    when “0100” => y<= a xor b;
    if y=”0000000000000000” then zflag<=’1’;else zflag<=’0’;end if;
    cflag<=’0’;
    oflag<=’0’; sflag<=y(15);
    when “0101” => y<= not a;
    if y=”0000000000000000” then zflag<=’1’;else zflag<=’0’;end if;
    cflag<=’0’;
    oflag<=’0’;
    sflag<=y(15);
    when “1000” => y<= to_stdlogicvector(to_bitvector(a) sll conv_integer(b) );
    if y=”0000000000000000” then zflag<=’1’;else zflag<=’0’;end if;
    if conv_integer(b)=”0”then cflag<= ;
    else cflag<=a(conv_integer(b)-1);
    oflag<=’0’;
    sflag<=y(15);
    when “1001” => y<= to_stdlogicvector(to_bitvector(a) srl conv_integer(b) );
    if y=”0000000000000000” then zflag<=’1’;else zflag<=’0’;end if;
    if conv_integer(b)=”0”then cflag<= ;
    else cflag<=a(16-conv_integer(b));
    oflag<=’0’;
    sflag<=y(15);
    when “1010” => y<= to_stdlogicvector(to_bitvector(a) sra conv_integer(b) );
    if y=”0000000000000000” then zflag<=’1’;else zflag<=’0’;end if;
    if conv_integer(b)=”0”then cflag<= ;
    else cflag<=a(16-conv_integer(b));
    oflag<=’0’;
    sflag<=y(15);
    when “1011” => y<= to_stdlogicvector(to_bitvector(a) rol conv_integer(b) );
    if y=”0000000000000000” then zflag<=’1’;else zflag<=’0’;end if;
    if conv_integer(b)=”0”then cflag<= ;
    else cflag<=a(conv_integer(b)-1);
    oflag<=’0’;
    sflag<=y(15);
    when others => y<=”0000000000000000”;
    4. 实验结果

    输入数据 实际输出 与预期一致性
    操作码 操作数A 操作数B 运算结果 标志位
    0000 FFFFH 0001H 0000H 0011 1
    0001 FFFFH 0001H FFFEH 0100 1
    0010 FFFFH 00FFH 00FFH 0000 1
    0011 FF00H 00FFH FFFFH 0100 1
    0100 F0F0H FF00H 0FF0H 0000 1
    0101 FFFFH 0000H 0100 1
    1000 0F00H 0002H 3C00H 0000 1
    1001 3C00H 0002H 0F00H 0000 1
    1010 FFFFH 0004H FFFFH 0110 1
    1011 0F00H 0004H F000H 0100 1
    1. 思考题
      (1)ALU进行算术逻辑运算所使用的电路是时序逻辑电路。
      三、综合实验总结
      1.
      实验难点
      本次实验的难点,我觉得是在代码实现上,但通过组员一起的努力,还是按要求编写完成代码并成功实现。
      2.
      心得体会
      通过本次实验,我掌握了ALU基本设计方法和简单运算器的数据传送通路,并参照任务书上的表格在教学计算机THINPAD上验证实现的ALU的功能。


      实验三 存储器实验
      一、目的与要求
      1. 熟悉掌握THINPAD教学计算机内存储器的配置及与总线的连接方式。
      2. 掌握教学机内存(RAM)的访问时序和方法。
      3. 理解总线数据传输的基本原理
      二、实验正文
      1. 实验内容
      使用教学计算机上的FPGA芯片,设计一个状态机和内存读写逻辑,完成对存储器RAM的访问。具体要求如下:
      (1)写RAM1。将手拨开关上的数据,写入到RAM1的相应存储单元中。首先,在手 拨开关上拨入写入地址单元的地址,按CLK键后,再在手拨开关上拨入要写入该单 元的数据,再按CLK键后,数据应写入到RAM1的对应单元中。继续按CLK键, 则地址和数据各加1后写入,共写10个数据。过程中,应在LED灯上分别显示地 址和数据。
      (2)读RAM1。RAM1中写入10组数据后,按CLK键后开始读RAM1的内容。按 CLK键,逐个将刚写入的10个数据从存储单元中读出,送到LED上显示。
      2. 实验步骤
      2.1 定义输入信号
      2.2 定义状态机,如下:


      2.3 验证过程
      3. 关键代码
      State switching:when N=> ctrl_state<=W;
      RAM1_EN<=’0’;=RAM1_OE<=’0’;=RAM1_WE<=’1’;
      when W=>ctrl_state<=R;
      RAM1_EN<=’0’;=RAM1_OE<=’1’;RAM1_WE<=’0’;
      when R=>ctrl_state<=W;
      RAM1_EN<=’0’;RAM1_OE<=’0’;RAM1_WE<=’1’;
      when others=>ctrl_state<=”11”;
      W:when W=>to_light<=tmp_data;
      case write_state is
      when waiting=>write_state<=prepare;
      read_state<=waiting;
      stateCnt <= not “1111001”; —1
      when prepare=> tmp_data<=Input_data;—input data
      stateCnt <= not “0100100”; —2
      ADDR<=tmp_addr;
      DATA<=tmp_data;
      write_state<=start;
      when start=>
      —tmp_addr<=Input_data; —input address
      ADDR<=tmp_addr;
      DATA<=tmp_data;
      stateCnt <= not “0110000”; —3 write_state<=achieve;
      when achieve=> ADDR<=tmp_addr;
      DATA<=tmp_data;
      datas(conv_integer(tmp_addr))<=tmp_data;— save in array

      stateCnt <= not “0011001”; —4
      write_state<=over;
      when over=> write_state<=waiting;
      tmp_addr<=tmp_addr+1;
      stateCnt <= not “1000000”;—0 address+ 1
      when others=> write_state<=”111”;
      end case;
      R:when R=>

      case read_state is
      when waiting=> read_state<=prepare;
      write_state<=waiting;
      stateCnt <= not “1111001”; —1
      when prepare=>
      —tmp_read_addr<=Input_data;
      ADDR<=tmp_read_addr;
      DATA<=(others=>’Z’);
      read_state<=start;
      stateCnt <= not “0100100”; —2 output address
      when start=> ADDR<=tmp_read_addr;
      to_light<=DATA;
      read_state<=achieve;
      stateCnt <= not “0110000”; —3 output data
      when achieve=>
      LIGHT<=datas(conv_integer(tmp_read_addr));
      read_state<=over;
      stateCnt <= not “0011001”; —4 wait time
      when over=>
      read_state<=waiting;
      tmp_read_addr<=tmp_read_addr+1;
      stateCnt <= not “1000000”; —0address+ 1
      when others=> read_state<=”111”; end case;
      4. 实验结果

    | address | data | expected results | | —- | —- | —- | | 0002F | 0001F | 1 | | 0003F | 0002F | 1 | | 0004F | 0003F | 1 | | 0005F | 0004F | 1 | | 0006F | 0005F | 1 | | 0007F | 0006F | 1 | | 0008F | 0007F | 1 | | 0009F | 0008F | 1 | | 000AF | 0009F | 1 | | 00BF | 000AF | 1 |

    5.思考题
    读、写时序在读信号与写信号变化上类似,但读时序持续时间更长,写时序时要从双向数据线上输入写数据需要状态转换。
    三、综合实验总结
    1.
    实验难点
    我觉得本次实验难点是代码实现部分。
    2.
    心得体会
    通过本次实验,我掌握了教学机内存(RAM)的访问时序和方法。 实验四 控制器实验
    一、目的与要求
    1. 进一步理解和掌握教学计算机THOINPAD指令系统,包括指令功能、指令格式等。
    2. 通过阅读一个简单的多周期控制器的VHDL语言源代码,了解控制器的基本组成和实现方法。
    3. 观测该控制器的运行过程,了解控制器的功能,加深对多周期CPU的控制器运行原理与指令周期的理解。
    二、实验正文
    1. 实验内容
    1.1 理解TEC-XP16教学计算机的功能部件组成和线路逻辑关系,分析教学计算机中已经设计好并正常运行的几条典型指令(例如,ADD、SHR、OUT、MVRD、JRC、CALA、RET等指令)的功能、格式和执行流程。
    1.2 设计5条指令,包括ADC、SBB、NOT以及RCL、RCR或ASR,给出指令的功能、格式和执行流程,并在教学计算机上实现、调试正确。在原来提供的MACH程序的基础上按照ABEL语言的要求添加新指令的控制信号,编译产生.JED文件并下载到MACH芯片里。
    1.3 单条运行指令,查看指令的功能、格式和执行流程。
    1.4 用监控程序的A、E(扩展指令必须用E命令置入)命令编写一段小程序,观察运行结果。观察终端显示的结果,检验设计的指令是否正确。若与预定结果不符,可查看指令的功能、格式、执行、流程设计的是否正确。
    2. 实验步骤
    2.1 定义输入信号
    2.2 定义13个需输出的控制信号
    2.3 定义状态机,如下:


    2.4 验证过程
    2.5 可以设置自定义的展示方式
    3. 关键代码
    when execute=>
    case instructions(15 downto 11) is
    when “00100” =>
    ALUSrcA<=’1’;
    ALUOp<=”10”;
    PCSource<=’1’;
    state<=instruction_fetch;
    when “10011”=>
    ALUSrcA<=’1’;
    ALUSrcB<=”10”;
    ALUOp<=”00”;
    state<=mem_control;
    when “11011”=>
    ALUSrcA<=’1’;
    ALUSrcB<=”10”;
    ALUOp<=”00”;
    state<=mem_control;
    when “11100” =>
    case instructions (1 downto 0) is
    when “01” => ——-addu
    ALUSrcA<=’1’;
    ALUSrcB<=”00”;
    ALUOp<=”00”;
    when “11” => ——-subu
    ALUSrcA<=’1’;
    ALUSrcB<=”00”;
    ALUOp<=”01”;
    when others =>
    null;
    end case;
    state <=write_reg;
    when “11101” =>
    case instructions(4 downto 0) is
    when “01101” =>
    ALUSrcA<=’1’;
    ALUSrcB<=”00”;
    ALUOp<=”10”;
    state<=write_reg;
    when “00000” =>
    case instructions(7 downto 5) is
    when “000”=>
    ALUSrcA<=’1’;
    ALUOp<=”10”;
    PCWrite<= ‘1’;
    PCSource <= ‘0’;
    state<= instruction_fetch;
    when others=>
    null;
    end case;
    when others =>
    null;
    end case;
    when others=>
    null;
    end case;
    when mem_control =>
    PCWrite<= ‘0’;
    RegWrite<=”000”;
    case instructions(15 downto 11) is
    when “10011” =>
    MemRead <= ‘1’;
    IorD <= ‘1’;
    state <= write_reg;
    when “11011” =>
    MemWrite <= ‘1’;
    IorD <= ‘1’;
    state <= write_reg;
    when others =>
    null;
    end case;
    when write_reg=>
    Memwrite <= ‘0’;
    MemRead <= ‘0’;
    case instructions (15 downto 11) is
    when “10011” =>
    RegDst <= “10”;
    RegWrite <= “001”;
    MemtoReg <= “01”;
    when “11011” =>
    MemWrite <= ‘0’;
    IorD <= ‘0’;
    when “11100” =>
    case instructions (1 downto 0) is
    when “01” =>
    RegDst<= “01”;
    RegWrite<= “001”;
    MemtoReg <= “00”;
    when “11” =>
    RegDst <=”01”;
    RegWrite<= “001”;
    MemtoReg <= “00”;
    when others =>
    null;
    end case;
    when “11101” =>
    case instructions (4 downto 0) is
    when “01101”=>
    RegDst <=”00”;
    RegWrite<= “001”;
    MemtoReg <= “00”;
    when others =>
    null;
    end case;
    when others=>
    null;
    end case;
    三、综合实验总结
    1.
    实验难点
    我觉得本次实验难点是另外扩展两条指令,不过经过全组成员的努力,我们成功验收了两条扩展指令。
    2.
    心得体会
    本次实验我们在完成初始实验的基础上,还成功扩展了两条指令,我对控制器的功能有了更深的了解,也加深了对多周期CPU的控制器运行原理与指令周期的理解。