⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i8051_alu.vhd

📁 8051 VHDL IP Core
💻 VHD
字号:
---- Copyright (c) 1999-2001 Tony Givargis.  Permission to copy is granted-- provided that this header remains intact.  This software is provided-- with no warranties.---- Version : 2.9---------------------------------------------------------------------------------library IEEE;use IEEE.STD_LOGIC_1164.all;use IEEE.STD_LOGIC_ARITH.all;use WORK.I8051_LIB.all;----------------------------------------------------------------------------------- rst (active hi) : alu outputs don't care values during reset-- op_code : defines the alu operation (see I8051_LIB)-- src_1 : first source operand of the alu-- src_2 : second source operand of the alu-- src_3 : third source operand of the alu-- src_cy : carry into the 7th bit of the alu-- src_ac : carry into the 4th bit of the alu-- des_1 : first destination operand of the alu-- des_2 : second destination operand of the alu-- des_cy : carry out of the 7th bit of the alu-- des_ac : carry out of the 4th bit of the alu-- des_ov : overflow out of the alu--entity I8051_ALU is    port(rst     : in  STD_LOGIC;         op_code : in  UNSIGNED (3 downto 0);         src_1   : in  UNSIGNED (7 downto 0);         src_2   : in  UNSIGNED (7 downto 0);         src_3   : in  UNSIGNED (7 downto 0);         src_cy  : in  STD_LOGIC;         src_ac  : in  STD_LOGIC;         des_1   : out UNSIGNED (7 downto 0);         des_2   : out UNSIGNED (7 downto 0);         des_cy  : out STD_LOGIC;         des_ac  : out STD_LOGIC;         des_ov  : out STD_LOGIC);end I8051_ALU;-------------------------------------------------------------------------------architecture BHV of I8051_ALU is-------------------------------------------------------------------------------    procedure PCSADD (a : UNSIGNED (15 downto 0);                      b : UNSIGNED (7 downto 0);                      r : out UNSIGNED (15 downto 0)) is        variable v1, v2 : SIGNED (15 downto 0);    begin        v1 := SIGNED(a);        if( b(7) = '1' ) then                        v2 := SIGNED(CM_8 & b);        else                        v2 := SIGNED(C0_8 & b);        end if;        v1 := v1 + v2;        r := UNSIGNED(v1);    end PCSADD;-------------------------------------------------------------------------------            procedure PCUADD (a : UNSIGNED (15 downto 0);                      b : UNSIGNED (7 downto 0);                      r : out UNSIGNED (15 downto 0)) is    begin        r := a + b;    end PCUADD;    -------------------------------------------------------------------------------    procedure DO_ADD (a, b : in  UNSIGNED (7 downto 0);                      c : in  STD_LOGIC;                      r : out UNSIGNED (7 downto 0);                      cy, ac, ov : out STD_LOGIC) is                variable v1, v2, v3, v4 : UNSIGNED (4 downto 0);        variable v5, v6, v7, v8 : UNSIGNED (3 downto 0);        variable v9, vA, vB, vC : UNSIGNED (1 downto 0);    begin        v1 := "0" & a(3 downto 0);        v2 := "0" & b(3 downto 0);        v3 := "0" & "000" & c;        v4 := v1 + v2 + v3;                v5 := "0" & a(6 downto 4);        v6 := "0" & b(6 downto 4);        v7 := "0" & "00" & v4(4);        v8 := v5 + v6 + v7;        v9 := "0" & a(7);        vA := "0" & b(7);        vB := "0" & v8(3);        vC := v9 + vA + vB;                r(7) := vC(0);        r(6) := v8(2);        r(5) := v8(1);        r(4) := v8(0);        r(3) := v4(3);        r(2) := v4(2);        r(1) := v4(1);        r(0) := v4(0);        cy := vC(1);        ac := v4(4);        ov := vC(1) xor v8(3);    end DO_ADD;-------------------------------------------------------------------------------        procedure DO_SUB (a, b : in  UNSIGNED (7 downto 0);                      c : in  STD_LOGIC;                      r : out UNSIGNED (7 downto 0);                      cy, ac, ov : out STD_LOGIC) is        variable v1, v2, v3, v4 : UNSIGNED (4 downto 0);        variable v5, v6, v7, v8 : UNSIGNED (3 downto 0);        variable v9, vA, vB, vC : UNSIGNED (1 downto 0);    begin        v1 := "1" & a(3 downto 0);        v2 := "0" & b(3 downto 0);        v3 := "0" & "000" & c;        v4 := v1 - v2 - v3;                v5 := "1" & a(6 downto 4);        v6 := "0" & b(6 downto 4);        v7 := "0" & "00" & (not v4(4));        v8 := v5 - v6 - v7;        v9 := "1" & a(7);        vA := "0" & b(7);        vB := "0" & (not v8(3));        vC := v9 - vA - vB;                r(7) := vC(0);        r(6) := v8(2);        r(5) := v8(1);        r(4) := v8(0);        r(3) := v4(3);        r(2) := v4(2);        r(1) := v4(1);        r(0) := v4(0);        cy := not vC(1);        ac := not v4(4);        ov := (not vC(1)) xor (not v8(3));    end DO_SUB;-------------------------------------------------------------------------------    procedure DO_MUL(a, b : in UNSIGNED (7 downto 0);                     r : out UNSIGNED (15 downto 0);                     ov : out STD_LOGIC) is        variable v1 : UNSIGNED (15 downto 0);    begin        v1 := a * b;        r := v1;        if( v1(15 downto 8) /= C0_8 ) then            ov := '1';        else                        ov := '0';        end if;    end DO_MUL;    -------------------------------------------------------------------------------    procedure DO_DIV(a, b : in UNSIGNED (7 downto 0);                     r : out UNSIGNED (15 downto 0);                     ov : out STD_LOGIC) is            variable v1 : UNSIGNED (15 downto 0);        variable v2, v3 : UNSIGNED (8 downto 0);    begin        if( b = C0_8 ) then                        r(7 downto 0) := CD_8;            r(15 downto 8) := CD_8;            ov := '1';        elsif( a = b ) then            r(7 downto 0) := C1_8;            r(15 downto 8) := C0_8;            ov := '0';        elsif( a < b ) then            r(7 downto 0) := C0_8;            r(15 downto 8) := src_1;            ov := '0';        else            v1(7 downto 0) := a;            v1(15 downto 8) := C0_8;            v3 := "0" & b;            for i in 0 to 7 loop                v1(15 downto 1) := v1(14 downto 0);                v1(0) := '0';                v2 := "1" & v1(15 downto 8);                v2 := v2 - v3;                if( v2(8) = '1' ) then                                        v1(0) := '1';                    v1(15 downto 8) := v2(7 downto 0);                end if;            end loop;            r := v1;            ov := '0';        end if;    end DO_DIV;    -------------------------------------------------------------------------------    procedure DO_DA(a : in UNSIGNED (7 downto 0);                    c1, c2 : in STD_LOGIC;                    r : out UNSIGNED (7 downto 0);                    cy : out STD_LOGIC) is        variable v : UNSIGNED (8 downto 0);    begin        v := "0" & a;        if( (c2 = '1') or (v(3 downto 0) > C9_4) ) then            v := v + "000000110";        end if;                v(8) := v(8) or c1;                if( v(8) = '1' ) then            v := v + "001100000";        end if;                r := v(7 downto 0);        cy := v(8);    end DO_DA;-------------------------------------------------------------------------------begin    process(rst, op_code, src_1, src_2, src_3, src_cy, src_ac)        variable v16 : UNSIGNED (15 downto 0);        variable v8 : UNSIGNED (7 downto 0);        variable v_cy, v_ac, v_ov : STD_LOGIC;    begin        if( rst = '1' ) then            des_1 <= CD_8;            des_2 <= CD_8;            des_cy <= '-';            des_ac <= '-';            des_ov <= '-';        else            case op_code is                when ALU_OPC_ADD    =>                    DO_ADD(src_1, src_2, src_cy, v8, v_cy, v_ac, v_ov);                    des_1 <= v8;                    des_2 <= CD_8;                    des_cy <= v_cy;                    des_ac <= v_ac;                    des_ov <= v_ov;                                    when ALU_OPC_SUB    =>                    DO_SUB(src_1, src_2, src_cy, v8, v_cy, v_ac, v_ov);                    des_1 <= v8;                    des_2 <= CD_8;                    des_cy <= v_cy;                    des_ac <= v_ac;                    des_ov <= v_ov;                when ALU_OPC_MUL    =>                    DO_MUL(src_1, src_2, v16, v_ov);                    des_1 <= v16(7 downto 0);                    des_2 <= v16(15 downto 8);                    des_cy <= '-';                    des_ac <= '-';                    des_ov <= v_ov;                                    when ALU_OPC_DIV    =>                    DO_DIV(src_1, src_2, v16, v_ov);                    des_1 <= v16(7 downto 0);                    des_2 <= v16(15 downto 8);                    des_cy <= '-';                    des_ac <= '-';                    des_ov <= v_ov;                                    when ALU_OPC_DA     =>                    DO_DA(src_1, src_cy, src_ac, v8, v_cy);                    des_1 <= v8;                    des_2 <= CD_8;                    des_cy <= v_cy;                    des_ac <= '-';                    des_ov <= '-';                when ALU_OPC_NOT    =>                    des_1(7) <= not src_1(7);                    des_1(6) <= not src_1(6);                    des_1(5) <= not src_1(5);                    des_1(4) <= not src_1(4);                    des_1(3) <= not src_1(3);                    des_1(2) <= not src_1(2);                    des_1(1) <= not src_1(1);                    des_1(0) <= not src_1(0);                    des_2 <= CD_8;                    des_cy <= '-';                    des_ac <= '-';                    des_ov <= '-';                when ALU_OPC_AND    =>                    des_1(7) <= src_1(7) and src_2(7);                    des_1(6) <= src_1(6) and src_2(6);                    des_1(5) <= src_1(5) and src_2(5);                    des_1(4) <= src_1(4) and src_2(4);                    des_1(3) <= src_1(3) and src_2(3);                    des_1(2) <= src_1(2) and src_2(2);                    des_1(1) <= src_1(1) and src_2(1);                    des_1(0) <= src_1(0) and src_2(0);                    des_2 <= CD_8;                    des_cy <= '-';                    des_ac <= '-';                    des_ov <= '-';                                    when ALU_OPC_XOR    =>                    des_1(7) <= src_1(7) xor src_2(7);                    des_1(6) <= src_1(6) xor src_2(6);                    des_1(5) <= src_1(5) xor src_2(5);                    des_1(4) <= src_1(4) xor src_2(4);                    des_1(3) <= src_1(3) xor src_2(3);                    des_1(2) <= src_1(2) xor src_2(2);                    des_1(1) <= src_1(1) xor src_2(1);                    des_1(0) <= src_1(0) xor src_2(0);                    des_2 <= CD_8;                    des_cy <= '-';                    des_ac <= '-';                    des_ov <= '-';                when ALU_OPC_OR     =>                    des_1(7) <= src_1(7) or src_2(7);                    des_1(6) <= src_1(6) or src_2(6);                    des_1(5) <= src_1(5) or src_2(5);                    des_1(4) <= src_1(4) or src_2(4);                    des_1(3) <= src_1(3) or src_2(3);                    des_1(2) <= src_1(2) or src_2(2);                    des_1(1) <= src_1(1) or src_2(1);                    des_1(0) <= src_1(0) or src_2(0);                    des_2 <= CD_8;                    des_cy <= '-';                    des_ac <= '-';                    des_ov <= '-';                when ALU_OPC_RL     =>                    des_1(0) <= src_1(7);                    des_1(7 downto 1) <= src_1(6 downto 0);                    des_2 <= CD_8;                    des_cy <= '-';                    des_ac <= '-';                    des_ov <= '-';                                     when ALU_OPC_RLC    =>                    des_1(0) <= src_cy;                    des_1(7 downto 1) <= src_1(6 downto 0);                    des_2 <= CD_8;                    des_cy <= src_1(7);                    des_ac <= '-';                    des_ov <= '-';                when ALU_OPC_RR     =>                    des_1(7) <= src_1(0);                    des_1(6 downto 0) <= src_1(7 downto 1);                    des_2 <= CD_8;                    des_cy <= '-';                    des_ac <= '-';                    des_ov<= '-';                when ALU_OPC_RRC    =>                    des_1(7) <= src_cy;                    des_1(6 downto 0) <= src_1(7 downto 1);                    des_2 <= CD_8;                    des_cy <= src_1(0);                    des_ac <= '-';                    des_ov <= '-';                when ALU_OPC_PCSADD =>                    PCSADD(src_2 & src_1, src_3, v16);                    des_1 <= v16(7 downto 0);                    des_2 <= v16(15 downto 8);                    des_cy <= '-';                    des_ac <= '-';                    des_ov <= '-';                                    when ALU_OPC_PCUADD =>                    PCUADD(src_2 & src_1, src_3, v16);                    des_1 <= v16(7 downto 0);                    des_2 <= v16(15 downto 8);                    des_cy <= '-';                    des_ac <= '-';                    des_ov <= '-';                when others         =>                    des_1 <= CD_8;                    des_2 <= CD_8;                    des_cy <= '-';                    des_ac <= '-';                    des_ov <= '-';            end case;        end if;    end process;end BHV;--------------------------------------------------------------------------------- end of file --

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -