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

Initial commit

parents
No related branches found
No related tags found
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.
Finish editing this message first!
Please register or to comment