-- EMACS settings: -*- tab-width: 2; indent-tabs-mode: t -*-
-- vim: tabstop=2:shiftwidth=2:noexpandtab
-- kate: tab-width 2; replace-tabs off; indent-width 2;
-- =============================================================================
-- Authors: Patrick Lehmann
--
-- Entity: TODO
--
-- Description:
--
-- .. TODO:: No documentation available.
--
-- License:
-- =============================================================================
-- Copyright 2007-2015 Technische Universitaet Dresden - Germany
-- Chair of VLSI-Design, Diagnostics and Architecture
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
-- =============================================================================
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use IEEE.math_real.all;
library PoC;
use PoC.utils.all;
use PoC.strings.all;
entity [docs]lut_Sine is
generic (
REG_OUTPUT : boolean := TRUE;
MAX_AMPLITUDE : positive := 255;
POINTS : positive := 4096;
OFFSET_DEG : REAL := 0.0;
QUARTERS : positive := 4
);
port (
Clock : in std_logic;
Input : in std_logic_vector(log2ceilnz(POINTS) - 1 downto 0);
Output : out std_logic_vector(log2ceilnz(MAX_AMPLITUDE + ((QUARTERS - 1) / 2)) downto 0)
);
end entity;
architecture [docs]rtl of lut_Sine is
signal Output_nxt : std_logic_vector(Output'range);
begin
-- ===========================================================================
-- 1 Qudrant LUT
-- ===========================================================================
genQ1 : if QUARTERS = 1 generate
subtype T_RESULT is natural range 0 to MAX_AMPLITUDE;
type T_LUT is array (natural range <>) of T_RESULT;
function generateLUT return T_LUT is
variable Result : T_LUT(0 to POINTS - 1) := (others => 0);
constant STEP : REAL := (90.0 / real(Result'length)) * MATH_DEG_TO_RAD;
constant AMPLITUDE_I : REAL := real(MAX_AMPLITUDE);
variable x : REAL := 0.0;
variable y : REAL;
begin
for i in Result'range loop
Result(i) := integer(sin(x) * AMPLITUDE_I);
x := x + STEP;
end loop;
return Result;
end function;
constant LUT : T_LUT := generateLUT;
begin
assert (OFFSET_DEG = 0.0) report "Offset > 0.0� is only supported in 4 quadrant mode." severity FAILURE;
Output_nxt <= std_logic_vector(to_unsigned(LUT(to_index(Input, LUT'length)), Output_nxt'length));
end generate;
-- ===========================================================================
-- 2 Qudrant LUT
-- ===========================================================================
genQ12 : if QUARTERS = 2 generate
subtype T_RESULT is natural range 0 to MAX_AMPLITUDE;
type T_LUT is array (natural range <>) of T_RESULT;
function generateLUT return T_LUT is
variable Result : T_LUT(0 to POINTS - 1) := (others => 0);
constant STEP : REAL := (180.0 / real(Result'length)) * MATH_DEG_TO_RAD;
constant AMPLITUDE_I : REAL := real(MAX_AMPLITUDE);
variable x : REAL := 0.0;
variable y : REAL;
begin
for i in Result'range loop
Result(i) := integer(sin(x) * AMPLITUDE_I);
x := x + STEP;
end loop;
return Result;
end function;
constant LUT : T_LUT := generateLUT;
begin
assert (OFFSET_DEG = 0.0) report "Offset > 0.0� is only supported in 4 quadrant mode." severity FAILURE;
Output_nxt <= std_logic_vector(to_unsigned(LUT(to_index(Input, LUT'length)), Output_nxt'length));
end generate;
-- ===========================================================================
-- 3 Qudrant LUT -> ERROR
-- ===========================================================================
genQ13 : if QUARTERS = 3 generate
assert false report "QUARTERS=3 is not supported." severity FAILURE;
end generate;
-- ===========================================================================
-- 4 Qudrant LUT
-- ===========================================================================
genQ14 : if QUARTERS = 4 generate
subtype T_RESULT is integer range -MAX_AMPLITUDE to MAX_AMPLITUDE;
type T_LUT is array (natural range <>) of T_RESULT;
function generateLUT return T_LUT is
variable Result : T_LUT(0 to POINTS - 1) := (others => 0);
constant STEP : REAL := (360.0 / real(Result'length)) * MATH_DEG_TO_RAD;
constant AMPLITUDE_I : REAL := real(MAX_AMPLITUDE);
variable x : REAL := OFFSET_DEG * MATH_DEG_TO_RAD;
variable y : REAL;
begin
for i in Result'range loop
Result(i) := integer(sin(x) * AMPLITUDE_I);
x := x + STEP;
end loop;
return Result;
end function;
constant LUT : T_LUT := generateLUT;
begin
Output_nxt <= std_logic_vector(to_signed(LUT(to_index(Input, LUT'length)), Output_nxt'length));
end generate;
-- ===========================================================================
-- No output registers
-- ===========================================================================
genNoReg : if not REG_OUTPUT generate
begin
Output <= Output_nxt;
end generate;
-- ===========================================================================
-- Output registers
-- ===========================================================================
genReg : if REG_OUTPUT generate
signal Output_d : std_logic_vector(Output'range) := (others => '0');
begin
Output_d <= Output_nxt when rising_edge(Clock);
Output <= Output_d;
end generate;
end;