您的位置:首页 > 理论基础

SWJTU计算机组成实验C-实验六 运算器的设计

2017-05-26 21:39 513 查看
实验目的,实验目的,说明实验仪器、设备等说明参见《计算机组成实验C》实验及课程设计指导书

程序代码

8bit ALU设计:

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY ALU_8BIT IS
PORT(INPUT_D : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
CTRL_S : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
SEL, WT, CIN, CLK : IN STD_LOGIC;
COUT : BUFFER STD_LOGIC;
OUTPUT_F : BUFFER STD_LOGIC_VECTOR(7 DOWNTO 0);
DIGITAL_DATA : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);--七段数码管控制
SEG_SEL : OUT STD_LOGIC_VECTOR(2 DOWNTO 0));--扫描刷新
END ENTITY ALU_8BIT;

ARCHITECTURE FRAME1 of ALU_8BIT IS
SHARED VARIABLE REG_A, REG_B : STD_LOGIC_VECTOR(7 DOWNTO 0);--寄存器A,B存放加数,被加数
SHARED VARIABLE RECEIVE : STD_LOGIC_VECTOR(8 DOWNTO 0);
SIGNAL OUTPUT_SEL : STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL DATA : STD_LOGIC_VECTOR(4 DOWNTO 0);
--全加器
FUNCTION ARITH_ADD(A, B : STD_LOGIC_VECTOR(7 DOWNTO 0); CIN : STD_LOGIC) RETURN STD_LOGIC_VECTOR IS
VARIABLE SINT, AA, BB : STD_LOGIC_VECTOR(8 DOWNTO 0);--9BIT长,防止溢出
BEGIN
AA := '0' & A;--高位补零
BB := '0' & B;
SINT := AA + BB + CIN;
RETURN SINT;
END ARITH_ADD;
--逻辑右移
FUNCTION SHIFT_RIGHT_LOGIC(A : STD_LOGIC_VECTOR(7 DOWNTO 0)) RETURN STD_LOGIC_VECTOR IS
VARIABLE AA : STD_LOGIC_VECTOR(7 DOWNTO 0);
BEGIN
AA(6 DOWNTO 0) := A(7 DOWNTO 1);
AA(7) := '0';--高位补零
RETURN AA;
END SHIFT_RIGHT_LOGIC;
--逻辑左移
FUNCTION SHIFT_LEFT_LOGIC(A : STD_LOGIC_VECTOR(7 DOWNTO 0)) RETURN STD_LOGIC_VECTOR IS
VARIABLE AA : STD_LOGIC_VECTOR(7 DOWNTO 0);
BEGIN
AA(7 DOWNTO 1) := A(6 DOWNTO 0);
AA(0) := '0';--低位补零
RETURN AA;
END SHIFT_LEFT_LOGIC;
--算术右移
FUNCTION SHIFT_RIGHT_ARITH(A : STD_LOGIC_VECTOR(7 DOWNTO 0)) RETURN STD_LOGIC_VECTOR IS
VARIABLE AA : STD_LOGIC_VECTOR(7 DOWNTO 0);--临时寄存器保留值
BEGIN
AA(6 DOWNTO 0) := A(7 DOWNTO 1);
AA(7) := A(7);
RETURN AA;
END SHIFT_RIGHT_ARITH;

BEGIN
PROCESS(CTRL_S, SEL, WT, CIN, CLK)
BEGIN
IF RISING_EDGE(CLK) THEN
IF(WT = '0') THEN
IF(SEL = '1') THEN
REG_A := INPUT_D;
ELSE
REG_B := INPUT_D;
END IF;
END IF;
CASE(CTRL_S) IS
WHEN "000" => OUTPUT_F <= "00000000";--清零
WHEN "001" => OUTPUT_F <= REG_A AND REG_B;--按位与
WHEN "010" => OUTPUT_F <= REG_A OR REG_B;--按位或
WHEN "011" => OUTPUT_F <= REG_A XOR REG_B;--按位异或
WHEN "100" => RECEIVE := ARITH_ADD(REG_A, REG_B, CIN); OUTPUT_F <= RECEIVE(7 DOWNTO 0); COUT <= RECEIVE(8);--全加器
WHEN "101" => OUTPUT_F <= SHIFT_LEFT_LOGIC(REG_A);--逻辑左移一位
WHEN "110" => OUTPUT_F <= SHIFT_RIGHT_LOGIC(REG_A);--逻辑右移一位
WHEN "111" => OUTPUT_F <= SHIFT_RIGHT_ARITH(REG_A);--算术右移一位
WHEN OTHERS => NULL;
END CASE;
OUTPUT_SEL <= OUTPUT_SEL + 1;--译码扫描
CASE(OUTPUT_SEL) IS
WHEN "000" => DATA(3 DOWNTO 0) <= REG_A(7 DOWNTO 4);DATA(4)<='0';
WHEN "001" => DATA(3 DOWNTO 0) <= REG_A(3 DOWNTO 0);DATA(4)<='0';
WHEN "010" => DATA(4)<='1';--最高位1,三号数码管不亮
WHEN "011" => DATA(3 DOWNTO 0) <= REG_B(7 DOWNTO 4);DATA(4)<='0';
WHEN "100" => DATA(3 DOWNTO 0) <= REG_B(3 DOWNTO 0);DATA(4)<='0';
WHEN "101" => DATA(3 DOWNTO 0) <= "0001"; DATA(4)<= NOT(COUT);
WHEN "110" => DATA(3 DOWNTO 0) <= OUTPUT_F(7 DOWNTO 4);DATA(4)<='0';
WHEN "111" => DATA(3 DOWNTO 0) <= OUTPUT_F(3 DOWNTO 0);DATA(4)<='0';
WHEN OTHERS => NULL;
END CASE;
CASE(CONV_INTEGER(DATA)) IS--数码管显示
WHEN 0 =>  DIGITAL_DATA <= X"3F";
WHEN 1 =>  DIGITAL_DATA <= X"06";
WHEN 2 =>  DIGITAL_DATA <= X"5B";
WHEN 3 =>  DIGITAL_DATA <= X"4F";
WHEN 4 =>  DIGITAL_DATA <= X"66";
WHEN 5 =>  DIGITAL_DATA <= X"6D";
WHEN 6 =>  DIGITAL_DATA <= X"7D";
WHEN 7 =>  DIGITAL_DATA <= X"07";
WHEN 8 =>  DIGITAL_DATA <= X"7F";
WHEN 9 =>  DIGITAL_DATA <= X"6F";
WHEN 10 => DIGITAL_DATA <= X"77";
WHEN 11 => DIGITAL_DATA <= X"7C";
WHEN 12 => DIGITAL_DATA <= X"39";
WHEN 13 => DIGITAL_DATA <= X"5E";
WHEN 14 => DIGITAL_DATA <= X"79";
WHEN 15 => DIGITAL_DATA <= X"71";
WHEN OTHERS =>DIGITAL_DATA <= X"00";
END CASE;
SEG_SEL <= OUTPUT_SEL-1;
END IF;
END PROCESS;
END FRAME1;
简易CPU设计:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity CPU is
port(CLK,Wr,Rd,RESET:in std_logic;--WR,RD,写/读控制,低电平有效
RA,M:in std_logic_vector(1 downto 0);--RA1 RA0控制4个通用寄存器 M1 M0控制PC寄存器四种操作
D: in std_logic_vector(7 downto 0);--ALU输出
INPUT:in std_logic_vector(7 downto 0);--外部置数
output:buffer std_logic_vector(7 downto 0);--输出到暂存器
Sin,Sout:in std_logic;--Sin控制置数或从ALU中读取数据,Sout控制输出R0-R3或PC寄存器的值到ALU暂存器
SEL:buffer std_logic_vector(2 downto 0);
LED7:out std_logic_vector(7 downto 0)
);
end entity CPU;

architecture one of CPU is
shared variable R0,R1,R2,R3,PC,temp:std_logic_vector(7 downto 0);
signal DATA:std_logic_vector(3 downto 0);
signal SEL_temp:std_logic_vector(2 downto 0);
signal times:std_logic_vector(7 downto 0);
begin
process(CLK,RESET,M)
begin
if CLK'event and CLK='0' then
times<=times+1;
if RESET='0' then PC:="00000000";
else -- RESET ='1'
if  times ="0" then
case M is
when "11" =>
if Sin='0' then
PC:=D(7 downto 0);
else
PC:=INPUT(7 downto 0);
end if;
when "01" =>PC:=PC+1;
when "10" =>PC:=PC-1;
when others=>null;
end case;
end if;
end if;
end if;
end process;

process(RA,Wr,Rd,Sin,Sout,INPUT)
begin
case RA is
when "00" => if Wr='0' and Rd='1' then
if Sin='0' then --为0表示从ALU中读取数据
R0:=D(7 downto 0); --写入数据到寄存器
else --Sin为1表示从输入端读取数据
R0:=INPUT(7 downto 0);
end if;

elsif Wr='1' and Rd='0' then temp:=R0;
end if;

when "01" => if Wr='0' and Rd='1' then
if Sin='0' then --为0表示从ALU中读取数据
R1:=D(7 downto 0); --写入数据到寄存器
else --Sin为1表示从输入端读取数据
R1:=INPUT(7 downto 0);
end if;

elsif Wr='1' and Rd='0' then temp:=R1;
end if;

when "10" => if Wr='0' and Rd='1' then
if Sin='0' then --为0表示从ALU中读取数据
R2:=D(7 downto 0); --写入数据到寄存器
else --Sin为1表示从输入端读取数据
R2:=INPUT(7 downto 0);
end if;

elsif Wr='1' and Rd='0' then temp:=R2;
end if;

when "11" => if Wr='0' and Rd='1' then

4000
if Sin='0' then --为0表示从ALU中读取数据
R3:=D(7 downto 0); --写入数据到寄存器
else --Sin为1表示从输入端读取数据
R3:=INPUT(7 downto 0);
end if;

elsif Wr='1' and Rd='0' then temp:=R3;
end if;

when others => null;
end case;
if Sout='0' then
output<=PC;
else
output<=temp;
end if;
end process;

process(CLK)
begin
if CLK'event and CLK='1' then
SEL_temp<=SEL_temp+1;
if SEL_temp>="111" then SEL_temp<="000";
end if;
SEL<=SEL_temp;
case SEL_temp is
when "000"=>DATA<=D(7 downto 4);
when "001"=>DATA<=D(3 downto 0);
when "010"=>DATA<=INPUT(7 downto 4);
when "011"=>DATA<=INPUT(3 downto 0);
when "100"=>DATA<=temp(7 downto 4);
when "101"=>DATA<=temp(3 downto 0);
when "110"=>DATA<=PC(7 downto 4);
when "111"=>DATA<=PC(3 downto 0);
when others=>NULL;
end case;
end if;
end process;

process(DATA)
begin
case DATA is
WHEN "0000"=> LED7<="00111111";--0
WHEN "0001"=> LED7<="00000110";--1
WHEN "0010"=> LED7<="01011011";--2
WHEN "0011"=> LED7<="01001111";--3
WHEN "0100"=> LED7<="01100110";--4
WHEN "0101"=> LED7<="01101101";--5
WHEN "0110"=> LED7<="01111101";--6
WHEN "0111"=> LED7<="00000111";--7
WHEN "1000"=> LED7<="01111111";--8
WHEN "1001"=> LED7<="01101111";--9
WHEN "1010"=> LED7<="01110111";--10
WHEN "1011"=> LED7<="01111100";--11
WHEN "1100"=> LED7<="00111001";--12
WHEN "1101"=> LED7<="01011110";--13
WHEN "1110"=> LED7<="01111001";--14
WHEN "1111"=> LED7<="01110001";--15
WHEN OTHERS =>NULL;
end case;
end process;
end architecture one;
连线参考图:



说明:ALU_8BIT模块直接使用实验4代码,在该实验中存在功能闲置情况——DIGITAL_DATA,SEG_SEL数码管动态扫描显示模块停用。

引脚锁定参考:



引脚锁定并非最优解决方案,仅供参考。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  计算机