Commit 2de3a3a1 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

wr_si57x_interface: made it working with SoftPLL on AFCZ.

parent d4a21c3f
Pipeline #173 failed with stages
in 7 seconds
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
--------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------
-- File : si570_if_wb.vhd -- File : si570_if_wb.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
...@@ -18,25 +18,31 @@ use work.si570_wbgen2_pkg.all; ...@@ -18,25 +18,31 @@ use work.si570_wbgen2_pkg.all;
entity si570_if_wb is entity si570_if_wb 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;
wb_sel_i : in std_logic_vector(3 downto 0); wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic; wb_stb_i : in std_logic;
wb_we_i : in std_logic; wb_we_i : in std_logic;
wb_ack_o : out std_logic; wb_ack_o : out std_logic;
wb_stall_o : out std_logic; wb_err_o : out std_logic;
regs_i : in t_si570_in_registers; wb_rty_o : out std_logic;
regs_o : out t_si570_out_registers wb_stall_o : out std_logic;
); regs_i : in t_si570_in_registers;
regs_o : out t_si570_out_registers
);
end si570_if_wb; end si570_if_wb;
architecture syn of si570_if_wb is architecture syn of si570_if_wb is
signal si570_cr_i2c_addr_int : std_logic_vector(7 downto 0);
signal si570_cr_enable_int : std_logic ;
signal si570_cr_gain_int : std_logic_vector(7 downto 0);
signal si570_cr_clk_div_int : std_logic_vector(7 downto 0);
signal si570_rfreql_int : std_logic_vector(31 downto 0); signal si570_rfreql_int : std_logic_vector(31 downto 0);
signal si570_rfreqh_int : std_logic_vector(7 downto 0); signal si570_rfreqh_int : std_logic_vector(7 downto 0);
signal si570_gpcr_scl_dly0 : std_logic ; signal si570_gpcr_scl_dly0 : std_logic ;
...@@ -47,7 +53,7 @@ signal ack_sreg : std_logic_vector(9 downto 0); ...@@ -47,7 +53,7 @@ signal ack_sreg : std_logic_vector(9 downto 0);
signal rddata_reg : std_logic_vector(31 downto 0); signal rddata_reg : std_logic_vector(31 downto 0);
signal wrdata_reg : std_logic_vector(31 downto 0); signal wrdata_reg : std_logic_vector(31 downto 0);
signal bwsel_reg : std_logic_vector(3 downto 0); signal bwsel_reg : std_logic_vector(3 downto 0);
signal rwaddr_reg : std_logic_vector(1 downto 0); signal rwaddr_reg : std_logic_vector(2 downto 0);
signal ack_in_progress : std_logic ; signal ack_in_progress : std_logic ;
signal wr_int : std_logic ; signal wr_int : std_logic ;
signal rd_int : std_logic ; signal rd_int : std_logic ;
...@@ -55,212 +61,241 @@ signal allones : std_logic_vector(31 downto 0); ...@@ -55,212 +61,241 @@ signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0); signal allzeros : std_logic_vector(31 downto 0);
begin begin
-- Some internal signals assignments. For (foreseen) compatibility with other bus standards. -- Some internal signals assignments
wrdata_reg <= wb_dat_i; wrdata_reg <= wb_dat_i;
bwsel_reg <= wb_sel_i;
rd_int <= wb_cyc_i and (wb_stb_i and (not wb_we_i));
wr_int <= wb_cyc_i and (wb_stb_i and wb_we_i);
allones <= (others => '1');
allzeros <= (others => '0');
-- --
-- Main register bank access process. -- Main register bank access process.
process (clk_sys_i, rst_n_i) process (clk_sys_i, rst_n_i)
begin begin
if (rst_n_i = '0') then if (rst_n_i = '0') then
ack_sreg <= "0000000000"; ack_sreg <= "0000000000";
ack_in_progress <= '0'; ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000"; rddata_reg <= "00000000000000000000000000000000";
si570_rfreql_int <= "00000000000000000000000000000000"; si570_cr_i2c_addr_int <= "00000000";
si570_rfreqh_int <= "00000000"; si570_cr_enable_int <= '0';
regs_o.gpsr_scl_load_o <= '0'; si570_cr_gain_int <= "00000000";
regs_o.gpsr_sda_load_o <= '0'; si570_cr_clk_div_int <= "00000000";
si570_gpcr_scl_int <= '0'; si570_rfreql_int <= "00000000000000000000000000000000";
si570_gpcr_sda_int <= '0'; si570_rfreqh_int <= "00000000";
elsif rising_edge(clk_sys_i) then regs_o.gpsr_scl_load_o <= '0';
regs_o.gpsr_sda_load_o <= '0';
si570_gpcr_scl_int <= '0';
si570_gpcr_sda_int <= '0';
elsif rising_edge(clk_sys_i) then
-- advance the ACK generator shift register -- advance the ACK generator shift register
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1); ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
ack_sreg(9) <= '0'; ack_sreg(9) <= '0';
if (ack_in_progress = '1') then if (ack_in_progress = '1') then
if (ack_sreg(0) = '1') then if (ack_sreg(0) = '1') then
regs_o.gpsr_scl_load_o <= '0'; regs_o.gpsr_scl_load_o <= '0';
regs_o.gpsr_sda_load_o <= '0'; regs_o.gpsr_sda_load_o <= '0';
si570_gpcr_scl_int <= '0'; si570_gpcr_scl_int <= '0';
si570_gpcr_sda_int <= '0'; si570_gpcr_sda_int <= '0';
ack_in_progress <= '0'; ack_in_progress <= '0';
else
regs_o.gpsr_scl_load_o <= '0';
regs_o.gpsr_sda_load_o <= '0';
end if;
else else
if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then regs_o.gpsr_scl_load_o <= '0';
case rwaddr_reg(1 downto 0) is regs_o.gpsr_sda_load_o <= '0';
when "00" => end if;
if (wb_we_i = '1') then else
si570_rfreql_int <= wrdata_reg(31 downto 0); if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then
end if; case rwaddr_reg(2 downto 0) is
rddata_reg(31 downto 0) <= si570_rfreql_int; when "000" =>
ack_sreg(0) <= '1'; if (wb_we_i = '1') then
ack_in_progress <= '1'; si570_cr_i2c_addr_int <= wrdata_reg(7 downto 0);
when "01" => si570_cr_enable_int <= wrdata_reg(8);
if (wb_we_i = '1') then si570_cr_gain_int <= wrdata_reg(16 downto 9);
si570_rfreqh_int <= wrdata_reg(7 downto 0); si570_cr_clk_div_int <= wrdata_reg(24 downto 17);
end if; end if;
rddata_reg(7 downto 0) <= si570_rfreqh_int; rddata_reg(7 downto 0) <= si570_cr_i2c_addr_int;
rddata_reg(8) <= 'X'; rddata_reg(8) <= si570_cr_enable_int;
rddata_reg(9) <= 'X'; rddata_reg(16 downto 9) <= si570_cr_gain_int;
rddata_reg(10) <= 'X'; rddata_reg(24 downto 17) <= si570_cr_clk_div_int;
rddata_reg(11) <= 'X'; rddata_reg(25) <= 'X';
rddata_reg(12) <= 'X'; rddata_reg(26) <= 'X';
rddata_reg(13) <= 'X'; rddata_reg(27) <= 'X';
rddata_reg(14) <= 'X'; rddata_reg(28) <= 'X';
rddata_reg(15) <= 'X'; rddata_reg(29) <= 'X';
rddata_reg(16) <= 'X'; rddata_reg(30) <= 'X';
rddata_reg(17) <= 'X'; rddata_reg(31) <= 'X';
rddata_reg(18) <= 'X'; ack_sreg(0) <= '1';
rddata_reg(19) <= 'X'; ack_in_progress <= '1';
rddata_reg(20) <= 'X'; when "001" =>
rddata_reg(21) <= 'X'; if (wb_we_i = '1') then
rddata_reg(22) <= 'X'; si570_rfreql_int <= wrdata_reg(31 downto 0);
rddata_reg(23) <= 'X'; end if;
rddata_reg(24) <= 'X'; rddata_reg(31 downto 0) <= si570_rfreql_int;
rddata_reg(25) <= 'X'; ack_sreg(0) <= '1';
rddata_reg(26) <= 'X'; ack_in_progress <= '1';
rddata_reg(27) <= 'X'; when "010" =>
rddata_reg(28) <= 'X'; if (wb_we_i = '1') then
rddata_reg(29) <= 'X'; si570_rfreqh_int <= wrdata_reg(7 downto 0);
rddata_reg(30) <= 'X'; end if;
rddata_reg(31) <= 'X'; rddata_reg(7 downto 0) <= si570_rfreqh_int;
ack_sreg(0) <= '1'; rddata_reg(8) <= 'X';
ack_in_progress <= '1'; rddata_reg(9) <= 'X';
when "10" => rddata_reg(10) <= 'X';
if (wb_we_i = '1') then rddata_reg(11) <= 'X';
regs_o.gpsr_scl_load_o <= '1'; rddata_reg(12) <= 'X';
regs_o.gpsr_sda_load_o <= '1'; rddata_reg(13) <= 'X';
end if; rddata_reg(14) <= 'X';
rddata_reg(0) <= regs_i.gpsr_scl_i; rddata_reg(15) <= 'X';
rddata_reg(1) <= regs_i.gpsr_sda_i; rddata_reg(16) <= 'X';
rddata_reg(2) <= 'X'; rddata_reg(17) <= 'X';
rddata_reg(3) <= 'X'; rddata_reg(18) <= 'X';
rddata_reg(4) <= 'X'; rddata_reg(19) <= 'X';
rddata_reg(5) <= 'X'; rddata_reg(20) <= 'X';
rddata_reg(6) <= 'X'; rddata_reg(21) <= 'X';
rddata_reg(7) <= 'X'; rddata_reg(22) <= 'X';
rddata_reg(8) <= 'X'; rddata_reg(23) <= 'X';
rddata_reg(9) <= 'X'; rddata_reg(24) <= 'X';
rddata_reg(10) <= 'X'; rddata_reg(25) <= 'X';
rddata_reg(11) <= 'X'; rddata_reg(26) <= 'X';
rddata_reg(12) <= 'X'; rddata_reg(27) <= 'X';
rddata_reg(13) <= 'X'; rddata_reg(28) <= 'X';
rddata_reg(14) <= 'X'; rddata_reg(29) <= 'X';
rddata_reg(15) <= 'X'; rddata_reg(30) <= 'X';
rddata_reg(16) <= 'X'; rddata_reg(31) <= 'X';
rddata_reg(17) <= 'X'; ack_sreg(0) <= '1';
rddata_reg(18) <= 'X'; ack_in_progress <= '1';
rddata_reg(19) <= 'X'; when "011" =>
rddata_reg(20) <= 'X'; if (wb_we_i = '1') then
rddata_reg(21) <= 'X'; regs_o.gpsr_scl_load_o <= '1';
rddata_reg(22) <= 'X'; regs_o.gpsr_sda_load_o <= '1';
rddata_reg(23) <= 'X'; end if;
rddata_reg(24) <= 'X'; rddata_reg(0) <= regs_i.gpsr_scl_i;
rddata_reg(25) <= 'X'; rddata_reg(1) <= regs_i.gpsr_sda_i;
rddata_reg(26) <= 'X'; rddata_reg(2) <= 'X';
rddata_reg(27) <= 'X'; rddata_reg(3) <= 'X';
rddata_reg(28) <= 'X'; rddata_reg(4) <= 'X';
rddata_reg(29) <= 'X'; rddata_reg(5) <= 'X';
rddata_reg(30) <= 'X'; rddata_reg(6) <= 'X';
rddata_reg(31) <= 'X'; rddata_reg(7) <= 'X';
ack_sreg(0) <= '1'; rddata_reg(8) <= 'X';
ack_in_progress <= '1'; rddata_reg(9) <= 'X';
when "11" => rddata_reg(10) <= 'X';
if (wb_we_i = '1') then rddata_reg(11) <= 'X';
si570_gpcr_scl_int <= wrdata_reg(0); rddata_reg(12) <= 'X';
si570_gpcr_sda_int <= wrdata_reg(1); rddata_reg(13) <= 'X';
end if; rddata_reg(14) <= 'X';
rddata_reg(0) <= '0'; rddata_reg(15) <= 'X';
rddata_reg(1) <= '0'; rddata_reg(16) <= 'X';
rddata_reg(0) <= 'X'; rddata_reg(17) <= 'X';
rddata_reg(1) <= 'X'; rddata_reg(18) <= 'X';
rddata_reg(2) <= 'X'; rddata_reg(19) <= 'X';
rddata_reg(3) <= 'X'; rddata_reg(20) <= 'X';
rddata_reg(4) <= 'X'; rddata_reg(21) <= 'X';
rddata_reg(5) <= 'X'; rddata_reg(22) <= 'X';
rddata_reg(6) <= 'X'; rddata_reg(23) <= 'X';
rddata_reg(7) <= 'X'; rddata_reg(24) <= 'X';
rddata_reg(8) <= 'X'; rddata_reg(25) <= 'X';
rddata_reg(9) <= 'X'; rddata_reg(26) <= 'X';
rddata_reg(10) <= 'X'; rddata_reg(27) <= 'X';
rddata_reg(11) <= 'X'; rddata_reg(28) <= 'X';
rddata_reg(12) <= 'X'; rddata_reg(29) <= 'X';
rddata_reg(13) <= 'X'; rddata_reg(30) <= 'X';
rddata_reg(14) <= 'X'; rddata_reg(31) <= 'X';
rddata_reg(15) <= 'X'; ack_sreg(0) <= '1';
rddata_reg(16) <= 'X'; ack_in_progress <= '1';
rddata_reg(17) <= 'X'; when "100" =>
rddata_reg(18) <= 'X'; if (wb_we_i = '1') then
rddata_reg(19) <= 'X'; si570_gpcr_scl_int <= wrdata_reg(0);
rddata_reg(20) <= 'X'; si570_gpcr_sda_int <= wrdata_reg(1);
rddata_reg(21) <= 'X'; end if;
rddata_reg(22) <= 'X'; rddata_reg(0) <= '0';
rddata_reg(23) <= 'X'; rddata_reg(1) <= '0';
rddata_reg(24) <= 'X'; rddata_reg(0) <= 'X';
rddata_reg(25) <= 'X'; rddata_reg(1) <= 'X';
rddata_reg(26) <= 'X'; rddata_reg(2) <= 'X';
rddata_reg(27) <= 'X'; rddata_reg(3) <= 'X';
rddata_reg(28) <= 'X'; rddata_reg(4) <= 'X';
rddata_reg(29) <= 'X'; rddata_reg(5) <= 'X';
rddata_reg(30) <= 'X'; rddata_reg(6) <= 'X';
rddata_reg(31) <= 'X'; rddata_reg(7) <= 'X';
ack_sreg(2) <= '1'; rddata_reg(8) <= 'X';
ack_in_progress <= '1'; rddata_reg(9) <= 'X';
when others => rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
ack_sreg(2) <= '1';
ack_in_progress <= '1';
when others =>
-- prevent the slave from hanging the bus on invalid address -- prevent the slave from hanging the bus on invalid address
ack_in_progress <= '1'; ack_in_progress <= '1';
ack_sreg(0) <= '1'; ack_sreg(0) <= '1';
end case; end case;
end if;
end if; end if;
end if; end if;
end process; end if;
end process;
-- Drive the data output bus -- Drive the data output bus
wb_dat_o <= rddata_reg; wb_dat_o <= rddata_reg;
-- Si57x Address
regs_o.cr_i2c_addr_o <= si570_cr_i2c_addr_int;
-- Si57x SPLL input enable
regs_o.cr_enable_o <= si570_cr_enable_int;
-- RFREQ gain/scalefactor
regs_o.cr_gain_o <= si570_cr_gain_int;
-- I2C Clock Divider
regs_o.cr_clk_div_o <= si570_cr_clk_div_int;
-- RFREQ low part -- RFREQ low part
regs_o.rfreql_o <= si570_rfreql_int; regs_o.rfreql_o <= si570_rfreql_int;
-- RFREQ hi part -- RFREQ hi part
regs_o.rfreqh_o <= si570_rfreqh_int; regs_o.rfreqh_o <= si570_rfreqh_int;
-- SIlabs I2C bitbanged SCL -- SIlabs I2C bitbanged SCL
regs_o.gpsr_scl_o <= wrdata_reg(0); regs_o.gpsr_scl_o <= wrdata_reg(0);
-- SIlabs I2C bitbanged SDA -- SIlabs I2C bitbanged SDA
regs_o.gpsr_sda_o <= wrdata_reg(1); regs_o.gpsr_sda_o <= wrdata_reg(1);
-- SILabs I2C bitbanged SCL -- SILabs I2C bitbanged SCL
process (clk_sys_i, rst_n_i) process (clk_sys_i, rst_n_i)
begin begin
if (rst_n_i = '0') then if (rst_n_i = '0') then
si570_gpcr_scl_dly0 <= '0'; si570_gpcr_scl_dly0 <= '0';
regs_o.gpcr_scl_o <= '0'; regs_o.gpcr_scl_o <= '0';
elsif rising_edge(clk_sys_i) then elsif rising_edge(clk_sys_i) then
si570_gpcr_scl_dly0 <= si570_gpcr_scl_int; si570_gpcr_scl_dly0 <= si570_gpcr_scl_int;
regs_o.gpcr_scl_o <= si570_gpcr_scl_int and (not si570_gpcr_scl_dly0); regs_o.gpcr_scl_o <= si570_gpcr_scl_int and (not si570_gpcr_scl_dly0);
end if; end if;
end process; end process;
-- SIlabs I2C bitbanged SDA -- SIlabs I2C bitbanged SDA
process (clk_sys_i, rst_n_i) process (clk_sys_i, rst_n_i)
begin begin
if (rst_n_i = '0') then if (rst_n_i = '0') then
si570_gpcr_sda_dly0 <= '0'; si570_gpcr_sda_dly0 <= '0';
regs_o.gpcr_sda_o <= '0'; regs_o.gpcr_sda_o <= '0';
elsif rising_edge(clk_sys_i) then elsif rising_edge(clk_sys_i) then
si570_gpcr_sda_dly0 <= si570_gpcr_sda_int; si570_gpcr_sda_dly0 <= si570_gpcr_sda_int;
regs_o.gpcr_sda_o <= si570_gpcr_sda_int and (not si570_gpcr_sda_dly0); regs_o.gpcr_sda_o <= si570_gpcr_sda_int and (not si570_gpcr_sda_dly0);
end if; end if;
end process; end process;
rwaddr_reg <= wb_adr_i; rwaddr_reg <= wb_adr_i;
wb_stall_o <= (not ack_sreg(0)) and (wb_stb_i and wb_cyc_i); wb_stall_o <= (not ack_sreg(0)) and (wb_stb_i and wb_cyc_i);
wb_err_o <= '0';
wb_rty_o <= '0';
-- ACK signal generation. Just pass the LSB of ACK counter. -- ACK signal generation. Just pass the LSB of ACK counter.
wb_ack_o <= ack_sreg(0); wb_ack_o <= ack_sreg(0);
end syn; end syn;
...@@ -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