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

Merge branch 'dev_corrfp' into dev

parents a1355d66 4631782c
Branches
Tags
No related merge requests found
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library desy;
use desy.math_signed.all;
use work.pkg_corr_matrix.all;
entity corr_iir is
port(
clk : in std_logic;
rst_n : in std_logic;
coef_a_x : in signed(C_W_COR_COEF-1 downto 0);
coef_b_x : in signed(C_W_COR_COEF-1 downto 0);
coef_c_x : in signed(C_W_COR_COEF-1 downto 0);
coef_d_x : in signed(C_W_COR_COEF-1 downto 0);
coef_a_y : in signed(C_W_COR_COEF-1 downto 0);
coef_b_y : in signed(C_W_COR_COEF-1 downto 0);
coef_c_y : in signed(C_W_COR_COEF-1 downto 0);
coef_d_y : in signed(C_W_COR_COEF-1 downto 0);
enable_corr_x : in std_logic;
reset_corr_x : in std_logic;
enable_corr_y : in std_logic;
reset_corr_y : in std_logic;
matmult : in signed_array(0 to C_N_MM_PSC-1)(C_W_MM-1 downto 0);
matmult_valid : in std_logic;
matmult_seq : in std_logic_vector(C_W_BPMSEQ-1 downto 0);
corrout_valid : out std_logic;
corrout_seq : out std_logic_vector(C_W_BPMSEQ-1 downto 0);
corrout : out signed_array(0 to C_N_MM_PSC-1)(C_W_COR-1 downto 0);
corrout_fp : out signed_array(0 to C_N_MM_PSC-1)(C_W_COR+C_W_FP-1 downto 0)
);
end entity corr_iir;
architecture rtl of corr_iir is
constant C_DELAY : natural := 6;
constant C_W_MULT : natural := C_W_MM+C_W_COR_COEF;
constant C_W_CORFP : natural := C_W_COR+C_W_FP;
type arr_slv is array (natural range <>) of std_logic_vector;
signal delay_valid : std_logic_vector(C_DELAY-1 downto 0);
signal delay_seq : arr_slv(0 to C_DELAY-1)(C_W_BPMSEQ-1 downto 0);
begin
----------------------
-- OUTPUT CONNEXION --
----------------------
corrout_valid <= delay_valid(delay_valid'left);
corrout_seq <= delay_seq(C_DELAY-1);
--------------------
-- DELAY REGISTER --
--------------------
p_delay:process(clk,rst_n)
begin
if rst_n = '0' then
delay_valid <= (others => '0');
delay_seq <= (others => (others => '0'));
elsif rising_edge(clk) then
delay_valid(0) <= matmult_valid;
delay_valid(delay_valid'left downto 1) <= delay_valid(delay_valid'left-1 downto 0);
delay_seq(0) <= matmult_seq;
for I in 1 to C_DELAY-1 loop
delay_seq(I) <= delay_seq(I-1);
end loop;
end if;
end process;
--------------------
-- CORRECTOR LINE --
--------------------
gen_corr:for I in 0 to C_N_MM_PSC-1 generate
signal mult_a : signed(C_W_MULT-1 downto 0);
signal mult_b : signed(C_W_MULT-1 downto 0);
signal mult_c : signed(C_W_MULT-1 downto 0);
signal mult_d : signed(C_W_CORFP+C_W_COR_COEF-1 downto 0);
signal sumsat_abd : signed(C_W_MM-1 downto 0);
signal reg_dout : signed(C_W_CORFP-1 downto 0);
signal reg_dout2 : signed(C_W_CORFP-1 downto 0);
signal reg_din : signed(C_W_MM-1 downto 0);
signal rnd_cor : signed(C_W_COR-1 downto 0);
signal rndsat_mult_a : signed(C_W_MM-1 downto 0);
signal rndsat_mult_b : signed(C_W_MM-1 downto 0);
signal rndsat_mult_d : signed(C_W_CORFP+C_W_COR_COEF-C_W_COR_COEFFP-1 downto 0);
signal coef_a : signed(C_W_COR_COEF-1 downto 0);
signal coef_b : signed(C_W_COR_COEF-1 downto 0);
signal coef_c : signed(C_W_COR_COEF-1 downto 0);
signal coef_d : signed(C_W_COR_COEF-1 downto 0);
signal enable_corr : std_logic;
signal reset_corr : std_logic;
begin
-- Signal rails for X/Y coef and enable/reset, based on PSCID number
gen_x_sigrail:if I < 50 generate
coef_a <= coef_a_x;
coef_b <= coef_b_x;
coef_c <= coef_c_x;
coef_d <= coef_d_x;
enable_corr <= enable_corr_x;
reset_corr <= reset_corr_x;
end generate;
gen_y_sigrail:if I > 49 generate
coef_a <= coef_a_y;
coef_b <= coef_b_y;
coef_c <= coef_c_y;
coef_d <= coef_d_y;
enable_corr <= enable_corr_y;
reset_corr <= reset_corr_y;
end generate;
p_main:process(clk, rst_n)
begin
if rst_n = '0' then
mult_a <= (others => '0');
mult_b <= (others => '0');
mult_c <= (others => '0');
mult_d <= (others => '0');
sumsat_abd <= (others => '0');
reg_din <= (others => '0');
reg_dout <= (others => '0');
reg_dout2 <= (others => '0');
rnd_cor <= (others => '0');
rndsat_mult_a <= (others => '0');
rndsat_mult_b <= (others => '0');
rndsat_mult_d <= (others => '0');
elsif rising_edge(clk) then
----------------------------------------------------------------------------------------------------------
-- Sequence registers (IIR z-1 steps)
if reset_corr = '1' then
reg_din <= (others => '0');
reg_dout <= (others => '0');
else
if matmult_valid = '1' then
reg_din <= matmult(I);
end if;
if delay_valid(delay_valid'left-2) = '1' and enable_corr = '1' then
-- Round then sat
if mult_c(C_W_COR_COEFFP-1) = '0' then
reg_dout <= f_resize_sat(
f_resize_lsb(mult_c, mult_c'length-C_W_COR_COEFFP),
C_W_CORFP);
else
reg_dout <= f_resize_sat(
f_sum_sat(f_resize_lsb(mult_c, mult_c'length-C_W_COR_COEFFP), to_signed(1,2)),
C_W_CORFP);
end if;
end if;
end if;
----------------------------------------------------------------------------------------------------------
-- Mutlipliers
mult_a <= matmult(I) * coef_a;
mult_b <= reg_din * coef_b;
mult_d <= reg_dout * coef_d;
mult_c <= sumsat_abd * coef_c;
----------------------------------------------------------------------------------------------------------
-- Round and resize
if mult_a(C_W_COR_COEFFP-1) = '0' then
rndsat_mult_a <= f_resize_sat(
f_resize_lsb(mult_a, mult_a'length-C_W_COR_COEFFP),
C_W_MM);
else
rndsat_mult_a <= f_resize_sat(
f_sum_sat(f_resize_lsb(mult_a, mult_a'length-C_W_COR_COEFFP), to_signed(1,2)),
C_W_MM);
end if;
if mult_b(C_W_COR_COEFFP-1) = '0' then
rndsat_mult_b <= f_resize_sat(
f_resize_lsb(mult_b, mult_b'length-C_W_COR_COEFFP),
C_W_MM);
else
rndsat_mult_b <= f_resize_sat(
f_sum_sat(f_resize_lsb(mult_b, mult_b'length-C_W_COR_COEFFP), to_signed(1,2)),
C_W_MM);
end if;
if mult_d(C_W_COR_COEFFP-1) = '0' then
rndsat_mult_d <= f_resize_sat(
f_resize_lsb(mult_d, mult_d'length-C_W_COR_COEFFP),
rndsat_mult_d'length);
else
rndsat_mult_d <= f_resize_sat(
f_sum_sat(f_resize_lsb(mult_d, mult_d'length-C_W_COR_COEFFP), to_signed(1,2)),
rndsat_mult_d'length);
end if;
----------------------------------------------------------------------------------------------------------
-- global sum
sumsat_abd <= f_sum_sat(f_sum_sat(rndsat_mult_a, rndsat_mult_b), rndsat_mult_d);
----------------------------------------------------------------------------------------------------------
-- Output rounding
if reg_dout(C_W_FP-1) = '0' then
rnd_cor <= f_resize_lsb(reg_dout, C_W_COR);
else
rnd_cor <= f_sum_sat(f_resize_lsb(reg_dout, C_W_COR), to_signed(1,2));
end if;
reg_dout2 <= reg_dout;
end if;
end process;
-- mapping
corrout(I) <= rnd_cor;
corrout_fp(I) <= reg_dout2;
end generate gen_corr;
end architecture;
......@@ -32,14 +32,14 @@ package pkg_corr_matrix is
constant C_W_MM_IDCNT : natural := 8; -- > natural(ceil(log2(real(C_N_MM_BPM))));
constant C_W_MM_ACCU : natural := 58; -- C_W_MM_MULT+C_W_MM_IDCNT;
constant C_N_MM_SAT : natural := 7;
constant C_N_MM_RND : natural := 15;
constant C_N_MM_SAT : natural := 8;
constant C_N_MM_RND : natural := 14;
constant C_W_MM : natural := 36; --C_W_MM_ACCU-C_N_MM_SAT-C_N_MM_RND
constant C_W_FP : natural := 16; -- decimal bits of the matmul fixed point
-- PI corrector
constant C_W_COR_COEF : natural := 17;
constant C_W_COR_SUMSAT : natural := 36;
constant C_N_COR_RND : natural := 20;
-- IIR corrector
constant C_W_COR_COEF : natural := 16;
constant C_W_COR_COEFFP : natural := 14; -- decimal bits of the coeff fixed point
constant C_W_COR : natural := 16;
......
......@@ -62,7 +62,7 @@ architecture struct of top_corr_matrix is
-- Corrector result, parallel
signal corrfirst_valid : std_logic;
signal corrfirst_seq : std_logic_vector(C_W_BPMSEQ-1 downto 0);
signal corrfirst : signed_array(0 to C_N_MM_PSC-1)(C_W_COR-1 downto 0);
signal corrfirst : signed_array(0 to C_N_MM_PSC-1)(C_W_COR+C_W_FP-1 downto 0);
signal corrfirst_resize: signed_array(0 to C_N_MM_PSC-1)(C_W_MM-1 downto 0);
signal corrout_valid : std_logic;
signal corrout_seq : std_logic_vector(C_W_BPMSEQ-1 downto 0);
......@@ -223,9 +223,9 @@ begin
);
------------------
-- LL CORRECTOR --
-- IIR CORRECTOR --
------------------
inst_corr: entity work.corr_ll
inst_corr: entity work.corr_iir
port map(
clk => clk,
rst_n => rst_n,
......@@ -238,11 +238,11 @@ begin
-- Corr coefs
coef_a_x => signed(mm_a2l.CORR_K1A_X.data.data),
coef_b_x => signed(mm_a2l.CORR_K1B_X.data.data),
coef_ic_x => signed(mm_a2l.CORR_K1IC_X.data.data),
coef_c_x => signed(mm_a2l.CORR_K1C_X.data.data),
coef_d_x => signed(mm_a2l.CORR_K1D_X.data.data),
coef_a_y => signed(mm_a2l.CORR_K1A_Y.data.data),
coef_b_y => signed(mm_a2l.CORR_K1B_Y.data.data),
coef_ic_y => signed(mm_a2l.CORR_K1IC_Y.data.data),
coef_c_y => signed(mm_a2l.CORR_K1C_Y.data.data),
coef_d_y => signed(mm_a2l.CORR_K1D_Y.data.data),
reset_corr_x => mm_a2l.CONTROL_X.RST_CORR.data(0),
......@@ -253,14 +253,15 @@ begin
-- Corr output
corrout_valid => corrfirst_valid,
corrout_seq => corrfirst_seq,
corrout => corrfirst
corrout_fp => corrfirst,
corrout => open
);
gen_resize:for I in 0 to C_N_MM_PSC-1 generate
corrfirst_resize(I) <= resize(corrfirst(I), C_W_MM);
end generate;
inst_corr2: entity work.corr_ll
inst_corr2: entity work.corr_iir
port map(
clk => clk,
rst_n => rst_n,
......@@ -273,11 +274,11 @@ begin
-- Corr coefs
coef_a_x => signed(mm_a2l.CORR_K2A_X.data.data),
coef_b_x => signed(mm_a2l.CORR_K2B_X.data.data),
coef_ic_x => signed(mm_a2l.CORR_K2IC_X.data.data),
coef_c_x => signed(mm_a2l.CORR_K2C_X.data.data),
coef_d_x => signed(mm_a2l.CORR_K2D_X.data.data),
coef_a_y => signed(mm_a2l.CORR_K2A_Y.data.data),
coef_b_y => signed(mm_a2l.CORR_K2B_Y.data.data),
coef_ic_y => signed(mm_a2l.CORR_K2IC_Y.data.data),
coef_c_y => signed(mm_a2l.CORR_K2C_Y.data.data),
coef_d_y => signed(mm_a2l.CORR_K2D_Y.data.data),
reset_corr_x => mm_a2l.CONTROL_X.RST_CORR.data(0),
......@@ -288,6 +289,7 @@ begin
-- Corr output
corrout_valid => corrout_valid,
corrout_seq => corrout_seq,
corrout_fp => open,
corrout => corrout
);
......
......@@ -67,10 +67,10 @@ addrmap corr_matrix {
} CORR_K1B_X;
reg {
desc="Correction coefficient (inverse) C.";
desc="Correction coefficient C.";
desyrdl_data_type="int32";
field {sw = rw; hw = r;} data[`C_W_COR_COEF];
} CORR_K1IC_X;
} CORR_K1C_X;
reg {
desc="Correction coefficient D.";
......@@ -92,10 +92,10 @@ addrmap corr_matrix {
} CORR_K2B_X;
reg {
desc="Correction coefficient (inverse) C.";
desc="Correction coefficient C.";
desyrdl_data_type="int32";
field {sw = rw; hw = r;} data[`C_W_COR_COEF];
} CORR_K2IC_X;
} CORR_K2C_X;
reg {
desc="Correction coefficient D.";
......@@ -116,10 +116,10 @@ addrmap corr_matrix {
} CORR_K1B_Y;
reg {
desc="Correction coefficient (inverse) C.";
desc="Correction coefficient C.";
desyrdl_data_type="int32";
field {sw = rw; hw = r;} data[`C_W_COR_COEF];
} CORR_K1IC_Y;
} CORR_K1C_Y;
reg {
desc="Correction coefficient D.";
......@@ -141,10 +141,10 @@ addrmap corr_matrix {
} CORR_K2B_Y;
reg {
desc="Correction coefficient (inverse) C.";
desc="Correction coefficient C.";
desyrdl_data_type="int32";
field {sw = rw; hw = r;} data[`C_W_COR_COEF];
} CORR_K2IC_Y;
} CORR_K2C_Y;
reg {
desc="Correction coefficient D.";
......
This diff is collapsed.
This diff is collapsed.
......@@ -8,6 +8,10 @@ import numpy as np
# The inverted response matrix, we use an actual true dataset
respmat = np.load("respmat.npy")
# Remove weirdcoeff and set to nm/DAC
#respmat= np.round(respmat/1.77/1717.412/170*10*0x7FFF*1e-6*2**30).astype('i4')
# write to file
with open("respmat.txt", "w") as fp:
for r in respmat.flatten():
......@@ -35,7 +39,7 @@ N_BPM=respmat.shape[1]*2
N_PSC=respmat.shape[0]
size=200
N_MM_RND=15
N_MM_RND=14
#############################################################################
# Generate data input
......@@ -43,7 +47,7 @@ N_MM_RND=15
bpmdata=np.empty((N_BPM, size), dtype="int32")
for i, DC, A, F, N in zip(
np.arange(N_BPM, dtype="int"),
np.random.default_rng().uniform(-1e6, 1e6, N_BPM),
np.random.default_rng().uniform(-1e5, 1e5, N_BPM),
np.random.default_rng().uniform(0, 200e3, N_BPM),
np.random.default_rng().uniform(2,2000, N_BPM),
np.random.default_rng().uniform(0, 20e3, N_BPM),):
......@@ -65,15 +69,15 @@ with open("bpmdata.txt", "w") as fp:
trespmat = np.zeros((N_PSC, N_BPM), dtype="int64")
trespmat[:50,:122] = respmat[:50]
trespmat[50:,122:] = respmat[50:]
C_N_RND = 20
C_N_A_RND = 8
C_N_RND = 14
C_N_FP = 16
SUMSAT=36
K_A = 256
K_B = 0
K_iC = 64
K_D = -16300
K_A = 4950
K_B = -4000
K_C = 16384
K_D = 16300
## -----------------------
......@@ -83,23 +87,25 @@ K_D = -16300
oe=bpmdata-refmat[:,np.newaxis]
# Step 2: matrix multiplication
mm=np.empty((N_PSC, size), dtype="int32")
mm=np.empty((N_PSC, size), dtype="i8")
for i in range(size):
# Stage 1 : matmul
_mm= np.matmul(oe[:,i].astype("int64"), trespmat.T, dtype='int64')
mm[:,i] = np.round(_mm*2**-N_MM_RND).astype("int32")
mm[:,i] = np.round(_mm*2**-N_MM_RND)
# Step 3: correction computation
corr = np.zeros((N_PSC, size), dtype="int64")
corrfp = np.zeros((N_PSC, size), dtype="i8")
_corr = (np.round(mm[:,0].astype('i8')*K_A*2**-C_N_A_RND)*K_iC).astype("int64")
corr[:,0] = np.clip(np.round(_corr/2**C_N_RND), -2**15, 2**15-1).astype('i8')
for i in range(1,size):
_sum = (np.round(mm[:,i].astype('i8')*K_A*2**-C_N_A_RND)).astype('i8') + mm[:,i-1].astype('i8')*K_B + corr[:,i-1]*K_D
_corr = np.clip(_sum, -2**(SUMSAT-1), 2**(SUMSAT-1)-1)*K_iC
corr[:,i] = np.clip(np.round(_corr/2**C_N_RND), -2**15, 2**15-1)
corrfp[:,0] = mm[:,0] *K_A*2**-C_N_RND *K_C*2**-C_N_RND
for i in range(1,size):
corrfp[:,i] = (mm[:,i] *K_A*2**-C_N_RND +
mm[:,i-1] *K_B*2**-C_N_RND +
corrfp[:,i-1] *K_D*2**-C_N_RND
)*K_C*2**-C_N_RND
corr = np.round(corrfp*2**-C_N_FP).astype('i2')
#############################################################################
# Write partial and results to files
......
......@@ -91,22 +91,22 @@ begin
log("+-- Global Config", INFO);
-- Correction coefficients
Write(ManagerRec, f_addr(16#18#), f_sdata(256));
Write(ManagerRec, f_addr(16#1C#), f_sdata(0));
Write(ManagerRec, f_addr(16#20#), f_sdata(64));
Write(ManagerRec, f_addr(16#24#), f_sdata(-16300));
Write(ManagerRec, f_addr(16#38#), f_sdata(256));
Write(ManagerRec, f_addr(16#3C#), f_sdata(0));
Write(ManagerRec, f_addr(16#40#), f_sdata(64));
Write(ManagerRec, f_addr(16#44#), f_sdata(-16300));
Write(ManagerRec, f_addr(16#28#), f_sdata(32768));
Write(ManagerRec, f_addr(16#18#), f_sdata(4950));
Write(ManagerRec, f_addr(16#1C#), f_sdata(-4000));
Write(ManagerRec, f_addr(16#20#), f_sdata(16384));
Write(ManagerRec, f_addr(16#24#), f_sdata(16300));
Write(ManagerRec, f_addr(16#38#), f_sdata(4950));
Write(ManagerRec, f_addr(16#3C#), f_sdata(-4000));
Write(ManagerRec, f_addr(16#40#), f_sdata(16384));
Write(ManagerRec, f_addr(16#44#), f_sdata(16300));
Write(ManagerRec, f_addr(16#28#), f_sdata(16384));
Write(ManagerRec, f_addr(16#2C#), f_sdata(0));
Write(ManagerRec, f_addr(16#30#), f_sdata(8192));
Write(ManagerRec, f_addr(16#30#), f_sdata(16384));
Write(ManagerRec, f_addr(16#34#), f_sdata(0));
Write(ManagerRec, f_addr(16#48#), f_sdata(32768));
Write(ManagerRec, f_addr(16#48#), f_sdata(16384));
Write(ManagerRec, f_addr(16#4C#), f_sdata(0));
Write(ManagerRec, f_addr(16#50#), f_sdata(8192));
Write(ManagerRec, f_addr(16#50#), f_sdata(16384));
Write(ManagerRec, f_addr(16#54#), f_sdata(0));
-- Num BPM
......
......@@ -19,7 +19,7 @@ proc setSources {} {
lappend Sources {"../hdl/pkg_corr_matrix_version.vhd" "VHDL"}
lappend Sources {"../hdl/pkg_corrmatrix.vhd" "VHDL 2008"}
lappend Sources {"../hdl/corr_ll.vhd" "VHDL 2008"}
lappend Sources {"../hdl/corr_iir.vhd" "VHDL 2008"}
lappend Sources {"../hdl/lvl_threshold.vhd" "VHDL 2008"}
lappend Sources {"../hdl/matrix_mul.vhd" "VHDL 2008"}
lappend Sources {"../hdl/orbit_error.vhd" "VHDL 2008"}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment