Skip to content
Snippets Groups Projects
Commit 1b162ee3 authored by BRONES Romain's avatar BRONES Romain
Browse files

feat: Add DDS and Scaler

parent e5351d21
Branches
Tags
No related merge requests found
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library desy;
use desy.ram_tdp;
use work.pkg_pscgen.all;
use work.pkg_pscgen_gen_ip.all;
entity MultiScaler is
port(
clk : in std_logic;
rstn : in std_logic;
-- Memory map to table
pi_table_en : in std_logic;
pi_table_we : in std_logic;
pi_table_addr : in std_logic_vector(C_W_TIDX-1 downto 0);
pi_table_data : in std_logic_vector(C_W_SCALE+C_W_OFFSET-1 downto 0);
po_table_data : out std_logic_vector(C_W_SCALE+C_W_OFFSET-1 downto 0);
-- Sine in
pi_sine : in std_logic_vector(C_W_SINE-1 downto 0);
pi_sine_tidx : in std_logic_vector(C_W_TIDX-1 downto 0);
pi_sine_valid : in std_logic;
-- Wave out
po_wave : out std_logic_vector(C_W_SIG-1 downto 0);
po_wave_tidx : out std_logic_vector(C_W_TIDX-1 downto 0);
po_wave_valid : out std_logic
);
end entity MultiScaler;
architecture rtl of MultiScaler is
-- CONSTANT
constant C_PIPE_LEN : natural := 5;
-- Array for TIDX pipeline delay
type t_tidx_array is array(C_PIPE_LEN-1 downto 0) of std_logic_vector(C_W_TIDX-1 downto 0);
------------------------
-- SIGNAL DECLARATION --
------------------------
signal r_valid : std_logic_vector(C_PIPE_LEN-1 downto 0);
signal r_sine : std_logic_vector(C_W_SINE-1 downto 0);
signal r_tidx : t_tidx_array;
signal r_offset : std_logic_vector(C_W_OFFSET-1 downto 0);
signal table_data : std_logic_vector(C_W_SCALE+C_W_OFFSET-1 downto 0);
signal scale : std_logic_vector(C_W_SCALE-1 downto 0);
signal offset : std_logic_vector(C_W_OFFSET-1 downto 0);
signal wave : std_logic_vector(C_W_SIG-1 downto 0);
begin
--------------------
-- PIPELINE DELAY --
--------------------
p_delay:process(clk, rstn)
begin
if rstn = '0' then
r_valid <= (others => '0');
r_sine <= (others => '0');
r_tidx <= (others => (others => '0'));
r_offset <= (others => '0');
elsif rising_edge(clk) then
r_valid <= pi_sine_valid & r_valid(C_PIPE_LEN-1 downto 1);
r_sine <= pi_sine;
r_offset <= offset;
r_tidx(C_PIPE_LEN-1) <= (pi_sine_tidx);
for I in 0 to C_PIPE_LEN-2 loop
r_tidx(I) <= r_tidx(I+1);
end loop;
end if;
end process;
------------------------
-- SCALE OFFSET TABLE --
------------------------
-- Port A is read write from AXI controller, Port B is read only from logic
inst_phase_table: entity desy.ram_tdp
generic map(
G_ADDR => C_W_TIDX,
G_DATA => C_W_SCALE+C_W_OFFSET
)
port map(
pi_clk_a => clk,
pi_en_a => pi_table_en,
pi_we_a => pi_table_we,
pi_addr_a => pi_table_addr,
pi_data_a => pi_table_data,
po_data_a => po_table_data,
pi_clk_b => clk,
pi_en_b => '1',
pi_we_b => '0',
pi_addr_b => std_logic_vector(pi_sine_tidx),
pi_data_b => (others => '0'),
po_data_b => table_data
);
-- Unpack table data
scale <= table_data(C_W_SCALE-1 downto 0);
offset <= table_data(C_W_SCALE+C_W_OFFSET-1 downto C_W_SCALE);
---------------------
-- MULTPLY AND ADD --
---------------------
inst_multadd : pscgen_multadd
port map (
clk => clk,
ce => '1',
sclr => '0',
a => r_sine,
b => scale,
c(C_W_OFFSET+C_W_PADDING-1 downto C_W_PADDING) => r_offset,
c(C_W_PADDING-1 downto 0) => (others => '0'),
subtract => '0',
p => wave,
pcout => open
);
--------------
-- PORT OUT --
--------------
po_wave <= wave;
po_wave_tidx <= r_tidx(0);
po_wave_valid <= r_valid(0);
end architecture;
...@@ -2,6 +2,13 @@ package pkg_pscgen is ...@@ -2,6 +2,13 @@ package pkg_pscgen is
constant C_W_PHASE : natural := 15; constant C_W_PHASE : natural := 15;
constant C_W_TIDX : natural := 8; constant C_W_TIDX : natural := 8;
constant C_W_SIG : natural := 31; constant C_W_SINE : natural := 26;
constant C_W_SIG : natural := 32;
constant C_W_SCALE : natural := 16;
constant C_W_OFFSET : natural := 16;
-- Will not be parsed by tcl, sadly
constant C_W_PADDING : natural := C_W_SINE+C_W_SCALE-C_W_SIG;
end package pkg_pscgen; end package pkg_pscgen;
library ieee;
use ieee.math_real.ceil;
use ieee.std_logic_1164.all;
use work.pkg_pscgen.all;
package pkg_pscgen_gen_ip is
-- DDS TDATA is extended to the next byte boundary
constant C_W_EXT_SINE : natural := natural(ceil(real(C_W_SINE)/8.0)*8.0);
constant C_W_EXT_PHASE : natural := natural(ceil(real(C_W_PHASE)/8.0)*8.0);
COMPONENT pscgen_dds
PORT (
aclk : IN STD_LOGIC;
aresetn : IN STD_LOGIC;
s_axis_phase_tvalid : IN STD_LOGIC;
s_axis_phase_tdata : IN STD_LOGIC_VECTOR(C_W_EXT_PHASE-1 DOWNTO 0);
s_axis_phase_tuser : IN STD_LOGIC_VECTOR(C_W_TIDX-1 DOWNTO 0);
m_axis_data_tvalid : OUT STD_LOGIC;
m_axis_data_tdata : OUT STD_LOGIC_VECTOR(C_W_EXT_SINE-1 DOWNTO 0);
m_axis_data_tuser : OUT STD_LOGIC_VECTOR(C_W_TIDX-1 DOWNTO 0)
);
END COMPONENT;
COMPONENT pscgen_multadd
PORT (
CLK : IN STD_LOGIC;
CE : IN STD_LOGIC;
SCLR : IN STD_LOGIC;
A : IN STD_LOGIC_VECTOR(C_W_SINE-1 DOWNTO 0);
B : IN STD_LOGIC_VECTOR(C_W_SCALE-1 DOWNTO 0);
C : IN STD_LOGIC_VECTOR(C_W_OFFSET+C_W_PADDING-1 DOWNTO 0);
SUBTRACT : IN STD_LOGIC;
P : OUT STD_LOGIC_VECTOR(C_W_SINE+C_W_SCALE-1 DOWNTO C_W_PADDING);
PCOUT : OUT STD_LOGIC_VECTOR(C_W_SINE+C_W_SCALE-1 DOWNTO 0)
);
END COMPONENT;
end package;
...@@ -7,6 +7,8 @@ use desyrdl.common.all; ...@@ -7,6 +7,8 @@ use desyrdl.common.all;
use desyrdl.pkg_pscgen.all; use desyrdl.pkg_pscgen.all;
use work.pkg_pscgen.all; use work.pkg_pscgen.all;
use work.pkg_pscgen_version.all;
use work.pkg_pscgen_gen_ip.all;
entity top_pscgen is entity top_pscgen is
port( port(
...@@ -19,8 +21,8 @@ entity top_pscgen is ...@@ -19,8 +21,8 @@ entity top_pscgen is
-- AXIS output -- AXIS output
m_axis_tdata : out std_logic_vector(C_W_SIG-1 downto 0); m_axis_tdata : out std_logic_vector(C_W_SIG-1 downto 0);
m_axis_tvalid : out std_logic; m_axis_tuser : out std_logic_vector(C_W_TIDX-1 downto 0);
m_axis_tready : in std_logic m_axis_tvalid : out std_logic
); );
end entity top_pscgen; end entity top_pscgen;
...@@ -38,6 +40,20 @@ architecture struct of top_pscgen is ...@@ -38,6 +40,20 @@ architecture struct of top_pscgen is
signal phase_incr_tidx : std_logic_vector(C_W_TIDX-1 downto 0); signal phase_incr_tidx : std_logic_vector(C_W_TIDX-1 downto 0);
signal phase_incr_valid : std_logic; signal phase_incr_valid : std_logic;
signal phase : std_logic_vector(C_W_PHASE-1 downto 0);
signal phase_tidx : std_logic_vector(C_W_TIDX-1 downto 0);
signal phase_valid : std_logic;
signal sine : std_logic_vector(C_W_EXT_SINE-1 downto 0);
signal sine_tidx : std_logic_vector(C_W_TIDX-1 downto 0);
signal sine_valid : std_logic;
signal wave : std_logic_vector(C_W_SIG-1 downto 0);
signal wave_tidx : std_logic_vector(C_W_TIDX-1 downto 0);
signal wave_valid : std_logic;
signal r_dds_tvalid : std_logic_vector(5 downto 0);
begin begin
rst <= not rstn; rst <= not rstn;
...@@ -56,6 +72,8 @@ begin ...@@ -56,6 +72,8 @@ begin
po_addrmap => addr_o po_addrmap => addr_o
); );
addr_i.version.data.data <= C_VERSION;
----------------- -----------------
-- PHASE TABLE -- -- PHASE TABLE --
----------------- -----------------
...@@ -101,10 +119,72 @@ begin ...@@ -101,10 +119,72 @@ begin
pi_phase_valid => phase_incr_valid, pi_phase_valid => phase_incr_valid,
-- phase out -- phase out
po_phase => open, po_phase => phase,
po_phase_tidx => open, po_phase_tidx => phase_tidx,
po_phase_valid => open po_phase_valid => phase_valid
);
---------
-- DDS --
---------
inst_dds: pscgen_dds
port map (
aclk => clk,
aresetn => rstn,
s_axis_phase_tvalid => '1', -- otherwise DDS get stuck...
s_axis_phase_tdata(C_W_EXT_PHASE-1 downto C_W_PHASE) => (others => '0'), -- unused
s_axis_phase_tdata(C_W_PHASE-1 downto 0) => phase,
s_axis_phase_tuser => phase_tidx,
m_axis_data_tvalid => sine_valid,
m_axis_data_tdata => sine,
m_axis_data_tuser => sine_tidx
);
-- Manual pipe delay of tvalid, otherwise DDS is stuck...
p_pipedelay:process(clk, rstn)
begin
if rstn='0' then
r_dds_tvalid <= (others => '0');
elsif rising_edge(clk) then
r_dds_tvalid <= phase_valid & r_dds_tvalid(r_dds_tvalid'left downto 1);
end if;
end process;
------------
-- SCALER --
------------
inst_scaler: entity work.MultiScaler
port map(
clk => clk,
rstn => rstn,
-- Memory map to table
pi_table_en => addr_o.table_scale.en,
pi_table_we => addr_o.table_scale.we,
pi_table_addr => addr_o.table_scale.addr(C_W_TIDX-1 downto 0),
pi_table_data => addr_o.table_scale.data,
po_table_data => addr_i.table_scale.data,
-- Sine in
pi_sine => sine(C_W_SINE-1 downto 0),
pi_sine_tidx => sine_tidx,
pi_sine_valid => r_dds_tvalid(0),
-- Wave out
po_wave => wave,
po_wave_tidx => wave_tidx,
po_wave_valid => wave_valid
); );
------------------
-- TIDX MAPPING --
------------------
-- Temporary
m_axis_tdata <= wave;
m_axis_tuser <= wave_tidx;
m_axis_tvalid <= wave_valid;
end architecture struct; end architecture struct;
...@@ -23,10 +23,7 @@ addrmap pscgen { ...@@ -23,10 +23,7 @@ addrmap pscgen {
desc="Module Version Number"; desc="Module Version Number";
default sw = r; default sw = r;
default hw = r; default hw = r;
field {} changes [8] = `C_VERSION & 0x000000FF; field {} data [32];
field {} patch [8] = (`C_VERSION & 0x0000FF00) >> 8;
field {} minor [8] = (`C_VERSION & 0x00FF0000) >> 16;
field {} major [8] = (`C_VERSION & 0xFF000000) >> 24;
} VERSION @0x04; } VERSION @0x04;
reg { reg {
...@@ -52,9 +49,15 @@ addrmap pscgen { ...@@ -52,9 +49,15 @@ addrmap pscgen {
external mem { external mem {
desc = "Phase increment and offset table"; desc = "Phase increment and offset table";
memwidth = 2*`C_W_PHASE+1; // 2*PHASE_W+1 memwidth = 2*`C_W_PHASE+1;
mementries = 2**`C_W_TIDX; // 2**TIDX_W mementries = 2**`C_W_TIDX;
} TABLE_PHASE; } TABLE_PHASE;
external mem {
desc = "Signal scale and offset table";
memwidth = `C_W_SCALE+`C_W_OFFSET;
mementries = 2**`C_W_TIDX;
} TABLE_SCALE;
}; };
...@@ -8,20 +8,22 @@ ...@@ -8,20 +8,22 @@
<top_module name="common" /> <top_module name="common" />
<top_module name="pkg_pscgen" /> <top_module name="pkg_pscgen" />
<top_module name="pkg_pscgen" /> <top_module name="pkg_pscgen" />
<top_module name="pkg_pscgen_gen_ip" />
<top_module name="pkg_pscgen_version" />
<top_module name="tb_pscgen" /> <top_module name="tb_pscgen" />
</top_modules> </top_modules>
</db_ref> </db_ref>
</db_ref_list> </db_ref_list>
<zoom_setting> <zoom_setting>
<ZoomStartTime time="8209642fs"></ZoomStartTime> <ZoomStartTime time="1243766fs"></ZoomStartTime>
<ZoomEndTime time="8392243fs"></ZoomEndTime> <ZoomEndTime time="1365367fs"></ZoomEndTime>
<Cursor1Time time="8289442fs"></Cursor1Time> <Cursor1Time time="1345100fs"></Cursor1Time>
</zoom_setting> </zoom_setting>
<column_width_setting> <column_width_setting>
<NameColumnWidth column_width="328"></NameColumnWidth> <NameColumnWidth column_width="328"></NameColumnWidth>
<ValueColumnWidth column_width="255"></ValueColumnWidth> <ValueColumnWidth column_width="239"></ValueColumnWidth>
</column_width_setting> </column_width_setting>
<WVObjectSize size="8" /> <WVObjectSize size="11" />
<wvobject type="logic" fp_name="/tb_pscgen/tb_clk"> <wvobject type="logic" fp_name="/tb_pscgen/tb_clk">
<obj_property name="ElementShortName">tb_clk</obj_property> <obj_property name="ElementShortName">tb_clk</obj_property>
<obj_property name="ObjectShortName">tb_clk</obj_property> <obj_property name="ObjectShortName">tb_clk</obj_property>
...@@ -81,6 +83,41 @@ ...@@ -81,6 +83,41 @@
<obj_property name="label">enable</obj_property> <obj_property name="label">enable</obj_property>
</wvobject> </wvobject>
</wvobject> </wvobject>
<wvobject type="group" fp_name="group284">
<obj_property name="label">Ticker</obj_property>
<obj_property name="DisplayName">label</obj_property>
<wvobject type="array" fp_name="/tb_pscgen/inst_dut/inst_phase_table/ticker_cnt">
<obj_property name="ElementShortName">ticker_cnt[31:0]</obj_property>
<obj_property name="ObjectShortName">ticker_cnt[31:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/tb_pscgen/inst_dut/inst_phase_table/tidx_cnt">
<obj_property name="ElementShortName">tidx_cnt[7:0]</obj_property>
<obj_property name="ObjectShortName">tidx_cnt[7:0]</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/tb_pscgen/inst_dut/inst_phase_table/ticker_tick">
<obj_property name="ElementShortName">ticker_tick</obj_property>
<obj_property name="ObjectShortName">ticker_tick</obj_property>
</wvobject>
</wvobject>
<wvobject type="group" fp_name="group285">
<obj_property name="label">Phase Table</obj_property>
<obj_property name="DisplayName">label</obj_property>
<obj_property name="isExpanded"></obj_property>
<wvobject type="array" fp_name="/tb_pscgen/inst_dut/inst_phase_table/tidx">
<obj_property name="ElementShortName">tidx[7:0]</obj_property>
<obj_property name="ObjectShortName">tidx[7:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/tb_pscgen/inst_dut/inst_phase_table/inst_phase_table/memory">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">memory[0:255][30:0]</obj_property>
<obj_property name="ObjectShortName">memory[0:255][30:0]</obj_property>
<obj_property name="label">Mem</obj_property>
</wvobject>
<wvobject type="array" fp_name="/tb_pscgen/inst_dut/inst_phase_table/table_data">
<obj_property name="ElementShortName">table_data[30:0]</obj_property>
<obj_property name="ObjectShortName">table_data[30:0]</obj_property>
</wvobject>
</wvobject>
<wvobject type="group" fp_name="group14"> <wvobject type="group" fp_name="group14">
<obj_property name="label">Phase Accu Input</obj_property> <obj_property name="label">Phase Accu Input</obj_property>
<obj_property name="DisplayName">label</obj_property> <obj_property name="DisplayName">label</obj_property>
...@@ -111,7 +148,6 @@ ...@@ -111,7 +148,6 @@
<wvobject type="group" fp_name="group20"> <wvobject type="group" fp_name="group20">
<obj_property name="label">Phase Accu Output</obj_property> <obj_property name="label">Phase Accu Output</obj_property>
<obj_property name="DisplayName">label</obj_property> <obj_property name="DisplayName">label</obj_property>
<obj_property name="isExpanded"></obj_property>
<wvobject type="array" fp_name="/tb_pscgen/inst_dut/inst_phase_accu/po_phase"> <wvobject type="array" fp_name="/tb_pscgen/inst_dut/inst_phase_accu/po_phase">
<obj_property name="ElementShortName">po_phase[14:0]</obj_property> <obj_property name="ElementShortName">po_phase[14:0]</obj_property>
<obj_property name="ObjectShortName">po_phase[14:0]</obj_property> <obj_property name="ObjectShortName">po_phase[14:0]</obj_property>
...@@ -126,38 +162,125 @@ ...@@ -126,38 +162,125 @@
<obj_property name="ObjectShortName">po_phase_valid</obj_property> <obj_property name="ObjectShortName">po_phase_valid</obj_property>
</wvobject> </wvobject>
</wvobject> </wvobject>
<wvobject type="group" fp_name="group284"> <wvobject type="group" fp_name="group41">
<obj_property name="label">Ticker</obj_property> <obj_property name="label">DDS</obj_property>
<obj_property name="DisplayName">label</obj_property> <obj_property name="DisplayName">label</obj_property>
<wvobject type="array" fp_name="/tb_pscgen/inst_dut/inst_phase_table/ticker_cnt"> <obj_property name="isExpanded"></obj_property>
<obj_property name="ElementShortName">ticker_cnt[31:0]</obj_property> <wvobject type="array" fp_name="/tb_pscgen/inst_dut/inst_dds/m_axis_data_tdata">
<obj_property name="ObjectShortName">ticker_cnt[31:0]</obj_property> <obj_property name="ElementShortName">m_axis_data_tdata[31:0]</obj_property>
<obj_property name="ObjectShortName">m_axis_data_tdata[31:0]</obj_property>
<obj_property name="Radix">SIGNEDDECRADIX</obj_property>
</wvobject> </wvobject>
<wvobject type="array" fp_name="/tb_pscgen/inst_dut/inst_phase_table/tidx_cnt"> <wvobject type="array" fp_name="/tb_pscgen/inst_dut/inst_dds/m_axis_data_tuser">
<obj_property name="ElementShortName">tidx_cnt[7:0]</obj_property> <obj_property name="ElementShortName">m_axis_data_tuser[7:0]</obj_property>
<obj_property name="ObjectShortName">tidx_cnt[7:0]</obj_property> <obj_property name="ObjectShortName">m_axis_data_tuser[7:0]</obj_property>
</wvobject> </wvobject>
<wvobject type="logic" fp_name="/tb_pscgen/inst_dut/inst_phase_table/ticker_tick"> <wvobject type="logic" fp_name="/tb_pscgen/inst_dut/inst_scaler/pi_sine_valid">
<obj_property name="ElementShortName">ticker_tick</obj_property> <obj_property name="ElementShortName">pi_sine_valid</obj_property>
<obj_property name="ObjectShortName">ticker_tick</obj_property> <obj_property name="ObjectShortName">pi_sine_valid</obj_property>
</wvobject> </wvobject>
</wvobject> </wvobject>
<wvobject type="group" fp_name="group285"> <wvobject type="group" fp_name="group45">
<obj_property name="label">Phase Table</obj_property> <obj_property name="label">Scaler</obj_property>
<obj_property name="DisplayName">label</obj_property> <obj_property name="DisplayName">label</obj_property>
<wvobject type="array" fp_name="/tb_pscgen/inst_dut/inst_phase_table/tidx"> <obj_property name="isExpanded"></obj_property>
<obj_property name="ElementShortName">tidx[7:0]</obj_property> <wvobject type="array" fp_name="/tb_pscgen/inst_dut/inst_scaler/po_wave">
<obj_property name="ObjectShortName">tidx[7:0]</obj_property> <obj_property name="ElementShortName">po_wave[31:0]</obj_property>
<obj_property name="ObjectShortName">po_wave[31:0]</obj_property>
<obj_property name="Radix">SIGNEDDECRADIX</obj_property>
</wvobject> </wvobject>
<wvobject type="array" fp_name="/tb_pscgen/inst_dut/inst_phase_table/inst_phase_table/memory"> <wvobject type="array" fp_name="/tb_pscgen/inst_dut/inst_scaler/po_wave_tidx">
<obj_property name="ElementShortName">po_wave_tidx[7:0]</obj_property>
<obj_property name="ObjectShortName">po_wave_tidx[7:0]</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/tb_pscgen/inst_dut/inst_scaler/po_wave_valid">
<obj_property name="ElementShortName">po_wave_valid</obj_property>
<obj_property name="ObjectShortName">po_wave_valid</obj_property>
</wvobject>
</wvobject>
<wvobject type="group" fp_name="group49">
<obj_property name="label">Result</obj_property>
<obj_property name="DisplayName">label</obj_property> <obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">memory[0:255][30:0]</obj_property> <obj_property name="isExpanded"></obj_property>
<obj_property name="ObjectShortName">memory[0:255][30:0]</obj_property> <wvobject type="array" fp_name="/tb_pscgen/tb_result_std[0]">
<obj_property name="label">Mem</obj_property> <obj_property name="ElementShortName">[0][31:0]</obj_property>
<obj_property name="ObjectShortName">[0][31:0]</obj_property>
<obj_property name="Radix">REALRADIX</obj_property>
<obj_property name="WaveformStyle">STYLE_ANALOG</obj_property>
<obj_property name="CellHeight">100</obj_property>
<obj_property name="radix_realType">SIGNEDFIXEDPOINTRADIX</obj_property>
<obj_property name="radix_fractionWidth">26</obj_property>
<obj_property name="radix_otherWidth">0</obj_property>
<obj_property name="AnalogYRangeType">ANALOG_YRANGETYPE_FIXED</obj_property>
<obj_property name="AnalogYRangeMin">-64.000000</obj_property>
<obj_property name="AnalogYRRangeMax">64.000000</obj_property>
<obj_property name="AnalogInterpolation">ANALOG_INTERPOLATION_LINEAR</obj_property>
<obj_property name="AnalogOffscale">ANALOG_OFFSCALE_OVERLAP</obj_property>
<obj_property name="AnalogHorizLine">0.000000</obj_property>
</wvobject> </wvobject>
<wvobject type="array" fp_name="/tb_pscgen/inst_dut/inst_phase_table/table_data"> <wvobject type="array" fp_name="/tb_pscgen/tb_result_std[1]">
<obj_property name="ElementShortName">table_data[30:0]</obj_property> <obj_property name="ElementShortName">[1][31:0]</obj_property>
<obj_property name="ObjectShortName">table_data[30:0]</obj_property> <obj_property name="ObjectShortName">[1][31:0]</obj_property>
<obj_property name="Radix">REALRADIX</obj_property>
<obj_property name="WaveformStyle">STYLE_ANALOG</obj_property>
<obj_property name="CellHeight">100</obj_property>
<obj_property name="radix_realType">SIGNEDFIXEDPOINTRADIX</obj_property>
<obj_property name="radix_fractionWidth">26</obj_property>
<obj_property name="radix_otherWidth">0</obj_property>
<obj_property name="AnalogYRangeType">ANALOG_YRANGETYPE_FIXED</obj_property>
<obj_property name="AnalogYRangeMin">-64.000000</obj_property>
<obj_property name="AnalogYRRangeMax">64.000000</obj_property>
<obj_property name="AnalogInterpolation">ANALOG_INTERPOLATION_LINEAR</obj_property>
<obj_property name="AnalogOffscale">ANALOG_OFFSCALE_OVERLAP</obj_property>
<obj_property name="AnalogHorizLine">0.000000</obj_property>
</wvobject>
<wvobject type="array" fp_name="/tb_pscgen/tb_result_std[2]">
<obj_property name="ElementShortName">[2][31:0]</obj_property>
<obj_property name="ObjectShortName">[2][31:0]</obj_property>
<obj_property name="Radix">REALRADIX</obj_property>
<obj_property name="WaveformStyle">STYLE_ANALOG</obj_property>
<obj_property name="CellHeight">100</obj_property>
<obj_property name="radix_realType">SIGNEDFIXEDPOINTRADIX</obj_property>
<obj_property name="radix_fractionWidth">26</obj_property>
<obj_property name="radix_otherWidth">0</obj_property>
<obj_property name="AnalogYRangeType">ANALOG_YRANGETYPE_FIXED</obj_property>
<obj_property name="AnalogYRangeMin">-64.000000</obj_property>
<obj_property name="AnalogYRRangeMax">64.000000</obj_property>
<obj_property name="AnalogInterpolation">ANALOG_INTERPOLATION_LINEAR</obj_property>
<obj_property name="AnalogOffscale">ANALOG_OFFSCALE_OVERLAP</obj_property>
<obj_property name="AnalogHorizLine">0.000000</obj_property>
</wvobject>
<wvobject type="array" fp_name="/tb_pscgen/tb_result_std[3]">
<obj_property name="ElementShortName">[3][31:0]</obj_property>
<obj_property name="ObjectShortName">[3][31:0]</obj_property>
<obj_property name="Radix">REALRADIX</obj_property>
<obj_property name="WaveformStyle">STYLE_ANALOG</obj_property>
<obj_property name="CellHeight">100</obj_property>
<obj_property name="radix_realType">SIGNEDFIXEDPOINTRADIX</obj_property>
<obj_property name="radix_fractionWidth">26</obj_property>
<obj_property name="radix_otherWidth">0</obj_property>
<obj_property name="AnalogYRangeType">ANALOG_YRANGETYPE_FIXED</obj_property>
<obj_property name="AnalogYRangeMin">-64.000000</obj_property>
<obj_property name="AnalogYRRangeMax">64.000000</obj_property>
<obj_property name="AnalogInterpolation">ANALOG_INTERPOLATION_LINEAR</obj_property>
<obj_property name="AnalogOffscale">ANALOG_OFFSCALE_OVERLAP</obj_property>
<obj_property name="AnalogHorizLine">0.000000</obj_property>
</wvobject>
<wvobject type="array" fp_name="/tb_pscgen/tb_result_std[4]">
<obj_property name="ElementShortName">[4][31:0]</obj_property>
<obj_property name="ObjectShortName">[4][31:0]</obj_property>
<obj_property name="Radix">REALRADIX</obj_property>
<obj_property name="WaveformStyle">STYLE_ANALOG</obj_property>
<obj_property name="CellHeight">100</obj_property>
<obj_property name="radix_realType">SIGNEDFIXEDPOINTRADIX</obj_property>
<obj_property name="radix_fractionWidth">26</obj_property>
<obj_property name="radix_otherWidth">0</obj_property>
<obj_property name="AnalogYRangeType">ANALOG_YRANGETYPE_FIXED</obj_property>
<obj_property name="AnalogYRangeMin">-64.000000</obj_property>
<obj_property name="AnalogYRRangeMax">64.000000</obj_property>
<obj_property name="AnalogInterpolation">ANALOG_INTERPOLATION_LINEAR</obj_property>
<obj_property name="AnalogOffscale">ANALOG_OFFSCALE_OVERLAP</obj_property>
<obj_property name="AnalogHorizLine">0.000000</obj_property>
</wvobject> </wvobject>
</wvobject> </wvobject>
</wave_config> </wave_config>
...@@ -19,13 +19,20 @@ architecture testbench of tb_pscgen is ...@@ -19,13 +19,20 @@ architecture testbench of tb_pscgen is
signal tb_s_axi_m2s : t_pscgen_m2s; signal tb_s_axi_m2s : t_pscgen_m2s;
signal tb_s_axi_s2m : t_pscgen_s2m; signal tb_s_axi_s2m : t_pscgen_s2m;
signal tb_m_axis_tdata : std_logic_vector(C_W_SIG-1 downto 0); signal tb_m_axis_tdata : std_logic_vector(C_W_SIG-1 downto 0);
signal tb_m_axis_tuser : std_logic_vector(C_W_TIDX-1 downto 0);
signal tb_m_axis_tvalid : std_logic; signal tb_m_axis_tvalid : std_logic;
signal tb_m_axis_tready : std_logic;
-- AXI4L helpers -- AXI4L helpers
signal tb_s_axi_awtransfer : std_logic; signal tb_s_axi_awtransfer : std_logic;
signal tb_s_axi_wtransfer : std_logic; signal tb_s_axi_wtransfer : std_logic;
-- Output check helper
type t_arr_int is array (0 to 2**C_W_TIDX-1) of integer;
type t_arr_std is array (0 to 2**C_W_TIDX-1) of std_logic_vector(C_W_SIG-1 downto 0);
signal tb_result : t_arr_int := (others => 0);
signal tb_result_std : t_arr_std;
begin begin
tb_clk <= not tb_clk after 5 ns; tb_clk <= not tb_clk after 5 ns;
...@@ -40,8 +47,8 @@ begin ...@@ -40,8 +47,8 @@ begin
s_axi_m2s => tb_s_axi_m2s, s_axi_m2s => tb_s_axi_m2s,
s_axi_s2m => tb_s_axi_s2m, s_axi_s2m => tb_s_axi_s2m,
m_axis_tdata => tb_m_axis_tdata, m_axis_tdata => tb_m_axis_tdata,
m_axis_tvalid => tb_m_axis_tvalid, m_axis_tuser => tb_m_axis_tuser,
m_axis_tready => tb_m_axis_tready m_axis_tvalid => tb_m_axis_tvalid
); );
------------------ ------------------
...@@ -82,6 +89,8 @@ begin ...@@ -82,6 +89,8 @@ begin
variable v_phase_incr : std_logic_vector(C_W_PHASE-1 downto 0); variable v_phase_incr : std_logic_vector(C_W_PHASE-1 downto 0);
variable v_phase_offs : std_logic_vector(C_W_PHASE-1 downto 0); variable v_phase_offs : std_logic_vector(C_W_PHASE-1 downto 0);
variable v_scale : std_logic_vector(C_W_SCALE-1 downto 0);
variable v_offset : std_logic_vector(C_W_OFFSET-1 downto 0);
variable v_axi4l_data : std_logic_vector(C_AXI4L_DATA_WIDTH-1 downto 0); variable v_axi4l_data : std_logic_vector(C_AXI4L_DATA_WIDTH-1 downto 0);
begin begin
...@@ -116,8 +125,8 @@ begin ...@@ -116,8 +125,8 @@ begin
-- Phase table parameters -- Phase table parameters
for I in 0 to 6 loop for I in 0 to 6 loop
v_phase_incr := std_logic_vector(to_unsigned(13*(I+1), C_W_PHASE)); v_phase_incr := std_logic_vector(to_unsigned(1300*(I+1), C_W_PHASE));
v_phase_offs := std_logic_vector(to_unsigned(33*I, C_W_PHASE)); v_phase_offs := std_logic_vector(to_unsigned(3300*2*I, C_W_PHASE));
v_axi4l_data := (others => '0'); v_axi4l_data := (others => '0');
v_axi4l_data(C_W_PHASE-1 downto 0) := v_phase_incr; v_axi4l_data(C_W_PHASE-1 downto 0) := v_phase_incr;
v_axi4l_data(2*C_W_PHASE-1 downto C_W_PHASE) := v_phase_offs; v_axi4l_data(2*C_W_PHASE-1 downto C_W_PHASE) := v_phase_offs;
...@@ -126,12 +135,24 @@ begin ...@@ -126,12 +135,24 @@ begin
v_axi4l_data); v_axi4l_data);
end loop; end loop;
-- Scaler table parameters
for I in 0 to 6 loop
v_scale := std_logic_vector(to_unsigned(2048+I*4096, C_W_SCALE));
v_offset := std_logic_vector(to_signed((6-I)*2096, C_W_OFFSET));
v_axi4l_data := (others => '0');
v_axi4l_data(C_W_SCALE-1 downto 0) := v_scale;
v_axi4l_data(C_W_OFFSET+C_W_SCALE-1 downto C_W_SCALE) := v_offset;
write_axi4l(std_logic_vector(C_MEM_INFO(1).address+to_unsigned(I*4, C_AXI4L_ADDR_WIDTH)),
v_axi4l_data);
end loop;
-- Start the phase accu -- Start the phase accu
v_axi4l_data := (0=> '1', others => '0'); v_axi4l_data := (0=> '1', others => '0');
write_axi4l(std_logic_vector(C_REGISTER_INFO(C_CONTROL_ID).address), write_axi4l(std_logic_vector(C_REGISTER_INFO(C_CONTROL_ID).address),
v_axi4l_data); v_axi4l_data);
-- Wait a few iterations -- Wait a few iterations, for the accu table to reset
wait for 3 us; wait for 3 us;
wait until rising_edge(tb_clk); wait until rising_edge(tb_clk);
...@@ -159,5 +180,24 @@ begin ...@@ -159,5 +180,24 @@ begin
tb_s_axi_awtransfer <= tb_s_axi_m2s.awvalid and tb_s_axi_s2m.awready; tb_s_axi_awtransfer <= tb_s_axi_m2s.awvalid and tb_s_axi_s2m.awready;
tb_s_axi_wtransfer <= tb_s_axi_m2s.wvalid and tb_s_axi_s2m.wready; tb_s_axi_wtransfer <= tb_s_axi_m2s.wvalid and tb_s_axi_s2m.wready;
--------------------
-- AXI4 STREAM RX --
--------------------
p_axis_rx:process(tb_clk, tb_rstn)
variable pscid : natural;
begin
if tb_rstn = '0' then
tb_result <= (others => 0);
tb_result_std <= (others => (others=>'0'));
elsif rising_edge(tb_clk) then
if tb_m_axis_tvalid = '1' then
pscid := to_integer(unsigned(tb_m_axis_tuser));
tb_result_std(pscid) <= tb_m_axis_tdata;
tb_result(pscid) <= to_integer(signed(tb_m_axis_tdata));
end if;
end if;
end process p_axis_rx;
end architecture testbench; end architecture testbench;
set bram_depth 32
set bram_width 8
set ProjectDirPath [file join ${::fwfwk::PrjBuildPath} ${::fwfwk::PrjBuildName}] set ProjectDirPath [file join ${::fwfwk::PrjBuildPath} ${::fwfwk::PrjBuildName}]
## ------------------------------------- ## ## ------------------------------------- ##
## BRAM CTRL for INCR BRAM ## DDS
## ------------------------------------- ## ## ------------------------------------- ##
set ipName "pscgen_incr_bramctrl" set ipName "pscgen_dds"
set xcipath [create_ip \ set xcipath [create_ip \
-name axi_bram_ctrl \ -name dds_compiler \
-vendor xilinx.com \ -vendor xilinx.com \
-library ip -version 4.1 \ -library ip -version 6.0 \
-module_name $ipName] -module_name $ipName]
set_property -dict [list \ set_property -dict [list \
CONFIG.PROTOCOL {AXI4LITE} \ CONFIG.PartsPresent {SIN_COS_LUT_only} \
CONFIG.SUPPORTS_NARROW_BURST {0} \ CONFIG.Phase_Width $Config(C_W_PHASE) \
CONFIG.SINGLE_PORT_BRAM {1} \ CONFIG.Output_Width $Config(C_W_SINE) \
CONFIG.USE_ECC {0} \ CONFIG.Output_Selection {Sine} \
CONFIG.BMG_INSTANCE {EXTERNAL} \ CONFIG.Has_TREADY {false} \
CONFIG.MEM_DEPTH $Config(TID_DEPTH) \ CONFIG.S_PHASE_Has_TUSER {User_Field} \
CONFIG.CLKIF.FREQ_HZ 250000000 \ CONFIG.S_PHASE_TUSER_Width $Config(C_W_TIDX) \
CONFIG.DATA_WIDTH 32 \ CONFIG.Parameter_Entry {Hardware_Parameters} \
CONFIG.Noise_Shaping {None} \
CONFIG.Has_Phase_Out {false} \
CONFIG.DATA_Has_TLAST {Not_Required} \
CONFIG.M_DATA_Has_TUSER {User_Field} \
CONFIG.M_PHASE_Has_TUSER {Not_Required} \
CONFIG.Has_ARESETn {true} \
CONFIG.Has_ACLKEN {false} \
CONFIG.Latency {6} \
CONFIG.Output_Frequency1 {0} \
CONFIG.PINC1 {0} \
] [get_ips $ipName] ] [get_ips $ipName]
generate_target all [get_files ${ProjectDirPath}.srcs/sources_1/ip/$ipName/$ipName.xci] generate_target all [get_files ${ProjectDirPath}.srcs/sources_1/ip/$ipName/$ipName.xci]
export_ip_user_files -of_objects [get_files ${ProjectDirPath}.srcs/sources_1/ip/$ipName/$ipName.xci] -no_script -sync -force -quiet export_ip_user_files -of_objects [get_files ${ProjectDirPath}.srcs/sources_1/ip/$ipName/$ipName.xci] -no_script -sync -force -quiet
create_ip_run [get_files -of_objects [get_fileset sources_1] ${ProjectDirPath}.srcs/sources_1/ip/$ipName/$ipName.xci] create_ip_run [get_files -of_objects [get_fileset sources_1] ${ProjectDirPath}.srcs/sources_1/ip/$ipName/$ipName.xci]
#set_property GENERATE_SYNTH_CHECKPOINT 0 [get_files $xcipath]
## ------------------------------------- ## ## ------------------------------------- ##
## BRAM for INCR ## Multiply adder
## ------------------------------------- ## ## ------------------------------------- ##
set ipName "pscgen_incr_bram" set ipName "pscgen_multadd"
set padding [expr $Config(C_W_SINE) + $Config(C_W_SCALE) - $Config(C_W_SIG)]
set xcipath [create_ip \ set xcipath [create_ip \
-name blk_mem_gen \ -name xbip_multadd \
-vendor xilinx.com \ -vendor xilinx.com \
-library ip -version 8.4 \ -library ip -version 3.0 \
-module_name $ipName] -module_name $ipName]
set_property -dict [list \ set_property -dict [list \
CONFIG.Memory_Type {True_Dual_Port_RAM} \ CONFIG.c_a_type {0} \
CONFIG.PRIM_type_to_Implement {BRAM} \ CONFIG.c_b_type {1} \
CONFIG.Use_Byte_Write_Enable {false} \ CONFIG.c_c_type {0} \
CONFIG.Assume_Synchronous_Clk {true} \ CONFIG.c_use_pcin {false} \
CONFIG.Byte_Size {8} \ CONFIG.c_a_width $Config(C_W_SINE) \
CONFIG.Write_Width_A $bram_width \ CONFIG.c_b_width $Config(C_W_SCALE) \
CONFIG.Write_Depth_A $Config(TID_DEPTH) \ CONFIG.c_c_width [expr $Config(C_W_OFFSET) + $padding] \
CONFIG.Read_Width_A $bram_width \ CONFIG.c_out_high [expr $Config(C_W_SINE) + $Config(C_W_SCALE)-1] \
CONFIG.Operating_Mode_A {WRITE_FIRST} \ CONFIG.c_out_low $padding \
CONFIG.Write_Width_B $bram_width \ CONFIG.c_c_latency {-1} \
CONFIG.Read_Width_B $bram_width \
CONFIG.Operating_Mode_B {WRITE_FIRST} \
CONFIG.Enable_A {Always_Enabled} \
CONFIG.Enable_B {Always_Enabled} \
CONFIG.Register_PortA_Output_of_Memory_Primitives {false} \
CONFIG.Register_PortA_Output_of_Memory_Core {false} \
CONFIG.Register_PortB_Output_of_Memory_Primitives {false} \
CONFIG.Port_B_Clock {250} \
CONFIG.Port_B_Write_Rate {0} \
CONFIG.Port_B_Enable_Rate {100} \
] [get_ips $ipName] ] [get_ips $ipName]
generate_target all [get_files ${ProjectDirPath}.srcs/sources_1/ip/$ipName/$ipName.xci] generate_target all [get_files ${ProjectDirPath}.srcs/sources_1/ip/$ipName/$ipName.xci]
export_ip_user_files -of_objects [get_files ${ProjectDirPath}.srcs/sources_1/ip/$ipName/$ipName.xci] -no_script -sync -force -quiet export_ip_user_files -of_objects [get_files ${ProjectDirPath}.srcs/sources_1/ip/$ipName/$ipName.xci] -no_script -sync -force -quiet
create_ip_run [get_files -of_objects [get_fileset sources_1] ${ProjectDirPath}.srcs/sources_1/ip/$ipName/$ipName.xci] create_ip_run [get_files -of_objects [get_fileset sources_1] ${ProjectDirPath}.srcs/sources_1/ip/$ipName/$ipName.xci]
set_property GENERATE_SYNTH_CHECKPOINT 0 [get_files $xcipath]
...@@ -24,13 +24,15 @@ proc setSources {} { ...@@ -24,13 +24,15 @@ proc setSources {} {
lappend Sources {"../hdl/pkg_pscgen_version.vhd" "VHDL"} lappend Sources {"../hdl/pkg_pscgen_version.vhd" "VHDL"}
lappend Sources {"../hdl/pkg_pscgen.vhd" "VHDL"} lappend Sources {"../hdl/pkg_pscgen.vhd" "VHDL"}
lappend Sources {"../hdl/pkg_pscgen_gen_ip.vhd" "VHDL"}
lappend Sources {"../hdl/MultiPhaseTable.vhd" "VHDL"} lappend Sources {"../hdl/MultiPhaseTable.vhd" "VHDL"}
lappend Sources {"../hdl/MultiPhaseAcc.vhd" "VHDL"} lappend Sources {"../hdl/MultiPhaseAcc.vhd" "VHDL"}
lappend Sources {"../hdl/MultiScaler.vhd" "VHDL"}
lappend Sources {"../hdl/top_pscgen.vhd" "VHDL"} lappend Sources {"../hdl/top_pscgen.vhd" "VHDL"}
lappend Sources [list "${::fwfwk::LibPath}/desy_vhdl/hdl/memory/ram/ram_tdp.vhd" "VHDL 2008" "desy"] lappend Sources [list "${::fwfwk::LibPath}/desy_vhdl/hdl/memory/ram/ram_tdp.vhd" "VHDL 2008" "desy"]
# Simulation sources # Simulation sources
lappend Sources {"../sim/tb_pscgen.vhd" "VHDL 2008" "simulation"} lappend Sources {"../sim/tb_pscgen.vhd" "VHDL 2008" "" "simulation"}
} }
# ============================================================================== # ==============================================================================
...@@ -50,6 +52,9 @@ proc doOnCreate {} { ...@@ -50,6 +52,9 @@ proc doOnCreate {} {
addSources "Sources" addSources "Sources"
# Generate Xilinx IPs
source "gen_ip.tcl"
} }
# ============================================================================== # ==============================================================================
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment