fpga: x400: Add support for X410 motherboard FPGA
Co-authored-by: Andrew Moch <Andrew.Moch@ni.com> Co-authored-by: Daniel Jepson <daniel.jepson@ni.com> Co-authored-by: Javier Valenzuela <javier.valenzuela@ni.com> Co-authored-by: Joerg Hofrichter <joerg.hofrichter@ni.com> Co-authored-by: Kumaran Subramoniam <kumaran.subramoniam@ni.com> Co-authored-by: Max Köhler <max.koehler@ni.com> Co-authored-by: Michael Auchter <michael.auchter@ni.com> Co-authored-by: Paul Butler <paul.butler@ni.com> Co-authored-by: Wade Fife <wade.fife@ettus.com> Co-authored-by: Hector Rubio <hrubio@ni.com> Original-commit: 6d3765605262016a80f71e36357f749ea35cbe5a
This commit is contained in:
committed by
Aaron Rossetto
co-authored by
Andrew Moch
Daniel Jepson
Javier Valenzuela
Joerg Hofrichter
Kumaran Subramoniam
Max Köhler
Michael Auchter
Paul Butler
Hector Rubio
parent
bfef20ea45
commit
61782b02d7
@@ -0,0 +1,220 @@
|
||||
--
|
||||
-- Copyright 2021 Ettus Research, a National Instruments Brand
|
||||
--
|
||||
-- SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
--
|
||||
-- Module: PkgRf
|
||||
--
|
||||
-- Description:
|
||||
--
|
||||
-- This package has some type definition and functions used in the RF data
|
||||
-- chain.
|
||||
--
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
|
||||
package PkgRf is
|
||||
|
||||
-- DDC sample data out width.
|
||||
constant kDdcDataOutWidth : natural := 17;
|
||||
-- Each sample is padded in MSB with 7 extra bits of zero to byte align.
|
||||
constant kDdcDataWordWidth : natural := kDdcDataOutWidth+7;
|
||||
-- DUC sample data out width.
|
||||
constant kDucDataOutWidth : natural := 18;
|
||||
-- Each sample is padded in MSB with 6 extra bits of zero to byte align.
|
||||
constant kDucDataWordWidth : natural := kDucDataOutWidth+6;
|
||||
-- Saturated data output width.
|
||||
constant kSatDataWidth : natural := 16;
|
||||
-- ADC sample resolution.
|
||||
constant kAdcSampleRes : natural := 16;
|
||||
|
||||
subtype Sample18_t is signed(17 downto 0);
|
||||
subtype Sample17_t is signed(16 downto 0);
|
||||
subtype Sample16_t is signed(15 downto 0);
|
||||
subtype Sample16slv_t is std_logic_vector(15 downto 0);
|
||||
|
||||
type Samples16_t is array(natural range<>) of Sample16_t;
|
||||
type Samples17_t is array(natural range<>) of Sample17_t;
|
||||
type Samples18_t is array(natural range<>) of Sample18_t;
|
||||
|
||||
-- These constants have the largest and smallest 18-bit, 17-bit, and 16-bit
|
||||
-- signed values.
|
||||
constant kLargest18 : Sample18_t := to_signed(2**17 - 1, 18);
|
||||
constant kSmallest18 : Sample18_t := to_signed(-2**17, 18);
|
||||
constant kLargest17 : Sample17_t := to_signed(2**16 - 1, 17);
|
||||
constant kSmallest17 : Sample17_t := to_signed(-2**16, 17);
|
||||
constant kLargest16 : Sample16_t := to_signed(2**15 - 1, 16);
|
||||
constant kSmallest16 : Sample16_t := to_signed(-2**15, 16);
|
||||
|
||||
function Saturate(s : signed ) return Sample16_t;
|
||||
function to_stdlogicvector(d : Samples16_t) return std_logic_vector;
|
||||
function to_Samples16(d : std_logic_vector) return Samples16_t;
|
||||
function to_Samples17(d : std_logic_vector) return Samples17_t;
|
||||
function to_Samples18(d : std_logic_vector) return Samples18_t;
|
||||
-- Shift the ADC sample to the left by 1 bit.
|
||||
function Gain2x(d : std_logic_vector) return std_logic_vector;
|
||||
function Gain2x(s : Samples16_t) return Samples16_t;
|
||||
--synopsys translate_off
|
||||
function tb_saturate(s: std_logic_vector) return Sample16slv_t;
|
||||
--synopsys translate_on
|
||||
|
||||
end package PkgRf;
|
||||
|
||||
|
||||
package body PkgRf is
|
||||
|
||||
-- Function to saturate any signed number greater then 16 bits.
|
||||
-- A saturated 16-bit data is returned.
|
||||
function Saturate ( s : signed) return Sample16_t is
|
||||
begin
|
||||
if s > kLargest16 then
|
||||
return kLargest16;
|
||||
elsif s < kSmallest16 then
|
||||
return kSmallest16;
|
||||
else
|
||||
return resize(s, 16);
|
||||
end if;
|
||||
end function Saturate;
|
||||
|
||||
-- This function will convert 16 bit signed array into a single
|
||||
-- std_logic_vector.
|
||||
function to_stdlogicvector(d : Samples16_t) return std_logic_vector is
|
||||
-- This alias is used to normalize the input vector to [d'length-1 downto 0]
|
||||
alias normalD : Samples16_t(d'length-1 downto 0) is d;
|
||||
variable rval : std_logic_vector(d'length * 16 - 1 downto 0);
|
||||
constant dataWidth : natural := Sample16_t'length;
|
||||
begin
|
||||
for i in normalD'range loop
|
||||
rval(i*dataWidth + dataWidth-1 downto i*dataWidth)
|
||||
:= std_logic_vector(normalD(i));
|
||||
end loop;
|
||||
return rval;
|
||||
end function to_stdlogicvector;
|
||||
|
||||
-- This function will convert a std_logic_vector into an array of 18 bit
|
||||
-- signed array. The input std_logic_vector has data packed in 24 bits. But
|
||||
-- only 18 bits has valid data and remaining 6 MSB bits are padded with
|
||||
-- zeros.
|
||||
function to_Samples18(d : std_logic_vector) return Samples18_t is
|
||||
-- This alias is used to normalize the input vector to [d'length-1 downto 0]
|
||||
alias normalD : std_logic_vector(d'length-1 downto 0) is d;
|
||||
variable rval : Samples18_t(d'length / kDucDataWordWidth - 1 downto 0);
|
||||
begin
|
||||
--synopsys translate_off
|
||||
assert (((d'length) mod kDucDataWordWidth) = 0)
|
||||
report "Input to the function to_Samples18 must be a multiple of kDucDataWordWidth"
|
||||
severity error;
|
||||
--synopsys translate_on
|
||||
for i in rval'range loop
|
||||
rval(i) := Sample18_t(normalD(i*kDucDataWordWidth + Sample18_t'length-1
|
||||
downto i*kDucDataWordWidth));
|
||||
end loop;
|
||||
return rval;
|
||||
end function to_Samples18;
|
||||
|
||||
-- This function will convert a std_logic_vector into an array of 16 bit
|
||||
-- signed array. The input std_logic_vector has data packed in 16 bits. But
|
||||
-- only 15 bits has valid data and the uper two bits only have the signed
|
||||
-- bit.
|
||||
function to_Samples16(d : std_logic_vector) return Samples16_t is
|
||||
-- This alias is used to normalize the input vector to [d'length-1 downto 0]
|
||||
alias normalD : std_logic_vector(d'length-1 downto 0) is d;
|
||||
variable rval : Samples16_t(d'length / kAdcSampleRes - 1 downto 0);
|
||||
begin
|
||||
--synopsys translate_off
|
||||
assert (((d'length) mod kAdcSampleRes) = 0)
|
||||
report "Input to the function to_Samples16 must be a multiple of kAdcSampleRes"
|
||||
severity error;
|
||||
--synopsys translate_on
|
||||
for i in rval'range loop
|
||||
rval(i) := Sample16_t(normalD(i*kAdcSampleRes + Sample16_t'length-1
|
||||
downto i*kAdcSampleRes));
|
||||
end loop;
|
||||
return rval;
|
||||
end function to_Samples16;
|
||||
|
||||
-- This function will convert a std_logic_vector into an array of 19 bit
|
||||
-- signed array. The input std_logic_vector has data packed in 24 bits. But
|
||||
-- only 17 bits has valid data and remaining 7 MSB bits are padded with
|
||||
-- zeros.
|
||||
function to_Samples17(d : std_logic_vector) return Samples17_t is
|
||||
-- This alias is used to normalize the input vector to [d'length-1 downto 0]
|
||||
alias normalD : std_logic_vector(d'length-1 downto 0) is d;
|
||||
variable rval : Samples17_t(d'length / kDdcDataWordWidth - 1 downto 0);
|
||||
begin
|
||||
--synopsys translate_off
|
||||
assert (((d'length) mod kDdcDataWordWidth) = 0)
|
||||
report "Input to the function to_Samples17 must be a multiple of kDdcDataWordWidth"
|
||||
severity error;
|
||||
--synopsys translate_on
|
||||
for i in rval'range loop
|
||||
rval(i) := Sample17_t(normalD(i*kDdcDataWordWidth + Sample17_t'length-1
|
||||
downto i*kDdcDataWordWidth));
|
||||
end loop;
|
||||
return rval;
|
||||
end function to_Samples17;
|
||||
|
||||
-- Function to shift the sample to the left by one bit and effectively
|
||||
-- multiply by 2.
|
||||
function Gain2x(s : Samples16_t) return Samples16_t is
|
||||
variable rval : Samples16_t(s'range);
|
||||
begin
|
||||
for i in rval'range loop
|
||||
rval(i) := s(i)(kAdcSampleRes-2 downto 0) & '0';
|
||||
end loop;
|
||||
return rval;
|
||||
end function Gain2x;
|
||||
|
||||
function Gain2x (d : std_logic_vector) return std_logic_vector is
|
||||
begin
|
||||
return to_stdlogicvector(Gain2x(to_Samples16(d)));
|
||||
end function;
|
||||
|
||||
--synopsys translate_off
|
||||
---------------------------------------------------------------
|
||||
-- Function below this comment is used only for testbench.
|
||||
---------------------------------------------------------------
|
||||
-- This function does saturation of a signed number in std_logic_vector data
|
||||
-- type. The current implementation supports only 17 or 18 bit signed
|
||||
-- number.
|
||||
function tb_saturate(s: std_logic_vector) return Sample16slv_t is
|
||||
-- This alias is used to normalize the input vector to [s'length-1 downto 0]
|
||||
alias normalS : std_logic_vector(s'length-1 downto 0) is s;
|
||||
variable rval : Sample16slv_t;
|
||||
constant len : integer := s'length;
|
||||
begin
|
||||
|
||||
-- If 2 MSBs = 00, output <= input without MSB, e.g. positive number < 1
|
||||
-- If 2 MSBs = 01, output <= 0.111111111111111, e.g. positive number >= 1
|
||||
-- If 2 MSBs = 10, output <= 1.000000000000000, e.g. negative number < -1
|
||||
-- If 2 MSBs = 11, output <= input without MSB, e.g. negative number >= -1
|
||||
if len = kDdcDataOutWidth then
|
||||
if normalS(len-1 downto len-2) = "01" then
|
||||
rval := "0111111111111111";
|
||||
elsif normalS(len-1 downto len-2) = "10" then
|
||||
rval := "1000000000000000";
|
||||
else
|
||||
rval := normalS(len-2 downto 0);
|
||||
end if;
|
||||
|
||||
-- If 3 MSBs = 000, output <= input without MSB, e.g. positive number < 1
|
||||
-- If 3 MSBs = 0x1/01x, output <= 0.111111111111111, e.g. positive number >= 1
|
||||
-- If 3 MSBs = 1x0/10x, output <= 1.000000000000000, e.g. negative number < -1
|
||||
-- If 3 MSBs = 111, output <= input without MSB, e.g. negative number >= -1
|
||||
else -- len = kDucDataOutWidth
|
||||
if normalS(len-1) = '0' and normalS(len-2 downto len-3) /= "00" then
|
||||
rval := "0111111111111111";
|
||||
elsif (normalS(len-1 downto len-3) = "000") or
|
||||
(normalS(len-1 downto len-3) = "111") then
|
||||
rval := normalS(len-3 downto 0);
|
||||
else
|
||||
rval := "1000000000000000";
|
||||
end if;
|
||||
end if;
|
||||
return rval;
|
||||
end function tb_saturate;
|
||||
--synopsys translate_on
|
||||
|
||||
end package body;
|
||||
Reference in New Issue
Block a user