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 @@
---------------------------------------------------------------------------------------
-- File : si570_if_wb.vhd
-- 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
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE si570_if_wb.wb
......@@ -18,25 +18,31 @@ use work.si570_wbgen2_pkg.all;
entity si570_if_wb is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(1 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_stall_o : out std_logic;
regs_i : in t_si570_in_registers;
regs_o : out t_si570_out_registers
);
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 si570_if_wb;
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_rfreqh_int : std_logic_vector(7 downto 0);
signal si570_gpcr_scl_dly0 : std_logic ;
......@@ -47,7 +53,7 @@ signal ack_sreg : std_logic_vector(9 downto 0);
signal rddata_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 rwaddr_reg : std_logic_vector(1 downto 0);
signal rwaddr_reg : std_logic_vector(2 downto 0);
signal ack_in_progress : std_logic ;
signal wr_int : std_logic ;
signal rd_int : std_logic ;
......@@ -55,212 +61,241 @@ signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments. For (foreseen) compatibility with other bus standards.
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');
-- Some internal signals assignments
wrdata_reg <= wb_dat_i;
--
-- Main register bank access process.
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
ack_sreg <= "0000000000";
ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000";
si570_rfreql_int <= "00000000000000000000000000000000";
si570_rfreqh_int <= "00000000";
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
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
ack_sreg <= "0000000000";
ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000";
si570_cr_i2c_addr_int <= "00000000";
si570_cr_enable_int <= '0';
si570_cr_gain_int <= "00000000";
si570_cr_clk_div_int <= "00000000";
si570_rfreql_int <= "00000000000000000000000000000000";
si570_rfreqh_int <= "00000000";
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
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
ack_sreg(9) <= '0';
if (ack_in_progress = '1') then
if (ack_sreg(0) = '1') 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';
ack_in_progress <= '0';
else
regs_o.gpsr_scl_load_o <= '0';
regs_o.gpsr_sda_load_o <= '0';
end if;
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
ack_sreg(9) <= '0';
if (ack_in_progress = '1') then
if (ack_sreg(0) = '1') 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';
ack_in_progress <= '0';
else
if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then
case rwaddr_reg(1 downto 0) is
when "00" =>
if (wb_we_i = '1') then
si570_rfreql_int <= wrdata_reg(31 downto 0);
end if;
rddata_reg(31 downto 0) <= si570_rfreql_int;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "01" =>
if (wb_we_i = '1') then
si570_rfreqh_int <= wrdata_reg(7 downto 0);
end if;
rddata_reg(7 downto 0) <= si570_rfreqh_int;
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
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(0) <= '1';
ack_in_progress <= '1';
when "10" =>
if (wb_we_i = '1') then
regs_o.gpsr_scl_load_o <= '1';
regs_o.gpsr_sda_load_o <= '1';
end if;
rddata_reg(0) <= regs_i.gpsr_scl_i;
rddata_reg(1) <= regs_i.gpsr_sda_i;
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
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(0) <= '1';
ack_in_progress <= '1';
when "11" =>
if (wb_we_i = '1') then
si570_gpcr_scl_int <= wrdata_reg(0);
si570_gpcr_sda_int <= wrdata_reg(1);
end if;
rddata_reg(0) <= '0';
rddata_reg(1) <= '0';
rddata_reg(0) <= 'X';
rddata_reg(1) <= 'X';
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
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 =>
regs_o.gpsr_scl_load_o <= '0';
regs_o.gpsr_sda_load_o <= '0';
end if;
else
if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then
case rwaddr_reg(2 downto 0) is
when "000" =>
if (wb_we_i = '1') then
si570_cr_i2c_addr_int <= wrdata_reg(7 downto 0);
si570_cr_enable_int <= wrdata_reg(8);
si570_cr_gain_int <= wrdata_reg(16 downto 9);
si570_cr_clk_div_int <= wrdata_reg(24 downto 17);
end if;
rddata_reg(7 downto 0) <= si570_cr_i2c_addr_int;
rddata_reg(8) <= si570_cr_enable_int;
rddata_reg(16 downto 9) <= si570_cr_gain_int;
rddata_reg(24 downto 17) <= si570_cr_clk_div_int;
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(0) <= '1';
ack_in_progress <= '1';
when "001" =>
if (wb_we_i = '1') then
si570_rfreql_int <= wrdata_reg(31 downto 0);
end if;
rddata_reg(31 downto 0) <= si570_rfreql_int;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "010" =>
if (wb_we_i = '1') then
si570_rfreqh_int <= wrdata_reg(7 downto 0);
end if;
rddata_reg(7 downto 0) <= si570_rfreqh_int;
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
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(0) <= '1';
ack_in_progress <= '1';
when "011" =>
if (wb_we_i = '1') then
regs_o.gpsr_scl_load_o <= '1';
regs_o.gpsr_sda_load_o <= '1';
end if;
rddata_reg(0) <= regs_i.gpsr_scl_i;
rddata_reg(1) <= regs_i.gpsr_sda_i;
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
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(0) <= '1';
ack_in_progress <= '1';
when "100" =>
if (wb_we_i = '1') then
si570_gpcr_scl_int <= wrdata_reg(0);
si570_gpcr_sda_int <= wrdata_reg(1);
end if;
rddata_reg(0) <= '0';
rddata_reg(1) <= '0';
rddata_reg(0) <= 'X';
rddata_reg(1) <= 'X';
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
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
ack_in_progress <= '1';
ack_sreg(0) <= '1';
end case;
end if;
ack_in_progress <= '1';
ack_sreg(0) <= '1';
end case;
end if;
end if;
end process;
end if;
end process;
-- 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
regs_o.rfreql_o <= si570_rfreql_int;
regs_o.rfreql_o <= si570_rfreql_int;
-- RFREQ hi part
regs_o.rfreqh_o <= si570_rfreqh_int;
regs_o.rfreqh_o <= si570_rfreqh_int;
-- SIlabs I2C bitbanged SCL
regs_o.gpsr_scl_o <= wrdata_reg(0);
regs_o.gpsr_scl_o <= wrdata_reg(0);
-- SIlabs I2C bitbanged SDA
regs_o.gpsr_sda_o <= wrdata_reg(1);
regs_o.gpsr_sda_o <= wrdata_reg(1);
-- SILabs I2C bitbanged SCL
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
si570_gpcr_scl_dly0 <= '0';
regs_o.gpcr_scl_o <= '0';
elsif rising_edge(clk_sys_i) then
si570_gpcr_scl_dly0 <= si570_gpcr_scl_int;
regs_o.gpcr_scl_o <= si570_gpcr_scl_int and (not si570_gpcr_scl_dly0);
end if;
end process;
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
si570_gpcr_scl_dly0 <= '0';
regs_o.gpcr_scl_o <= '0';
elsif rising_edge(clk_sys_i) then
si570_gpcr_scl_dly0 <= si570_gpcr_scl_int;
regs_o.gpcr_scl_o <= si570_gpcr_scl_int and (not si570_gpcr_scl_dly0);
end if;
end process;
-- SIlabs I2C bitbanged SDA
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
si570_gpcr_sda_dly0 <= '0';
regs_o.gpcr_sda_o <= '0';
elsif rising_edge(clk_sys_i) then
si570_gpcr_sda_dly0 <= si570_gpcr_sda_int;
regs_o.gpcr_sda_o <= si570_gpcr_sda_int and (not si570_gpcr_sda_dly0);
end if;
end process;
rwaddr_reg <= wb_adr_i;
wb_stall_o <= (not ack_sreg(0)) and (wb_stb_i and wb_cyc_i);
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
si570_gpcr_sda_dly0 <= '0';
regs_o.gpcr_sda_o <= '0';
elsif rising_edge(clk_sys_i) then
si570_gpcr_sda_dly0 <= si570_gpcr_sda_int;
regs_o.gpcr_sda_o <= si570_gpcr_sda_int and (not si570_gpcr_sda_dly0);
end if;
end process;
rwaddr_reg <= wb_adr_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.
wb_ack_o <= ack_sreg(0);
wb_ack_o <= ack_sreg(0);
end syn;
......@@ -4,6 +4,47 @@ peripheral {
name = "silabs interface";
hdl_entity = "si570_if_wb";
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 {
name = "RFREQ low part";
......@@ -31,6 +72,7 @@ peripheral {
};
};
reg {
name = "GPIO Set/Readback Register";
prefix = "GPSR";
......
......@@ -3,7 +3,7 @@
---------------------------------------------------------------------------------------
-- File : si570_if_wbgen2_pkg.vhd
-- 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
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE si570_if_wb.wb
......@@ -22,67 +22,100 @@ package si570_wbgen2_pkg is
type t_si570_in_registers is record
gpsr_scl_i : std_logic;
gpsr_sda_i : std_logic;
end record;
end record;
constant c_si570_in_registers_init_value: t_si570_in_registers := (
gpsr_scl_i => '0',
gpsr_sda_i => '0'
);
-- Output registers (WB slave -> user design)
type t_si570_out_registers is record
rfreql_o : std_logic_vector(31 downto 0);
rfreqh_o : std_logic_vector(7 downto 0);
gpsr_scl_o : std_logic;
gpsr_scl_load_o : std_logic;
gpsr_sda_o : std_logic;
gpsr_sda_load_o : std_logic;
gpcr_scl_o : std_logic;
gpcr_sda_o : std_logic;
end record;
constant c_si570_out_registers_init_value: t_si570_out_registers := (
rfreql_o => (others => '0'),
rfreqh_o => (others => '0'),
gpsr_scl_o => '0',
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;
);
-- Output registers (WB slave -> user design)
type t_si570_out_registers is record
cr_i2c_addr_o : std_logic_vector(7 downto 0);
cr_enable_o : std_logic;
cr_gain_o : std_logic_vector(7 downto 0);
cr_clk_div_o : std_logic_vector(7 downto 0);
rfreql_o : std_logic_vector(31 downto 0);
rfreqh_o : std_logic_vector(7 downto 0);
gpsr_scl_o : std_logic;
gpsr_scl_load_o : std_logic;
gpsr_sda_o : std_logic;
gpsr_sda_load_o : std_logic;
gpcr_scl_o : std_logic;
gpcr_sda_o : std_logic;
end record;
constant c_si570_out_registers_init_value: t_si570_out_registers := (
cr_i2c_addr_o => (others => '0'),
cr_enable_o => '0',
cr_gain_o => (others => '0'),
cr_clk_div_o => (others => '0'),
rfreql_o => (others => '0'),
rfreqh_o => (others => '0'),
gpsr_scl_o => '0',
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;
package body si570_wbgen2_pkg is
function f_x_to_zero (x:std_logic) return std_logic is
begin
if x = '1' then
return '1';
else
return '0';
end if;
if x = '1' then
return '1';
else
return '0';
end if;
end function;
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
for i in 0 to x'length-1 loop
if x(i) = '1' then
tmp(i):= '1';
else
tmp(i):= '0';
end if;
end loop;
return tmp;
for i in 0 to x'length-1 loop
if(x(i) = 'X' or x(i) = 'U') then
tmp(i):= '0';
else
tmp(i):=x(i);
end if;
end loop;
return tmp;
end function;
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
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);
return tmp;
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);
return tmp;
end function;
end package body;
......@@ -6,7 +6,7 @@
-- Author : Tomasz Wlostowski
-- Company : CERN BE-Co-HT
-- Created : 2010-04-26
-- Last update: 2013-03-19
-- Last update: 2020-03-14
-- Platform : FPGA-generic
-- Standard : VHDL '93
-------------------------------------------------------------------------------
......@@ -51,7 +51,10 @@ use work.si570_wbgen2_pkg.all;
entity wr_si57x_interface is
generic (
g_simulation : integer := 0);
g_simulation : integer := 0;
g_sys_clock_freq : integer := 62500000;
g_i2c_freq : integer := 400000
);
port (
clk_sys_i : in std_logic;
......@@ -90,7 +93,7 @@ architecture rtl of wr_si57x_interface is
port (
rst_n_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_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
......@@ -107,16 +110,20 @@ architecture rtl of wr_si57x_interface is
signal regs_out : t_si570_out_registers;
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_divider : unsigned(4 downto 0);
signal i2c_divider : unsigned(7 downto 0);
signal scl_int : std_logic;
signal sda_int : std_logic;
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);
......@@ -193,6 +200,14 @@ architecture rtl of wr_si57x_interface is
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
......@@ -200,7 +215,7 @@ begin -- rtl
port map (
rst_n_i => rst_n_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_o => wb_dat_o,
wb_cyc_i => wb_cyc_i,
......@@ -215,9 +230,6 @@ begin -- rtl
rfreq_base(31 downto 0) <= unsigned(regs_out.rfreql_o);
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);
p_rfreq : process(clk_sys_i)
......@@ -226,10 +238,18 @@ begin -- rtl
if rst_n_i = '0' then
new_rfreq <= '0';
else
tm_dac_value_wr_d <= tm_dac_value_wr_i;
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;
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 process;
......@@ -241,11 +261,12 @@ begin -- rtl
i2c_divider <= (others => '0');
i2c_tick <= '0';
else
i2c_divider <= i2c_divider + 1;
if(i2c_divider = 0) then
if(i2c_divider = unsigned(regs_out.cr_clk_div_o)) then
i2c_tick <= '1';
i2c_divider <= (others => '0');
else
i2c_tick <= '0';
i2c_divider <= i2c_divider + 1;
end if;
end if;
end if;
......@@ -268,9 +289,9 @@ begin -- rtl
end if;
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 =>
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 =>
f_i2c_iterate(i2c_tick, seq_count, x"87", SEND_BYTE, scl_out_fsm, sda_out_fsm, state, SI_FREEZE0);
when SI_FREEZE0 =>
......@@ -280,7 +301,7 @@ begin -- rtl
when SI_START1 =>
f_i2c_iterate(i2c_tick, seq_count, x"00", START, scl_out_fsm, sda_out_fsm, state, 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 =>
f_i2c_iterate(i2c_tick, seq_count, x"08", SEND_BYTE, scl_out_fsm, sda_out_fsm, state, SI_RF0);
when SI_RF0 =>
......@@ -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);
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 =>
f_i2c_iterate(i2c_tick, seq_count, x"00", START, scl_out_fsm, sda_out_fsm, state, 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 =>
f_i2c_iterate(i2c_tick, seq_count, x"87", SEND_BYTE, scl_out_fsm, sda_out_fsm, state, SI_FREEZE2);
when SI_FREEZE2 =>
......
......@@ -6,7 +6,7 @@
-- Author : Tomasz Wlostowski
-- Company : CERN BE-Co-HT
-- Created : 2010-04-26
-- Last update: 2013-03-19
-- Last update: 2020-03-10
-- Platform : FPGA-generic
-- Standard : VHDL '93
-------------------------------------------------------------------------------
......@@ -81,7 +81,6 @@ architecture wrapper of xwr_si57x_interface is
wb_stb_i : in std_logic := '0';
wb_ack_o : out std_logic;
wb_err_o : out std_logic;
wb_rty_o : out std_logic;
wb_stall_o : out std_logic);
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