Line 1... |
Line 1... |
-- Copyright (c)2006, 2015, 2020 Jeremy Seth Henry
|
-- Copyright (c)2006, 2015, 2019, 2020 Jeremy Seth Henry
|
-- All rights reserved.
|
-- All rights reserved.
|
--
|
--
|
-- Redistribution and use in source and binary forms, with or without
|
-- Redistribution and use in source and binary forms, with or without
|
-- modification, are permitted provided that the following conditions are met:
|
-- modification, are permitted provided that the following conditions are met:
|
-- * Redistributions of source code must retain the above copyright
|
-- * Redistributions of source code must retain the above copyright
|
Line 152... |
Line 152... |
-- Author Date Change
|
-- Author Date Change
|
------------------ -------- --------------------------------------------------
|
------------------ -------- --------------------------------------------------
|
-- Seth Henry 07/19/06 Design Start
|
-- Seth Henry 07/19/06 Design Start
|
-- Seth Henry 03/13/15 Added "Almost Equal" instruction
|
-- Seth Henry 03/13/15 Added "Almost Equal" instruction
|
-- Seth Henry 12/19/19 Renamed to o8_alu16 to fit "theme"
|
-- Seth Henry 12/19/19 Renamed to o8_alu16 to fit "theme"
|
|
-- Seth Henry 04/10/20 Comment and code cleanup
|
|
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_arith.all;
|
use ieee.std_logic_arith.all;
|
use ieee.std_logic_unsigned.all;
|
use ieee.std_logic_unsigned.all;
|
Line 244... |
Line 245... |
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
|
|
constant User_Addr : std_logic_vector(15 downto 5):=
|
constant User_Addr : std_logic_vector(15 downto 5):=
|
Address(15 downto 5);
|
Address(15 downto 5);
|
alias Comp_Addr is Bus_Address(15 downto 5);
|
alias Comp_Addr is Bus_Address(15 downto 5);
|
signal Reg_Addr : std_logic_vector(4 downto 0);
|
signal Reg_Addr : std_logic_vector(4 downto 0) := (others => '0');
|
|
|
signal Addr_Match : std_logic;
|
signal Addr_Match : std_logic := '0';
|
signal Wr_En : std_logic;
|
signal Wr_En : std_logic := '0';
|
signal Wr_Data_q : DATA_TYPE;
|
signal Wr_Data_q : DATA_TYPE := (others => '0');
|
signal Rd_En : std_logic;
|
signal Rd_En : std_logic := '0';
|
|
|
type REG_ARRAY is array( 0 to 7 ) of std_logic_vector(15 downto 0);
|
type REG_ARRAY is array( 0 to 7 ) of std_logic_vector(15 downto 0);
|
signal regfile : REG_ARRAY;
|
signal regfile : REG_ARRAY := (
|
|
x"0000",x"0000",x"0000",x"0000",
|
signal Start : std_logic;
|
x"0000",x"0000",x"0000",x"0000");
|
signal Opcode : std_logic_vector(4 downto 0);
|
|
signal Operand_Sel : std_logic_vector(2 downto 0);
|
signal Start : std_logic := '0';
|
|
signal Opcode : std_logic_vector(4 downto 0) := (others => '0');
|
signal Tolerance : std_logic_vector(15 downto 0);
|
signal Operand_Sel : std_logic_vector(2 downto 0) := (others => '0');
|
signal High_Tol : signed(16 downto 0);
|
|
signal Low_Tol : signed(16 downto 0);
|
signal Tolerance : std_logic_vector(15 downto 0) := (others => '0');
|
signal Almost_Equal : std_logic;
|
signal High_Tol : signed(16 downto 0) := (others => '0');
|
|
signal Low_Tol : signed(16 downto 0) := (others => '0');
|
|
signal Almost_Equal : std_logic := '0';
|
|
|
constant FLAG_Z : integer := 0;
|
constant FLAG_Z : integer := 0;
|
constant FLAG_C : integer := 1;
|
constant FLAG_C : integer := 1;
|
constant FLAG_N : integer := 2;
|
constant FLAG_N : integer := 2;
|
constant FLAG_O : integer := 3;
|
constant FLAG_O : integer := 3;
|
|
|
signal Flags : std_logic_vector(3 downto 0);
|
signal Flags : std_logic_vector(3 downto 0) := (others => '0');
|
|
|
type ALU_STATES is ( IDLE, LOAD, EXECUTE, IDIV_INIT, IDIV_WAIT,
|
type ALU_STATES is ( IDLE, LOAD, EXECUTE, IDIV_INIT, IDIV_WAIT,
|
DAW_INIT, DAB_INIT, DAA_WAIT1, DAA_STEP2,
|
DAW_INIT, DAB_INIT, DAA_WAIT1, DAA_STEP2,
|
DAA_WAIT2, DAA_STEP3, DAA_WAIT3, DAA_STEP4,
|
DAA_WAIT2, DAA_STEP3, DAA_WAIT3, DAA_STEP4,
|
STORE );
|
STORE );
|
signal alu_ctrl : ALU_STATES;
|
signal alu_ctrl : ALU_STATES := IDLE;
|
|
|
signal Busy : std_logic;
|
signal Busy : std_logic := '0';
|
signal Busy_q : std_logic;
|
signal Busy_q : std_logic := '0';
|
|
|
signal Operand_1 : std_logic_vector(15 downto 0);
|
signal Operand_1 : std_logic_vector(15 downto 0) := (others => '0');
|
signal Operand_2 : std_logic_vector(15 downto 0);
|
signal Operand_2 : std_logic_vector(15 downto 0) := (others => '0');
|
|
|
alias Dividend is Operand_1;
|
alias Dividend is Operand_1;
|
alias Divisor is Operand_2;
|
alias Divisor is Operand_2;
|
|
|
alias u_Operand_1 is Operand_1;
|
alias u_Operand_1 is Operand_1;
|
alias u_Operand_2 is Operand_2;
|
alias u_Operand_2 is Operand_2;
|
|
|
alias u_Addend_1 is Operand_1;
|
alias u_Addend_1 is Operand_1;
|
alias u_Addend_2 is Operand_2;
|
alias u_Addend_2 is Operand_2;
|
|
|
signal s_Operand_1 : signed(16 downto 0);
|
signal s_Operand_1 : signed(16 downto 0) := (others => '0');
|
signal s_Operand_2 : signed(16 downto 0);
|
signal s_Operand_2 : signed(16 downto 0) := (others => '0');
|
|
|
alias s_Addend_1 is S_Operand_1;
|
alias s_Addend_1 is S_Operand_1;
|
alias s_Addend_2 is S_Operand_2;
|
alias s_Addend_2 is S_Operand_2;
|
|
|
signal u_accum : std_logic_vector(16 downto 0);
|
signal u_accum : std_logic_vector(16 downto 0) := (others => '0');
|
alias u_data is u_accum(15 downto 0);
|
alias u_data is u_accum(15 downto 0);
|
alias u_sign is u_accum(15);
|
alias u_sign is u_accum(15);
|
alias u_carry is u_accum(16);
|
alias u_carry is u_accum(16);
|
|
|
signal u_prod : std_logic_vector(31 downto 0);
|
signal u_prod : std_logic_vector(31 downto 0) := (others => '0');
|
|
|
signal s_accum : signed(16 downto 0);
|
signal s_accum : signed(16 downto 0) := (others => '0');
|
alias s_data is s_accum(15 downto 0);
|
alias s_data is s_accum(15 downto 0);
|
alias s_sign is s_accum(15);
|
alias s_sign is s_accum(15);
|
alias s_ovf is s_accum(16);
|
alias s_ovf is s_accum(16);
|
|
|
signal s_prod : signed(33 downto 0);
|
signal s_prod : signed(33 downto 0) := (others => '0');
|
|
|
signal IDIV_Start : std_logic;
|
signal IDIV_Start : std_logic := '0';
|
signal IDIV_Busy : std_logic;
|
signal IDIV_Busy : std_logic := '0';
|
|
|
constant DIV_WIDTH : integer := 16; -- Width of Operands
|
constant DIV_WIDTH : integer := 16; -- Width of Operands
|
|
|
signal q : std_logic_vector(DIV_WIDTH*2-1 downto 0);
|
signal q : std_logic_vector(DIV_WIDTH*2-1 downto 0) :=
|
signal diff : std_logic_vector(DIV_WIDTH downto 0);
|
(others => '0');
|
signal count : integer range 0 to DIV_WIDTH + 1;
|
|
|
signal diff : std_logic_vector(DIV_WIDTH downto 0) :=
|
signal Quotient_i : std_logic_vector(15 downto 0);
|
(others => '0');
|
signal Quotient : std_logic_vector(15 downto 0);
|
|
|
signal count : integer range 0 to DIV_WIDTH + 1 := 0;
|
signal Remainder_i : std_logic_vector(15 downto 0);
|
|
signal Remainder : std_logic_vector(15 downto 0);
|
signal Quotient_i : std_logic_vector(15 downto 0) := (others => '0');
|
|
signal Quotient : std_logic_vector(15 downto 0) := (others => '0');
|
signal DAA_intreg : std_logic_vector(15 downto 0);
|
|
signal DAA_mode : std_logic;
|
signal Remainder_i : std_logic_vector(15 downto 0) := (others => '0');
|
signal DAA_sign : std_logic;
|
signal Remainder : std_logic_vector(15 downto 0) := (others => '0');
|
signal DAA_p4 : std_logic_vector(3 downto 0);
|
|
signal DAA_p3 : std_logic_vector(3 downto 0);
|
signal DAA_intreg : std_logic_vector(15 downto 0) := (others => '0');
|
signal DAA_p2 : std_logic_vector(3 downto 0);
|
signal DAA_mode : std_logic := '0';
|
|
signal DAA_sign : std_logic := '0';
|
|
signal DAA_p4 : std_logic_vector(3 downto 0) := (others => '0');
|
|
signal DAA_p3 : std_logic_vector(3 downto 0) := (others => '0');
|
|
signal DAA_p2 : std_logic_vector(3 downto 0) := (others => '0');
|
alias DAA_p1 is Quotient(3 downto 0);
|
alias DAA_p1 is Quotient(3 downto 0);
|
alias DAA_p0 is Remainder(3 downto 0);
|
alias DAA_p0 is Remainder(3 downto 0);
|
signal DAA_result : std_logic_vector(19 downto 0);
|
signal DAA_result : std_logic_vector(19 downto 0) := (others => '0');
|
|
|
begin
|
begin
|
|
|
Addr_Match <= '1' when Comp_Addr = User_Addr else '0';
|
Addr_Match <= '1' when Comp_Addr = User_Addr else '0';
|
|
|