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

Initial commit

parents
Branches
Tags
No related merge requests found
= Documentation
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library desy;
use desy.math_signed;
use work.pkg_corr_matrixpi.all;
entity corr_pi is
port(
clk : in std_logic;
rst_n : in std_logic;
-- matmult input
matmult : in signed_array(0 to C_N_MM_PSC-1)(C_W_MM_ACCU-1 downto 0);
matmult_valid : in std_logic;
matmult_seq : in std_logic_vector(C_W_SEQ-1 downto 0);
-- Corr coefs
corr_kp : signed(C_W_COR_KP-1 downto 0);
corr_ki : signed(C_W_COR_KI-1 downto 0);
reset_accu : in std_logic;
enable_corr : in std_logic;
-- Corr output
corrout_valid : out std_logic;
corrout_seq : out std_logic_vector(C_W_SEQ-1 downto 0);
corrout : out signed_array(0 to C_N_MM_PSC-1)(C_W_COR_OUT-1 downto 0)
);
end entity corr_pi;
architecture rtl of corr_pi is
type arr_slv is array (natural range <>) of std_logic_vector;
------------------------
-- SIGNAL DECLARATION --
------------------------
signal r_valid : std_logic_vector(2 downto 0);
signal r_seq : arr_slv(0 downto 2)(C_W_SEQ-1 downto 0);
begin
--------------------
-- DELAY REGISTER --
--------------------
p_delay:process(clk,rst_n)
begin
if rst_n = '0' then
r_valid <= (others => '0');
r_seq <= (others => (others => '0'));
elsif rising_edge(clk) then
r_valid <= r_valid(r_valid'left-1 downto 0) & matmult_valid;
r_seq(0) <= matmul_seq;
for I in 1 to r_seq'right loop
r_seq(I) <= r_seq(I-1);
end loop;
end if;
end process;
----------------------
-- OUTPUT CONNEXION --
----------------------
corrout_valid <= r_valid(2);
corrout_seq <= r_seq(2);
--------------------
-- CORRECTOR LINE --
--------------------
G_CORR:for I in 0 to C_N_MM_PSC-1 generate
signal r_matmult : signed(C_W_MM_ACCU-1 downto 0);
signal accu_pre : signed(C_W_MM_ACCU-1 downto 0);
signal accu_post : signed(C_W_COR_ACCU-1 downto 0);
signal ki_mult : signed(C_W_COR_KI+C_W_COR_ACCU-1 downto 0);
signal kp_mult : signed(C_W_COR_KP+C_W_COR_ACCU-1 downto 0);
signal ki_mult_rnd : signed(ki_mult'left-C_N_COR_KIRND downto 0);
signal corr_sum : signed(ki_mult_rnd'left downto 0);
signal corr_sum_rnd : signed(C_W_COR_OUT-1 downto 0);
begin
p_acc:process(clk, rst_n)
begin
if rst_n = '0' then
accu_pre <= (others => '0');
accu_post <= (others => '0');
ki_mult <= (others => '0');
kp_mult <= (others => '0');
corrout <= (others => (others => '0'));
elsif rising_edge(clk) then
-----------------
-- ACCUMULATOR --
-----------------
-- This is a bilinear integrator !
if matmult_valid = '1' then
accu_pre <= matmult(I);
end if;
if rst_accu = '1' then
accu_post <= (others => '0');
else
if ena_accu = '1' then
accu_post <= f_sum_sat(f_sum_sat(accu_post, matmult), accu_pre);
end if;
end if;
-- Delay
r_matmult <= matmult(I);
----------------------
-- COEFF MULTIPLIER --
----------------------
ki_mult <= accu_post * corr_ki;
kp_mult <= r_matmult * corr_kp;
--------------------------
-- FINAL ADDER REGISTER --
--------------------------
corrout(I) <= f_resize_sat(ki_mult_rnd, C_W_COR_OUT);
end if;
end process;
----------------------
-- KI MULT ROUNDING --
----------------------
ki_mult_rnd <= ki_mult(ki_mult'left downto C_N_COR_KIRND) when ki_mult(C_N_COR_KIRND-1) = '1' else
f_sum_sat(ki_mult(ki_mult'left downto C_N_COR_KIRND), to_signed(1,1));
-----------------------
-- FINAL ADDER LOGIC --
-----------------------
corr_sum <= f_sum_sat(ki_mult_rnd, kp_mult);
--------------------
-- FINAL ROUNDING --
--------------------
corr_sum_rnd <= corr_sum(corr_sum'left downto C_N_COR_RND) when corr_sum(C_N_COR_RND-1) = '1' else
f_sum_sat(corr_sum(corr_sum'left downto C_N_COR_RND), to_signed(1,1));
end generate;
end architecture;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.pkg_corr_matrixpi.all;
entity data_serializer is
port(
clk : in std_logic;
rst_n : in std_logic;
-- PSCID memory
pscid_table_i : in t_mem_PSCIDTABLE_out;
pscid_table_o : out t_mem_PSCIDTABLE_in;
-- Status
overrun : out std_logic;
-- Corr parallel input
corrout_valid : in std_logic;
corrout_seq : in std_logic_vector(C_W_SEQ-1 downto 0);
corrout : in signed_array(0 to C_N_MM_PSC-1)(C_W_COR_OUT-1 downto 0);
-- AXIS serial output
m_axis_tdata : out std_logic_vector(C_W_COR_OUT-1 downto 0);
m_axis_tuser : out std_logic_vector(C_W_SEQ-1 downto 0);
m_axis_tvalid : out std_logic;
m_axis_tready : in std_logic
);
end entity data_serializer;
architecture rtl of data_serializer is
------------------------
-- SIGNAL DECLARATION --
------------------------
signal cnt : unsigned(pscif_table_i.addr'length-1 downto 0);
signal run_serial : std_logic;
signal r_corr : signed_array(0 to C_N_MM_PSC-1)(C_W_COR_OUT-1 downto 0);
signal r_seq : std_logic_vector(C_W_SEQ-1 downto 0);
begin
------------------------
-- SERIALIZER COUNTER --
------------------------
p_cnt:process(clk, rst_n)
begin
if rst_n = '0' then
cnt <= (others => '0');
run_serial <= '0';
overrun <= '0';
elsif rising_edge(clk) then
if run_serial = '1' then
if cnt = 0 then
-- stop at the end
run_serial <= '0';
else
if m_axis_tready = '1' then
cnt <= cnt-1;
end if;
end if;
-- Transmit overrun if a valid comes here
overrun <= corrout_valid;
else
if corrout_valid= '1' then
-- start on valid
run_serial <= '1';
cnt <= to_unsigned(C_N_MM_PSC, cnt'length);
end if;
-- No overrun possible here
overrun <= '0';
end if;
end if;
end process;
---------------------
-- SHIFT REGISTERS --
---------------------
p_shiftreg:process(clk, rst_n)
begin
if rst_n = '0' then
r_corr <= (others => (others => '0'));
r_seq <= (others => '0');
elsif rising_edge(clk) then
if run_serial = '1' then
if m_axis_tready = '1' then
for I in 0 to C_N_MM_PSC-1 loop
r_corr(I) <= r_corr(I+1);
end loop;
end if;
else
r_corr <= corrout;
r_seq <= corrout_seq;
end if;
end if;
end process;
-----------------
-- PSCID TABLE --
------------------
-- Port A is read write from AXI controller, Port B is read only from logic
inst_refx_table: entity desy.ram_tdp
generic map(
G_ADDR => pscif_table_i.addr'length,
G_DATA => C_W_PSDID
)
port map(
pi_clk_a => clk,
pi_en_a => pscif_table_i.en,
pi_we_a => pscif_table_i.we,
pi_addr_a => pscif_table_i.addr,
pi_data_a => pscif_table_i.data,
po_data_a => pscif_table_o.data,
pi_clk_b => clk,
pi_en_b => '1',
pi_we_b => '0',
pi_addr_b => std_logic_vector(cnt),
pi_data_b => (others => '0'),
po_data_b => pscid
);
-----------------------
-- OUTPUT CONNEXIONS --
-----------------------
m_axis_tdata <= pscid & r_corr(0);
m_axis_tuser <= r_seq;
m_axis_tvalid <= run_serial;
end architecture;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library desy;
use desy.ram_tdp;
use desy.math_signed;
library desyrdl;
use desyrdl.pkg_corr_matrixpi.t_mem_MATRIXCOEF_out;
use desyrdl.pkg_corr_matrixpi.t_mem_MATRIXCOEF_in;
use work.pkg_corr_matrixpi.all;
entity matrix_mul is
port(
clk : in std_logic;
rst_n : in std_logic;
-- Coef table, desyrdl
mm_coef_i : in t_mem_MATRIXCOEF_out;
mm_coef_o : out t_mem_MATRIXCOEF_in;
id_cnt_load : in std_logic_vector(C_W_MM_IDCNT-1 downto 0);
-- Position data in
pos_x : in signed(C_W_BPMPOS-1 downto 0);
pos_y : in signed(C_W_BPMPOS-1 downto 0);
pos_id : in std_logic_vector(C_W_BPMID-1 downto 0);
pos_seq : in std_logic_vector(C_W_BPMSEQ-1 downto 0);
pos_tvalid : in std_logic;
-- Data out
matmult : out signed_array(0 to C_N_MM_PSC-1)(C_W_MM_ACCU-1 downto 0);
matmult_tvalid : out std_logic;
matmult_seq : out std_logic_vector(C_W_BPMSEQ-1 downto 0)
);
end entity;
architecture rtl of matrix_mul is
type arr_slv is array (natural range <>) of std_logic_vector;
------------------------
-- SIGNAL DECLARATION --
------------------------
-- delay registers
signal r_pos_x : signed(C_W_BPMPOS-1 downto 0);
signal r_pos_y : signed(C_W_BPMPOS-1 downto 0);
signal r_seq : arr_slv(0 downto 2)(C_W_BPMSEQ-1 downto 0);
signal r_tvalid : std_logic_vector(2 downto 0);
-- Accumulators general control
signal rst_accu : std_logic;
signal ena_accu : std_logic;
signal id_cnt : unsigned(C_W_MM_IDCNT-1 downto 0);
signal new_seq : std_logic;
begin
---------------------
-- DELAY REGISTERS --
---------------------
p_reg:process(clk, rst_n)
begin
if rst_n = '0' then
r_pos_x <= (others => '0');
r_pos_y <= (others => '0');
r_seq <= (others => (others => '0'));
r_tvalid <= (others => '0');
elsif rising_edge(clk) then
r_pos_x <= pos_x;
r_pos_y <= pos_y;
r_seq(0) <= pos_seq;
for I in 1 to r_seq'right loop
r_seq(I) <= r_seq(I-1);
end loop;
r_tvalid <= r_tvalid(r_tvalid'left-1 downto 0) & pos_tvalid;
end if;
end process;
ena_accu <= r_tvalid(1);
----------------
-- SEQ DETECT --
----------------
new_seq <= '1' when pos_seq /= r_seq(0) else '0';
----------------
-- ID COUNTER --
----------------
p_idcnt:process(clk, rst_n)
begin
if rst_n = '0' then
id_cnt <= (others => '1');
elsif rising_edge(clk) then
if id_cnt = 0 then
id_cnt <= unsigned(id_cnt_load);
else
if new_seq= '1' then
id_cnt <= unsigned(id_cnt_load);
else
if r_tvalid(0) = '1' then
id_cnt <= id_cnt - 1;
end if;
end if;
end if;
end if;
end process;
---------------------------
-- MATRIX MULTIPLICATION --
---------------------------
-- Generate matrix line multiplication, two planes by loop iteration
G_MATRIX:for I in 0 to C_N_MM_PSC/2 generate
signal mult_x : signed(C_W_MM_MULT-1 downto 0);
signal mult_y : signed(C_W_MM_MULT-1 downto 0);
signal accu_x : signed(C_W_MM_ACCU-1 downto 0);
signal accu_y : signed(C_W_MM_ACCU-1 downto 0);
signal table_coefx : std_logic_vector(C_W_MM_COEF-1 downto 0);
signal table_coefy : std_logic_vector(C_W_MM_COEF-1 downto 0);
begin
------------------------------------------------------------------
-- COEF TABLES
inst_coefx_table: entity desy.ram_tdp
generic map(
G_ADDR => C_W_MM_IDCNT,
G_DATA => C_W_MM_COEF
)
port map(
pi_clk_a => clk,
pi_en_a => mm_coef_i(2*I).en,
pi_we_a => mm_coef_i(2*I).we,
pi_addr_a => mm_coef_i(2*I).addr,
pi_data_a => mm_coef_i(2*I).data,
po_data_a => mm_coef_o(2*I).data,
pi_clk_b => clk,
pi_en_b => '1',
pi_we_b => '0',
pi_addr_b => pos_id(C_W_MM_IDCNT-1 downto 0),
pi_data_b => (others => '0'),
po_data_b => table_coefx
);
inst_coefx_table: entity desy.ram_tdp
generic map(
G_ADDR => C_W_MM_IDCNT,
G_DATA => C_W_MM_COEF
)
port map(
pi_clk_a => clk,
pi_en_a => mm_coef_i(2*I+1).en,
pi_we_a => mm_coef_i(2*I+1).we,
pi_addr_a => mm_coef_i(2*I+1).addr,
pi_data_a => mm_coef_i(2*I+1).data,
po_data_a => mm_coef_o(2*I+1).data,
pi_clk_b => clk,
pi_en_b => '1',
pi_we_b => '0',
pi_addr_b => pos_id(C_W_MM_IDCNT-1 downto 0),
pi_data_b => (others => '0'),
po_data_b => table_coefy
);
------------------------------------------------------------------
-- MULT ACCU
p_multaccu:process(clk, rst_n)
begin
if rst_n = '0' then
mult_x <= (others => '0');
accu_x <= (others => '0');
mult_y <= (others => '0');
accu_y <= (others => '0');
elsif rising_edge(clk) then
mult_x <= r_pos_x * signed(table_coefx);
mult_y <= r_pos_y * signed(table_coefy);
if rst_accu = '1' then
accu_x <= (others => '0');
accu_y <= (others => '0');
elsif ena_accu = '1' then
accu_x <= f_sum_sat(accu_x, mult_x);
accu_y <= f_sum_sat(accu_y, mult_y);
end if;
end if;
end process;
------------------------------------------------------------------
-- MAP RESULT
matmult(2*I) <= accu_x;
matmult(2*I+1) <= accu_y;
end generate;
--------------------
-- OUTPUT CONNECT --
--------------------
matmult_tvalid <= r_tvalid(2);
matmult_seq <= r_seq(2);
end architecture;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library desyrdl;
use desyrdl.pkg_corr_matrixpi.all;
library desy;
use desy.ram_tdp;
use desy.math_signed.all;
use work.pkg_corr_matrixpi.all;
entity orbit_error is
port(
clk : in std_logic;
rst_n : in std_logic;
-- RefOrbit table, desyrdl
reforbitx_i : in t_mem_REFORBITX_out;
reforbitx_o : out t_mem_REFORBITX_in;
reforbity_i : in t_mem_REFORBITY_out;
reforbity_o : out t_mem_REFORBITY_in;
-- BPM position input
bpm_x : in signed(C_W_BPMPOS-1 downto 0);
bpm_y : in signed(C_W_BPMPOS-1 downto 0);
bpm_id : in std_logic_vector(C_W_BPMID-1 downto 0);
bpm_seq : in std_logic_vector(C_W_BPMSEQ-1 downto 0);
bpm_tvalid : in std_logic;
-- Orbit error output
errbpm_x : out signed(C_W_BPMPOS-1 downto 0);
errbpm_y : out signed(C_W_BPMPOS-1 downto 0);
errbpm_id : out std_logic_vector(C_W_BPMID-1 downto 0);
errbpm_seq : out std_logic_vector(C_W_BPMSEQ-1 downto 0);
errbpm_tvalid : out std_logic
);
end entity orbit_error;
architecture rtl of orbit_error is
type arr_slv is array (natural range <>) of std_logic_vector;
------------------------
-- SIGNAL DECLARATION --
------------------------
signal table_refx : std_logic_vector(C_W_BPMPOS-1 downto 0);
signal table_refy : std_logic_vector(C_W_BPMPOS-1 downto 0);
signal r_bpm_x : signed(C_W_BPMPOS-1 downto 0);
signal r_bpm_y : signed(C_W_BPMPOS-1 downto 0);
signal r_bpm_id : arr_slv(0 to 1)(C_W_BPMID-1 downto 0);
signal r_bpm_seq : arr_slv(0 to 1)(C_W_BPMSEQ-1 downto 0);
signal r_tvalid : std_logic_vector(1 downto 0);
signal pi_table_refx_en : std_logic;
signal pi_table_refy_en : std_logic;
signal pi_table_refx_we : std_logic;
signal pi_table_refy_we : std_logic;
begin
-------------------------------
-- POSITION REFERENCE TABLES --
-------------------------------
-- Port A is read write from AXI controller, Port B is read only from logic
inst_refx_table: entity desy.ram_tdp
generic map(
G_ADDR => C_W_BPMID,
G_DATA => C_W_BPMPOS
)
port map(
pi_clk_a => clk,
pi_en_a => reforbitx_i.en,
pi_we_a => reforbitx_i.we,
pi_addr_a => reforbitx_i.addr,
pi_data_a => reforbitx_i.data,
po_data_a => reforbitx_o.data,
pi_clk_b => clk,
pi_en_b => '1',
pi_we_b => '0',
pi_addr_b => bpm_id,
pi_data_b => (others => '0'),
po_data_b => table_refx
);
inst_refy_table: entity desy.ram_tdp
generic map(
G_ADDR => C_W_BPMID,
G_DATA => C_W_BPMPOS
)
port map(
pi_clk_a => clk,
pi_en_a => reforbity_i.en,
pi_we_a => reforbity_i.we,
pi_addr_a => reforbity_i.addr,
pi_data_a => reforbity_i.data,
po_data_a => reforbity_o.data,
pi_clk_b => clk,
pi_en_b => '1',
pi_we_b => '0',
pi_addr_b => bpm_id,
pi_data_b => (others => '0'),
po_data_b => table_refy
);
-----------------------
-- ERROR SUBSTRACTOR --
-----------------------
p_sub_err:process(clk, rst_n)
begin
if rst_n = '0' then
errbpm_x <= (others => '0');
errbpm_y <= (others => '0');
elsif rising_edge(clk) then
errbpm_x <= f_diff_sat(r_bpm_x, signed(table_refx));
errbpm_y <= f_diff_sat(r_bpm_y, signed(table_refy));
end if;
end process;
---------------------
-- DELAY REGISTERS --
---------------------
p_delay_reg:process(clk, rst_n)
begin
if rst_n = '0' then
r_bpm_id <= (others => (others => '0'));
r_bpm_seq <= (others => (others => '0'));
r_tvalid <= (others => '0');
elsif rising_edge(clk) then
r_bpm_id(0) <= bpm_id;
for I in 1 to r_bpm_id'right loop
r_bpm_id(I) <= r_bpm_id(I-1);
end loop;
r_bpm_seq(0) <= bpm_seq;
for I in 1 to r_bpm_seq'right loop
r_bpm_seq(I) <= r_bpm_seq(I-1);
end loop;
r_tvalid <= r_tvalid(r_tvalid'left-1 downto 0) & bpm_tvalid;
end if;
end process;
----------------------
-- OUTPUT CONNEXION --
----------------------
errbpm_id <= r_bpm_id(r_bpm_id'right);
errbpm_seq <= r_bpm_seq(r_bpm_seq'right);
errbpm_tvalid <= r_tvalid(r_tvalid'left);
end architecture;
library ieee;
use ieee.std_logic_1164.all;
use ieee.math_real.log2;
use ieee.math_real.ceil;
use ieee.numeric_std.all;
package pkg_corr_matrixpi is
--------------------------
-- CONSTANT DECLARATION --
--------------------------
-- Data input width
constant C_W_BPMPOS : natural := 32;
constant C_W_BPMID : natural := 8;
constant C_W_BPMSEQ : natural := 8;
constant C_W_PSCID : natural := 16;
-- Matrix multiplier
constant C_N_MM_BPM : natural := 122; -- number of bpm (matrix columns)
constant C_N_MM_PSC : natural := 100; -- number of psc (matrix lines)
constant C_W_MM_COEF : natural := 32;
constant C_W_MM_MULT : natural := C_W_BPMPOS+C_W_MM_COEF;
constant C_W_MM_IDCNT : natural := natural(ceil(log2(real(C_N_MM_BPM))));
constant C_W_MM_ACCU : natural := C_W_MM_MULT+C_W_MM_IDCNT;
-- PI corrector
constant C_W_COR_KP : natural := 32;
constant C_W_COR_KI : natural := 32;
constant C_W_COR_ACCU : natural := C_W_MM_ACCU;
constant C_W_COR_OUT : natural := 16;
----------------------
-- TYPE DECLARATION --
----------------------
type signed_array is array (natural range <>) of signed;
end package;
-------------------------------------------------------------------------------
-- ____ _____________ __ --
-- / __ \/ ____/ ___/\ \/ / _ _ _ --
-- / / / / __/ \__ \ \ / / \ / \ / \ --
-- / /_/ / /___ ___/ / / / = ( M | S | K )= --
-- /_____/_____//____/ /_/ \_/ \_/ \_/ --
-- --
-------------------------------------------------------------------------------
-- Copyright (c) 2020 DESY
-------------------------------------------------------------------------------
--! @brief template for the version package for a particular module
--! @created 2020-01-30
-------------------------------------------------------------------------------
--! Description:
--! This template is used by fwk to inject Version and Timestamp information
--! in to the module's register map
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
package pkg_corr_matrixpi_version is
constant C_VERSION : std_logic_vector(31 downto 0) := x"00000000";
constant C_TIMESTAMP : std_logic_vector(31 downto 0) := x"64495b71";
end pkg_corr_matrixpi_version ;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library desyrdl;
use desyrdl.pkg_corr_matrixpi.all;
use work.pkg_corr_matrixpi_version.all;
use work.pkg_corr_matrixpi.all;
entity top_corr_matrixpi is
port(
clk : in std_logic;
rst_n : in std_logic;
-- AXI-MM interface
s_axi_m2s : in t_corr_matrixpi_m2s;
s_axi_s2m : out t_corr_matrixpi_s2m;
-- AXIS input
s_axis_tdata : in std_logic_vector(2*C_W_BPMPOS+C_W_BPMID-1 downto 0);
s_axis_tuser : in std_logic_vector(C_W_BPMSEQ-1 downto 0);
s_axis_tvalid : in std_logic;
-- AXIS output
m_axis_tdata : out std_logic_vector(C_W_COR_OUT+C_W_PSCID-1 downto 0);
m_axis_tuser : out std_logic_vector(C_W_BPMSEQ-1 downto 0);
m_axis_tvalid : out std_logic;
m_axis_tready : in std_logic
);
end entity;
architecture struct of top_corr_matrixpi is
------------------------
-- SIGNAL DECLARATION --
------------------------
signal rst : std_logic;
signal mm_a2l : t_addrmap_corr_matrixpi_in;
signal mm_l2a : t_addrmap_corr_matrixpi_out;
-- unpacked input
signal bpm_x : signed(C_W_BPMPOS-1 downto 0);
signal bpm_y : signed(C_W_BPMPOS-1 downto 0);
signal bpm_id : std_logic_vector(C_W_BPMID-1 downto 0);
signal bpm_seq : std_logic_vector(C_W_BPMSEQ-1 downto 0);
-- Position error
signal errbpm_x : signed(C_W_BPMPOS-1 downto 0);
signal errbpm_y : signed(C_W_BPMPOS-1 downto 0);
signal errbpm_id : std_logic_vector(C_W_BPMID-1 downto 0);
signal errbpm_seq : std_logic_vector(C_W_BPMSEQ-1 downto 0);
signal errbpm_tvalid : std_logic;
-- Matrix mutliplication result
signal matmult : signed_array(0 to C_N_MM_PSC-1)(C_W_MM_ACCU-1 downto 0);
signal matmult_tvalid : std_logic;
signal matmult_seq : std_logic_vector(C_W_BPMSEQ-1 downto 0);
-- Corrector result, parallel
signal corrout_valid : std_logic;
signal corrout_seq : std_logic_vector(C_W_BPMSEQ-1 downto 0);
signal corrout : signed_array(0 to C_N_MM_PSC-1)(C_W_COR_OUT-1 downto 0);
-- Serializer
signal overrun_flag : std_logic;
begin
rst <= not rst_n;
----------------------
-- AXI-MM INTERFACE --
----------------------
inst_aximm: entity desyrdl.corr_matrixpi
port map(
pi_clock => clk,
pi_reset => rst,
-- TOP subordinate memory mapped interface
pi_s_top => s_axi_m2s,
po_s_top => s_axi_s2m,
-- to logic interface
pi_addrmap => mm_a2l,
po_addrmap => mm_l2a
);
------------------
-- UNPACK INPUT --
------------------
bpm_x <= signed(s_axis_tdata(C_W_BPMPOS-1 downto 0));
bpm_y <= signed(s_axis_tdata(2*C_W_BPMPOS-1 downto C_W_BPMPOS));
bpm_id <= s_axis_tdata(C_W_BPMID+2*C_W_BPMPOS-1 downto 2*C_W_BPMPOS);
bpm_seq <= s_axis_tuser(C_W_BPMSEQ-1 downto 0);
------------------------------
-- ORBIT ERROR TO REFERENCE --
------------------------------
inst_orbit_error: entity work.orbit_error
port map(
clk => clk,
rst_n => rst_n,
-- RefOrbit table, desyrdl
reforbitx_i => mm_a2l.REFORBITX,
reforbitx_o => mm_l2a.REFORBITX,
reforbity_i => mm_a2l.REFORBITY,
reforbity_o => mm_l2a.REFORBITY,
-- BPM position input
bpm_x => bpm_x,
bpm_y => bpm_y,
bpm_id => bpm_id,
bpm_seq => bpm_seq,
bpm_tvalid => s_axis_tvalid,
-- Orbit error output
errbpm_x => errbpm_x,
errbpm_y => errbpm_y,
errbpm_id => errbpm_id,
errbpm_seq => errbpm_seq,
errbpm_tvalid => errbpm_tvalid
);
---------------------------
-- MATRIX MULTIPLICATION --
---------------------------
inst_matrix_mul: entity work.matrix_mul
port map(
clk => clk,
rst_n => rst_n,
-- Coef table, desyrdl
mm_coef_i => mm_a2l.MATRIXCOEF,
mm_coef_o => mm_l2a.MATRIXCOEF,
id_cnt_load => ll_a2l.MM_ID_CNT.data,
-- Position data in
pos_x => errbpm_x,
pos_y => errbpm_y,
pos_id => errbpm_id,
pos_seq => errbpm_seq,
pos_tvalid => errbpm_tvalid,
-- Data out
matmult => matmult,
matmult_tvalid => matmult_tvalid,
matmult_seq => matmult_seq
);
------------------
-- PI CORRECTOR --
------------------
inst_corr_pi: entity work.corr_pi
port map(
clk => clk,
rst_n => rst_n,
-- matmult input
matmult => matmult,
matmult_valid => matmult_valid,
matmult_seq => matmult_seq,
-- Corr coefs
corr_kp => mm_a2l.CORR_KP.data,
corr_ki => mm_a2l.CORR_KI.data,
reset_accu => mm.a2l.CONTROL.RST_ACCU,
enable_corr => mm.a2l.CONTROL.ENABLE,
-- Corr output
corrout_valid => corrout_valid,
corrout_seq => corrout_seq,
corrout => corrout
);
---------------------
-- DATA SERIALIZER --
---------------------
inst_data_serializer: entity work.data_serializer
port map(
clk => clk,
rst_n => rst_n,
-- PSCID memory
pscid_table_i => mm_a2l.PSCIDTABLE,
pscid_table_o => mm_l2a.PSCIDTABLE,
-- Status
overrun => overrun_flag,
-- Corr parallel input
corrout_valid => corrout_valid,
corrout_seq => corrout_seq,
corrout => corrout,
-- AXIS serial output
m_axis_tdata => m_axis_tdata,
m_axis_tuser => m_axis_tuser,
m_axis_tvalid => m_axis_tvalid,
m_axis_tready => m_axis_tready
);
end architecture;
`include "corr_matrixpi.vh" //automatically created and added by fwk with conf variables such a C_VERSION ...
/* default values of defined variables */
`ifndef C_ID
`define C_ID 0x507E1730
`endif
`ifndef C_VERSION
`define C_VERSION 0x00000000
`endif
addrmap corr_matrixpi {
name = "PI corrector with matrix multiplier";
desyrdl_interface = "AXI4L";
reg {
desc="Module Identification Number.";
default sw = r;
default hw = r;
field {} data[32] = `C_ID;
} ID @0x00;
reg {
desc="Module Version Number.";
default sw = r;
default hw = r;
field {} data [32];
} VERSION @0x04;
reg {
desc="Global control of the corrector.";
field {sw = rw; hw = r;} ENABLE;
field {sw = rw; hw = r;} RST_ACC;
} CONTROL;
reg {
desc="Correction proportionnal coefficient.";
field {sw = rw; hw = r;} data[`C_W_COR_KP];
} CORR_KP;
reg {
desc="Correction intergral coefficient.";
field {sw = rw; hw = r;} data[`C_W_COR_KI];
} CORR_KI;
mem {
desc = "X Reference orbit.";
memwidth = `C_W_BPMID;
mementries = `C_N_MM_BPM;
} external REFORBITX;
mem {
desc = "Y Reference orbit.";
memwidth = `C_W_BPMID;
mementries = `C_N_MM_BPM;
} external REFORBITY;
mem {
desc = "PSC identifier table.";
memwidth = `C_W_PSCID;
mementries = `C_N_MM_PSC;
} external PSCIDTABLE;
mem {
desc = "Matrix multiplication coefficients.";
memwidth = `C_W_MM_COEF;
mementries = `C_N_MM_BPM;
} external MATRIXCOEF[`C_N_MM_PSC];
};
################################################################################
# Main tcl for the module
################################################################################
# ==============================================================================
proc init {} {
variable Config
# Parse configuration from VHDL package
parseVhdlConfigFile Config "../hdl/pkg_corr_matrixpi.vhd"
}
# ==============================================================================
proc setSources {} {
variable Sources
# Generate VHDL package with modversion
genModVerFile VHDL ../hdl/pkg_corr_matrixpi_version.vhd
lappend Sources {"../hdl/pkg_corr_matrixpi_version.vhd" "VHDL"}
lappend Sources {"../hdl/pkg_corr_matrixpi.vhd" "VHDL 2008"}
lappend Sources {"../hdl/corr_pi.vhd" "VHDL 2008"}
lappend Sources {"../hdl/matrix_mul.vhd" "VHDL 2008"}
lappend Sources {"../hdl/orbit_error.vhd" "VHDL 2008"}
lappend Sources {"../hdl/data_serializer.vhd" "VHDL 2008"}
lappend Sources {"../hdl/top_corr_matrixpi.vhd" "VHDL 2008"}
lappend Sources [list "${::fwfwk::LibPath}/desy_vhdl/hdl/memory/ram/ram_tdp.vhd" "VHDL 2008" "desy"]
lappend Sources [list "${::fwfwk::LibPath}/desy_vhdl/hdl/math/pkg_math_signed.vhd" "VHDL 2008" "desy"]
}
# ==============================================================================
proc setAddressSpace {} {
variable AddressSpace
addAddressSpace AddressSpace "corr_matrixpi" RDL {} ../rdl/corr_matrixpi.rdl
}
# ==============================================================================
proc doOnCreate {} {
variable Sources
addSources "Sources"
}
# ==============================================================================
proc doOnBuild {} {
}
# ==============================================================================
proc setSim {} {
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment