-- IEEE Library library ieee; use ieee.std_logic_1164.all; use IEEE.std_logic_unsigned.all; entity DCT_Calc is --generic parameters generic (n: integer := 16; m: integer:= 36 ); port( -- Global System Inputs Clk: IN STD_LOGIC; -- Global Clk Reset: IN STD_LOGIC; -- Global Reset --Inputs to the Calculator unit fx: IN STD_LOGIC_VECTOR(n-1 downto 0); Cos: IN STD_LOGIC_VECTOR(n-1 downto 0); --Outputs of the Calculator Unit FofX: OUT STD_LOGIC_VECTOR(m-1 downto 0); --Inputs from Controller Neg_Reg_En: IN STD_LOGIC;--Signals related to Neg_Reg Mult_Reg_En: IN STD_LOGIC;--Signals related to Mult_Reg Mult_Sel: IN STD_LOGIC; SOP_Reg_En: IN STD_LOGIC; Output_Sel: IN STD_LOGIC; Clr_SOP_Reg: IN STD_LOGIC; --Outputs to the Controller Negative: OUT STD_LOGIC; --Debug Mult_Debug: OUT STD_LOGIC_VECTOR(m-1 downto 0); Neg_No_Debug: OUT STD_LOGIC; Twos_Comp_Debug: OUT STD_LOGIC_VECTOR(m-1 downto 0); Sum_Debug: OUT STD_LOGIC_VECTOR(m-1 downto 0); SOP_Debug: OUT STD_LOGIC_VECTOR(m-1 downto 0) ); end DCT_Calc; architecture DCT_Calc_arch of DCT_Calc is --Signals related to Neg_Reg signal Neg_No_Reg: STD_LOGIC; --Signals related to Detect_Neg signal Cos_Pos: STD_LOGIC_VECTOR(n-1 downto 0); --Signals related to Multiplier Multiply_fx_Cos signal Mult_Out: STD_LOGIC_VECTOR(m-1 downto 0); --Signals related to Mult_Reg signal Mult_Out_Reg: STD_LOGIC_VECTOR(m-1 downto 0); --Signals related to Two_Comp signal Ones_Comp: STD_LOGIC_VECTOR(m-1 downto 0); signal Twos_Comp: STD_LOGIC_VECTOR(m-1 downto 0); --Signals related to Mult_Select signal Prod: STD_LOGIC_VECTOR(m-1 downto 0); --Signals related to Adder signal Sum: STD_LOGIC_VECTOR(m-1 downto 0); --Signals related to SOP_Reg signal SOP_Reg: STD_LOGIC_VECTOR(m-1 downto 0); --Signal related to calculating output when x is 0 signal Temp_Out0: STD_LOGIC_VECTOR(m-1 downto 0) := (others => '0'); signal Output0: STD_LOGIC_VECTOR(m-1 downto 0); --Signal related to calculating output when x is otherwise signal Output: STD_LOGIC_VECTOR(m-1 downto 0); component Multiplier port( S: in std_logic_vector(n-1 downto 0); L: in std_logic_vector(n-1 downto 0); Prod: out std_logic_vector(m-1 downto 0) ); end component; begin --Debug Mult_Debug <= Mult_Out_Reg; Neg_No_Debug <= Neg_No_Reg; Twos_Comp_Debug <= Twos_Comp; Sum_Debug <= Sum; SOP_Debug <= SOP_Reg; --Neg_Reg stores one if Cos is negative Neg_Reg: process (Clk, Reset, Neg_Reg_En) begin if (Reset='1') then Neg_No_Reg <= '0'; elsif (CLK'event and CLK='1') then if (Neg_Reg_En = '1') then Neg_No_Reg <= Cos(n-1); elsif (Neg_Reg_En = '0') then NULL; end if; end if; end process; Negative <= Neg_No_Reg; --Detect_Neg detects if the input Cos number is Negative --If number is negative, then the MSB is reset to 0 Detect_Neg: process (Cos) begin if (Cos(n-1) = '1') then Cos_Pos(n-1) <= '0'; Cos_Pos(n-2 downto 0) <= Cos(n-2 downto 0); else Cos_Pos(n-1 downto 0) <= Cos(n-1 downto 0); end if; end process; --This multiplier multiplies f(x) and the cos term Multiply_fx_Cos: Multiplier port map( S => fx, L => Cos_Pos, Prod => Mult_Out ); --This register stores the outpur of multiplier Mult_Reg: process (Clk, Reset, Mult_Reg_En) begin if (Reset='1') then Mult_Out_Reg <= (others => '0'); elsif (CLK'event and CLK='1') then if (Mult_Reg_En = '1') then Mult_Out_Reg <= Mult_Out; elsif (Mult_Reg_En = '0') then NULL; end if; end if; end process; --Det 2's Complement of Mult Two_Comp: process(Neg_No_Reg, Mult_Out_Reg, Ones_Comp) begin if (Neg_No_Reg = '1') then Ones_Comp <= not Mult_Out_Reg; Twos_Comp <= Ones_Comp + "000000000000000000000000000000000001"; else NULL; end if; end process; --Select between the product and its 2's complement Mult_Select: process(Mult_Sel,Mult_Out_Reg,Twos_Comp) begin case Mult_Sel is when '0' => Prod <= Mult_Out_Reg; when '1' => Prod <= Twos_Comp; when others => Prod <= (others => '0'); end case; end process; Sum <= Prod + SOP_Reg; --SOP_Reg stores the final result SOP_Register: process (Clk, Reset, SOP_Reg_En) begin if (Reset='1') then SOP_Reg <= (others => '0'); elsif (CLK'event and CLK='1') then if (Clr_SOP_Reg = '1') then SOP_Reg <= (others => '0'); else if (SOP_Reg_En = '1') then SOP_Reg <= Sum; elsif (SOP_Reg_En = '0') then NULL; end if; end if; end if; end process; --Calculate the output when x is 0 CU0_Mult: process (SOP_Reg) begin if (SOP_Reg(m-1) = '1') then Temp_Out0(m-1 downto m-3) <= "111"; elsif (SOP_Reg(m-1) = '0') then Temp_Out0(m-1 downto m-3) <= "000"; end if; end process; Temp_Out0(m-4 downto 0) <= SOP_Reg(m-1 downto 3); Output0 <= Temp_Out0 + Temp_Out0 + Temp_Out0; --Calculate the output when x is otherwise CU_Mult: process (SOP_Reg) begin if (SOP_Reg(m-1) = '1') then Output(m-1) <= '1'; else Output(m-1) <= '0'; end if; end process; Output(m-2 downto 0) <= SOP_Reg(m-1 downto 1); --Select between the product and its 2's complement Output_Select: process(Output_Sel,Output,Output0) begin case Output_Sel is when '0' => FofX <= Output; when '1' => FofX <= Output0; when others => FofX <= (others => '0'); end case; end process; end DCT_Calc_arch;