Commit dc6b579a authored by Tomasz Wlostowski's avatar Tomasz Wlostowski Committed by Grzegorz Daniluk

wr_si57x_interface: made it working with SoftPLL on AFCZ.

parent 1d31cc8a
This diff is collapsed.
...@@ -4,6 +4,47 @@ peripheral { ...@@ -4,6 +4,47 @@ peripheral {
name = "silabs interface"; name = "silabs interface";
hdl_entity = "si570_if_wb"; hdl_entity = "si570_if_wb";
prefix = "si570"; prefix = "si570";
reg {
name = "Control Register";
prefix = "CR";
field {
name = "Si57x Address";
size = 8;
type = SLV;
prefix = "I2C_ADDR";
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
field {
name = "Si57x SPLL input enable";
prefix = "ENABLE";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
field {
name = "RFREQ gain/scalefactor";
prefix = "GAIN";
size = 8;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
field {
name = "I2C Clock Divider";
prefix = "CLK_DIV";
size = 8;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg { reg {
name = "RFREQ low part"; name = "RFREQ low part";
...@@ -31,6 +72,7 @@ peripheral { ...@@ -31,6 +72,7 @@ peripheral {
}; };
}; };
reg { reg {
name = "GPIO Set/Readback Register"; name = "GPIO Set/Readback Register";
prefix = "GPSR"; prefix = "GPSR";
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
--------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------
-- File : si570_if_wbgen2_pkg.vhd -- File : si570_if_wbgen2_pkg.vhd
-- Author : auto-generated by wbgen2 from si570_if_wb.wb -- Author : auto-generated by wbgen2 from si570_if_wb.wb
-- Created : Thu Aug 6 16:04:41 2015 -- Created : Thu Mar 12 23:41:40 2020
-- Standard : VHDL'87 -- Standard : VHDL'87
--------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE si570_if_wb.wb -- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE si570_if_wb.wb
...@@ -22,67 +22,100 @@ package si570_wbgen2_pkg is ...@@ -22,67 +22,100 @@ package si570_wbgen2_pkg is
type t_si570_in_registers is record type t_si570_in_registers is record
gpsr_scl_i : std_logic; gpsr_scl_i : std_logic;
gpsr_sda_i : std_logic; gpsr_sda_i : std_logic;
end record; end record;
constant c_si570_in_registers_init_value: t_si570_in_registers := ( constant c_si570_in_registers_init_value: t_si570_in_registers := (
gpsr_scl_i => '0', gpsr_scl_i => '0',
gpsr_sda_i => '0' gpsr_sda_i => '0'
); );
-- Output registers (WB slave -> user design) -- Output registers (WB slave -> user design)
type t_si570_out_registers is record type t_si570_out_registers is record
rfreql_o : std_logic_vector(31 downto 0); cr_i2c_addr_o : std_logic_vector(7 downto 0);
rfreqh_o : std_logic_vector(7 downto 0); cr_enable_o : std_logic;
gpsr_scl_o : std_logic; cr_gain_o : std_logic_vector(7 downto 0);
gpsr_scl_load_o : std_logic; cr_clk_div_o : std_logic_vector(7 downto 0);
gpsr_sda_o : std_logic; rfreql_o : std_logic_vector(31 downto 0);
gpsr_sda_load_o : std_logic; rfreqh_o : std_logic_vector(7 downto 0);
gpcr_scl_o : std_logic; gpsr_scl_o : std_logic;
gpcr_sda_o : std_logic; gpsr_scl_load_o : std_logic;
end record; gpsr_sda_o : std_logic;
gpsr_sda_load_o : std_logic;
constant c_si570_out_registers_init_value: t_si570_out_registers := ( gpcr_scl_o : std_logic;
rfreql_o => (others => '0'), gpcr_sda_o : std_logic;
rfreqh_o => (others => '0'), end record;
gpsr_scl_o => '0',
gpsr_scl_load_o => '0', constant c_si570_out_registers_init_value: t_si570_out_registers := (
gpsr_sda_o => '0', cr_i2c_addr_o => (others => '0'),
gpsr_sda_load_o => '0', cr_enable_o => '0',
gpcr_scl_o => '0', cr_gain_o => (others => '0'),
gpcr_sda_o => '0' cr_clk_div_o => (others => '0'),
); rfreql_o => (others => '0'),
function "or" (left, right: t_si570_in_registers) return t_si570_in_registers; rfreqh_o => (others => '0'),
function f_x_to_zero (x:std_logic) return std_logic; gpsr_scl_o => '0',
function f_x_to_zero (x:std_logic_vector) return std_logic_vector; gpsr_scl_load_o => '0',
gpsr_sda_o => '0',
gpsr_sda_load_o => '0',
gpcr_scl_o => '0',
gpcr_sda_o => '0'
);
function "or" (left, right: t_si570_in_registers) return t_si570_in_registers;
function f_x_to_zero (x:std_logic) return std_logic;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector;
component si570_if_wb is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(2 downto 0);
wb_dat_i : in std_logic_vector(31 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
wb_err_o : out std_logic;
wb_rty_o : out std_logic;
wb_stall_o : out std_logic;
regs_i : in t_si570_in_registers;
regs_o : out t_si570_out_registers
);
end component;
end package; end package;
package body si570_wbgen2_pkg is package body si570_wbgen2_pkg is
function f_x_to_zero (x:std_logic) return std_logic is function f_x_to_zero (x:std_logic) return std_logic is
begin begin
if x = '1' then if x = '1' then
return '1'; return '1';
else else
return '0'; return '0';
end if; end if;
end function; end function;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector is function f_x_to_zero (x:std_logic_vector) return std_logic_vector is
variable tmp: std_logic_vector(x'length-1 downto 0); variable tmp: std_logic_vector(x'length-1 downto 0);
begin begin
for i in 0 to x'length-1 loop for i in 0 to x'length-1 loop
if x(i) = '1' then if(x(i) = 'X' or x(i) = 'U') then
tmp(i):= '1'; tmp(i):= '0';
else else
tmp(i):= '0'; tmp(i):=x(i);
end if; end if;
end loop; end loop;
return tmp; return tmp;
end function; end function;
function "or" (left, right: t_si570_in_registers) return t_si570_in_registers is function "or" (left, right: t_si570_in_registers) return t_si570_in_registers is
variable tmp: t_si570_in_registers; variable tmp: t_si570_in_registers;
begin begin
tmp.gpsr_scl_i := f_x_to_zero(left.gpsr_scl_i) or f_x_to_zero(right.gpsr_scl_i); tmp.gpsr_scl_i := f_x_to_zero(left.gpsr_scl_i) or f_x_to_zero(right.gpsr_scl_i);
tmp.gpsr_sda_i := f_x_to_zero(left.gpsr_sda_i) or f_x_to_zero(right.gpsr_sda_i); tmp.gpsr_sda_i := f_x_to_zero(left.gpsr_sda_i) or f_x_to_zero(right.gpsr_sda_i);
return tmp; return tmp;
end function; end function;
end package body; end package body;
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- Author : Tomasz Wlostowski -- Author : Tomasz Wlostowski
-- Company : CERN BE-Co-HT -- Company : CERN BE-Co-HT
-- Created : 2010-04-26 -- Created : 2010-04-26
-- Last update: 2013-03-19 -- Last update: 2020-03-14
-- Platform : FPGA-generic -- Platform : FPGA-generic
-- Standard : VHDL '93 -- Standard : VHDL '93
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
...@@ -51,7 +51,10 @@ use work.si570_wbgen2_pkg.all; ...@@ -51,7 +51,10 @@ use work.si570_wbgen2_pkg.all;
entity wr_si57x_interface is entity wr_si57x_interface is
generic ( generic (
g_simulation : integer := 0); g_simulation : integer := 0;
g_sys_clock_freq : integer := 62500000;
g_i2c_freq : integer := 400000
);
port ( port (
clk_sys_i : in std_logic; clk_sys_i : in std_logic;
...@@ -90,7 +93,7 @@ architecture rtl of wr_si57x_interface is ...@@ -90,7 +93,7 @@ architecture rtl of wr_si57x_interface is
port ( port (
rst_n_i : in std_logic; rst_n_i : in std_logic;
clk_sys_i : in std_logic; clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(1 downto 0); wb_adr_i : in std_logic_vector(2 downto 0);
wb_dat_i : in std_logic_vector(31 downto 0); wb_dat_i : in std_logic_vector(31 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0); wb_dat_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic; wb_cyc_i : in std_logic;
...@@ -107,16 +110,20 @@ architecture rtl of wr_si57x_interface is ...@@ -107,16 +110,20 @@ architecture rtl of wr_si57x_interface is
signal regs_out : t_si570_out_registers; signal regs_out : t_si570_out_registers;
signal new_rfreq : std_logic; signal new_rfreq : std_logic;
signal rfreq_base, rfreq_adj, rfreq_current : unsigned(37 downto 0); signal rfreq_base, rfreq_current : unsigned(37 downto 0);
signal tm_dac_value_wr_d : std_logic;
signal i2c_tick : std_logic; signal i2c_tick : std_logic;
signal i2c_divider : unsigned(4 downto 0); signal i2c_divider : unsigned(7 downto 0);
signal scl_int : std_logic; signal scl_int : std_logic;
signal sda_int : std_logic; signal sda_int : std_logic;
signal seq_count : unsigned(8 downto 0); signal seq_count : unsigned(8 downto 0);
signal rfreq_adj_scaled : signed(16 + 8 +1 downto 0);
type t_i2c_transaction is (START, STOP, SEND_BYTE); type t_i2c_transaction is (START, STOP, SEND_BYTE);
...@@ -193,6 +200,14 @@ architecture rtl of wr_si57x_interface is ...@@ -193,6 +200,14 @@ architecture rtl of wr_si57x_interface is
end f_i2c_iterate; end f_i2c_iterate;
function f_sign_extend( x : signed; l : integer ) return unsigned is
variable rv : unsigned(l-1 downto 0);
begin
rv ( x'length-1 downto 0) := unsigned(x);
rv( l-1 downto x'length ) := (others => x(x'length-1));
return rv;
end f_sign_extend;
begin -- rtl begin -- rtl
...@@ -200,7 +215,7 @@ begin -- rtl ...@@ -200,7 +215,7 @@ begin -- rtl
port map ( port map (
rst_n_i => rst_n_i, rst_n_i => rst_n_i,
clk_sys_i => clk_sys_i, clk_sys_i => clk_sys_i,
wb_adr_i => wb_adr_i(3 downto 2), wb_adr_i => wb_adr_i(4 downto 2),
wb_dat_i => wb_dat_i, wb_dat_i => wb_dat_i,
wb_dat_o => wb_dat_o, wb_dat_o => wb_dat_o,
wb_cyc_i => wb_cyc_i, wb_cyc_i => wb_cyc_i,
...@@ -215,9 +230,6 @@ begin -- rtl ...@@ -215,9 +230,6 @@ begin -- rtl
rfreq_base(31 downto 0) <= unsigned(regs_out.rfreql_o); rfreq_base(31 downto 0) <= unsigned(regs_out.rfreql_o);
rfreq_base(37 downto 32) <= unsigned(regs_out.rfreqh_o(5 downto 0)); rfreq_base(37 downto 32) <= unsigned(regs_out.rfreqh_o(5 downto 0));
rfreq_adj (15 downto 0) <= unsigned(tm_dac_value_i(15 downto 0));
rfreq_adj (37 downto 16) <= (others => tm_dac_value_i(15));
n1 <= regs_out.rfreqh_o(7 downto 6); n1 <= regs_out.rfreqh_o(7 downto 6);
p_rfreq : process(clk_sys_i) p_rfreq : process(clk_sys_i)
...@@ -226,10 +238,18 @@ begin -- rtl ...@@ -226,10 +238,18 @@ begin -- rtl
if rst_n_i = '0' then if rst_n_i = '0' then
new_rfreq <= '0'; new_rfreq <= '0';
else else
tm_dac_value_wr_d <= tm_dac_value_wr_i;
if(tm_dac_value_wr_i = '1') then if(tm_dac_value_wr_i = '1') then
rfreq_current <= rfreq_base + rfreq_adj; rfreq_adj_scaled <= (signed('0' & tm_dac_value_i(15 downto 0)) - to_signed(32768, 17)) * signed('0' & regs_out.cr_gain_o);
end if;
if(tm_dac_value_wr_d = '1') then
rfreq_current <= rfreq_base + f_sign_extend(rfreq_adj_scaled, rfreq_base'length);
end if; end if;
new_rfreq <= tm_dac_value_wr_i;
new_rfreq <= tm_dac_value_wr_d and regs_out.cr_enable_o;
end if; end if;
end if; end if;
end process; end process;
...@@ -241,11 +261,12 @@ begin -- rtl ...@@ -241,11 +261,12 @@ begin -- rtl
i2c_divider <= (others => '0'); i2c_divider <= (others => '0');
i2c_tick <= '0'; i2c_tick <= '0';
else else
i2c_divider <= i2c_divider + 1; if(i2c_divider = unsigned(regs_out.cr_clk_div_o)) then
if(i2c_divider = 0) then
i2c_tick <= '1'; i2c_tick <= '1';
i2c_divider <= (others => '0');
else else
i2c_tick <= '0'; i2c_tick <= '0';
i2c_divider <= i2c_divider + 1;
end if; end if;
end if; end if;
end if; end if;
...@@ -268,9 +289,9 @@ begin -- rtl ...@@ -268,9 +289,9 @@ begin -- rtl
end if; end if;
when SI_START0 => when SI_START0 =>
f_i2c_iterate(i2c_tick, seq_count, x"00", START, scl_out_fsm, sda_out_fsm, state, SI_ADDR0); f_i2c_iterate(i2c_tick, seq_count, x"00", START, scl_out_fsm, sda_out_fsm, state, SI_ADDR1);
when SI_ADDR0 => when SI_ADDR0 =>
f_i2c_iterate(i2c_tick, seq_count, x"aa", SEND_BYTE, scl_out_fsm, sda_out_fsm, state, SI_REG0); f_i2c_iterate(i2c_tick, seq_count, regs_out.cr_i2c_addr_o, SEND_BYTE, scl_out_fsm, sda_out_fsm, state, SI_REG0);
when SI_REG0 => when SI_REG0 =>
f_i2c_iterate(i2c_tick, seq_count, x"87", SEND_BYTE, scl_out_fsm, sda_out_fsm, state, SI_FREEZE0); f_i2c_iterate(i2c_tick, seq_count, x"87", SEND_BYTE, scl_out_fsm, sda_out_fsm, state, SI_FREEZE0);
when SI_FREEZE0 => when SI_FREEZE0 =>
...@@ -280,7 +301,7 @@ begin -- rtl ...@@ -280,7 +301,7 @@ begin -- rtl
when SI_START1 => when SI_START1 =>
f_i2c_iterate(i2c_tick, seq_count, x"00", START, scl_out_fsm, sda_out_fsm, state, SI_ADDR1); f_i2c_iterate(i2c_tick, seq_count, x"00", START, scl_out_fsm, sda_out_fsm, state, SI_ADDR1);
when SI_ADDR1 => when SI_ADDR1 =>
f_i2c_iterate(i2c_tick, seq_count, x"aa", SEND_BYTE, scl_out_fsm, sda_out_fsm, state, SI_REG1); f_i2c_iterate(i2c_tick, seq_count, regs_out.cr_i2c_addr_o, SEND_BYTE, scl_out_fsm, sda_out_fsm, state, SI_REG1);
when SI_REG1 => when SI_REG1 =>
f_i2c_iterate(i2c_tick, seq_count, x"08", SEND_BYTE, scl_out_fsm, sda_out_fsm, state, SI_RF0); f_i2c_iterate(i2c_tick, seq_count, x"08", SEND_BYTE, scl_out_fsm, sda_out_fsm, state, SI_RF0);
when SI_RF0 => when SI_RF0 =>
...@@ -299,11 +320,12 @@ begin -- rtl ...@@ -299,11 +320,12 @@ begin -- rtl
f_i2c_iterate(i2c_tick, seq_count, std_logic_vector(rfreq_current(7 downto 0)), SEND_BYTE, scl_out_fsm, sda_out_fsm, state, SI_STOP1); f_i2c_iterate(i2c_tick, seq_count, std_logic_vector(rfreq_current(7 downto 0)), SEND_BYTE, scl_out_fsm, sda_out_fsm, state, SI_STOP1);
when SI_STOP1 => when SI_STOP1 =>
f_i2c_iterate(i2c_tick, seq_count, x"00", STOP, scl_out_fsm, sda_out_fsm, state, SI_START2); f_i2c_iterate(i2c_tick, seq_count, x"00", STOP, scl_out_fsm, sda_out_fsm, state, IDLE);
when SI_START2 => when SI_START2 =>
f_i2c_iterate(i2c_tick, seq_count, x"00", START, scl_out_fsm, sda_out_fsm, state, SI_ADDR2); f_i2c_iterate(i2c_tick, seq_count, x"00", START, scl_out_fsm, sda_out_fsm, state, SI_ADDR2);
when SI_ADDR2 => when SI_ADDR2 =>
f_i2c_iterate(i2c_tick, seq_count, x"aa", SEND_BYTE, scl_out_fsm, sda_out_fsm, state, SI_REG2); f_i2c_iterate(i2c_tick, seq_count, regs_out.cr_i2c_addr_o, SEND_BYTE, scl_out_fsm, sda_out_fsm, state, SI_REG2);
when SI_REG2 => when SI_REG2 =>
f_i2c_iterate(i2c_tick, seq_count, x"87", SEND_BYTE, scl_out_fsm, sda_out_fsm, state, SI_FREEZE2); f_i2c_iterate(i2c_tick, seq_count, x"87", SEND_BYTE, scl_out_fsm, sda_out_fsm, state, SI_FREEZE2);
when SI_FREEZE2 => when SI_FREEZE2 =>
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- Author : Tomasz Wlostowski -- Author : Tomasz Wlostowski
-- Company : CERN BE-Co-HT -- Company : CERN BE-Co-HT
-- Created : 2010-04-26 -- Created : 2010-04-26
-- Last update: 2013-03-19 -- Last update: 2020-03-10
-- Platform : FPGA-generic -- Platform : FPGA-generic
-- Standard : VHDL '93 -- Standard : VHDL '93
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
...@@ -81,7 +81,6 @@ architecture wrapper of xwr_si57x_interface is ...@@ -81,7 +81,6 @@ architecture wrapper of xwr_si57x_interface is
wb_stb_i : in std_logic := '0'; wb_stb_i : in std_logic := '0';
wb_ack_o : out std_logic; wb_ack_o : out std_logic;
wb_err_o : out std_logic; wb_err_o : out std_logic;
wb_rty_o : out std_logic;
wb_stall_o : out std_logic); wb_stall_o : out std_logic);
end component; end component;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment