📄 isp8_alu.vhd
字号:
------------------------------------------------------------------------------
--
-- Name: isp8_alu.vhd
--
-- Description: Arithmetic logic unit
--
-- $Revision: 1.1 $
--
------------------------------------------------------------------------------
-- Permission:
--
-- Lattice Semiconductor grants permission to use this code for use
-- in synthesis for any Lattice programmable logic product. Other
-- use of this code, including the selling or duplication of any
-- portion is strictly prohibited.
--
-- Disclaimer:
--
-- This VHDL or Verilog source code is intended as a design reference
-- which illustrates how these types of functions can be implemented.
-- It is the user's responsibility to verify their design for
-- consistency and functionality through the use of formal
-- verification methods. Lattice Semiconductor provides no warranty
-- regarding the use or functionality of this code.
------------------------------------------------------------------------------
--
-- Lattice Semiconductor Corporation
-- 5555 NE Moore Court
-- Hillsboro, OR 97124
-- U.S.A
--
-- TEL: 1-800-Lattice (USA and Canada)
-- 408-826-6000 (other locations)
--
-- web: http://www.latticesemi.com/
-- email: techsupport@latticesemi.com
--
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity isp8_alu is
generic (
FAMILY_NAME : string);
port(instr : in std_logic_vector(17 downto 0);
dout_rd : in std_logic_vector(7 downto 0);
dout_rb : in std_logic_vector(7 downto 0);
imi_data : in std_logic_vector(7 downto 0);
imi_instr : in std_logic;
carry_flag : in std_logic;
sub : in std_logic;
subc : in std_logic;
addc : in std_logic;
cmp : in std_logic;
dout_alu : out std_logic_vector(7 downto 0);
cout_alu : out std_logic);
end isp8_alu;
architecture behave of isp8_alu is
component pmi_addsub
generic (
pmi_data_width : integer;
pmi_result_width : integer;
pmi_sign : string;
pmi_family : string;
module_type : string
);
port (DataA : in std_logic_vector(pmi_data_width-1 downto 0);
DataB : in std_logic_vector(pmi_data_width-1 downto 0);
Cin : in std_logic;
Add_Sub : in std_logic;
Result : out std_logic_vector(pmi_data_width-1 downto 0);
Cout : out std_logic;
Overflow : out std_logic
);
end component;
signal dout_r, dout_l : std_logic_vector(7 downto 0);
signal cout_r : std_logic;
signal data_rd : std_logic_vector(7 downto 0);
signal data_rb_int : std_logic_vector(7 downto 0);
signal data_rb : std_logic_vector(7 downto 0);
signal data_add : std_logic_vector(7 downto 0);
signal carry_add_int : std_logic;
signal carry_add : std_logic;
signal adsu_ci : std_logic;
signal add_sel, add_sel_inv : std_logic;
signal adsu_ci_int : std_logic;
attribute syn_black_box : boolean;
attribute syn_black_box of pmi_addsub: component is true;
begin
data_rd <= dout_rd;
data_rb <= dout_rb;
add_sel <= (sub OR subc OR cmp);
add_sel_inv <= NOT(add_sel);
adsu_ci_int <= carry_flag AND (addc OR subc);
adsu_ci <= NOT(adsu_ci_int) when (add_sel = '1') else adsu_ci_int;
data_rb_int <= imi_data when (imi_instr = '1') else dout_rb;
u1_addsub8 : pmi_addsub
generic map (
pmi_data_width => 8,
pmi_result_width => 8,
pmi_sign => "off",
pmi_family => FAMILY_NAME,
module_type => "pmi_addsub"
)
port map (DataA => dout_rd,
DataB => data_rb_int,
Cin => adsu_ci,
Add_Sub => add_sel_inv,
Result => data_add,
Cout => carry_add_int,
Overflow => open);
carry_add <= NOT(carry_add_int) when (add_sel = '1') else carry_add_int;
process(instr, data_rd, data_rb_int)
begin
case instr(15 downto 14) is
-- move function
when "00" =>
for i in 0 to 7 loop
if ((data_rd(i) = '0') AND (data_rb_int(i) = '0')) then
dout_l(i) <= '0';
elsif ((data_rd(i) = '0') AND (data_rb_int(i) = '1')) then
dout_l(i) <= '1';
elsif ((data_rd(i) = '1') AND (data_rb_int(i) = '0')) then
dout_l(i) <= '0';
else
dout_l(i) <= '1';
end if;
end loop;
-- and function
when "01" =>
for i in 0 to 7 loop
if ((data_rd(i) = '0') AND (data_rb_int(i) = '0')) then
dout_l(i) <= '0';
elsif ((data_rd(i) = '0') AND (data_rb_int(i) = '1')) then
dout_l(i) <= '0';
elsif ((data_rd(i) = '1') AND (data_rb_int(i) = '0')) then
dout_l(i) <= '0';
else
dout_l(i) <= '1';
end if;
end loop;
-- or function
when "10" =>
for i in 0 to 7 loop
if ((data_rd(i) = '0') AND (data_rb_int(i) = '0')) then
dout_l(i) <= '0';
elsif ((data_rd(i) = '0') AND (data_rb_int(i) = '1')) then
dout_l(i) <= '1';
elsif ((data_rd(i) = '1') AND (data_rb_int(i) = '0')) then
dout_l(i) <= '1';
else
dout_l(i) <= '1';
end if;
end loop;
-- xor function
when "11" =>
for i in 0 to 7 loop
if ((data_rd(i) = '0') AND (data_rb_int(i) = '0')) then
dout_l(i) <= '0';
elsif ((data_rd(i) = '0') AND (data_rb_int(i) = '1')) then
dout_l(i) <= '1';
elsif ((data_rd(i) = '1') AND (data_rb_int(i) = '0')) then
dout_l(i) <= '1';
else
dout_l(i) <= '0';
end if;
end loop;
when others => dout_l <= "00000000";
end case;
end process;
process(instr, carry_flag, data_rb)
begin
case instr(1 downto 0) is
-- ror
when "00" =>
cout_r <= carry_flag;
dout_r <= data_rb(0) & data_rb(7 downto 1);
-- rorc
when "10" =>
cout_r <= data_rb(0);
dout_r <= carry_flag & data_rb(7 downto 1);
-- rol
when "01" =>
cout_r <= carry_flag;
dout_r <= data_rb(6 downto 0) & data_rb(7);
-- rolc
when "11" =>
cout_r <= data_rb(7);
dout_r <= data_rb(6 downto 0) & carry_flag;
when others =>
cout_r <= '0';
dout_r <= "00000000";
end case;
end process;
process(instr, cout_r, carry_flag, carry_add, dout_r, dout_l, data_add)
begin
case instr(17 downto 14) is
when "1000" =>
cout_alu <= carry_add;
dout_alu <= data_add;
when "0000" =>
cout_alu <= carry_add;
dout_alu <= data_add;
when "0001" =>
cout_alu <= carry_add;
dout_alu <= data_add;
when "0010" =>
cout_alu <= carry_add;
dout_alu <= data_add;
when "0011" =>
cout_alu <= carry_add;
dout_alu <= data_add;
when "0100" =>
cout_alu <= carry_flag;
dout_alu <= dout_l;
when "0101" =>
cout_alu <= carry_flag;
dout_alu <= dout_l;
when "0110" =>
cout_alu <= carry_flag;
dout_alu <= dout_l;
when "0111" =>
cout_alu <= carry_flag;
dout_alu <= dout_l;
when "1001" =>
cout_alu <= carry_flag; --Note: change from original verilog
dout_alu <= dout_l; --Note: change from original verilog
when "1010" =>
cout_alu <= cout_r;
dout_alu <= dout_r;
when "1011" =>
cout_alu <= cout_r;
dout_alu <= dout_r;
when others =>
cout_alu <= '0';
dout_alu <= "00000000";
end case;
end process;
end behave;
--------------------------------- E O F --------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -