Commit 271a30e4 authored by Theodor-Adrian Stana's avatar Theodor-Adrian Stana

Fixed active file indentations & some naming.

parent 494c7f90
...@@ -76,6 +76,7 @@ ...@@ -76,6 +76,7 @@
<transforms xmlns="http://www.xilinx.com/XMLSchema"> <transforms xmlns="http://www.xilinx.com/XMLSchema">
<transform xil_pn:end_ts="1361359864" xil_pn:name="TRAN_copyInitialToXSTAbstractSynthesis" xil_pn:start_ts="1361359864"> <transform xil_pn:end_ts="1361359864" xil_pn:name="TRAN_copyInitialToXSTAbstractSynthesis" xil_pn:start_ts="1361359864">
<status xil_pn:value="SuccessfullyRun"/> <status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform> </transform>
<transform xil_pn:end_ts="1361359864" xil_pn:name="TRAN_schematicsToHdl" xil_pn:prop_ck="1112065682908869959" xil_pn:start_ts="1361359864"> <transform xil_pn:end_ts="1361359864" xil_pn:name="TRAN_schematicsToHdl" xil_pn:prop_ck="1112065682908869959" xil_pn:start_ts="1361359864">
<status xil_pn:value="SuccessfullyRun"/> <status xil_pn:value="SuccessfullyRun"/>
...@@ -101,7 +102,7 @@ ...@@ -101,7 +102,7 @@
<status xil_pn:value="SuccessfullyRun"/> <status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/> <status xil_pn:value="ReadyToRun"/>
</transform> </transform>
<transform xil_pn:end_ts="1361359880" xil_pn:in_ck="2481835375757340990" xil_pn:name="TRANEXT_xstsynthesize_spartan6" xil_pn:prop_ck="-2283666785813565085" xil_pn:start_ts="1361359864"> <transform xil_pn:end_ts="1361383048" xil_pn:in_ck="2481835375757340990" xil_pn:name="TRANEXT_xstsynthesize_spartan6" xil_pn:prop_ck="-2283666785813565085" xil_pn:start_ts="1361383029">
<status xil_pn:value="SuccessfullyRun"/> <status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="WarningsGenerated"/> <status xil_pn:value="WarningsGenerated"/>
<status xil_pn:value="ReadyToRun"/> <status xil_pn:value="ReadyToRun"/>
...@@ -123,7 +124,7 @@ ...@@ -123,7 +124,7 @@
<status xil_pn:value="SuccessfullyRun"/> <status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/> <status xil_pn:value="ReadyToRun"/>
</transform> </transform>
<transform xil_pn:end_ts="1361359886" xil_pn:in_ck="-662876564851204570" xil_pn:name="TRANEXT_ngdbuild_FPGA" xil_pn:prop_ck="-883419811469213931" xil_pn:start_ts="1361359880"> <transform xil_pn:end_ts="1361383079" xil_pn:in_ck="-662876564851204570" xil_pn:name="TRANEXT_ngdbuild_FPGA" xil_pn:prop_ck="-883419811469213931" xil_pn:start_ts="1361383072">
<status xil_pn:value="SuccessfullyRun"/> <status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="WarningsGenerated"/> <status xil_pn:value="WarningsGenerated"/>
<status xil_pn:value="ReadyToRun"/> <status xil_pn:value="ReadyToRun"/>
...@@ -133,11 +134,9 @@ ...@@ -133,11 +134,9 @@
<outfile xil_pn:name="image1_top.ngd"/> <outfile xil_pn:name="image1_top.ngd"/>
<outfile xil_pn:name="image1_top_ngdbuild.xrpt"/> <outfile xil_pn:name="image1_top_ngdbuild.xrpt"/>
</transform> </transform>
<transform xil_pn:end_ts="1361359919" xil_pn:in_ck="-662876564851204569" xil_pn:name="TRANEXT_map_spartan6" xil_pn:prop_ck="4807565132092422995" xil_pn:start_ts="1361359886"> <transform xil_pn:end_ts="1361383118" xil_pn:in_ck="-662876564851204569" xil_pn:name="TRANEXT_map_spartan6" xil_pn:prop_ck="4807565132092422995" xil_pn:start_ts="1361383079">
<status xil_pn:value="SuccessfullyRun"/> <status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/> <status xil_pn:value="ReadyToRun"/>
<status xil_pn:value="OutOfDateForOutputs"/>
<status xil_pn:value="OutputChanged"/>
<outfile xil_pn:name="_xmsgs/map.xmsgs"/> <outfile xil_pn:name="_xmsgs/map.xmsgs"/>
<outfile xil_pn:name="image1_top.pcf"/> <outfile xil_pn:name="image1_top.pcf"/>
<outfile xil_pn:name="image1_top_map.map"/> <outfile xil_pn:name="image1_top_map.map"/>
...@@ -148,7 +147,7 @@ ...@@ -148,7 +147,7 @@
<outfile xil_pn:name="image1_top_summary.xml"/> <outfile xil_pn:name="image1_top_summary.xml"/>
<outfile xil_pn:name="image1_top_usage.xml"/> <outfile xil_pn:name="image1_top_usage.xml"/>
</transform> </transform>
<transform xil_pn:end_ts="1361359953" xil_pn:in_ck="7206782387671427264" xil_pn:name="TRANEXT_par_spartan6" xil_pn:prop_ck="3214117756270688487" xil_pn:start_ts="1361359919"> <transform xil_pn:end_ts="1361383152" xil_pn:in_ck="7206782387671427264" xil_pn:name="TRANEXT_par_spartan6" xil_pn:prop_ck="3214117756270688487" xil_pn:start_ts="1361383118">
<status xil_pn:value="SuccessfullyRun"/> <status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="WarningsGenerated"/> <status xil_pn:value="WarningsGenerated"/>
<status xil_pn:value="ReadyToRun"/> <status xil_pn:value="ReadyToRun"/>
...@@ -163,7 +162,7 @@ ...@@ -163,7 +162,7 @@
<outfile xil_pn:name="image1_top_pad.txt"/> <outfile xil_pn:name="image1_top_pad.txt"/>
<outfile xil_pn:name="image1_top_par.xrpt"/> <outfile xil_pn:name="image1_top_par.xrpt"/>
</transform> </transform>
<transform xil_pn:end_ts="1361359972" xil_pn:in_ck="7803888278084704457" xil_pn:name="TRANEXT_bitFile_spartan6" xil_pn:prop_ck="396117104113915555" xil_pn:start_ts="1361359953"> <transform xil_pn:end_ts="1361383171" xil_pn:in_ck="7803888278084704457" xil_pn:name="TRANEXT_bitFile_spartan6" xil_pn:prop_ck="396117104113915555" xil_pn:start_ts="1361383152">
<status xil_pn:value="SuccessfullyRun"/> <status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/> <status xil_pn:value="ReadyToRun"/>
<outfile xil_pn:name="_xmsgs/bitgen.xmsgs"/> <outfile xil_pn:name="_xmsgs/bitgen.xmsgs"/>
...@@ -174,15 +173,13 @@ ...@@ -174,15 +173,13 @@
<outfile xil_pn:name="webtalk.log"/> <outfile xil_pn:name="webtalk.log"/>
<outfile xil_pn:name="webtalk_pn.xml"/> <outfile xil_pn:name="webtalk_pn.xml"/>
</transform> </transform>
<transform xil_pn:end_ts="1361359976" xil_pn:in_ck="7803888278084691603" xil_pn:name="TRAN_configureTargetDevice" xil_pn:prop_ck="4629081730735892968" xil_pn:start_ts="1361359976"> <transform xil_pn:end_ts="1361383284" xil_pn:in_ck="7803888278084691603" xil_pn:name="TRAN_configureTargetDevice" xil_pn:prop_ck="4629081730735892968" xil_pn:start_ts="1361383284">
<status xil_pn:value="SuccessfullyRun"/> <status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/> <status xil_pn:value="ReadyToRun"/>
<status xil_pn:value="OutOfDateForOutputs"/>
<status xil_pn:value="OutputChanged"/>
<outfile xil_pn:name="_impactbatch.log"/> <outfile xil_pn:name="_impactbatch.log"/>
<outfile xil_pn:name="ise_impact.cmd"/> <outfile xil_pn:name="ise_impact.cmd"/>
</transform> </transform>
<transform xil_pn:end_ts="1361359953" xil_pn:in_ck="-662876564851204701" xil_pn:name="TRAN_postRouteTrce" xil_pn:prop_ck="445577401284416185" xil_pn:start_ts="1361359944"> <transform xil_pn:end_ts="1361383152" xil_pn:in_ck="-662876564851204701" xil_pn:name="TRAN_postRouteTrce" xil_pn:prop_ck="445577401284416185" xil_pn:start_ts="1361383144">
<status xil_pn:value="FailedRun"/> <status xil_pn:value="FailedRun"/>
<status xil_pn:value="ReadyToRun"/> <status xil_pn:value="ReadyToRun"/>
<outfile xil_pn:name="_xmsgs/trce.xmsgs"/> <outfile xil_pn:name="_xmsgs/trce.xmsgs"/>
......
...@@ -46,67 +46,86 @@ use work.bicolor_led_ctrl_pkg.ALL; ...@@ -46,67 +46,86 @@ use work.bicolor_led_ctrl_pkg.ALL;
use UNISIM.VCOMPONENTS.ALL; use UNISIM.VCOMPONENTS.ALL;
entity image1_core is entity image1_core is
generic(g_NUMBER_OF_CHANNELS : NATURAL := 6); generic
port (rst_n : in STD_LOGIC; (
clk_20MHz_i : in STD_LOGIC; g_NUMBER_OF_CHANNELS : NATURAL := 6
clk_125MHz_i : in STD_LOGIC; );
--! LEDs port
led_array_o : out t_led_array_o; (
--! I/Os for pulses rst_n : in STD_LOGIC;
led_front_n : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1); clk_20MHz_i : in STD_LOGIC;
led_rear_n : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1); clk_125MHz_i : in STD_LOGIC;
pulse_i_front_n : in STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
pulse_o_front : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1); --! LEDs
pulse_i_rear : in STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1); led_array_o : out t_led_array_o;
pulse_o_rear : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1); led_front_n : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
inv_i_n : in STD_LOGIC_VECTOR(4 downto 1); led_rear_n : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
inv_o : out STD_LOGIC_VECTOR(4 downto 1);
--! Lines for the i2c_slave --! I/Os for pulses
i2c_slave_i : in t_i2c_slave_i; pulse_i_front_n : in STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
i2c_slave_o : out t_i2c_slave_o; pulse_o_front : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
--! FPGA Geographical address pins (reused for i2c address) pulse_i_rear : in STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
FPGA_GA : in STD_LOGIC_VECTOR(4 downto 0); pulse_o_rear : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
FPGA_GAP : in STD_LOGIC; inv_i_n : in STD_LOGIC_VECTOR(4 downto 1);
--! Pins of the SPI interface to write into the Flash memory inv_o : out STD_LOGIC_VECTOR(4 downto 1);
spi_master_i : in t_spi_master_i;
spi_master_o : out t_spi_master_o; --! Lines for the i2c_slave
--! RTM identifiers, should match with the expected values i2c_slave_i : in t_i2c_slave_i;
--! TODO: add matching i2c_slave_o : out t_i2c_slave_o;
fpga_o_en : out STD_LOGIC;
fpga_o_blo_en : out STD_LOGIC; --! FPGA Geographical address pins (reused for i2c address)
fpga_o_ttl_en : out STD_LOGIC; FPGA_GA : in STD_LOGIC_VECTOR(4 downto 0);
fpga_o_inv_en : out STD_LOGIC; FPGA_GAP : in STD_LOGIC;
level_i : in STD_LOGIC;
switch_i : in STD_LOGIC;--! General enable --! Pins of the SPI interface to write into the Flash memory
manual_rst_n_o : out STD_LOGIC;--! It allows power sequencing of the spi_master_i : in t_spi_master_i;
--! 24V rail after a security given spi_master_o : out t_spi_master_o;
--! delay
rtm_i : in t_rtm_i);
--! Enable signals
fpga_o_en : out STD_LOGIC;
fpga_o_blo_en : out STD_LOGIC;
fpga_o_ttl_en : out STD_LOGIC;
fpga_o_inv_en : out STD_LOGIC;
-- Level and switch inputs
level_i : in STD_LOGIC;
switch_i : in STD_LOGIC;
--! Manual reset, allows power sequencing of the
--! 24V rail after a security given delay
manual_rst_n_o : out STD_LOGIC;
--! RTM identifiers, should match with the expected values
--! TODO: add matching
rtm_i : in t_rtm_i
);
end image1_core; end image1_core;
architecture Behavioral of image1_core is architecture Behavioral of image1_core is
type t_clocks is type t_clocks is
record record
PLL_IN : STD_LOGIC; --! 125MHz Input clock PLL_IN : STD_LOGIC; --! 125MHz Input clock
PLL_FB_IN : STD_LOGIC; PLL_FB_IN : STD_LOGIC;
PLL_FB_OUT : STD_LOGIC; PLL_FB_OUT : STD_LOGIC;
PLL_SYS_A : STD_LOGIC; --! 50MHz Wishbone clock PLL_SYS_A : STD_LOGIC; --! 50MHz Wishbone clock
PLL_SYS_B : STD_LOGIC; --! 200MHz Pulse sampling PLL_SYS_B : STD_LOGIC; --! 200MHz Pulse sampling
SYS_A : STD_LOGIC; SYS_A : STD_LOGIC;
SYS_B : STD_LOGIC; SYS_B : STD_LOGIC;
end record; end record;
type t_rst is type t_rst is
record record
PLL : STD_LOGIC_VECTOR(c_RST_PLL_CLKS - 1 downto 0); PLL : STD_LOGIC_VECTOR(c_RST_PLL_CLKS - 1 downto 0);
SYS_A : STD_LOGIC_VECTOR(c_RST_A_CLKS - 1 downto 0); SYS_A : STD_LOGIC_VECTOR(c_RST_A_CLKS - 1 downto 0);
SYS_B : STD_LOGIC_VECTOR(c_RST_B_CLKS - 1 downto 0); SYS_B : STD_LOGIC_VECTOR(c_RST_B_CLKS - 1 downto 0);
end record; end record;
component test_trigleds_wb is component test_trigleds_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_dat_i : in std_logic_vector(31 downto 0); wb_dat_i : in std_logic_vector(31 downto 0);
...@@ -117,200 +136,229 @@ architecture Behavioral of image1_core is ...@@ -117,200 +136,229 @@ architecture Behavioral of image1_core is
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_stall_o : out std_logic;
-- Port for std_logic_vector field: 'Bits' in reg: 'LED' -- Port for std_logic_vector field: 'Bits' in reg: 'LED'
trigleds_reg_bits_o : out std_logic_vector(5 downto 0) trigleds_reg_bits_o : out std_logic_vector(5 downto 0)
); );
end component test_trigleds_wb; end component test_trigleds_wb;
signal s_clk : t_clocks; signal s_clk : t_clocks;
signal s_rst : t_rst := (PLL => (others => '1'), signal s_rst : t_rst := (
PLL => (others => '1'),
SYS_A => (others => '1'), SYS_A => (others => '1'),
SYS_B => (others => '1')); SYS_B => (others => '1')
);
signal s_rst_n : STD_LOGIC; signal s_rst_n : STD_LOGIC;
signal s_locked : STD_LOGIC; signal s_locked : STD_LOGIC;
signal s_ok_RTMM : STD_LOGIC; signal s_ok_RTMM : STD_LOGIC;
signal s_ok_RTMP : STD_LOGIC; signal s_ok_RTMP : STD_LOGIC;
signal s_slave_i : t_wishbone_slave_in_array (c_NUM_MASTERS - 1 downto 0); signal s_slave_i : t_wishbone_slave_in_array (c_NUM_MASTERS - 1 downto 0);
signal s_slave_o : t_wishbone_slave_out_array (c_NUM_MASTERS - 1 downto 0); signal s_slave_o : t_wishbone_slave_out_array (c_NUM_MASTERS - 1 downto 0);
signal s_master_i : t_wishbone_master_in_array (c_NUM_SLAVES - 1 downto 0); signal s_master_i : t_wishbone_master_in_array (c_NUM_SLAVES - 1 downto 0);
signal s_master_o : t_wishbone_master_out_array (c_NUM_SLAVES - 1 downto 0); signal s_master_o : t_wishbone_master_out_array (c_NUM_SLAVES - 1 downto 0);
signal s_i2c_addr : STD_LOGIC_VECTOR(6 downto 0); signal s_i2c_addr : STD_LOGIC_VECTOR(6 downto 0);
signal s_pulse_i_front : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1); signal s_pulse_i_front : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
signal s_leds_array_image1 : t_leds_array; signal s_leds_array_image1 : t_leds_array;
signal s_led_state_array : t_led_state_array( signal s_led_state_array : t_led_state_array(c_NB_ARRAY_LEDS - 1 downto 0);
c_NB_ARRAY_LEDS - 1 downto 0);
signal i2c_rd_done : std_logic;
signal i2c_rd_done : std_logic; signal i2c_wr_done : std_logic;
signal i2c_wr_done : std_logic; signal i2c_up : std_logic;
signal i2c_up : std_logic;
-- --
-- --
-- !!!!!!!!!!!!!!!!!!! -- !!!!!!!!!!!!!!!!!!!
-- --
-- --
-- --
signal trigleds : std_logic_vector(5 downto 0); signal trigleds : std_logic_vector(5 downto 0);
signal leds_from_trig : std_logic_vector(5 downto 0); signal leds_from_trig : std_logic_vector(5 downto 0);
signal sda_dummy : std_logic; signal sda_dummy : std_logic;
signal sda_dummy_n : std_logic; signal sda_dummy_n : std_logic;
-- signal s_check_cfg : BOOLEAN; -- signal s_check_cfg : BOOLEAN;
begin begin
-- s_check_cfg <= check_sys_cfg; -- s_check_cfg <= check_sys_cfg;
s_i2c_addr <= "10" & FPGA_GA; -- f_RENESAS_I2C_ADDRESSING(UNSIGNED(FPGA_GA)); s_i2c_addr <= "10" & FPGA_GA; -- f_RENESAS_I2C_ADDRESSING(UNSIGNED(FPGA_GA));
s_leds_array_image1.top.ERR <= '1' when s_ok_RTMM = '1' AND s_ok_RTMP = '1' s_leds_array_image1.top.ERR <= '1' when s_ok_RTMM = '1' AND s_ok_RTMP = '1' else
else '0'; '0';
s_clk.PLL_IN <= clk_125MHz_i; s_clk.PLL_IN <= clk_125MHz_i;
s_pulse_i_front <= not(pulse_i_front_n); s_pulse_i_front <= not(pulse_i_front_n);
s_clk_fb_bufg : BUFG s_clk_fb_bufg : BUFG
port map (O => s_clk.PLL_FB_IN, I => s_clk.PLL_FB_OUT); port map
(
I => s_clk.PLL_FB_OUT,
O => s_clk.PLL_FB_IN
);
-- set up the fabric PLL_BASE to drive the BUFPLL -- set up the fabric PLL_BASE to drive the BUFPLL
pll_base_inst : PLL_BASE pll_base_inst : PLL_BASE
generic map ( generic map
BANDWIDTH => "OPTIMIZED", (
CLK_FEEDBACK => "CLKFBOUT", BANDWIDTH => "OPTIMIZED",
COMPENSATION => "SYSTEM_SYNCHRONOUS", CLK_FEEDBACK => "CLKFBOUT",
DIVCLK_DIVIDE => 1, CLKFBOUT_MULT => 8, COMPENSATION => "SYSTEM_SYNCHRONOUS",
CLKFBOUT_PHASE => 0.000, DIVCLK_DIVIDE => 1,
CLKOUT0_DIVIDE => 20, CLKOUT0_PHASE => 0.000, CLKFBOUT_MULT => 8,
CLKOUT0_DUTY_CYCLE => 0.500, CLKFBOUT_PHASE => 0.000,
CLKOUT1_DIVIDE => 5, CLKOUT1_PHASE => 0.000, CLKOUT0_DIVIDE => 20,
CLKOUT1_DUTY_CYCLE => 0.500, CLKOUT0_PHASE => 0.000,
CLKIN_PERIOD => c_CLKIN_PERIOD, CLKOUT0_DUTY_CYCLE => 0.500,
REF_JITTER => 0.010) CLKOUT1_DIVIDE => 5,
port map ( CLKOUT1_PHASE => 0.000,
-- Output clocks CLKOUT1_DUTY_CYCLE => 0.500,
CLKFBOUT => s_clk.PLL_FB_OUT, CLKIN_PERIOD => c_CLKIN_PERIOD,
CLKOUT0 => s_clk.PLL_SYS_A, REF_JITTER => 0.010
CLKOUT1 => s_clk.PLL_SYS_B, )
CLKOUT2 => open, CLKOUT3 => open, port map
CLKOUT4 => open, CLKOUT5 => open, (
-- Status and control signals -- Output clocks
LOCKED => s_locked, RST => s_rst.PLL(c_RST_PLL_CLKS - 1), CLKFBOUT => s_clk.PLL_FB_OUT,
-- Input clock control CLKOUT0 => s_clk.PLL_SYS_A,
CLKFBIN => s_clk.PLL_FB_IN, CLKOUT1 => s_clk.PLL_SYS_B,
CLKIN => s_clk.PLL_IN); CLKOUT2 => open,
CLKOUT3 => open,
s_clk_50M_bufg : BUFG CLKOUT4 => open,
port map (O => s_clk.SYS_A, I => s_clk.PLL_SYS_A); CLKOUT5 => open,
-- Status and control signals
s_clk_200M_bufg : BUFG LOCKED => s_locked,
port map (O => s_clk.SYS_B, I => s_clk.PLL_SYS_B); RST => s_rst.PLL(c_RST_PLL_CLKS - 1),
-- Input clock control
--! @brief Reset chain for PLL CLKFBIN => s_clk.PLL_FB_IN,
--! @param s_clk.PLL Wishbone clock CLKIN => s_clk.PLL_IN
p_reset_PLL_chain : process(s_clk.PLL_IN) is );
begin
if rising_edge(s_clk.PLL_IN) then s_clk_50M_bufg : BUFG
s_rst.PLL <= (others => '1'); port map
(
s_rst.PLL(0) <= '0'; I => s_clk.PLL_SYS_A,
for i in 1 to c_RST_PLL_CLKS - 1 loop O => s_clk.SYS_A
s_rst.PLL(i) <= s_rst.PLL(i-1); );
end loop;
s_clk_200M_bufg : BUFG
if s_rst.PLL(c_RST_PLL_CLKS - 1) = '1' then port map
end if; (
I => s_clk.PLL_SYS_B,
end if; O => s_clk.SYS_B
end process p_reset_PLL_chain; );
--! @brief Reset chain for PLL
--! @brief Reset chain --! @param s_clk.PLL Wishbone clock
--! @param s_clk.SYS_A Wishbone clock p_reset_PLL_chain : process(s_clk.PLL_IN) is
p_reset_A_chain : process(s_clk.SYS_A) is begin
begin if rising_edge(s_clk.PLL_IN) then
if rising_edge(s_clk.SYS_A) then s_rst.PLL <= (others => '1');
if s_locked = '0' then
s_rst.SYS_A <= (others => '1'); s_rst.PLL(0) <= '0';
else for i in 1 to c_RST_PLL_CLKS - 1 loop
s_rst.SYS_A(0) <= '0'; s_rst.PLL(i) <= s_rst.PLL(i-1);
for i in 1 to c_RST_A_CLKS - 1 loop end loop;
s_rst.SYS_A(i) <= s_rst.SYS_A(i-1);
end loop; -- if s_rst.PLL(c_RST_PLL_CLKS - 1) = '1' then
-- end if;
if s_rst.SYS_A(c_RST_A_CLKS - 1) = '1' then
end if; end if;
end process p_reset_PLL_chain;
end if;
--! @brief Reset chain
--! @param s_clk.SYS_A Wishbone clock
p_reset_A_chain : process(s_clk.SYS_A) is
begin
if rising_edge(s_clk.SYS_A) then
if s_locked = '0' then
s_rst.SYS_A <= (others => '1');
else
s_rst.SYS_A(0) <= '0';
for i in 1 to c_RST_A_CLKS - 1 loop
s_rst.SYS_A(i) <= s_rst.SYS_A(i-1);
end loop;
-- if s_rst.SYS_A(c_RST_A_CLKS - 1) = '1' then
-- end if;
end if; end if;
end process p_reset_A_chain; end if;
end process p_reset_A_chain;
--! @brief Reset chain
--! @param s_clk.SYS_B System of clock domain B --! @brief Reset chain
p_reset_B_chain : process(s_clk.SYS_B) is --! @param s_clk.SYS_B System of clock domain B
begin p_reset_B_chain : process(s_clk.SYS_B) is
if rising_edge(s_clk.SYS_B) then begin
if s_locked = '0' then if rising_edge(s_clk.SYS_B) then
s_rst.SYS_B <= (others => '1'); if s_locked = '0' then
else s_rst.SYS_B <= (others => '1');
s_rst.SYS_B(0) <= '0'; else
for i in 1 to c_RST_B_CLKS - 1 loop s_rst.SYS_B(0) <= '0';
s_rst.SYS_B(i) <= s_rst.SYS_B(i-1); for i in 1 to c_RST_B_CLKS - 1 loop
end loop; s_rst.SYS_B(i) <= s_rst.SYS_B(i-1);
end loop;
if s_rst.SYS_B(c_RST_B_CLKS - 1) = '1' then
end if; -- if s_rst.SYS_B(c_RST_B_CLKS - 1) = '1' then
-- end if;
end if;
end if; end if;
end process p_reset_B_chain; end if;
end process p_reset_B_chain;
-- !!!!! -- !!!!!
-- led_front_n <= "111000"; -- led_front_n <= "111000";
led_front_n <= not trigleds; led_front_n <= not trigleds;
inst_basic_trigger: basic_trigger_top inst_basic_trigger: basic_trigger_top
generic map(g_NUMBER_OF_CHANNELS => c_NUMBER_OF_CHANNELS, generic map
g_CLK_PERIOD => c_CLKB_PERIOD, (
g_OUTPUT_PULSE_LENGTH => c_OUTPUT_PULSE_LENGTH, g_NUMBER_OF_CHANNELS => c_NUMBER_OF_CHANNELS,
g_LED_BLINKING_LENGTH => c_LED_BLINKING_LENGTH) g_CLK_PERIOD => c_CLKB_PERIOD,
port map(clk_i => s_clk.SYS_B, g_OUTPUT_PULSE_LENGTH => c_OUTPUT_PULSE_LENGTH,
rst_i => s_rst.SYS_B(c_RST_B_CLKS - 1), g_LED_BLINKING_LENGTH => c_LED_BLINKING_LENGTH
led_ttl_o => s_leds_array_image1.top.TTL_N, )
fpga_o_en => fpga_o_en, port map
fpga_o_ttl_en => fpga_o_ttl_en, (
fpga_o_inv_en => fpga_o_inv_en, clk_i => s_clk.SYS_B,
fpga_o_blo_en => fpga_o_blo_en, rst_i => s_rst.SYS_B(c_RST_B_CLKS - 1),
level_i => level_i, led_ttl_o => s_leds_array_image1.top.TTL_N,
switch_i => switch_i, fpga_o_en => fpga_o_en,
manual_rst_n_o => manual_rst_n_o, fpga_o_ttl_en => fpga_o_ttl_en,
pulse_i_front => s_pulse_i_front, fpga_o_inv_en => fpga_o_inv_en,
pulse_o_front => pulse_o_front, fpga_o_blo_en => fpga_o_blo_en,
pulse_i_rear => pulse_i_rear, level_i => level_i,
pulse_o_rear => pulse_o_rear, switch_i => switch_i,
manual_rst_n_o => manual_rst_n_o,
pulse_i_front => s_pulse_i_front,
-- !!!!!!!!!!!! pulse_o_front => pulse_o_front,
led_o_front => leds_from_trig, -- led_front_n, pulse_i_rear => pulse_i_rear,
pulse_o_rear => pulse_o_rear,
-- !!!!!!!!!!!!
led_o_front => leds_from_trig, -- led_front_n,
led_o_rear => open, --led_rear_n,
inv_i => inv_i_n,
inv_o => inv_o);
led_o_rear => led_rear_n,
inv_i => inv_i_n,
inv_o => inv_o
);
-- --
-- -- s_slave_o(c_MASTER_I2C_SLAVE).stall; -- -- s_slave_o(c_MASTER_I2C_SLAVE).stall;
...@@ -335,43 +383,42 @@ begin ...@@ -335,43 +383,42 @@ begin
s_slave_i(c_MASTER_I2C_SLAVE).adr(31 downto 16) <= (others => '0'); s_slave_i(c_MASTER_I2C_SLAVE).adr(31 downto 16) <= (others => '0');
i2c_slave_o.sda_o <= sda_dummy; inst_i2c_slave: i2c_slave_top
sda_dummy_n <= not sda_dummy; port map
led_rear_n <= (others => sda_dummy_n); (
inst_i2c_slave: i2c_slave_top sda_oen => i2c_slave_o.SDA_OE,
port map(sda_oen => i2c_slave_o.SDA_OE, sda_i => i2c_slave_i.SDA_I,
sda_i => i2c_slave_i.SDA_I, sda_o => i2c_slave_o.SDA_O,
sda_o => sda_dummy, -- i2c_slave_o.SDA_O, scl_oen => i2c_slave_o.SCL_OE,
scl_oen => i2c_slave_o.SCL_OE, scl_i => i2c_slave_i.SCL_I,
scl_i => i2c_slave_i.SCL_I, scl_o => i2c_slave_o.SCL_O,
scl_o => i2c_slave_o.SCL_O, wb_clk_i => s_clk.SYS_A,
wb_clk_i => s_clk.SYS_A, wb_rst_i => s_rst.SYS_A(c_RST_A_CLKS - 1),
wb_rst_i => s_rst.SYS_A(c_RST_A_CLKS - 1), wb_master_stb_o => s_slave_i(c_MASTER_I2C_SLAVE).stb,
wb_master_stb_o => s_slave_i(c_MASTER_I2C_SLAVE).stb, wb_master_cyc_o => s_slave_i(c_MASTER_I2C_SLAVE).cyc,
wb_master_cyc_o => s_slave_i(c_MASTER_I2C_SLAVE).cyc, wb_master_sel_o => s_slave_i(c_MASTER_I2C_SLAVE).sel,
wb_master_sel_o => s_slave_i(c_MASTER_I2C_SLAVE).sel, wb_master_we_o => s_slave_i(c_MASTER_I2C_SLAVE).we,
wb_master_we_o => s_slave_i(c_MASTER_I2C_SLAVE).we, wb_master_data_i => s_slave_o(c_MASTER_I2C_SLAVE).dat,
wb_master_data_i => s_slave_o(c_MASTER_I2C_SLAVE).dat, wb_master_data_o => s_slave_i(c_MASTER_I2C_SLAVE).dat,
wb_master_data_o => s_slave_i(c_MASTER_I2C_SLAVE).dat, wb_master_addr_o => s_slave_i(c_MASTER_I2C_SLAVE).adr(15 downto 0),
wb_master_addr_o => s_slave_i(c_MASTER_I2C_SLAVE).adr(15 downto 0), wb_master_ack_i => s_slave_o(c_MASTER_I2C_SLAVE).ack,
wb_master_ack_i => s_slave_o(c_MASTER_I2C_SLAVE).ack, wb_master_rty_i => s_slave_o(c_MASTER_I2C_SLAVE).rty,
wb_master_rty_i => s_slave_o(c_MASTER_I2C_SLAVE).rty, wb_master_err_i => s_slave_o(c_MASTER_I2C_SLAVE).err,
wb_master_err_i => s_slave_o(c_MASTER_I2C_SLAVE).err, wb_slave_stb_i => s_master_o(c_SLAVE_I2C_SLAVE).stb,
wb_slave_stb_i => s_master_o(c_SLAVE_I2C_SLAVE).stb, wb_slave_cyc_i => s_master_o(c_SLAVE_I2C_SLAVE).cyc,
wb_slave_cyc_i => s_master_o(c_SLAVE_I2C_SLAVE).cyc, wb_slave_sel_i => s_master_o(c_SLAVE_I2C_SLAVE).sel,
wb_slave_sel_i => s_master_o(c_SLAVE_I2C_SLAVE).sel, wb_slave_we_i => s_master_o(c_SLAVE_I2C_SLAVE).we,
wb_slave_we_i => s_master_o(c_SLAVE_I2C_SLAVE).we, wb_slave_data_i => s_master_o(c_SLAVE_I2C_SLAVE).dat,
wb_slave_data_i => s_master_o(c_SLAVE_I2C_SLAVE).dat, wb_slave_data_o => s_master_i(c_SLAVE_I2C_SLAVE).dat,
wb_slave_data_o => s_master_i(c_SLAVE_I2C_SLAVE).dat, wb_slave_addr_i => s_master_o(c_SLAVE_I2C_SLAVE).adr( 5 downto 2),
wb_slave_addr_i => s_master_o(c_SLAVE_I2C_SLAVE).adr( 5 downto 2), wb_slave_ack_o => s_master_i(c_SLAVE_I2C_SLAVE).ack,
wb_slave_ack_o => s_master_i(c_SLAVE_I2C_SLAVE).ack, wb_slave_rty_o => s_master_i(c_SLAVE_I2C_SLAVE).rty,
wb_slave_rty_o => s_master_i(c_SLAVE_I2C_SLAVE).rty, wb_slave_err_o => s_master_i(c_SLAVE_I2C_SLAVE).err,
wb_slave_err_o => s_master_i(c_SLAVE_I2C_SLAVE).err, pf_wb_addr_o => open,
pf_wb_addr_o => open, rd_done_o => i2c_rd_done,
rd_done_o => i2c_rd_done, wr_done_o => i2c_wr_done,
wr_done_o => i2c_wr_done, i2c_addr_i => s_i2c_addr
i2c_addr_i => s_i2c_addr );
);
-- Process to set the I2C_UP signal for display on the front panel -- Process to set the I2C_UP signal for display on the front panel
...@@ -434,9 +481,9 @@ begin ...@@ -434,9 +481,9 @@ begin
s_master_i(c_SLAVE_I2C_SLAVE).stall <= '0'; s_master_i(c_SLAVE_I2C_SLAVE).stall <= '0';
s_master_i(c_SLAVE_I2C_SLAVE).int <= '0'; s_master_i(c_SLAVE_I2C_SLAVE).int <= '0';
s_master_i(c_slave_trigleds_wb).int <= '0'; s_master_i(c_slave_trigleds_wb).int <= '0';
-- s_master_i(c_SLAVE_M25P32).stall <= '0'; -- s_master_i(c_SLAVE_M25P32).stall <= '0';
...@@ -444,113 +491,115 @@ begin ...@@ -444,113 +491,115 @@ begin
-- s_master_i(c_SLAVE_MULTIBOOT).stall <= '0'; -- s_master_i(c_SLAVE_MULTIBOOT).stall <= '0';
-- s_master_i(c_SLAVE_MULTIBOOT).int <= '0'; -- s_master_i(c_SLAVE_MULTIBOOT).int <= '0';
inst_wb_crossbar: xwb_crossbar inst_wb_crossbar: xwb_crossbar
generic map(g_num_masters => c_NUM_MASTERS, generic map
g_num_slaves => c_NUM_SLAVES, (
g_registered => false, g_num_masters => c_NUM_MASTERS,
-- Address of the slaves connected g_num_slaves => c_NUM_SLAVES,
--! It should be noted that the default address length is 32 g_registered => false,
--! In our project only 16 bits are addressable -- Address of the slaves connected
g_address => c_addresses, --! It should be noted that the default address length is 32
g_mask => c_masks) --! In our project only 16 bits are addressable
port map(clk_sys_i => s_clk.SYS_A, g_address => c_addresses,
rst_n_i => s_rst_n, g_mask => c_masks
slave_i => s_slave_i , )
slave_o => s_slave_o , port map
master_i => s_master_i, (
master_o => s_master_o); clk_sys_i => s_clk.SYS_A,
rst_n_i => s_rst_n,
slave_i => s_slave_i ,
slave_o => s_slave_o ,
master_i => s_master_i,
master_o => s_master_o
);
cmp_test_trigleds: test_trigleds_wb cmp_test_trigleds: test_trigleds_wb
port map ( port map
rst_n_i => s_rst_n, (
clk_sys_i => s_clk.sys_a, rst_n_i => s_rst_n,
wb_dat_i => s_master_o(c_slave_trigleds_wb).dat, clk_sys_i => s_clk.sys_a,
wb_dat_o => s_master_i(c_slave_trigleds_wb).dat, wb_dat_i => s_master_o(c_slave_trigleds_wb).dat,
wb_cyc_i => s_master_o(c_slave_trigleds_wb).cyc, wb_dat_o => s_master_i(c_slave_trigleds_wb).dat,
wb_sel_i => s_master_o(c_slave_trigleds_wb).sel, wb_cyc_i => s_master_o(c_slave_trigleds_wb).cyc,
wb_stb_i => s_master_o(c_slave_trigleds_wb).stb, wb_sel_i => s_master_o(c_slave_trigleds_wb).sel,
wb_we_i => s_master_o(c_slave_trigleds_wb).we, wb_stb_i => s_master_o(c_slave_trigleds_wb).stb,
wb_ack_o => s_master_i(c_slave_trigleds_wb).ack, wb_we_i => s_master_o(c_slave_trigleds_wb).we,
wb_stall_o => s_master_i(c_slave_trigleds_wb).stall, wb_ack_o => s_master_i(c_slave_trigleds_wb).ack,
-- Port for std_logic_vector field: 'Bits' in reg: 'LED' wb_stall_o => s_master_i(c_slave_trigleds_wb).stall,
trigleds_reg_bits_o => trigleds -- Port for std_logic_vector field: 'Bits' in reg: 'LED'
); trigleds_reg_bits_o => trigleds
);
s_leds_array_image1.top.pwr <= '1';
s_leds_array_image1.middle.wr_ok <= '0'; s_leds_array_image1.top.pwr <= '1';
s_leds_array_image1.middle.wr_link <= '0'; s_leds_array_image1.middle.wr_ok <= '0';
s_leds_array_image1.middle.wr_addr <= '0'; s_leds_array_image1.middle.wr_link <= '0';
s_leds_array_image1.middle.wr_addr <= '0';
--! Here are organized in the same disposition as in the front panel.
--! Take a look to image1_led_pkg.vhd for the correct order for
--! bicolor_led_ctrl
s_led_state_array(c_LED_NB_PWR) <= f_LED_STATE(c_LED_COLOR_PWR)
when s_leds_array_image1.top.PWR = '1'
else f_LED_STATE(c_LED_OFF);
s_led_state_array(c_LED_NB_ERR) <= f_LED_STATE(c_LED_COLOR_ERR)
when s_leds_array_image1.top.ERR = '1'
else f_LED_STATE(c_LED_OFF);
s_led_state_array(c_LED_NB_TTL_N) <= f_LED_STATE(c_LED_COLOR_TTL_N)
when s_leds_array_image1.top.TTL_N = '1'
else f_LED_STATE(c_LED_OFF);
s_led_state_array(c_LED_NB_I2C) <= f_LED_STATE(c_LED_COLOR_I2C)
when i2c_up = '1'
else f_LED_STATE(c_LED_RED);
s_led_state_array(c_LED_NB_WR_OK) <= f_LED_STATE(c_LED_COLOR_WR_OK)
when s_leds_array_image1.middle.WR_OK = '1'
else f_LED_STATE(c_LED_RED);
s_led_state_array(c_LED_NB_WR_LINK) <= f_LED_STATE(c_LED_COLOR_WR_LINK)
when s_leds_array_image1.middle.WR_LINK = '1'
else f_LED_STATE(c_LED_RED);
s_led_state_array(c_LED_NB_WR_GMT) <= f_LED_STATE(c_LED_COLOR_WR_GMT)
when s_leds_array_image1.middle.WR_GMT = '1'
else f_LED_STATE(c_LED_RED);
s_led_state_array(c_LED_NB_WR_ADDR) <= f_LED_STATE(c_LED_COLOR_WR_ADDR)
when s_leds_array_image1.middle.WR_ADDR = '1'
else f_LED_STATE(c_LED_RED);
s_led_state_array(c_LED_NB_MULTICAST3) <= f_LED_STATE(c_LED_COLOR_MULTICAST3)
when s_leds_array_image1.bottom.MULTICAST(3) = '1'
else f_LED_STATE(c_LED_OFF);
s_led_state_array(c_LED_NB_MULTICAST2) <= f_LED_STATE(c_LED_COLOR_MULTICAST2)
when s_leds_array_image1.bottom.MULTICAST(2) = '1'
else f_LED_STATE(c_LED_OFF);
s_led_state_array(c_LED_NB_MULTICAST1) <= f_LED_STATE(c_LED_COLOR_MULTICAST1)
when s_leds_array_image1.bottom.MULTICAST(1) = '1'
else f_LED_STATE(c_LED_OFF);
s_led_state_array(c_LED_NB_MULTICAST0) <= f_LED_STATE(c_LED_COLOR_MULTICAST0)
when s_leds_array_image1.bottom.MULTICAST(0) = '1'
else f_LED_STATE(c_LED_OFF);
s_rst_n <= not(s_rst.SYS_A(c_RST_A_CLKS - 1));
--! Here are organized in the same disposition as in the front panel.
inst_bicolor_led_ctrl: bicolor_led_ctrl --! Take a look to image1_led_pkg.vhd for the correct order for
generic map(g_NB_COLUMN => c_NB_COLUMN, --! bicolor_led_ctrl
g_NB_LINE => c_NB_LINE, s_led_state_array(c_LED_NB_PWR) <= f_LED_STATE(c_LED_COLOR_PWR) when s_leds_array_image1.top.PWR = '1' else
g_CLK_FREQ => 20000000, f_LED_STATE(c_LED_OFF);
g_REFRESH_RATE => 250) s_led_state_array(c_LED_NB_ERR) <= f_LED_STATE(c_LED_COLOR_ERR) when s_leds_array_image1.top.ERR = '1' else
port map(rst_n_i => s_rst_n, f_LED_STATE(c_LED_OFF);
clk_i => clk_20MHz_i, s_led_state_array(c_LED_NB_TTL_N) <= f_LED_STATE(c_LED_COLOR_TTL_N) when s_leds_array_image1.top.TTL_N = '1' else
led_intensity_i => c_LED_INTENSITY, f_LED_STATE(c_LED_OFF);
led_state_i => f_STD_LOGIC_VECTOR(s_led_state_array), s_led_state_array(c_LED_NB_I2C) <= f_LED_STATE(c_LED_COLOR_I2C) when i2c_up = '1' else
column_o(0) => led_array_o.WR_OWNADDR_I2C, f_LED_STATE(c_LED_RED);
column_o(1) => led_array_o.WR_GMT_TTL_TTLN, s_led_state_array(c_LED_NB_WR_OK) <= f_LED_STATE(c_LED_COLOR_WR_OK) when s_leds_array_image1.middle.WR_OK = '1' else
column_o(2) => led_array_o.WR_LINK_SYSERROR, f_LED_STATE(c_LED_RED);
column_o(3) => led_array_o.WR_OK_SYSPW, s_led_state_array(c_LED_NB_WR_LINK) <= f_LED_STATE(c_LED_COLOR_WR_LINK) when s_leds_array_image1.middle.WR_LINK = '1' else
column_o(4) => led_array_o.MULTICAST_2_0, f_LED_STATE(c_LED_RED);
column_o(5) => led_array_o.MULTICAST_3_1, s_led_state_array(c_LED_NB_WR_GMT) <= f_LED_STATE(c_LED_COLOR_WR_GMT) when s_leds_array_image1.middle.WR_GMT = '1'else
line_o(0) => led_array_o.CTRL0, f_LED_STATE(c_LED_RED);
line_o(1) => led_array_o.CTRL1, s_led_state_array(c_LED_NB_WR_ADDR) <= f_LED_STATE(c_LED_COLOR_WR_ADDR) when s_leds_array_image1.middle.WR_ADDR = '1' else
line_oen_o(0) => led_array_o.CTRL0_OEN, f_LED_STATE(c_LED_RED);
line_oen_o(1) => led_array_o.CTRL1_OEN); s_led_state_array(c_LED_NB_MULTICAST3) <= f_LED_STATE(c_LED_COLOR_MULTICAST3) when s_leds_array_image1.bottom.MULTICAST(3) = '1' else
f_LED_STATE(c_LED_OFF);
inst_rtm_detector: rtm_detector s_led_state_array(c_LED_NB_MULTICAST2) <= f_LED_STATE(c_LED_COLOR_MULTICAST2) when s_leds_array_image1.bottom.MULTICAST(2) = '1' else
port map(RTMM_i => rtm_i.RTMM_N, f_LED_STATE(c_LED_OFF);
RTMP_i => rtm_i.RTMP_N, s_led_state_array(c_LED_NB_MULTICAST1) <= f_LED_STATE(c_LED_COLOR_MULTICAST1) when s_leds_array_image1.bottom.MULTICAST(1) = '1' else
ok_RTMM_o => s_ok_RTMM, f_LED_STATE(c_LED_OFF);
ok_RTMP_o => s_ok_RTMP); s_led_state_array(c_LED_NB_MULTICAST0) <= f_LED_STATE(c_LED_COLOR_MULTICAST0) when s_leds_array_image1.bottom.MULTICAST(0) = '1' else
f_LED_STATE(c_LED_OFF);
s_rst_n <= not(s_rst.SYS_A(c_RST_A_CLKS - 1));
inst_bicolor_led_ctrl: bicolor_led_ctrl
generic map
(
g_NB_COLUMN => c_NB_COLUMN,
g_NB_LINE => c_NB_LINE,
g_CLK_FREQ => 20000000,
g_REFRESH_RATE => 250
)
port map
(
rst_n_i => s_rst_n,
clk_i => clk_20MHz_i,
led_intensity_i => c_LED_INTENSITY,
led_state_i => f_STD_LOGIC_VECTOR(s_led_state_array),
column_o(0) => led_array_o.WR_OWNADDR_I2C,
column_o(1) => led_array_o.WR_GMT_TTL_TTLN,
column_o(2) => led_array_o.WR_LINK_SYSERROR,
column_o(3) => led_array_o.WR_OK_SYSPW,
column_o(4) => led_array_o.MULTICAST_2_0,
column_o(5) => led_array_o.MULTICAST_3_1,
line_o(0) => led_array_o.CTRL0,
line_o(1) => led_array_o.CTRL1,
line_oen_o(0) => led_array_o.CTRL0_OEN,
line_oen_o(1) => led_array_o.CTRL1_OEN
);
inst_rtm_detector: rtm_detector
port map
(
RTMM_i => rtm_i.RTMM_N,
RTMP_i => rtm_i.RTMP_N,
ok_RTMM_o => s_ok_RTMM,
ok_RTMP_o => s_ok_RTMP
);
end Behavioral; end Behavioral;
...@@ -43,173 +43,196 @@ use work.wishbone_pkg.ALL; ...@@ -43,173 +43,196 @@ use work.wishbone_pkg.ALL;
use UNISIM.VCOMPONENTS.ALL; use UNISIM.VCOMPONENTS.ALL;
entity image1_top is entity image1_top is
generic(g_NUMBER_OF_CHANNELS : NATURAL := 6); generic
port (RST_N : in STD_LOGIC; (
CLK20_VCXO : in STD_LOGIC; g_NUMBER_OF_CHANNELS : NATURAL := 6
FPGA_CLK_P : in STD_LOGIC; --Using the 125MHz clock );
FPGA_CLK_N : in STD_LOGIC; port
(
RST_N : in STD_LOGIC;
CLK20_VCXO : in STD_LOGIC;
FPGA_CLK_P : in STD_LOGIC; --Using the 125MHz clock
FPGA_CLK_N : in STD_LOGIC;
--! LEDs --! LEDs
LED_CTRL0 : out STD_LOGIC; LED_CTRL0 : out STD_LOGIC;
LED_CTRL0_OEN : out STD_LOGIC; LED_CTRL0_OEN : out STD_LOGIC;
LED_CTRL1 : out STD_LOGIC; LED_CTRL1 : out STD_LOGIC;
LED_CTRL1_OEN : out STD_LOGIC; LED_CTRL1_OEN : out STD_LOGIC;
LED_MULTICAST_2_0 : out STD_LOGIC; LED_MULTICAST_2_0 : out STD_LOGIC;
LED_MULTICAST_3_1 : out STD_LOGIC; LED_MULTICAST_3_1 : out STD_LOGIC;
LED_WR_GMT_TTL_TTLN : out STD_LOGIC; LED_WR_GMT_TTL_TTLN : out STD_LOGIC;
LED_WR_LINK_SYSERROR : out STD_LOGIC; LED_WR_LINK_SYSERROR : out STD_LOGIC;
LED_WR_OK_SYSPW : out STD_LOGIC; LED_WR_OK_SYSPW : out STD_LOGIC;
LED_WR_OWNADDR_I2C : out STD_LOGIC; LED_WR_OWNADDR_I2C : out STD_LOGIC;
--! I/Os for pulses --! I/Os for pulses
PULSE_FRONT_LED_N : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1); PULSE_FRONT_LED_N : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
PULSE_REAR_LED_N : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1); PULSE_REAR_LED_N : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
FPGA_INPUT_TTL_N : in STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1); FPGA_INPUT_TTL_N : in STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
FPGA_OUT_TTL : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1); FPGA_OUT_TTL : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
FPGA_BLO_IN : in STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1); FPGA_BLO_IN : in STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
FPGA_TRIG_BLO : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1); FPGA_TRIG_BLO : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
INV_IN_N : in STD_LOGIC_VECTOR(4 downto 1); INV_IN_N : in STD_LOGIC_VECTOR(4 downto 1);
INV_OUT : out STD_LOGIC_VECTOR(4 downto 1); INV_OUT : out STD_LOGIC_VECTOR(4 downto 1);
--! Lines for the i2c_slave --! Lines for the i2c_slave
SCL_I : in STD_LOGIC; SCL_I : in STD_LOGIC;
SCL_O : out STD_LOGIC; SCL_O : out STD_LOGIC;
SCL_OE : out STD_LOGIC; SCL_OE : out STD_LOGIC;
SDA_I : in STD_LOGIC; SDA_I : in STD_LOGIC;
SDA_O : out STD_LOGIC; SDA_O : out STD_LOGIC;
SDA_OE : out STD_LOGIC; SDA_OE : out STD_LOGIC;
FPGA_GA : in STD_LOGIC_VECTOR(4 downto 0); FPGA_GA : in STD_LOGIC_VECTOR(4 downto 0);
FPGA_GAP : in STD_LOGIC; FPGA_GAP : in STD_LOGIC;
--! Pins of the SPI interface to write into the Flash memory --! Pins of the SPI interface to write into the Flash memory
FPGA_PROM_CCLK : out STD_LOGIC; FPGA_PROM_CCLK : out STD_LOGIC;
FPGA_PROM_CSO_B_N : out STD_LOGIC; FPGA_PROM_CSO_B_N : out STD_LOGIC;
FPGA_PROM_DIN : in STD_LOGIC; FPGA_PROM_DIN : in STD_LOGIC;
FPGA_PROM_MOSI : out STD_LOGIC; FPGA_PROM_MOSI : out STD_LOGIC;
--! RTM identifiers, should match with the expected values --! RTM identifiers, should match with the expected values
--! TODO: add matching --! TODO: add matching
FPGA_OE : out STD_LOGIC; FPGA_OE : out STD_LOGIC;
FPGA_BLO_OE : out STD_LOGIC; FPGA_BLO_OE : out STD_LOGIC;
FPGA_TRIG_TTL_OE : out STD_LOGIC; FPGA_TRIG_TTL_OE : out STD_LOGIC;
FPGA_INV_OE : out STD_LOGIC; FPGA_INV_OE : out STD_LOGIC;
LEVEL : in STD_LOGIC;--!TTL/INV_TTL_N LEVEL : in STD_LOGIC;--!TTL/INV_TTL_N
EXTRA_SWITCH : in STD_LOGIC_VECTOR(1 downto 1);--! General enable EXTRA_SWITCH : in STD_LOGIC_VECTOR(1 downto 1);--! General enable
MR_N : out STD_LOGIC;--! It allows power sequencing of the MR_N : out STD_LOGIC;--! It allows power sequencing of the
--! 24V rail after a security given --! 24V rail after a security given
--! delay --! delay
FPGA_RTMM_N : in STD_LOGIC_VECTOR(2 downto 0); FPGA_RTMM_N : in STD_LOGIC_VECTOR(2 downto 0);
FPGA_RTMP_N : in STD_LOGIC_VECTOR(2 downto 0)); FPGA_RTMP_N : in STD_LOGIC_VECTOR(2 downto 0)
);
end image1_top; end image1_top;
architecture Behavioral of image1_top is architecture Behavioral of image1_top is
component image1_core is component image1_core is
generic(g_NUMBER_OF_CHANNELS : NATURAL := 6); generic
port (rst_n : in STD_LOGIC; (
clk_20MHz_i : in STD_LOGIC; g_NUMBER_OF_CHANNELS : NATURAL := 6
clk_125MHz_i : in STD_LOGIC; );
--! LEDs port
led_array_o : out t_led_array_o; (
--! I/Os for pulses rst_n : in STD_LOGIC;
led_front_n : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1); clk_20MHz_i : in STD_LOGIC;
led_rear_n : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1); clk_125MHz_i : in STD_LOGIC;
pulse_i_front_n : in STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1); --! LEDs
pulse_o_front : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1); led_array_o : out t_led_array_o;
pulse_i_rear : in STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1); --! I/Os for pulses
pulse_o_rear : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1); led_front_n : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
inv_i_n : in STD_LOGIC_VECTOR(4 downto 1); led_rear_n : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
inv_o : out STD_LOGIC_VECTOR(4 downto 1); pulse_i_front_n : in STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
--! Lines for the i2c_slave pulse_o_front : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
i2c_slave_i : in t_i2c_slave_i; pulse_i_rear : in STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
i2c_slave_o : out t_i2c_slave_o; pulse_o_rear : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
--! FPGA Geographical address pins (reused for i2c address) inv_i_n : in STD_LOGIC_VECTOR(4 downto 1);
FPGA_GA : in STD_LOGIC_VECTOR(4 downto 0); inv_o : out STD_LOGIC_VECTOR(4 downto 1);
FPGA_GAP : in STD_LOGIC; --! Lines for the i2c_slave
--! Pins of the SPI interface to write into the Flash memory i2c_slave_i : in t_i2c_slave_i;
spi_master_i : in t_spi_master_i; i2c_slave_o : out t_i2c_slave_o;
spi_master_o : out t_spi_master_o; --! FPGA Geographical address pins (reused for i2c address)
--! RTM identifiers, should match with the expected values FPGA_GA : in STD_LOGIC_VECTOR(4 downto 0);
--! TODO: add matching FPGA_GAP : in STD_LOGIC;
fpga_o_en : out STD_LOGIC; --! Pins of the SPI interface to write into the Flash memory
fpga_o_blo_en : out STD_LOGIC; spi_master_i : in t_spi_master_i;
fpga_o_ttl_en : out STD_LOGIC; spi_master_o : out t_spi_master_o;
fpga_o_inv_en : out STD_LOGIC; --! RTM identifiers, should match with the expected values
level_i : in STD_LOGIC; --! TODO: add matching
switch_i : in STD_LOGIC; --! General enable fpga_o_en : out STD_LOGIC;
manual_rst_n_o : out STD_LOGIC; --! It allows power sequencing of the fpga_o_blo_en : out STD_LOGIC;
--! 24V rail after a security given fpga_o_ttl_en : out STD_LOGIC;
--! delay fpga_o_inv_en : out STD_LOGIC;
rtm_i : in t_rtm_i); level_i : in STD_LOGIC;
end component; switch_i : in STD_LOGIC; --! General enable
manual_rst_n_o : out STD_LOGIC; --! It allows power sequencing of the
signal s_clk_125MHz : STD_LOGIC; --! 24V rail after a security given
signal s_led_array : t_led_array_o := c_led_array_default; --! delay
signal s_i2c_slave_i : t_i2c_slave_i; rtm_i : in t_rtm_i
signal s_i2c_slave_o : t_i2c_slave_o; );
signal s_spi_master_i : t_spi_master_i; end component;
signal s_spi_master_o : t_spi_master_o;
signal s_rtm_i : t_rtm_i; signal s_clk_125MHz : STD_LOGIC;
signal s_switch_i : STD_LOGIC_VECTOR(1 downto 1); signal s_led_array : t_led_array_o := c_led_array_default;
signal s_i2c_slave_i : t_i2c_slave_i;
signal s_i2c_slave_o : t_i2c_slave_o;
signal s_spi_master_i : t_spi_master_i;
signal s_spi_master_o : t_spi_master_o;
signal s_rtm_i : t_rtm_i;
signal s_switch_i : STD_LOGIC_VECTOR(1 downto 1);
begin begin
inst_125m_IBUFGDS : IBUFGDS inst_125m_IBUFGDS : IBUFGDS
generic map (DIFF_TERM => TRUE, IBUF_LOW_PWR => TRUE) generic map
port map (O => s_clk_125MHz, I => FPGA_CLK_P, (
IB => FPGA_CLK_N); DIFF_TERM => TRUE,
IBUF_LOW_PWR => TRUE
LED_CTRL0 <= s_led_array.CTRL0; )
LED_CTRL0_OEN <= s_led_array.CTRL0_OEN; port map
LED_CTRL1 <= s_led_array.CTRL1; (
LED_CTRL1_OEN <= s_led_array.CTRL1_OEN; I => FPGA_CLK_P,
LED_MULTICAST_2_0 <= s_led_array.MULTICAST_2_0; IB => FPGA_CLK_N,
LED_MULTICAST_3_1 <= s_led_array.MULTICAST_3_1; O => s_clk_125MHz
LED_WR_GMT_TTL_TTLN <= s_led_array.WR_GMT_TTL_TTLN; );
LED_WR_LINK_SYSERROR <= s_led_array.WR_LINK_SYSERROR;
LED_WR_OK_SYSPW <= s_led_array.WR_OK_SYSPW; LED_CTRL0 <= s_led_array.CTRL0;
LED_WR_OWNADDR_I2C <= s_led_array.WR_OWNADDR_I2C; LED_CTRL0_OEN <= s_led_array.CTRL0_OEN;
LED_CTRL1 <= s_led_array.CTRL1;
s_i2c_slave_i.SCL_I <= SCL_I; LED_CTRL1_OEN <= s_led_array.CTRL1_OEN;
s_i2c_slave_i.SDA_I <= SDA_I; LED_MULTICAST_2_0 <= s_led_array.MULTICAST_2_0;
SCL_O <= s_i2c_slave_o.SCL_O; LED_MULTICAST_3_1 <= s_led_array.MULTICAST_3_1;
SCL_OE <= s_i2c_slave_o.SCL_OE; LED_WR_GMT_TTL_TTLN <= s_led_array.WR_GMT_TTL_TTLN;
SDA_O <= s_i2c_slave_o.SDA_O; LED_WR_LINK_SYSERROR <= s_led_array.WR_LINK_SYSERROR;
SDA_OE <= s_i2c_slave_o.SDA_OE; LED_WR_OK_SYSPW <= s_led_array.WR_OK_SYSPW;
LED_WR_OWNADDR_I2C <= s_led_array.WR_OWNADDR_I2C;
s_spi_master_i.DIN <= FPGA_PROM_DIN;
FPGA_PROM_CCLK <= s_spi_master_o.CCLK; s_i2c_slave_i.SCL_I <= SCL_I;
FPGA_PROM_CSO_B_N <= s_spi_master_o.CSO_B_N; s_i2c_slave_i.SDA_I <= SDA_I;
FPGA_PROM_MOSI <= s_spi_master_o.MOSI; SCL_O <= s_i2c_slave_o.SCL_O;
SCL_OE <= s_i2c_slave_o.SCL_OE;
s_rtm_i.RTMM_N <= FPGA_RTMM_N; SDA_O <= s_i2c_slave_o.SDA_O;
s_rtm_i.RTMP_N <= fpga_rtmp_n; SDA_OE <= s_i2c_slave_o.SDA_OE;
s_switch_i <= EXTRA_SWITCH; s_spi_master_i.DIN <= FPGA_PROM_DIN;
FPGA_PROM_CCLK <= s_spi_master_o.CCLK;
inst_image1_core: image1_core FPGA_PROM_CSO_B_N <= s_spi_master_o.CSO_B_N;
generic map(g_NUMBER_OF_CHANNELS => 6) FPGA_PROM_MOSI <= s_spi_master_o.MOSI;
port map(rst_n => RST_N,
clk_20MHz_i => CLK20_VCXO, s_rtm_i.RTMM_N <= FPGA_RTMM_N;
clk_125MHz_i => s_clk_125MHz, s_rtm_i.RTMP_N <= fpga_rtmp_n;
led_array_o => s_led_array,
led_front_n => PULSE_FRONT_LED_N, s_switch_i <= EXTRA_SWITCH;
led_rear_n => PULSE_REAR_LED_N,
pulse_i_front_n => FPGA_INPUT_TTL_N, inst_image1_core: image1_core
pulse_o_front => FPGA_OUT_TTL, generic map(g_NUMBER_OF_CHANNELS => 6)
pulse_i_rear => FPGA_BLO_IN, port map
pulse_o_rear => FPGA_TRIG_BLO, (
inv_i_n => INV_IN_N, rst_n => RST_N,
inv_o => INV_OUT, clk_20MHz_i => CLK20_VCXO,
i2c_slave_i => s_i2c_slave_i, clk_125MHz_i => s_clk_125MHz,
i2c_slave_o => s_i2c_slave_o, led_array_o => s_led_array,
FPGA_GA => FPGA_GA , led_front_n => PULSE_FRONT_LED_N,
FPGA_GAP => FPGA_GAP, led_rear_n => PULSE_REAR_LED_N,
spi_master_i => s_spi_master_i, pulse_i_front_n => FPGA_INPUT_TTL_N,
spi_master_o => s_spi_master_o, pulse_o_front => FPGA_OUT_TTL,
fpga_o_en => FPGA_OE, pulse_i_rear => FPGA_BLO_IN,
fpga_o_blo_en => FPGA_BLO_OE, pulse_o_rear => FPGA_TRIG_BLO,
fpga_o_ttl_en => FPGA_TRIG_TTL_OE, inv_i_n => INV_IN_N,
fpga_o_inv_en => FPGA_INV_OE, inv_o => INV_OUT,
level_i => LEVEL, i2c_slave_i => s_i2c_slave_i,
switch_i => s_switch_i(1), i2c_slave_o => s_i2c_slave_o,
manual_rst_n_o => MR_N, FPGA_GA => FPGA_GA ,
rtm_i => s_rtm_i); FPGA_GAP => FPGA_GAP,
spi_master_i => s_spi_master_i,
spi_master_o => s_spi_master_o,
fpga_o_en => FPGA_OE,
fpga_o_blo_en => FPGA_BLO_OE,
fpga_o_ttl_en => FPGA_TRIG_TTL_OE,
fpga_o_inv_en => FPGA_INV_OE,
level_i => LEVEL,
switch_i => s_switch_i(1),
manual_rst_n_o => MR_N,
rtm_i => s_rtm_i
);
end Behavioral; end Behavioral;
...@@ -24,19 +24,25 @@ use IEEE.NUMERIC_STD.ALL; ...@@ -24,19 +24,25 @@ use IEEE.NUMERIC_STD.ALL;
use work.ctdah_pkg.ALL; use work.ctdah_pkg.ALL;
entity basic_trigger_core is entity basic_trigger_core is
generic(g_CLK_PERIOD : TIME; generic
g_OUTPUT_PULSE_LENGTH : TIME; (
g_LED_BLINKING_LENGTH : TIME); g_CLK_PERIOD : TIME;
port (wb_rst_i : in STD_LOGIC; g_OUTPUT_PULSE_LENGTH : TIME;
wb_clk_i : in STD_LOGIC; g_LED_BLINKING_LENGTH : TIME
);
port
(
wb_rst_i : in STD_LOGIC;
wb_clk_i : in STD_LOGIC;
pulse_i : in STD_LOGIC; pulse_i : in STD_LOGIC;
pulse_o : out STD_LOGIC; pulse_o : out STD_LOGIC;
pulse_n_o : out STD_LOGIC; pulse_n_o : out STD_LOGIC;
crop_o : out STD_LOGIC; crop_o : out STD_LOGIC;
led_o : out STD_LOGIC); led_o : out STD_LOGIC
);
end basic_trigger_core; end basic_trigger_core;
architecture Behavioral of basic_trigger_core is architecture Behavioral of basic_trigger_core is
...@@ -59,44 +65,60 @@ architecture Behavioral of basic_trigger_core is ...@@ -59,44 +65,60 @@ architecture Behavioral of basic_trigger_core is
-- return v; -- return v;
-- end ledlen; -- end ledlen;
constant c_PULSE_LENGTH : NATURAL := g_OUTPUT_PULSE_LENGTH/g_CLK_PERIOD;
constant c_LED_LENGTH : NATURAL := g_LED_BLINKING_LENGTH/g_CLK_PERIOD;
constant c_PULSE_LENGTH : NATURAL := g_OUTPUT_PULSE_LENGTH/g_CLK_PERIOD; signal s_pulse : STD_LOGIC;
constant c_LED_LENGTH : NATURAL := g_LED_BLINKING_LENGTH/g_CLK_PERIOD;
signal s_pulse : STD_LOGIC;
signal s_deglitched_pulse : STD_LOGIC;
signal s_deglitched_pulse_d0 : STD_LOGIC;
signal s_pulse_parity : STD_LOGIC; signal s_deglitched_pulse : STD_LOGIC;
signal s_deglitched_pulse_d0 : STD_LOGIC;
signal s_pulse_parity : STD_LOGIC;
begin begin
s_pulse <= pulse_i; s_pulse <= pulse_i;
inst_debo: gc_debouncer cmp_debouncer: gc_debouncer
generic map( g_LENGTH => 2) generic map
port map(rst => wb_rst_i, (
clk => wb_clk_i, g_LENGTH => 2
input => s_pulse, )
output => s_deglitched_pulse, port map
glitch_mask => "11"); (
rst => wb_rst_i,
pulse_monostable : gc_simple_monostable clk => wb_clk_i,
generic map (g_PULSE_LENGTH => c_PULSE_LENGTH) input => s_pulse,
port map (rst => wb_rst_i, output => s_deglitched_pulse,
clk => wb_clk_i, glitch_mask => "11"
input => s_deglitched_pulse, );
output => pulse_o,
output_n => pulse_n_o); cmp_pulse_monostable : gc_simple_monostable
generic map
led_monostable : gc_simple_monostable (
generic map (g_PULSE_LENGTH => c_LED_LENGTH) g_PULSE_LENGTH => c_PULSE_LENGTH
port map (rst => wb_rst_i, )
clk => wb_clk_i, port map
input => s_deglitched_pulse, (
output => led_o, rst => wb_rst_i,
output_n => open); clk => wb_clk_i,
input => s_deglitched_pulse,
output => pulse_o,
output_n => pulse_n_o
);
cmp_led_monostable : gc_simple_monostable
generic map
(
g_PULSE_LENGTH => c_LED_LENGTH
)
port map
(
rst => wb_rst_i,
clk => wb_clk_i,
input => s_deglitched_pulse,
output => led_o,
output_n => open
);
end Behavioral; end Behavioral;
...@@ -29,11 +29,15 @@ use IEEE.NUMERIC_STD.ALL; ...@@ -29,11 +29,15 @@ use IEEE.NUMERIC_STD.ALL;
use UNISIM.VCOMPONENTS.ALL; use UNISIM.VCOMPONENTS.ALL;
entity basic_trigger_top is entity basic_trigger_top is
generic(g_NUMBER_OF_CHANNELS : NATURAL := 6; generic
(
g_NUMBER_OF_CHANNELS : NATURAL := 6;
g_CLK_PERIOD : TIME := 20 ns; g_CLK_PERIOD : TIME := 20 ns;
g_OUTPUT_PULSE_LENGTH : TIME := 1000 ns; g_OUTPUT_PULSE_LENGTH : TIME := 1000 ns;
g_LED_BLINKING_LENGTH : TIME := (10**6)*250 ns); g_LED_BLINKING_LENGTH : TIME := (10**6)*250 ns
port ( );
port
(
clk_i : in STD_LOGIC; clk_i : in STD_LOGIC;
rst_i : in STD_LOGIC; rst_i : in STD_LOGIC;
led_ttl_o : out STD_LOGIC; led_ttl_o : out STD_LOGIC;
...@@ -41,7 +45,7 @@ entity basic_trigger_top is ...@@ -41,7 +45,7 @@ entity basic_trigger_top is
fpga_o_ttl_en : out STD_LOGIC; fpga_o_ttl_en : out STD_LOGIC;
fpga_o_inv_en : out STD_LOGIC; fpga_o_inv_en : out STD_LOGIC;
fpga_o_blo_en : out STD_LOGIC; fpga_o_blo_en : out STD_LOGIC;
level_i : in STD_LOGIC; level_i : in STD_LOGIC;
switch_i : in STD_LOGIC; --! General enable switch_i : in STD_LOGIC; --! General enable
manual_rst_n_o : out STD_LOGIC; --! It allows power sequencing of the manual_rst_n_o : out STD_LOGIC; --! It allows power sequencing of the
--! 24V rail after a security given --! 24V rail after a security given
...@@ -61,40 +65,44 @@ end basic_trigger_top; ...@@ -61,40 +65,44 @@ end basic_trigger_top;
architecture Behavioral of basic_trigger_top is architecture Behavioral of basic_trigger_top is
signal s_pulse_i : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1); signal s_pulse_i : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
signal s_pulse_i_front : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1); signal s_pulse_i_front : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
signal s_pulse_o : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1); signal s_pulse_o : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
signal s_pulse_n_o : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1); signal s_pulse_n_o : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
signal s_led : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1); signal s_led : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
signal s_crop : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1) signal s_crop : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1) := (others => '0');
:= (others => '0'); signal s_level : STD_LOGIC;
signal s_level : STD_LOGIC;
signal s_fpga_o_en : STD_LOGIC;
signal s_fpga_o_en : STD_LOGIC; signal s_fpga_o_ttl_en : STD_LOGIC;
signal s_fpga_o_ttl_en : STD_LOGIC; signal s_fpga_o_inv_en : STD_LOGIC;
signal s_fpga_o_inv_en : STD_LOGIC; signal s_fpga_o_blo_en : STD_LOGIC;
signal s_fpga_o_blo_en : STD_LOGIC;
type delay_array is array (g_NUMBER_OF_CHANNELS downto 1) of STD_LOGIC_VECTOR(3 downto 0);
type delay_array is array (g_NUMBER_OF_CHANNELS downto 1) signal s_pulse_i_reg : delay_array;
of STD_LOGIC_VECTOR(3 downto 0);
signal s_pulse_i_reg : delay_array; component basic_trigger_core is
generic
component basic_trigger_core is (
generic(g_CLK_PERIOD : TIME := g_CLK_PERIOD; g_CLK_PERIOD : TIME := g_CLK_PERIOD;
g_OUTPUT_PULSE_LENGTH : TIME := g_OUTPUT_PULSE_LENGTH; g_OUTPUT_PULSE_LENGTH : TIME := g_OUTPUT_PULSE_LENGTH;
g_LED_BLINKING_LENGTH : TIME := g_LED_BLINKING_LENGTH); g_LED_BLINKING_LENGTH : TIME := g_LED_BLINKING_LENGTH
port (wb_rst_i : in STD_LOGIC; );
wb_clk_i : in STD_LOGIC; port
(
pulse_i : in STD_LOGIC; wb_rst_i : in STD_LOGIC;
pulse_o : out STD_LOGIC; wb_clk_i : in STD_LOGIC;
pulse_n_o : out STD_LOGIC;
pulse_i : in STD_LOGIC;
crop_o : out STD_LOGIC; pulse_o : out STD_LOGIC;
pulse_n_o : out STD_LOGIC;
led_o : out STD_LOGIC);
end component; crop_o : out STD_LOGIC;
led_o : out STD_LOGIC
);
end component;
begin begin
...@@ -109,7 +117,7 @@ begin ...@@ -109,7 +117,7 @@ begin
not pulse_i_front; not pulse_i_front;
s_pulse_i <= s_pulse_i_front or pulse_i_rear; s_pulse_i <= s_pulse_i_front or pulse_i_rear;
fpga_o_en <= s_fpga_o_en when switch_i = '0' else '0'; fpga_o_en <= s_fpga_o_en when (switch_i = '0') else '0';
fpga_o_ttl_en <= s_fpga_o_ttl_en; fpga_o_ttl_en <= s_fpga_o_ttl_en;
fpga_o_inv_en <= s_fpga_o_inv_en; fpga_o_inv_en <= s_fpga_o_inv_en;
fpga_o_blo_en <= s_fpga_o_blo_en; fpga_o_blo_en <= s_fpga_o_blo_en;
...@@ -121,47 +129,47 @@ begin ...@@ -121,47 +129,47 @@ begin
not s_pulse_o; not s_pulse_o;
pulse_o_rear <= s_pulse_o; pulse_o_rear <= s_pulse_o;
inv_o <= inv_i;--! As we have one Schmitt inverter in the input, --! As we have one Schmitt inverter in the input,
--! and a buffer in the output, there's no need --! and a buffer in the output, there's no need
--! to invert here. --! to invert here.
inv_o <= inv_i;
i_repetitors: for i in 1 to g_NUMBER_OF_CHANNELS generate
begin gen_trig_cores: for i in 1 to g_NUMBER_OF_CHANNELS generate
trigger: basic_trigger_core trigger: basic_trigger_core
port map port map
( (
wb_rst_i => rst_i, wb_rst_i => rst_i,
wb_clk_i => clk_i, wb_clk_i => clk_i,
pulse_i => s_pulse_i(i), pulse_i => s_pulse_i(i),
pulse_o => s_pulse_o(i), pulse_o => s_pulse_o(i),
pulse_n_o => s_pulse_n_o(i), pulse_n_o => s_pulse_n_o(i),
crop_o => open, crop_o => open,
led_o => s_led(i) led_o => s_led(i)
); );
end generate i_repetitors; end generate gen_trig_cores;
--! @brief Process to lock the enables so to avoid output glitches --! @brief Process to lock the enables so to avoid output glitches
--! on the startup. --! on the startup.
--! @param clk_i Main clock used in this clock domain. --! @param clk_i Main clock used in this clock domain.
p_reset_chain : process(clk_i) is p_reset_chain : process(clk_i) is
begin begin
if rising_edge(clk_i) then if rising_edge(clk_i) then
if rst_i = '1' then if rst_i = '1' then
--! First we reset the FPGA general output enable --! First we reset the FPGA general output enable
--! Then we let one clock delay for the rest of signals --! Then we let one clock delay for the rest of signals
manual_rst_n_o <= '0'; manual_rst_n_o <= '0';
s_fpga_o_en <= '0'; s_fpga_o_en <= '0';
s_fpga_o_ttl_en <= '0'; s_fpga_o_ttl_en <= '0';
s_fpga_o_inv_en <= '0'; s_fpga_o_inv_en <= '0';
s_fpga_o_blo_en <= '0'; s_fpga_o_blo_en <= '0';
else else
manual_rst_n_o <= '1'; manual_rst_n_o <= '1';
s_fpga_o_en <= '1'; s_fpga_o_en <= '1';
s_fpga_o_ttl_en <= s_fpga_o_en; s_fpga_o_ttl_en <= s_fpga_o_en;
s_fpga_o_inv_en <= s_fpga_o_en; s_fpga_o_inv_en <= s_fpga_o_en;
s_fpga_o_blo_en <= s_fpga_o_en; s_fpga_o_blo_en <= s_fpga_o_en;
end if; end if;
end if; end if;
end process p_reset_chain; end process p_reset_chain;
end Behavioral; end Behavioral;
...@@ -41,15 +41,17 @@ use IEEE.STD_LOGIC_1164.ALL; ...@@ -41,15 +41,17 @@ use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL; use IEEE.NUMERIC_STD.ALL;
entity gc_counter is entity gc_counter is
generic( generic
g_DATA_WIDTH: NATURAL (
); g_DATA_WIDTH: NATURAL
port ( );
clk_i : in STD_LOGIC; port
rst_i : in STD_LOGIC; (
en_i : in STD_LOGIC; clk_i : in STD_LOGIC;
cnt_o : out STD_LOGIC_VECTOR (g_DATA_WIDTH - 1 downto 0) rst_i : in STD_LOGIC;
); en_i : in STD_LOGIC;
cnt_o : out STD_LOGIC_VECTOR (g_DATA_WIDTH - 1 downto 0)
);
end gc_counter; end gc_counter;
architecture Behavioral of gc_counter is architecture Behavioral of gc_counter is
...@@ -57,24 +59,17 @@ architecture Behavioral of gc_counter is ...@@ -57,24 +59,17 @@ architecture Behavioral of gc_counter is
begin begin
main_proc: process(clk_i, rst_i) p_main: process(clk_i, rst_i)
variable cnt_s : UNSIGNED(g_DATA_WIDTH - 1 downto 0);
variable cnt_s : UNSIGNED(g_DATA_WIDTH - 1 downto 0); begin
if rst_i = '1' then
begin cnt_s := (others => '0');
elsif rising_edge(clk_i) then
if rst_i = '1' then if en_i = '1' then
cnt_s := (others => '0'); cnt_s := cnt_s + 1;
elsif rising_edge(clk_i) then
if en_i = '1' then
-- Increment the counter if counting is enabled
cnt_s := cnt_s + 1;
else
end if;
else
end if; end if;
cnt_o <= std_logic_vector(cnt_s); end if;
cnt_o <= std_logic_vector(cnt_s);
end process; end process p_main;
end Behavioral; end Behavioral;
...@@ -35,49 +35,51 @@ entity gc_debouncer is ...@@ -35,49 +35,51 @@ entity gc_debouncer is
end gc_debouncer; end gc_debouncer;
architecture Behavioral of gc_debouncer is architecture Behavioral of gc_debouncer is
-- Signals
signal meta_ff1 : std_logic;
signal delay_s : std_logic_vector(g_LENGTH - 1 downto 0);
signal meta_ff1 : std_logic; component gc_ff
signal delay_s : std_logic_vector(g_LENGTH - 1 downto 0); port
(
component gc_ff Q : out STD_LOGIC;
port ( C : in STD_LOGIC;
Q : out STD_LOGIC; CLR : in STD_LOGIC;
C : in STD_LOGIC; D : in STD_LOGIC
CLR : in STD_LOGIC; );
D : in STD_LOGIC end component;
);
end component;
begin begin
ff1: gc_ff ff1: gc_ff
port map( port map
Q => meta_ff1, (
C => clk, Q => meta_ff1,
CLR => rst, C => clk,
D => input CLR => rst,
); D => input
);
ff2: gc_ff ff2: gc_ff
port map( port map
Q => delay_s(0), (
C => clk, Q => delay_s(0),
CLR => rst, C => clk,
D => meta_ff1 CLR => rst,
); D => meta_ff1
);
-- Metastability solved here
delay_line: for i in 1 to g_LENGTH-1 generate -- Metastability solved here
gen_delay_line: for i in 1 to g_LENGTH-1 generate
D_Flip_Flop : gc_ff D_Flip_Flop : gc_ff
port map ( port map
Q => delay_s(i), (
C => clk, Q => delay_s(i),
CLR => rst, C => clk,
D => delay_s(i-1)); CLR => rst,
end generate delay_line; D => delay_s(i-1)
);
end generate gen_delay_line;
process (clk) process (clk)
begin begin
......
...@@ -23,12 +23,13 @@ use IEEE.NUMERIC_STD.ALL; ...@@ -23,12 +23,13 @@ use IEEE.NUMERIC_STD.ALL;
entity gc_ff is entity gc_ff is
port( port
Q : out STD_LOGIC; (
C : in STD_LOGIC; Q : out STD_LOGIC;
CLR : in STD_LOGIC; C : in STD_LOGIC;
D : in STD_LOGIC CLR : in STD_LOGIC;
); D : in STD_LOGIC
);
end gc_ff; end gc_ff;
architecture Behavioral of gc_ff is architecture Behavioral of gc_ff is
...@@ -43,7 +44,6 @@ begin ...@@ -43,7 +44,6 @@ begin
else else
Q <= D; Q <= D;
end if; end if;
else
end if; end if;
end process; end process;
......
...@@ -23,71 +23,74 @@ use IEEE.NUMERIC_STD.ALL; ...@@ -23,71 +23,74 @@ use IEEE.NUMERIC_STD.ALL;
entity gc_simple_monostable is entity gc_simple_monostable is
generic(g_PULSE_LENGTH : NATURAL := 20); generic
port ( (
rst : in STD_LOGIC; g_PULSE_LENGTH : NATURAL := 20
clk : in STD_LOGIC; );
input : in STD_LOGIC; port
output : out STD_LOGIC; (
output_n : out STD_LOGIC); rst : in STD_LOGIC;
clk : in STD_LOGIC;
input : in STD_LOGIC;
output : out STD_LOGIC;
output_n : out STD_LOGIC
);
end gc_simple_monostable; end gc_simple_monostable;
architecture Behavioral of gc_simple_monostable is architecture Behavioral of gc_simple_monostable is
constant c_count_max : UNSIGNED (63 downto 0) := constant c_count_max : UNSIGNED (63 downto 0) := to_unsigned(g_PULSE_LENGTH, 64);
to_unsigned(g_PULSE_LENGTH, 64);
signal s_count : UNSIGNED (63 downto 0) := to_unsigned(0, 64); signal s_count : UNSIGNED (63 downto 0) := to_unsigned(0, 64);
signal s_input : STD_LOGIC := '0'; signal s_input : STD_LOGIC := '0';
signal s_input_d0 : STD_LOGIC := '0'; signal s_input_d0 : STD_LOGIC := '0';
signal s_running : STD_LOGIC := '0'; signal s_running : STD_LOGIC := '0';
signal s_output : STD_LOGIC := '0'; signal s_output : STD_LOGIC := '0';
signal s_output_n : STD_LOGIC := '1'; signal s_output_n : STD_LOGIC := '1';
begin begin
s_input <= input; s_input <= input;
output <= s_output; output <= s_output;
output_n <= s_output_n; output_n <= s_output_n;
p_mono: process(clk) p_mono: process(clk)
begin begin
if rising_edge(clk) then if rising_edge(clk) then
if rst = '1' then if rst = '1' then
s_count <= to_unsigned(0, 64); s_count <= to_unsigned(0, 64);
s_running <= '0'; s_running <= '0';
s_input_d0 <= '0'; s_input_d0 <= '0';
s_output <= '0'; s_output <= '0';
s_output_n <= '1'; s_output_n <= '1';
else else
s_input_d0 <= s_input; s_input_d0 <= s_input;
s_output <= '0'; s_output <= '0';
s_output_n <= '1'; s_output_n <= '1';
s_count <= to_unsigned(0, 64); s_count <= to_unsigned(0, 64);
s_running <= '0'; s_running <= '0';
if (s_input = '1') if (s_input = '1') and (s_input_d0 = '0') then
and (s_input_d0 = '0') then s_count <= s_count + 1;
s_count <= s_count + 1; s_running <= '1';
s_running <= '1'; s_output <= '1';
s_output <= '1'; s_output_n <= '0';
s_output_n <= '0'; elsif (s_running = '1') then
elsif s_running = '1' then if (s_count < c_count_max) then
if s_count < c_count_max then s_count <= s_count + 1;
s_count <= s_count + 1; s_running <= '1';
s_running <= '1'; s_output <= '1';
s_output <= '1'; s_output_n <= '0';
s_output_n <= '0'; else
else s_count <= to_unsigned(0, 64);
s_count <= to_unsigned(0, 64); s_running <= '0';
s_running <= '0'; end if;
end if;
end if;
end if; end if;
end if; end if;
end if;
end process; end process;
end Behavioral; end Behavioral;
...@@ -29,220 +29,246 @@ use work.i2c_slave_pkg.ALL; ...@@ -29,220 +29,246 @@ use work.i2c_slave_pkg.ALL;
use work.ctdah_pkg.ALL; use work.ctdah_pkg.ALL;
entity i2c_bit is entity i2c_bit is
port (rst_i : in STD_LOGIC; port
wb_clk_i : in STD_LOGIC; (
rst_i : in STD_LOGIC;
wb_clk_i : in STD_LOGIC;
sda_i : in STD_LOGIC; sda_i : in STD_LOGIC;
scl_i : in STD_LOGIC; scl_i : in STD_LOGIC;
start_o : out STD_LOGIC; start_o : out STD_LOGIC;
pause_o : out STD_LOGIC; pause_o : out STD_LOGIC;
rcved_o : out STD_LOGIC; rcved_o : out STD_LOGIC;
done_o : out STD_LOGIC); done_o : out STD_LOGIC
);
end i2c_bit; end i2c_bit;
architecture Behavioral of i2c_bit is architecture Behavioral of i2c_bit is
type t_state is (
R0_RESET,
S0_IDLE,
S1A_HIGH_TMP,
S1A_HIGH,
S1B_LOW_TMP,
S1B_LOW,
S2A_START_TMP,
S2A_START,
S2B_STOP_DETECT,
Q1_ERROR
);
type bit_fsm is (R0_RESET, -- It specifies the maximum number of stages that will be employed for
S0_IDLE, -- deglitching. Clocked with wb_clk_i
S1A_HIGH_TMP,
S1A_HIGH,
S1B_LOW_TMP,
S1B_LOW,
S2A_START_TMP,
S2A_START,
S2B_STOP_DETECT,
Q1_ERROR);
--! It specifies the maximum number of stages that will be employed for
--! deglitching. Clocked with wb_clk_i
constant c_MAX_GLITCH_DELAY : NATURAL := 6; constant c_MAX_GLITCH_DELAY : NATURAL := 6;
--! Three delay stages out of six
-- Three delay stages out of six
constant c_GLITCH_MASK : STD_LOGIC_VECTOR (5 downto 0) := "000111"; constant c_GLITCH_MASK : STD_LOGIC_VECTOR (5 downto 0) := "000111";
signal s_sda_deglitched : STD_LOGIC; signal s_sda_deglitched : STD_LOGIC;
signal s_sda_deglitched_d1 : STD_LOGIC; signal s_sda_deglitched_d1 : STD_LOGIC;
signal s_scl_deglitched : STD_LOGIC; signal s_scl_deglitched : STD_LOGIC;
signal s_scl_deglitched_d1 : STD_LOGIC; signal s_scl_deglitched_d1 : STD_LOGIC;
signal i2c_bit_fsm : bit_fsm; signal state : t_state;
signal s_scl_rising : STD_LOGIC; signal s_scl_rising : STD_LOGIC;
signal s_scl_falling : STD_LOGIC; signal s_scl_falling : STD_LOGIC;
begin begin
cmp_scl_debouncer: i2c_debouncer
generic map
(
g_LENGTH => 6
)
port map
(
rst => rst_i,
clk => wb_clk_i,
input => scl_i,
output => s_scl_deglitched,
glitch_mask => c_GLITCH_MASK
);
-- Probably safer operation if we add one extra delay to the scl line.
-- However, we increase the glitch time while placing an ACK.
-- We have not implemented a counter to foresee the glitch due to the
-- strange behaviour in Renesas I2C which rescales dinamically (that
-- means in the middle of an I2C transaction) the scl line.
-- Due to the variability of the scl period when an I2C transaction is
cmp_scl_ff: gc_ff
port map
(
Q => s_scl_deglitched_d1,
C => wb_clk_i,
CLR => rst_i,
D => s_scl_deglitched
);
cmp_sda_debounce: i2c_debouncer
generic map
(
g_LENGTH => 6
)
port map
(
rst => rst_i,
clk => wb_clk_i,
input => sda_i,
output => s_sda_deglitched,
glitch_mask => c_GLITCH_MASK
);
debouncer_scl_i: i2c_debouncer cmp_sda_ff: gc_ff
generic map(g_LENGTH => 6) port map
port map(rst => rst_i, (
clk => wb_clk_i, Q => s_sda_deglitched_d1,
input => scl_i, C => wb_clk_i,
output => s_scl_deglitched, CLR => rst_i,
glitch_mask => c_GLITCH_MASK); D => s_sda_deglitched
);
--! Probably safer operation if we add one extra delay to the scl line.
--! However, we increase the glitch time while placing an ACK. -- This is the process that samples the scl for detecting
--! We have not implemented a counter to foresee the glitch due to the -- rise and falling edges
--! strange behaviour in Renesas I2C which rescales dinamically (that reg_proc: process (wb_clk_i)
--! means in the middle of an I2C transaction) the scl line. begin
--! Due to the variability of the scl period when an I2C transaction is if rising_edge(wb_clk_i) then
--! in progress, it is better not to add a "guesser" of the scl period. if (s_scl_deglitched xor s_scl_deglitched_d1) = '1' then
if s_scl_deglitched = '0' then
ff1_scl : gc_ff s_scl_falling <= '1';
port map(Q => s_scl_deglitched_d1, else
C => wb_clk_i, s_scl_rising <= '1';
CLR => rst_i, end if;
D => s_scl_deglitched);
debouncer_sda_i: i2c_debouncer
generic map(g_LENGTH => 6)
port map(rst => rst_i,
clk => wb_clk_i,
input => sda_i,
output => s_sda_deglitched,
glitch_mask => c_GLITCH_MASK);
ff1_sda : gc_ff
port map(Q => s_sda_deglitched_d1,
C => wb_clk_i,
CLR => rst_i,
D => s_sda_deglitched);
--! This is the process that samples the scl for detecting
--! rise and falling edges
reg_proc: process (wb_clk_i)
begin
if rising_edge(wb_clk_i) then
if (s_scl_deglitched xor s_scl_deglitched_d1) = '1' then
if s_scl_deglitched = '0' then
s_scl_falling <= '1';
else
s_scl_rising <= '1';
end if;
else
s_scl_rising <= '0';
s_scl_falling <= '0';
end if;
else else
s_scl_rising <= '0';
s_scl_falling <= '0';
end if; end if;
end process; end if;
end process;
--! @brief Combiantion process to update the outputs.
--! @param i2c_bit_fsm Finite state machine for the SDA bit detection. -- Combinatorial process to update the outputs.
p_comb_output: process(i2c_bit_fsm) p_comb_output: process(state)
begin begin
start_o <= '0'; start_o <= '0';
pause_o <= '0'; pause_o <= '0';
rcved_o <= '0'; rcved_o <= '0';
--! done_o is a one-clock signal done_o <= '0';
done_o <= '0';
case i2c_bit_fsm is case state is
when R0_RESET =>
null; when R0_RESET =>
when S0_IDLE => null;
null;
when S1A_HIGH => when S0_IDLE =>
rcved_o <= '1'; null;
done_o <= '1';
when S1B_LOW => when S1A_HIGH =>
rcved_o <= '0'; rcved_o <= '1';
done_o <= '1'; done_o <= '1';
when S2A_START =>
start_o <= '1'; when S1B_LOW =>
done_o <= '1'; rcved_o <= '0';
when S2B_STOP_DETECT => done_o <= '1';
pause_o <= '1';
done_o <= '1'; when S2A_START =>
when Q1_ERROR => start_o <= '1';
null; done_o <= '1';
when others =>
null; when S2B_STOP_DETECT =>
end case; pause_o <= '1';
end process; done_o <= '1';
when Q1_ERROR =>
--! @brief The fsm of this module, later on the sda sampled line is null;
--! validated in the falling edge of scl.
--! @bparam wb_clk_i when others =>
p_fsm: process(wb_clk_i) null;
begin
if rising_edge(wb_clk_i) then end case;
if rst_i = '1' then end process p_comb_output;
i2c_bit_fsm <= R0_RESET;
--! After a detection of a falling edge we update the
--! detection of a '0', a '1' and a start condition. -- The fsm of this module, later on the sda sampled line is
elsif s_scl_falling = '1' then -- validated in the falling edge of scl.
case i2c_bit_fsm is p_fsm: process(wb_clk_i)
when S1A_HIGH_TMP => begin
i2c_bit_fsm <= S1A_HIGH; if rising_edge(wb_clk_i) then
when S1B_LOW_TMP => if (rst_i = '1') then
i2c_bit_fsm <= S1B_LOW; state <= R0_RESET;
when S2A_START_TMP =>
i2c_bit_fsm <= S2A_START; elsif (s_scl_falling = '1') then
when others => -- After a detection of a falling edge we update the
i2c_bit_fsm <= S0_IDLE; -- detection of a '0', a '1' and a start condition.
end case; case state is
when S1A_HIGH_TMP =>
--! When a rising edge is detected we annotate the first value state <= S1A_HIGH;
--! in SDA: either a temporary '0' or '1'
elsif s_scl_rising = '1' then when S1B_LOW_TMP =>
if s_sda_deglitched_d1 = '1' then state <= S1B_LOW;
i2c_bit_fsm <= S1A_HIGH_TMP;
else when S2A_START_TMP =>
i2c_bit_fsm <= S1B_LOW_TMP; state <= S2A_START;
end if;
when others =>
else state <= S0_IDLE;
--! When we are in high level of a scl cycle, we keep on updating end case;
--! the fsm
if s_scl_deglitched = '1' then elsif (s_scl_rising = '1') then
case i2c_bit_fsm is -- When a rising edge is detected we annotate the first value
--! Just for random bit swapped coverage. -- in SDA: either a temporary '0' or '1'
when S0_IDLE => if (s_sda_deglitched_d1 = '1') then
if s_sda_deglitched = '1' then state <= S1A_HIGH_TMP;
i2c_bit_fsm <= S1A_HIGH_TMP; else
else state <= S1B_LOW_TMP;
i2c_bit_fsm <= S1B_LOW_TMP; end if;
end if;
when S1A_HIGH_TMP =>
if s_sda_deglitched = '0' then
-- The detection of the start condition will be reported
-- in the next SCL rising edge.
i2c_bit_fsm <= S2A_START_TMP;
else
end if;
when S1B_LOW_TMP =>
if s_sda_deglitched = '1' then
-- The detection of the pause condition MUST be
-- reported immediately.
i2c_bit_fsm <= S2B_STOP_DETECT;
else
end if;
when S2A_START_TMP =>
if s_sda_deglitched = '1' then
--! This happens if the deglitching is not enough
i2c_bit_fsm <= Q1_ERROR;
else
end if;
when others =>
i2c_bit_fsm <= S0_IDLE;
end case;
else
if s_scl_deglitched_d1 = '0' then
i2c_bit_fsm <= S0_IDLE;
else
end if;
end if;
end if;
else else
-- When we are in high level of a scl cycle, we keep on updating
-- the FSM
if (s_scl_deglitched = '1') then
case state is
-- Just for random bit swapped coverage.
when S0_IDLE =>
if (s_sda_deglitched = '1') then
state <= S1A_HIGH_TMP;
else
state <= S1B_LOW_TMP;
end if;
when S1A_HIGH_TMP =>
if s_sda_deglitched = '0' then
-- The detection of the start condition will be reported
-- in the next SCL rising edge.
state <= S2A_START_TMP;
end if;
when S1B_LOW_TMP =>
if s_sda_deglitched = '1' then
-- The detection of the pause condition MUST be
-- reported immediately.
state <= S2B_STOP_DETECT;
end if;
when S2A_START_TMP =>
if (s_sda_deglitched = '1') then
--! This happens if the deglitching is not enough
state <= Q1_ERROR;
end if;
when others =>
state <= S0_IDLE;
end case;
else
if (s_scl_deglitched_d1 = '0') then
state <= S0_IDLE;
end if;
end if;
end if; end if;
end process; end if;
end process p_fsm;
end Behavioral; end Behavioral;
...@@ -30,61 +30,73 @@ use work.i2c_slave_pkg.ALL; ...@@ -30,61 +30,73 @@ use work.i2c_slave_pkg.ALL;
use work.ctdah_pkg.ALL; use work.ctdah_pkg.ALL;
entity i2c_debouncer is entity i2c_debouncer is
generic (g_LENGTH : NATURAL := c_DEBOUNCE_LENGTH); generic
port (rst : in STD_LOGIC; (
clk : in STD_LOGIC; g_LENGTH : NATURAL := c_DEBOUNCE_LENGTH
input : in STD_LOGIC; );
output : out STD_LOGIC; port
glitch_mask : in STD_LOGIC_VECTOR(g_LENGTH - 1 downto 0)); (
rst : in STD_LOGIC;
clk : in STD_LOGIC;
input : in STD_LOGIC;
output : out STD_LOGIC;
glitch_mask : in STD_LOGIC_VECTOR(g_LENGTH - 1 downto 0)
);
end i2c_debouncer; end i2c_debouncer;
architecture Behavioral of i2c_debouncer is architecture Behavioral of i2c_debouncer is
signal s_input_d0 : STD_LOGIC; signal s_input_d0 : STD_LOGIC;
--! The first of this signal is already stable (ff'ed two times at [0]) -- The first of this signal is already stable (ff'ed two times at [0])
signal s_delay : STD_LOGIC_VECTOR(g_LENGTH - 1 downto 0); signal s_delay : STD_LOGIC_VECTOR(g_LENGTH - 1 downto 0);
begin begin
ff1: gc_ff cmp_ff1: gc_ff
port map( port map
Q => s_input_d0, (
C => clk, Q => s_input_d0,
CLR => rst, C => clk,
D => input); CLR => rst,
D => input
);
ff2: gc_ff cmp_ff2: gc_ff
port map( port map
Q => s_delay(0), (
C => clk, Q => s_delay(0),
CLR => rst, C => clk,
D => s_input_d0); CLR => rst,
D => s_input_d0
);
sync_delay_line: for i in 1 to g_LENGTH - 1 generate gen_sync_delay_line: for i in 1 to g_LENGTH - 1 generate
D_Flip_Flop : gc_ff cmp_ff: gc_ff
port map ( port map
Q => s_delay(i), (
C => clk, Q => s_delay(i),
CLR => rst, C => clk,
D => s_delay(i-1)); CLR => rst,
end generate sync_delay_line; D => s_delay(i-1)
);
end generate gen_sync_delay_line;
p_output : process (clk) p_output: process (clk)
begin begin
if rising_edge(clk) then if rising_edge(clk) then
if rst = '1' then if (rst = '1') then
output <= '1'; output <= '1';
else else
--! We can deglitch either zeros or ones -- We can deglitch either zeros or ones
if ( (s_delay and glitch_mask) = glitch_mask if ( (s_delay and glitch_mask) = glitch_mask
or (not(s_delay)and glitch_mask) = glitch_mask) then or (not(s_delay) and glitch_mask) = glitch_mask) then
output <= s_delay(0); output <= s_delay(0);
else else
--! Internall pull-up of the pin -- Internall pull-up of the pin
output <= '1'; output <= '1';
end if; end if;
end if; end if;
end if; end if;
end process p_output; end process p_output;
end Behavioral; end Behavioral;
...@@ -29,308 +29,293 @@ use IEEE.NUMERIC_STD.ALL; ...@@ -29,308 +29,293 @@ use IEEE.NUMERIC_STD.ALL;
use work.i2c_slave_pkg.ALL; use work.i2c_slave_pkg.ALL;
entity i2c_regs is entity i2c_regs is
port (wb_clk_i : in STD_LOGIC; port
wb_rst_i : in STD_LOGIC; (
wb_clk_i : in STD_LOGIC;
wb_master_we_o : out STD_LOGIC; wb_rst_i : in STD_LOGIC;
wb_master_stb_o : out STD_LOGIC;
wb_master_cyc_o : out STD_LOGIC; wb_master_we_o : out STD_LOGIC;
wb_master_sel_o : out STD_LOGIC_VECTOR (3 downto 0); wb_master_stb_o : out STD_LOGIC;
wb_master_data_i : in STD_LOGIC_VECTOR (31 downto 0); wb_master_cyc_o : out STD_LOGIC;
wb_master_data_o : out STD_LOGIC_VECTOR (31 downto 0); wb_master_sel_o : out STD_LOGIC_VECTOR (3 downto 0);
wb_master_addr_o : out STD_LOGIC_VECTOR (15 downto 0); wb_master_data_i : in STD_LOGIC_VECTOR (31 downto 0);
wb_master_ack_i : in STD_LOGIC; wb_master_data_o : out STD_LOGIC_VECTOR (31 downto 0);
wb_master_rty_i : in STD_LOGIC; wb_master_addr_o : out STD_LOGIC_VECTOR (15 downto 0);
wb_master_err_i : in STD_LOGIC; wb_master_ack_i : in STD_LOGIC;
wb_master_rty_i : in STD_LOGIC;
-- These are the registers offers to others modules of the FPGA wb_master_err_i : in STD_LOGIC;
wb_slave_we_i : in STD_LOGIC;
wb_slave_stb_i : in STD_LOGIC; -- These are the registers offers to others modules of the FPGA
wb_slave_cyc_i : in STD_LOGIC; wb_slave_we_i : in STD_LOGIC;
wb_slave_sel_i : in STD_LOGIC_VECTOR (3 downto 0); wb_slave_stb_i : in STD_LOGIC;
wb_slave_data_i : in STD_LOGIC_VECTOR (31 downto 0); wb_slave_cyc_i : in STD_LOGIC;
wb_slave_data_o : out STD_LOGIC_VECTOR (31 downto 0); wb_slave_sel_i : in STD_LOGIC_VECTOR (3 downto 0);
wb_slave_addr_i : in STD_LOGIC_VECTOR (3 downto 0); wb_slave_data_i : in STD_LOGIC_VECTOR (31 downto 0);
wb_slave_ack_o : out STD_LOGIC; wb_slave_data_o : out STD_LOGIC_VECTOR (31 downto 0);
wb_slave_rty_o : out STD_LOGIC; wb_slave_addr_i : in STD_LOGIC_VECTOR (3 downto 0);
wb_slave_err_o : out STD_LOGIC; wb_slave_ack_o : out STD_LOGIC;
wb_slave_rty_o : out STD_LOGIC;
-- These are the registers that are offered to the i2c slave core wb_slave_err_o : out STD_LOGIC;
CTR0_o : out STD_LOGIC_VECTOR (r_CTR0'a_length - 1 downto 0);
LT_i : in STD_LOGIC_VECTOR (r_LT'a_length -1 downto 0); -- These are the registers that are offered to the i2c slave core
DRXA_i : in STD_LOGIC_VECTOR (r_DRX'a_length - 1 downto 0); CTR0_o : out STD_LOGIC_VECTOR (r_CTR0'a_length - 1 downto 0);
DRXB_i : in STD_LOGIC_VECTOR (r_DRX'a_length - 1 downto 0); LT_i : in STD_LOGIC_VECTOR (r_LT'a_length -1 downto 0);
DRXA_i : in STD_LOGIC_VECTOR (r_DRX'a_length - 1 downto 0);
pf_wb_addr_i : in STD_LOGIC; DRXB_i : in STD_LOGIC_VECTOR (r_DRX'a_length - 1 downto 0);
pf_wb_data_o : out STD_LOGIC_VECTOR(31 downto 0);
rd_done_i : in STD_LOGIC; pf_wb_addr_i : in STD_LOGIC;
wr_done_i : in STD_LOGIC; pf_wb_data_o : out STD_LOGIC_VECTOR(31 downto 0);
i2c_addr_i : in STD_LOGIC_VECTOR(6 downto 0)); rd_done_i : in STD_LOGIC;
wr_done_i : in STD_LOGIC;
i2c_addr_i : in STD_LOGIC_VECTOR(6 downto 0)
);
end i2c_regs; end i2c_regs;
architecture Behavioral of i2c_regs is architecture Behavioral of i2c_regs is
type t_wb_state is (
R0_RESET,
S0_IDLE,
S1P_WB_RD_RQT, --! Prefetch
S1_WB_RD_RQT,
S1N_WB_NOOP,
S1_PF_WB_DATA_OUT,
S2P_WB_WR_RQT, --! Prefetch
S2_WB_WR_RQT,
S2N_WB_NOOP,
S3_WB_ACK
);
type WB_BASIC_fsm is (R0_RESET, signal wb_state : t_wb_state := R0_RESET;
S0_IDLE,
S1P_WB_RD_RQT, --! Prefetch
S1_WB_RD_RQT,
S1N_WB_NOOP,
S1_PF_WB_DATA_OUT,
S2P_WB_WR_RQT, --! Prefetch
S2_WB_WR_RQT,
S2N_WB_NOOP,
S3_WB_ACK);
signal i2c_master_WB_BASIC_fsm : WB_BASIC_fsm := R0_RESET; signal s_wb_slave_addr : UNSIGNED(3 downto 0);
signal s_wb_slave_ack : STD_LOGIC := '0';
signal s_wb_slave_rty : STD_LOGIC := '0';
signal s_wb_slave_err : STD_LOGIC := '0';
signal s_wb_slave_addr : UNSIGNED(3 downto 0); signal s_CTR0_slv : STD_LOGIC_VECTOR (r_CTR0'a_length - 1 downto 0);
signal s_wb_slave_ack : STD_LOGIC := '0'; signal s_CTR0 : r_CTR0 := c_CTR0_default;
signal s_wb_slave_rty : STD_LOGIC := '0'; signal s_LT : r_LT;
signal s_wb_slave_err : STD_LOGIC := '0'; signal s_DTX : STD_LOGIC_VECTOR (r_DTX'a_length - 1 downto 0);
signal s_CTR0_slv : STD_LOGIC_VECTOR (r_CTR0'a_length - 1 downto 0); signal s_wb_master_we_o : STD_LOGIC;
signal s_CTR0 : r_CTR0 := c_CTR0_default;
signal s_LT : r_LT;
signal s_DTX : STD_LOGIC_VECTOR (r_DTX'a_length - 1 downto 0);
signal s_wb_master_ack_retries : STD_LOGIC_VECTOR(c_RETRY_LENGTH - 1 downto 0) := (others => '0');
signal s_wb_master_we_o : STD_LOGIC; signal s_wb_addr_rd : STD_LOGIC_VECTOR(15 downto 0) := (others => '0');
signal s_wb_master_ack_retries : STD_LOGIC_VECTOR(c_RETRY_LENGTH - 1 downto 0)
:= (others => '0');
signal s_wb_addr_rd : STD_LOGIC_VECTOR(15 downto 0) := (others => '0');
attribute keep : string;
signal wbm_dat_out : std_logic_vector(31 downto 0);
attribute keep of wbm_dat_out : signal is "true";
begin begin
wb_master_we_o <= s_wb_master_we_o; wb_master_we_o <= s_wb_master_we_o;
s_wb_slave_addr <= UNSIGNED(wb_slave_addr_i); s_wb_slave_addr <= UNSIGNED(wb_slave_addr_i);
s_CTR0_slv <= f_STD_LOGIC_VECTOR(s_CTR0); s_CTR0_slv <= f_STD_LOGIC_VECTOR(s_CTR0);
s_LT <= f_LT(LT_i); s_LT <= f_LT(LT_i);
wb_master_data_o <= wbm_dat_out;
wb_slave_ack_o <= s_wb_slave_ack;
wb_slave_ack_o <= s_wb_slave_ack; wb_slave_rty_o <= s_wb_slave_rty;
wb_slave_rty_o <= s_wb_slave_rty; wb_slave_err_o <= s_wb_slave_err;
wb_slave_err_o <= s_wb_slave_err;
CTR0_o <= s_CTR0_slv;
CTR0_o <= s_CTR0_slv; pf_wb_data_o <= s_DTX;
pf_wb_data_o <= s_DTX;
--! @brief Process that controls the retries of the wishbone interface
--! @brief Process that controls the retries of the wishbone interface --! @param wb_clk_i Main clock
--! @param wb_clk_i Main clock p_wb_master_retries: process (wb_clk_i)
p_wb_master_retries: process (wb_clk_i) begin
begin if rising_edge(wb_clk_i) then
if rising_edge(wb_clk_i) then if wb_state = S3_WB_ACK then
if i2c_master_WB_BASIC_fsm = S3_WB_ACK then s_wb_master_ack_retries(0) <= '1';
s_wb_master_ack_retries(0) <= '1'; for i in 1 to c_RETRY_LENGTH - 1 loop
for i in 1 to c_RETRY_LENGTH - 1 loop s_wb_master_ack_retries(i) <= s_wb_master_ack_retries(i-1);
s_wb_master_ack_retries(i) <= s_wb_master_ack_retries(i-1); end loop;
end loop; else
else s_wb_master_ack_retries <= (others => '0');
s_wb_master_ack_retries <= (others => '0');
end if;
end if; end if;
end process; end if;
end process;
--! @brief Process that outputs the wishbone
--! master interface. It should be noted -- Process that outputs the wishbone
--! that we double-buffer the received data -- master interface. It should be noted
--! to assure consistency of the data to be -- that we double-buffer the received data
--! read/written when repetitions of the -- to assure consistency of the data to be
--! wishbone master interface happen. -- read/written when repetitions of the
--! @param i2c_master_WB_BASIC_fsm fsm of the wishone master interface -- wishbone master interface happen.
wbmaster_comb_proc : process(wb_clk_i) p_wb_master: process(wb_clk_i)
begin
-- function f_le2be(val : std_logic_vector(31 downto 0)) if rising_edge(wb_clk_i) then
-- return std_logic_vector(31 downto 0) is if (wb_rst_i = '1') then
-- variable retval; s_wb_master_we_o <= '0';
-- begin wb_master_stb_o <= '0';
-- retval( 7 downto 0) <= val(31 downto 24); wb_master_cyc_o <= '0';
-- retval(15 downto 8) <= val(23 downto 16); wb_master_sel_o <= (others => '0');
-- retval(23 downto 16) <= val(15 downto 8); wb_master_data_o <= (others => '0');
-- retval(31 downto 24) <= val(7 downto 0); wb_master_addr_o <= (others => '0');
-- s_dtx <= (others => '0');
-- return retval; else
-- end function; case wb_state is
when R0_RESET =>
null;
begin
if rising_edge(wb_clk_i) then when S0_IDLE =>
if (wb_rst_i = '1') then null;
s_wb_master_we_o <= '0';
wb_master_stb_o <= '0'; when S1P_WB_RD_RQT =>
wb_master_cyc_o <= '0'; s_wb_addr_rd <= DRXA_i(23 downto 8);
wb_master_sel_o <= (others => '0');
wbm_dat_out <= (others => '0'); when S1_WB_RD_RQT =>
wb_master_addr_o <= (others => '0'); wb_master_cyc_o <= '1';
s_dtx <= (others => '0'); wb_master_stb_o <= '1';
else wb_master_sel_o <= X"F";
case i2c_master_WB_BASIC_fsm is wb_master_addr_o <= s_wb_addr_rd;
when R0_RESET =>
null; when S1N_WB_NOOP =>
when S0_IDLE => wb_master_cyc_o <= '1';
null; wb_master_stb_o <= '1';
when S1P_WB_RD_RQT => wb_master_sel_o <= X"F";
s_wb_addr_rd <= DRXA_i(23 downto 8); wb_master_addr_o <= s_wb_addr_rd;
when S1_WB_RD_RQT =>
wb_master_cyc_o <= '1'; when S1_PF_WB_DATA_OUT =>
wb_master_stb_o <= '1'; s_DTX <= wb_master_data_i;
wb_master_sel_o <= X"F";
wb_master_addr_o <= s_wb_addr_rd; when S2P_WB_WR_RQT =>
when S1N_WB_NOOP => null;
wb_master_cyc_o <= '1';
wb_master_stb_o <= '1'; when S2_WB_WR_RQT =>
wb_master_sel_o <= X"F"; wb_master_cyc_o <= '1';
wb_master_addr_o <= s_wb_addr_rd; wb_master_stb_o <= '1';
when S1_PF_WB_DATA_OUT => s_wb_master_we_o <= '1';
s_DTX <= wb_master_data_i; wb_master_sel_o <= X"F";
when S2P_WB_WR_RQT => wb_master_data_o <= f_ch_endian(DRXA_i);
null; wb_master_addr_o <= DRXB_i(15 downto 0);
when S2_WB_WR_RQT =>
wb_master_cyc_o <= '1'; when S2N_WB_NOOP =>
wb_master_stb_o <= '1'; wb_master_cyc_o <= '1';
s_wb_master_we_o <= '1'; wb_master_stb_o <= '1';
wb_master_sel_o <= X"F"; s_wb_master_we_o <= '1';
wbm_dat_out <= f_ch_endian(DRXA_i); wb_master_sel_o <= X"F";
wb_master_addr_o <= DRXB_i(15 downto 0); wb_master_data_o <= f_ch_endian(DRXA_i);
when S2N_WB_NOOP => wb_master_addr_o <= DRXB_i(15 downto 0);
wb_master_cyc_o <= '1';
wb_master_stb_o <= '1'; when S3_WB_ACK =>
s_wb_master_we_o <= '1'; -- null;
wb_master_sel_o <= X"F"; wb_master_cyc_o <= '0';
wbm_dat_out <= f_ch_endian(DRXA_i); wb_master_stb_o <= '0';
wb_master_addr_o <= DRXB_i(15 downto 0); s_wb_master_we_o <= '0';
when S3_WB_ACK => when others =>
-- null; null;
wb_master_cyc_o <= '0'; end case;
wb_master_stb_o <= '0';
s_wb_master_we_o <= '0';
when others =>
null;
end case;
end if;
end if;
end process;
--! @brief Process to rule slave wishbone outputs
--! @param wb_clk_i Main clock
p_wb_slave: process (wb_clk_i)
begin
if rising_edge(wb_clk_i) then
if i2c_master_WB_BASIC_fsm = R0_RESET then
s_CTR0 <= c_CTR0_default;
s_CTR0.I2C_ADDR <= UNSIGNED(i2c_addr_i);
s_wb_slave_ack <= '0';
s_wb_slave_rty <= '0';
s_wb_slave_err <= '0';
else
s_wb_slave_ack <= '0';
s_wb_slave_rty <= '0';
s_wb_slave_err <= '0';
if ( (wb_slave_stb_i = '1' and wb_slave_cyc_i = '1')
and s_wb_slave_ack = '0'
and s_wb_slave_rty = '0'
and s_wb_slave_err = '0') then
case wb_slave_we_i is
when '1' =>
s_wb_slave_ack <= '1';
case s_wb_slave_addr is
-- when c_CTR0_addr =>
-- s_CTR0 <= f_CTR0(wb_slave_data_i);
when others =>
s_wb_slave_ack <= '0';
s_wb_slave_err <= '1';
end case;
when others =>
s_wb_slave_ack <= '1';
case s_wb_slave_addr is
when c_CTR0_addr =>
wb_slave_data_o <= f_STD_LOGIC_VECTOR(s_CTR0);
when c_LT_addr =>
wb_slave_data_o <= f_STD_LOGIC_VECTOR(s_LT);
when c_DTX_addr =>
wb_slave_data_o <= s_DTX;
when c_DRXA_addr =>
wb_slave_data_o <= DRXA_i;
when c_DRXB_addr =>
wb_slave_data_o <= DRXB_i;
when others =>
s_wb_slave_ack <= '0';
s_wb_slave_err <= '1';
end case;
end case;
end if;
end if;
end if; end if;
end process; end if;
end process p_wb_master;
--! @brief This is the process that controls the wishbone master interface -- Process to rule slave wishbone outputs
--! which bridges the i2c interface with the wishbone interface. p_wb_slave: process (wb_clk_i)
--! @param wb_clk_i Main clock begin
p_master_fsm: process(wb_clk_i) if rising_edge(wb_clk_i) then
begin if wb_state = R0_RESET then
if rising_edge(wb_clk_i) then s_CTR0 <= c_CTR0_default;
if wb_rst_i = '1' then s_CTR0.I2C_ADDR <= UNSIGNED(i2c_addr_i);
--! Here is the part in which we propagate the reset, let one-clock s_wb_slave_ack <= '0';
--! for it. s_wb_slave_rty <= '0';
i2c_master_WB_BASIC_fsm <= R0_RESET; s_wb_slave_err <= '0';
else else
case i2c_master_WB_BASIC_fsm is s_wb_slave_ack <= '0';
when R0_RESET => s_wb_slave_rty <= '0';
i2c_master_WB_BASIC_fsm <= S0_IDLE; s_wb_slave_err <= '0';
when S0_IDLE => if (wb_slave_stb_i = '1') and (wb_slave_cyc_i = '1') and
if pf_wb_addr_i = '1' then (s_wb_slave_ack = '0') and (s_wb_slave_rty = '0') and
i2c_master_WB_BASIC_fsm <= S1P_WB_RD_RQT; (s_wb_slave_err = '0') then
elsif rd_done_i = '1' then case wb_slave_we_i is
i2c_master_WB_BASIC_fsm <= S2P_WB_WR_RQT; when '1' =>
end if; s_wb_slave_ack <= '1';
when S1P_WB_RD_RQT => case s_wb_slave_addr is
i2c_master_WB_BASIC_fsm <= S1_WB_RD_RQT; -- when c_CTR0_addr =>
when S1_WB_RD_RQT => -- s_CTR0 <= f_CTR0(wb_slave_data_i);
i2c_master_WB_BASIC_fsm <= S1N_WB_NOOP; when others =>
when S1N_WB_NOOP => s_wb_slave_ack <= '0';
i2c_master_WB_BASIC_fsm <= S1_PF_WB_DATA_OUT; s_wb_slave_err <= '1';
when S1_PF_WB_DATA_OUT => end case;
i2c_master_WB_BASIC_fsm <= S3_WB_ACK; when others =>
when S2P_WB_WR_RQT => s_wb_slave_ack <= '1';
i2c_master_WB_BASIC_fsm <= S2_WB_WR_RQT; case s_wb_slave_addr is
when S2_WB_WR_RQT => when c_CTR0_addr =>
i2c_master_WB_BASIC_fsm <= S2N_WB_NOOP; wb_slave_data_o <= f_STD_LOGIC_VECTOR(s_CTR0);
when S2N_WB_NOOP => when c_LT_addr =>
i2c_master_WB_BASIC_fsm <= S3_WB_ACK; wb_slave_data_o <= f_STD_LOGIC_VECTOR(s_LT);
when S3_WB_ACK => when c_DTX_addr =>
i2c_master_WB_BASIC_fsm <= R0_RESET; wb_slave_data_o <= s_DTX;
if wb_master_ack_i = '1' then when c_DRXA_addr =>
i2c_master_WB_BASIC_fsm <= R0_RESET; wb_slave_data_o <= DRXA_i;
when c_DRXB_addr =>
wb_slave_data_o <= DRXB_i;
when others =>
s_wb_slave_ack <= '0';
s_wb_slave_err <= '1';
end case;
end case;
end if;
end if;
end if;
end process;
-- This is the process that controls the wishbone master interface
-- which bridges the i2c interface with the wishbone interface.
-- wb_clk_i Main clock
p_master_fsm: process(wb_clk_i)
begin
if rising_edge(wb_clk_i) then
if wb_rst_i = '1' then
-- Here is the part in which we propagate the reset, let one-clock
-- for it.
wb_state <= R0_RESET;
else
case wb_state is
when R0_RESET =>
wb_state <= S0_IDLE;
when S0_IDLE =>
if pf_wb_addr_i = '1' then
wb_state <= S1P_WB_RD_RQT;
elsif rd_done_i = '1' then
wb_state <= S2P_WB_WR_RQT;
end if;
when S1P_WB_RD_RQT =>
wb_state <= S1_WB_RD_RQT;
when S1_WB_RD_RQT =>
wb_state <= S1N_WB_NOOP;
when S1N_WB_NOOP =>
wb_state <= S1_PF_WB_DATA_OUT;
when S1_PF_WB_DATA_OUT =>
wb_state <= S3_WB_ACK;
when S2P_WB_WR_RQT =>
wb_state <= S2_WB_WR_RQT;
when S2_WB_WR_RQT =>
wb_state <= S2N_WB_NOOP;
when S2N_WB_NOOP =>
wb_state <= S3_WB_ACK;
when S3_WB_ACK =>
wb_state <= R0_RESET;
if wb_master_ack_i = '1' then
wb_state <= R0_RESET;
else
if wb_master_rty_i = '1' then
if s_wb_master_ack_retries(c_RETRY_LENGTH - 1) = '1' then
-- We stop retrying to not block the core
wb_state <= R0_RESET;
else
if s_wb_master_we_o = '1' then
wb_state <= S1_WB_RD_RQT;
else else
if wb_master_rty_i = '1' then wb_state <= S2_WB_WR_RQT;
if s_wb_master_ack_retries(c_RETRY_LENGTH - 1) = '1' then
--! We stop retrying to not block the core
i2c_master_WB_BASIC_fsm <= R0_RESET;
else
if s_wb_master_we_o = '1' then
i2c_master_WB_BASIC_fsm <= S1_WB_RD_RQT;
else
i2c_master_WB_BASIC_fsm <= S2_WB_WR_RQT;
end if;
end if;
end if;
end if; end if;
when others => end if;
i2c_master_WB_BASIC_fsm <= R0_RESET; end if;
end case; end if;
end if; when others =>
else wb_state <= R0_RESET;
end case;
end if; end if;
end process p_master_fsm; else
end if;
end process p_master_fsm;
end Behavioral; end Behavioral;
...@@ -59,120 +59,125 @@ use work.i2c_slave_pkg.ALL; ...@@ -59,120 +59,125 @@ use work.i2c_slave_pkg.ALL;
use work.ctdah_pkg.ALL; use work.ctdah_pkg.ALL;
entity i2c_slave_core is entity i2c_slave_core is
generic(g_WB_CLK_PERIOD : TIME := 50 ns); generic
port ( (
clk_i : in STD_LOGIC; g_WB_CLK_PERIOD : time := 50 ns
rst_i : in STD_LOGIC; );
-- I2C pins port
sda_oen : out STD_LOGIC; (
sda_i : in STD_LOGIC; clk_i : in std_logic;
sda_o : out STD_LOGIC; rst_i : in std_logic;
scl_oen : out STD_LOGIC; -- I2C pins
scl_i : in STD_LOGIC; sda_oen : out std_logic;
scl_o : out STD_LOGIC; sda_i : in std_logic;
-- Registers directly accesible sda_o : out std_logic;
scl_oen : out std_logic;
CTR0_i : in STD_LOGIC_VECTOR (r_CTR0'a_length - 1 downto 0); scl_i : in std_logic;
LT_o : out STD_LOGIC_VECTOR (r_LT'a_length - 1 downto 0); scl_o : out std_logic;
DRXA_o : out STD_LOGIC_VECTOR (r_DRX'a_length - 1 downto 0);
DRXB_o : out STD_LOGIC_VECTOR (r_DRX'a_length - 1 downto 0); -- Registers
CTR0_i : in std_logic_vector (r_CTR0'a_length - 1 downto 0);
-- Alarms for controlling the i2c states LT_o : out std_logic_vector (r_LT'a_length - 1 downto 0);
pf_wb_addr_o : out STD_LOGIC; DRXA_o : out std_logic_vector (r_DRX'a_length - 1 downto 0);
pf_wb_data_i : in STD_LOGIC_VECTOR(31 downto 0); DRXB_o : out std_logic_vector (r_DRX'a_length - 1 downto 0);
rd_done_o : out STD_LOGIC;
wr_done_o : out STD_LOGIC); -- Alarms for controlling the i2c states
pf_wb_addr_o : out std_logic;
pf_wb_data_i : in std_logic_vector(31 downto 0);
rd_done_o : out std_logic;
wr_done_o : out std_logic
);
end i2c_slave_core; end i2c_slave_core;
architecture Behavioral of i2c_slave_core is
type SLA_fsm is (R0_RESET,
S0_IDLE,
S1_START_DETECT,
S2_I2C_ADDR,
S2A_I2C_ADDR_ACK,
S2NA_I2C_ADDR_NACK,
S3_WISHBONE_ADDR,
S3A_WISHBONE_ADDR_ACK,
S4_DETECT_OPERATION,
S5R_READ_SDA,
S5RA_READ_SDA_ACK,
S5W0_RESTART,
S5W1_I2C_ADDR,
S5W1A_I2C_ADDR_ACK,
S5W1NA_I2C_ADDR_NACK,
S5W2_WRITE_SDA,
S5W2A_WRITE_SDA_ACK,
S5W3_NACK,
S6_WAIT_START_PAUSE,
S7_PAUSE_DETECT);
-------------------------------------------------------------------------------
-- FSM signals for the I2C module
-------------------------------------------------------------------------------
-- Four signals are employed to govern the FSM behaviour and its outputs.
--
-- These signals are updated in done_comb_proc process, dependant of the done
-- signal coming from i2c_bit.vhd
-- Every time a deglitched falling edge of the SCL line is detected in the
-- aforementioned i2c_bit.vhd, the signals done, start_o, pause_o, rcved_o are
-- considered valid to be studied in i2c_slave_core.vhd processes.
--
-------------------------------------------------------------------------------
constant c_WATCHDOG_END_VALUE : NATURAL := c_WATCHDOG_DEADLINE/g_WB_CLK_PERIOD;
signal i2c_SLA_fsm : SLA_fsm := R0_RESET;
signal i2c_SLA_fsm_d0 : SLA_fsm := R0_RESET;
signal s_DRXA_slv : STD_LOGIC_VECTOR(r_DRX'a_length - 1 downto 0)
:= (others => '0');
signal s_DRXB_slv : STD_LOGIC_VECTOR(r_DRX'a_length - 1 downto 0)
:= (others => '0');
signal s_DRX_slv : STD_LOGIC_VECTOR(r_DRX'a_length*2 - 1 downto 0)
:= (others => '0');
signal s_DTX_slv : STD_LOGIC_VECTOR(r_DTX'a_length - 1 downto 0);
signal s_CTR0 : r_CTR0;
signal s_LT : r_LT := c_LT_default;
signal s_i2c_addr_ctr0 : STD_LOGIC_VECTOR(7 downto 0);
signal s_i2c_addr : STD_LOGIC_VECTOR(7 downto 0);
-------------------------------------------------------------------------------
-- i2c signals
-------------------------------------------------------------------------------
signal s_sda_o : STD_LOGIC;
signal s_sda_oen : STD_LOGIC;
signal s_bit_done : STD_LOGIC;
-- Bit counter signals
signal s_bit_cnt_slv : STD_LOGIC_VECTOR(c_COUNTER_WIDTH - 1 downto 0);
signal s_bit_cnt : unsigned(7 downto 0);
signal s_bit_cnt_rst : STD_LOGIC;
-- Byte counter signals
signal s_byte_cnt_slv : STD_LOGIC_VECTOR(c_COUNTER_WIDTH - 1 downto 0);
signal s_byte_cnt : unsigned(7 downto 0);
signal s_byte_cnt_rst : STD_LOGIC;
signal s_byte_cnt_en : STD_LOGIC := '0';
-- Interrupting signals (i2c_bit.vhd) architecture Behavioral of i2c_slave_core is
signal s_start_o : STD_LOGIC;
signal s_pause_o : STD_LOGIC;
signal s_rcved_o : STD_LOGIC;
signal s_pf_wb_data : STD_LOGIC_VECTOR(31 downto 0) := (others => '1');
signal s_pf_wb_data_arr : STD_LOGIC_VECTOR(31 downto 0) := (others => '1');
signal s_watchdog_cnt_rst : STD_LOGIC;
signal s_watchdog_cnt_slv : STD_LOGIC_VECTOR(c_WATCHDOG_WIDTH - 1 downto 0);
signal s_watchdog_cnt : NATURAL;
signal txsr : std_logic_vector(31 downto 0); type t_state is (
R0_RESET,
S0_IDLE,
S1_START_DETECT,
S2_I2C_ADDR,
S2A_I2C_ADDR_ACK,
S2NA_I2C_ADDR_NACK,
S3_WISHBONE_ADDR,
S3A_WISHBONE_ADDR_ACK,
S4_DETECT_OPERATION,
S5R_READ_SDA,
S5RA_READ_SDA_ACK,
S5W0_RESTART,
S5W1_I2C_ADDR,
S5W1A_I2C_ADDR_ACK,
S5W1NA_I2C_ADDR_NACK,
S5W2_WRITE_SDA,
S5W2A_WRITE_SDA_ACK,
S5W3_NACK,
S6_WAIT_START_PAUSE,
S7_PAUSE_DETECT
);
-------------------------------------------------------------------------------
-- FSM signals for the I2C module
-------------------------------------------------------------------------------
-- Four signals are employed to govern the FSM behaviour and its outputs.
--
-- These signals are updated in done_comb_proc process, dependant of the done
-- signal coming from i2c_bit.vhd
-- Every time a deglitched falling edge of the SCL line is detected in the
-- aforementioned i2c_bit.vhd, the signals done, start_o, pause_o, rcved_o are
-- considered valid to be studied in i2c_slave_core.vhd processes.
--
-------------------------------------------------------------------------------
constant c_WATCHDOG_END_VALUE : NATURAL := c_WATCHDOG_DEADLINE/g_WB_CLK_PERIOD;
signal state : t_state := R0_RESET;
signal state_d0 : t_state := R0_RESET;
signal s_DRXA_slv : std_logic_vector(r_DRX'a_length - 1 downto 0) := (others => '0');
signal s_DRXB_slv : std_logic_vector(r_DRX'a_length - 1 downto 0) := (others => '0');
signal s_DRX_slv : std_logic_vector(r_DRX'a_length*2 - 1 downto 0) := (others => '0');
signal s_DTX_slv : std_logic_vector(r_DTX'a_length - 1 downto 0);
signal s_CTR0 : r_CTR0;
signal s_LT : r_LT := c_LT_default;
signal s_i2c_addr_ctr0 : std_logic_vector(7 downto 0);
signal s_i2c_addr : std_logic_vector(7 downto 0);
-------------------------------------------------------------------------------
-- i2c signals
-------------------------------------------------------------------------------
signal s_sda_o : std_logic;
signal s_sda_oen : std_logic;
signal s_bit_done : std_logic;
-- Bit counter signals
signal s_bit_cnt_slv : std_logic_vector(c_COUNTER_WIDTH - 1 downto 0);
signal s_bit_cnt : unsigned(7 downto 0);
signal s_bit_cnt_rst : std_logic;
-- Byte counter signals
signal s_byte_cnt_slv : std_logic_vector(c_COUNTER_WIDTH - 1 downto 0);
signal s_byte_cnt : unsigned(7 downto 0);
signal s_byte_cnt_rst : std_logic;
signal s_byte_cnt_en : std_logic := '0';
-- Interrupting signals (i2c_bit.vhd)
signal s_start_o : std_logic;
signal s_pause_o : std_logic;
signal s_rcved_o : std_logic;
signal s_pf_wb_data : std_logic_vector(31 downto 0) := (others => '1');
signal s_pf_wb_data_arr : std_logic_vector(31 downto 0) := (others => '1');
signal s_watchdog_cnt_rst : std_logic;
signal s_watchdog_cnt_slv : std_logic_vector(c_WATCHDOG_WIDTH - 1 downto 0);
signal s_watchdog_cnt : NATURAL;
signal txsr : std_logic_vector(31 downto 0);
begin begin
...@@ -180,73 +185,72 @@ begin ...@@ -180,73 +185,72 @@ begin
LT_o <= f_STD_LOGIC_VECTOR(s_LT); LT_o <= f_STD_LOGIC_VECTOR(s_LT);
s_pf_wb_data <= pf_wb_data_i; s_pf_wb_data <= pf_wb_data_i;
inst_i2c_bit : i2c_bit cmp_i2c_bit: i2c_bit
port map(rst_i => rst_i, port map
wb_clk_i => clk_i, (
sda_i => sda_i, rst_i => rst_i,
scl_i => scl_i, wb_clk_i => clk_i,
start_o => s_start_o, sda_i => sda_i,
pause_o => s_pause_o, scl_i => scl_i,
rcved_o => s_rcved_o, start_o => s_start_o,
done_o => s_bit_done); pause_o => s_pause_o,
rcved_o => s_rcved_o,
done_o => s_bit_done
bit_counter_8: gc_counter );
generic map (g_data_width => c_DATA_WIDTH)
port map (clk_i => clk_i, cmp_bit_counter: gc_counter
rst_i => s_bit_cnt_rst, generic map
en_i => s_bit_done, (
cnt_o => s_bit_cnt_slv); g_data_width => c_DATA_WIDTH
)
port map
(
clk_i => clk_i,
rst_i => s_bit_cnt_rst,
en_i => s_bit_done,
cnt_o => s_bit_cnt_slv
);
s_bit_cnt <= unsigned(s_bit_cnt_slv); s_bit_cnt <= unsigned(s_bit_cnt_slv);
byte_counter_8: gc_counter cmp_byte_counter: gc_counter
generic map (g_data_width => c_DATA_WIDTH) generic map
port map (clk_i => clk_i, (
rst_i => s_byte_cnt_rst, g_data_width => c_DATA_WIDTH
en_i => s_byte_cnt_en, )
cnt_o => s_byte_cnt_slv); port map
(
clk_i => clk_i,
rst_i => s_byte_cnt_rst,
en_i => s_byte_cnt_en,
cnt_o => s_byte_cnt_slv
);
s_byte_cnt <= unsigned(s_byte_cnt_slv); s_byte_cnt <= unsigned(s_byte_cnt_slv);
watchdog_counter_8: gc_counter cmp_watchdog_counter: gc_counter
generic map (g_data_width => c_WATCHDOG_WIDTH) generic map
port map (clk_i => clk_i, (
rst_i => s_watchdog_cnt_rst, g_data_width => c_WATCHDOG_WIDTH
en_i => c_WATCHDOG_ENABLE, )
cnt_o => s_watchdog_cnt_slv); port map
(
s_watchdog_cnt <= to_integer(UNSIGNED(s_watchdog_cnt_slv)); clk_i => clk_i,
rst_i => s_watchdog_cnt_rst,
en_i => c_WATCHDOG_ENABLE,
cnt_o => s_watchdog_cnt_slv
);
s_watchdog_cnt <= to_integer(UNSIGNED(s_watchdog_cnt_slv));
scl_o <= '1'; scl_o <= '1';
scl_oen <= '0'; scl_oen <= '0';
sda_o <= s_sda_o; sda_o <= s_sda_o;
-- Process to control the TX shift register p_sda_o: process(state, txsr)
-- p_txsr: process (clk_i)
-- begin
-- if rising_edge(clk_i) then
-- if (rst_i = '1') then
-- txsr <= (others => '0');
-- elsif (i2c_sla_fsm = S5W1A_I2C_ADDR_ACK) then
-- txsr <= f_ch_endian(pf_wb_data_i);
-- elsif (i2c_sla_fsm = S5W2_WRITE_SDA) then
-- txsr <= txsr(30 downto 0) & '0';
-- end if;
-- end if;
-- end process p_txsr;
p_sda_o: process(i2c_SLA_fsm, txsr)
-- variable v_bit_inv : UNSIGNED(s_ctr0.bia downto 0);
-- variable v_bit_order : NATURAL;
variable v_bit_un : UNSIGNED(2 downto 0);
variable v_pf_wb_data : STD_LOGIC_VECTOR(0 to 31);
-- variable v_pf_wb_data : std_logic_vector(31 downto 0);
begin begin
case i2c_SLA_fsm is case state is
when S2A_I2C_ADDR_ACK => when S2A_I2C_ADDR_ACK =>
s_sda_o <= '0'; s_sda_o <= '0';
when S3A_WISHBONE_ADDR_ACK => when S3A_WISHBONE_ADDR_ACK =>
...@@ -256,454 +260,473 @@ begin ...@@ -256,454 +260,473 @@ begin
when S5W1A_I2C_ADDR_ACK => when S5W1A_I2C_ADDR_ACK =>
s_sda_o <= '0'; s_sda_o <= '0';
when S5W2_WRITE_SDA => when S5W2_WRITE_SDA =>
-- v_bit_inv := UNSIGNED(not(s_bit_cnt_slv(s_ctr0.bia downto 0))); s_sda_o <= txsr(31);
-- v_bit_order := to_integer(v_bit_inv); when others =>
-- s_sda_o <= s_pf_wb_data(s_byte_cnt*8 + v_bit_order); s_sda_o <= '1';
end case;
end process;
sda_oen <= s_sda_oen;
p_sda_oen: process(state)
begin
s_sda_oen <= '0';
case state is
when S2A_I2C_ADDR_ACK =>
s_sda_oen <= '1';
when S3A_WISHBONE_ADDR_ACK =>
s_sda_oen <= '1';
when S5RA_READ_SDA_ACK =>
s_sda_oen <= '1';
when S5W1A_I2C_ADDR_ACK =>
s_sda_oen <= '1';
when S5W2_WRITE_SDA =>
s_sda_oen <= '1';
when others =>
null;
end case;
end process;
s_DRXA_slv <= s_DRX_slv(r_DRX'a_length - 1 downto 0);
s_DRXB_slv <= s_DRX_slv(r_DRX'a_length*2 - 1 downto r_DRX'a_length);
--Process to store the incoming data
p_store_FIFO: process(clk_i)
procedure shift_DRX is
begin
for i in 1 to s_DRX_slv'length - 1 loop
s_DRX_slv(i) <= s_DRX_slv(i-1);
end loop;
s_DRX_slv(0) <= s_rcved_o;
end procedure;
-- v_pf_wb_data(0 to 31) := f_ch_endian(s_pf_wb_data(31 downto 0)); begin
-- -- v_pf_wb_data := s_pf_wb_data; -- f_ch_endian(s_pf_wb_data); if rising_edge(clk_i) then
-- s_sda_o <= v_pf_wb_data(s_byte_cnt*8 + (s_bit_cnt mod 8)); if s_bit_done = '1' then
case state is
when S2_I2C_ADDR =>
shift_DRX;
when S3_WISHBONE_ADDR =>
shift_DRX;
when S4_DETECT_OPERATION =>
if s_start_o = '0'
and s_pause_o = '0' then
shift_DRX;
end if;
when S5R_READ_SDA =>
shift_DRX;
when S5W1_I2C_ADDR =>
shift_DRX;
when others =>
null;
end case;
end if;
end if;
end process;
s_i2c_addr_ctr0(7 downto 1) <= std_logic_vector(s_CTR0.I2C_ADDR);
s_i2c_addr(0) <= '0';
gen_i2c: for i in 1 to 7 generate
s_i2c_addr(8-i) <= s_i2c_addr_ctr0(i);
end generate gen_i2c;
p_delays : process(clk_i)
begin
if rising_edge(clk_i) then
state_d0 <= state;
end if;
end process;
-- Process to generate the pf_wb_addr_o signal.
p_pf_wb_addr: process(clk_i)
begin
if rising_edge(clk_i) then
pf_wb_addr_o <= '0';
if state = S5W1A_I2C_ADDR_ACK
and state_d0 = S5W1_I2C_ADDR then
pf_wb_addr_o <= '1';
end if;
end if;
end process;
-- Process to generate the rd_done_o signal.
p_rd_done: process(clk_i)
begin
if rising_edge(clk_i) then
rd_done_o <= '0';
if state = S6_WAIT_START_PAUSE
and state_d0 = S5RA_READ_SDA_ACK then
rd_done_o <= '1';
end if;
end if;
end process;
-- Process to generate the wr_done_o signal.
p_wr_done: process(clk_i)
begin
if rising_edge(clk_i) then
wr_done_o <= '0';
if state = S6_WAIT_START_PAUSE
and state_d0 = S5W3_NACK then
wr_done_o <= '1';
end if;
end if;
end process;
DRXA_o <= s_DRXA_slv;
DRXB_o <= s_DRXB_slv;
-- Process to update the signals that drive bit_counter_8
p_bit_counter_comb : process(state, state_d0, s_byte_cnt)
begin
s_bit_cnt_rst <= '0';
s_byte_cnt_rst <= '0';
case state is
when R0_RESET =>
if state_d0 /= R0_RESET then
s_bit_cnt_rst <= '1';
s_byte_cnt_rst <= '1';
end if;
when S0_IDLE =>
null;
when S1_START_DETECT =>
s_bit_cnt_rst <= '1';
s_byte_cnt_rst <= '1';
when S2_I2C_ADDR =>
null;
when S2A_I2C_ADDR_ACK =>
if (state_d0 = S2_I2C_ADDR) then
s_byte_cnt_rst <= '1';
end if;
when S3_WISHBONE_ADDR =>
if (state_d0 = S2A_I2C_ADDR_ACK) or
(state_d0 = S3A_WISHBONE_ADDR_ACK) or
(state_d0 = S5W1A_I2C_ADDR_ACK) then
s_bit_cnt_rst <= '1';
end if;
if (s_byte_cnt = s_ctr0.bia) and (state_d0 = S2A_I2C_ADDR_ACK) then
s_byte_cnt_rst <= '1';
end if;
when S3A_WISHBONE_ADDR_ACK =>
if (state_d0 = S3_WISHBONE_ADDR) then
s_bit_cnt_rst <= '1';
end if;
when S4_DETECT_OPERATION =>
if (state_d0 = S3A_WISHBONE_ADDR_ACK) then
s_bit_cnt_rst <= '1';
s_byte_cnt_rst <= '1';
end if;
when S5W1_I2C_ADDR =>
null;
when S5W1A_I2C_ADDR_ACK =>
if (state_d0 <= S5W1_I2C_ADDR) then
s_bit_cnt_rst <= '1';
end if;
when S5W2_WRITE_SDA =>
null;
when S5W2A_WRITE_SDA_ACK =>
if (state_d0 = S5W2_WRITE_SDA) then
s_bit_cnt_rst <= '1';
end if;
when S5W0_RESTART =>
if (state_d0 = S4_DETECT_OPERATION) then
s_bit_cnt_rst <= '1';
end if;
when S5R_READ_SDA =>
if (s_byte_cnt = s_ctr0.bia) and (state_d0 = S3A_WISHBONE_ADDR_ACK) then
s_byte_cnt_rst <= '1';
end if;
if (state_d0 = S5RA_READ_SDA_ACK) then
s_bit_cnt_rst <= '1';
end if;
when S5RA_READ_SDA_ACK =>
if (state_d0 = S5R_READ_SDA) then
s_bit_cnt_rst <= '1';
end if;
when S6_WAIT_START_PAUSE =>
if (state_d0 /= S6_WAIT_START_PAUSE) then
s_bit_cnt_rst <= '1';
s_byte_cnt_rst <= '1';
end if;
when S7_PAUSE_DETECT =>
null;
s_sda_o <= txsr(31);
when others => when others =>
s_sda_o <= '1'; null;
end case; end case;
end process; end process;
sda_oen <= s_sda_oen; p_byte_counter_en: process (state, state_d0)
begin
p_sda_oen: process(i2c_SLA_fsm) s_byte_cnt_en <= '0';
begin
s_sda_oen <= '0';
case i2c_SLA_fsm is
when S2A_I2C_ADDR_ACK =>
s_sda_oen <= '1';
when S3A_WISHBONE_ADDR_ACK =>
s_sda_oen <= '1';
when S5RA_READ_SDA_ACK =>
s_sda_oen <= '1';
when S5W1A_I2C_ADDR_ACK =>
s_sda_oen <= '1';
when S5W2_WRITE_SDA =>
s_sda_oen <= '1';
when others =>
null;
end case;
end process;
s_DRXA_slv <= s_DRX_slv(r_DRX'a_length - 1 downto 0);
s_DRXB_slv <= s_DRX_slv(r_DRX'a_length*2 - 1 downto r_DRX'a_length);
--! @brief Process to store the incoming data
--! @param clk_i Clock that samples the data
p_store_FIFO: process(clk_i)
procedure shift_DRX is
begin
for i in 1 to s_DRX_slv'length - 1 loop
s_DRX_slv(i) <= s_DRX_slv(i-1);
end loop;
s_DRX_slv(0) <= s_rcved_o;
end procedure;
begin
if rising_edge(clk_i) then
if s_bit_done = '1' then
case i2c_SLA_fsm is
when S2_I2C_ADDR =>
shift_DRX;
when S3_WISHBONE_ADDR =>
shift_DRX;
when S4_DETECT_OPERATION =>
if s_start_o = '0'
and s_pause_o = '0' then
shift_DRX;
end if;
when S5R_READ_SDA =>
shift_DRX;
when S5W1_I2C_ADDR =>
shift_DRX;
when others =>
null;
end case;
end if;
end if;
end process;
case state is
s_i2c_addr_ctr0(7 downto 1) <= STD_LOGIC_VECTOR(s_CTR0.I2C_ADDR); when R0_RESET =>
s_i2c_addr(0) <= '0'; null;
-- if state_d0 /= R0_RESET then
-- end if;
gen_i2c: for i in 1 to 7 generate when S3A_WISHBONE_ADDR_ACK =>
s_i2c_addr(8-i) <= s_i2c_addr_ctr0(i); if (state_d0 = S3_WISHBONE_ADDR) then
end generate gen_i2c; s_byte_cnt_en <= '1';
end if;
when S5RA_READ_SDA_ACK =>
if (state_d0 = S5R_READ_SDA) then
s_byte_cnt_en <= '1';
end if;
when S5W2A_WRITE_SDA_ACK =>
if (state_d0 = S5W2_WRITE_SDA) then
s_byte_cnt_en <= '1';
end if;
p_delays : process(clk_i) when others =>
begin null;
if rising_edge(clk_i) then end case;
i2c_SLA_fsm_d0 <= i2c_SLA_fsm; end process p_byte_counter_en;
-- Watchdog reset process
p_watchdog_rst: process(clk_i)
begin
if rising_edge(clk_i) then
s_watchdog_cnt_rst <= '0';
if rst_i = '1' then
s_watchdog_cnt_rst <= '1';
end if; end if;
end process; if s_watchdog_cnt >= c_WATCHDOG_END_VALUE then
s_watchdog_cnt_rst <= '1';
--! @brief Process to generate the pf_wb_addr_o signal.
--! @param clk_i Main clock
p_pf_wb_addr: process(clk_i)
begin
if rising_edge(clk_i) then
pf_wb_addr_o <= '0';
if i2c_SLA_fsm = S5W1A_I2C_ADDR_ACK
and i2c_SLA_fsm_d0 = S5W1_I2C_ADDR then
pf_wb_addr_o <= '1';
end if;
end if; end if;
end process; if state /= state_d0 then
s_watchdog_cnt_rst <= '1';
--! @brief Process to generate the rd_done_o signal.
--! @param clk_i Main clock
p_rd_done: process(clk_i)
begin
if rising_edge(clk_i) then
rd_done_o <= '0';
if i2c_SLA_fsm = S6_WAIT_START_PAUSE
and i2c_SLA_fsm_d0 = S5RA_READ_SDA_ACK then
rd_done_o <= '1';
end if;
end if; end if;
end process; end if;
end process;
--! @brief Process to generate the wr_done_o signal.
--! @param clk_i Main clock
p_wr_done: process(clk_i) -- Small process that records the length of a
begin -- bit over the I2C interface.
if rising_edge(clk_i) then p_lt_sclp: process(clk_i)
wr_done_o <= '0'; variable v_count : std_logic_vector(23 downto 0);
if i2c_SLA_fsm = S6_WAIT_START_PAUSE begin
and i2c_SLA_fsm_d0 = S5W3_NACK then if rising_edge(clk_i) then
wr_done_o <= '1'; if state = R0_RESET then
end if; s_LT.SCLP <= c_LT_default.SCLP;
else
if (state = S2A_I2C_ADDR_ACK) and (state_d0 = S2_I2C_ADDR) then
-- Here we do a division bit 8, because the watchdog timer counts for
-- 8 scl clocks
v_count := s_watchdog_cnt_slv(24 - 1 + 3 downto 3);
s_LT.SCLP <= UNSIGNED(v_count);
end if;
end if; end if;
end process; end if;
end process p_lt_sclp;
DRXA_o <= s_DRXA_slv;
DRXB_o <= s_DRXB_slv; -- Process to set the next fsm
p_fsm: process(clk_i)
--! @brief process to update the signals that drive bit_counter_8
--! @param i2c_SLA_fsm Current value of the i2c fsm procedure check_start_stop is
--! @param i2c_SLA_fsm_d0 Current value of the i2c fsm begin
p_bit_counter_comb : process(i2c_SLA_fsm, if (s_start_o = '1') then
i2c_SLA_fsm_d0, state <= S1_START_DETECT;
s_byte_cnt) elsif (s_pause_o = '1') then
begin state <= R0_RESET;
s_bit_cnt_rst <= '0'; end if;
s_byte_cnt_rst <= '0'; end procedure;
case i2c_SLA_fsm is
when R0_RESET => begin
if i2c_SLA_fsm_d0 /= R0_RESET then
s_bit_cnt_rst <= '1'; if rising_edge(clk_i) then
s_byte_cnt_rst <= '1'; if (rst_i = '1') or (s_watchdog_cnt >= c_WATCHDOG_END_VALUE) then
end if; state <= R0_RESET;
when S0_IDLE => txsr <= (others => '0');
null; else
when S1_START_DETECT => case state is
s_bit_cnt_rst <= '1';
s_byte_cnt_rst <= '1'; when R0_RESET =>
when S2_I2C_ADDR => state <= S0_IDLE;
null;
when S2A_I2C_ADDR_ACK => when S0_IDLE =>
if i2c_SLA_fsm_d0 = S2_I2C_ADDR then if (s_bit_done = '1') then
s_byte_cnt_rst <= '1'; if (s_start_o = '1') then
end if; state <= S1_START_DETECT;
when S3_WISHBONE_ADDR => else
if i2c_SLA_fsm_d0 = S2A_I2C_ADDR_ACK state <= R0_RESET;
or i2c_SLA_fsm_d0 = S3A_WISHBONE_ADDR_ACK end if;
or i2c_SLA_fsm_d0 = S5W1A_I2C_ADDR_ACK then
s_bit_cnt_rst <= '1';
end if;
if s_byte_cnt = s_ctr0.bia then
if i2c_SLA_fsm_d0 = S2A_I2C_ADDR_ACK then
s_byte_cnt_rst <= '1';
end if;
end if; end if;
when S3A_WISHBONE_ADDR_ACK =>
if i2c_SLA_fsm_d0 = S3_WISHBONE_ADDR then when S1_START_DETECT =>
s_bit_cnt_rst <= '1'; state <= S2_I2C_ADDR;
when S2_I2C_ADDR =>
if (s_bit_done = '1') then
if (s_bit_cnt = 7) then
if (s_DRX_slv(6 downto 0) = "0000000") or
(s_DRX_slv(6 downto 0) = std_logic_vector(s_CTR0.I2C_ADDR)) then
state <= S2A_I2C_ADDR_ACK;
else
state <= S2NA_I2C_ADDR_NACK;
end if;
end if;
check_start_stop;
end if; end if;
when S4_DETECT_OPERATION =>
if i2c_SLA_fsm_d0 = S3A_WISHBONE_ADDR_ACK then when S2A_I2C_ADDR_ACK =>
s_bit_cnt_rst <= '1'; if (s_bit_done = '1') then
s_byte_cnt_rst <= '1'; state <= S3_WISHBONE_ADDR;
end if; end if;
when S5W1_I2C_ADDR =>
null; when S2NA_I2C_ADDR_NACK =>
when S5W1A_I2C_ADDR_ACK => if (s_bit_done = '1') then
if i2c_SLA_fsm_d0 <= S5W1_I2C_ADDR then state <= S6_WAIT_START_PAUSE;
s_bit_cnt_rst <= '1';
end if; end if;
when S5W2_WRITE_SDA =>
null; when S3_WISHBONE_ADDR =>
when S5W2A_WRITE_SDA_ACK => if (s_bit_done = '1') then
if i2c_SLA_fsm_d0 = S5W2_WRITE_SDA then if (s_bit_cnt = 7) then
s_bit_cnt_rst <= '1'; state <= S3A_WISHBONE_ADDR_ACK;
end if;
check_start_stop;
end if; end if;
when S5W0_RESTART =>
if i2c_SLA_fsm_d0 = S4_DETECT_OPERATION then when S3A_WISHBONE_ADDR_ACK =>
s_bit_cnt_rst <= '1'; if (s_bit_done = '1') then
if (s_byte_cnt = s_ctr0.bia) then
state <= S4_DETECT_OPERATION;
else
state <= S3_WISHBONE_ADDR;
end if;
end if; end if;
when S5R_READ_SDA =>
if s_byte_cnt = s_ctr0.bia then when S4_DETECT_OPERATION =>
if i2c_SLA_fsm_d0 = S3A_WISHBONE_ADDR_ACK then if (s_bit_done = '1') then
s_byte_cnt_rst <= '1'; if (s_start_o = '1') then
end if; state <= S5W0_RESTART;
elsif (s_pause_o = '1') then
state <= R0_RESET;
else
state <= S5R_READ_SDA;
check_start_stop;
end if;
end if; end if;
if i2c_SLA_fsm_d0 = S5RA_READ_SDA_ACK then
s_bit_cnt_rst <= '1'; when S5R_READ_SDA =>
if (s_bit_done = '1') then
if (s_bit_cnt = 7) then
state <= S5RA_READ_SDA_ACK;
end if;
check_start_stop;
end if; end if;
when S5RA_READ_SDA_ACK =>
if i2c_SLA_fsm_d0 = S5R_READ_SDA then when S5RA_READ_SDA_ACK =>
s_bit_cnt_rst <= '1'; if (s_bit_done = '1') then
if (s_byte_cnt < s_ctr0.brd) then
state <= S5R_READ_SDA;
else
state <= S6_WAIT_START_PAUSE;
end if;
end if; end if;
when S6_WAIT_START_PAUSE =>
if i2c_SLA_fsm_d0 /= S6_WAIT_START_PAUSE then when S5W0_RESTART =>
s_bit_cnt_rst <= '1'; state <= S5W1_I2C_ADDR;
s_byte_cnt_rst <= '1';
when S5W1_I2C_ADDR =>
if (s_bit_done = '1') then
if (s_bit_cnt = 7) then
if (s_DRX_slv(6 downto 0) = "0000000") -- ????????????????
or (s_DRX_slv(6 downto 0) = std_logic_vector(s_CTR0.I2C_ADDR)) then
state <= S5W1A_I2C_ADDR_ACK;
else
state <= S5W1NA_I2C_ADDR_NACK;
end if;
end if;
check_start_stop;
end if; end if;
when S7_PAUSE_DETECT =>
null; when S5W1A_I2C_ADDR_ACK =>
when others => txsr <= f_ch_endian(pf_wb_data_i);
null; if s_bit_done = '1' then
end case; state <= S5W2_WRITE_SDA;
end process;
p_byte_counter_en: process (i2c_SLA_fsm, i2c_SLA_fsm_d0)
begin
s_byte_cnt_en <= '0';
case i2c_SLA_fsm is
when R0_RESET =>
if i2c_SLA_fsm_d0 /= R0_RESET then
end if; end if;
when S3A_WISHBONE_ADDR_ACK =>
if i2c_SLA_fsm_d0 = S3_WISHBONE_ADDR then when S5W1NA_I2C_ADDR_NACK =>
s_byte_cnt_en <= '1'; if s_bit_done = '1' then
state <= S6_WAIT_START_PAUSE;
end if; end if;
when S5RA_READ_SDA_ACK =>
if i2c_SLA_fsm_d0 = S5R_READ_SDA then when S5W2_WRITE_SDA =>
s_byte_cnt_en <= '1'; if (s_bit_done = '1') then
txsr <= txsr(30 downto 0) & '0';
if (s_bit_cnt = 8) then
state <= S5W2A_WRITE_SDA_ACK;
end if;
--! It can be removed, never reached
check_start_stop;
end if; end if;
when S5W2A_WRITE_SDA_ACK =>
if i2c_SLA_fsm_d0 = S5W2_WRITE_SDA then when S5W2A_WRITE_SDA_ACK =>
s_byte_cnt_en <= '1'; if (s_bit_done = '1') then
if (s_rcved_o = '0') then
if (s_byte_cnt < s_ctr0.bwr) then
state <= S5W2_WRITE_SDA;
else
state <= R0_RESET;
end if;
else
state <= S5W3_NACK;
check_start_stop;
end if;
end if; end if;
when others =>
null; when S5W3_NACK =>
end case; state <= S6_WAIT_START_PAUSE;
end process;
when S6_WAIT_START_PAUSE =>
--! @brief Watchdog reset process if (s_bit_done = '1') then
--! @param clk_i Main clock if (s_pause_o = '1') then
p_watchdog_rst: process(clk_i) state <= S7_PAUSE_DETECT;
begin elsif (s_start_o = '1') then
if rising_edge(clk_i) then state <= S1_START_DETECT;
s_watchdog_cnt_rst <= '0'; else
if rst_i = '1' then state <= R0_RESET;
s_watchdog_cnt_rst <= '1'; check_start_stop;
end if; end if;
if s_watchdog_cnt >= c_WATCHDOG_END_VALUE then
s_watchdog_cnt_rst <= '1';
end if;
if i2c_SLA_fsm /= i2c_SLA_fsm_d0 then
s_watchdog_cnt_rst <= '1';
end if;
end if;
end process;
--! @brief Small process that records the length of a
--! bit over the I2C interface.
--! @param clk_i Main clock
p_LT_SCLP: process(clk_i)
variable v_count : STD_LOGIC_VECTOR(23 downto 0);
begin
if rising_edge(clk_i) then
if i2c_SLA_fsm = R0_RESET then
s_LT.SCLP <= c_LT_default.SCLP;
else
if i2c_SLA_fsm = S2A_I2C_ADDR_ACK
and i2c_SLA_fsm_d0 = S2_I2C_ADDR then
--! Here we do a division bit 8, because the watchdog timer,
--! is counting for 8 scl clocks
v_count := s_watchdog_cnt_slv(24 - 1 + 3 downto 3);
s_LT.SCLP <= UNSIGNED(v_count);
end if; end if;
end if;
end if; when S7_PAUSE_DETECT =>
end process; state <= R0_RESET;
check_start_stop;
--! @brief Process to set the next fsm
--! @param clk_i Clock that rules the fsm transitions when others =>
fsm_proc: process(clk_i) state <= R0_RESET;
end case;
procedure check_start_stop is
begin
if s_start_o = '1' then
i2c_SLA_fsm <= S1_START_DETECT;
elsif s_pause_o = '1' then
i2c_SLA_fsm <= R0_RESET;
end if;
end procedure;
begin
if rising_edge(clk_i) then
if rst_i = '1'
or s_watchdog_cnt >= c_WATCHDOG_END_VALUE then
i2c_SLA_fsm <= R0_RESET;
txsr <= (others => '0');
else
case i2c_SLA_fsm is
when R0_RESET =>
i2c_SLA_fsm <= S0_IDLE;
when S0_IDLE =>
if s_bit_done = '1' then
if s_start_o = '1' then
i2c_SLA_fsm <= S1_START_DETECT;
else
i2c_SLA_fsm <= R0_RESET;
end if;
end if;
when S1_START_DETECT =>
i2c_SLA_fsm <= S2_I2C_ADDR;
when S2_I2C_ADDR =>
if s_bit_done = '1' then
if s_bit_cnt = 7 then
if s_DRX_slv(6 downto 0) = "0000000"
or s_DRX_slv(6 downto 0) =
STD_LOGIC_VECTOR(s_CTR0.I2C_ADDR) then
i2c_SLA_fsm <= S2A_I2C_ADDR_ACK;
else
i2c_SLA_fsm <= S2NA_I2C_ADDR_NACK;
end if;
end if;
check_start_stop;
end if;
when S2A_I2C_ADDR_ACK =>
if s_bit_done = '1' then
i2c_SLA_fsm <= S3_WISHBONE_ADDR;
end if;
when S2NA_I2C_ADDR_NACK =>
if s_bit_done = '1' then
i2c_SLA_fsm <= S6_WAIT_START_PAUSE;
end if;
when S3_WISHBONE_ADDR =>
if s_bit_done = '1' then
if s_bit_cnt = 7 then
i2c_SLA_fsm <= S3A_WISHBONE_ADDR_ACK;
end if;
check_start_stop;
end if;
when S3A_WISHBONE_ADDR_ACK =>
if s_bit_done = '1' then
if s_byte_cnt < s_ctr0.bia then
i2c_SLA_fsm <= S3_WISHBONE_ADDR;
else
i2c_SLA_fsm <= S4_DETECT_OPERATION;
end if;
end if;
when S4_DETECT_OPERATION =>
if s_bit_done = '1' then
if s_start_o = '1' then
i2c_SLA_fsm <= S5W0_RESTART;
elsif s_pause_o = '1' then
i2c_SLA_fsm <= R0_RESET;
else
i2c_SLA_fsm <= S5R_READ_SDA;
check_start_stop;
end if;
end if;
when S5R_READ_SDA =>
if s_bit_done = '1' then
if s_bit_cnt = 7 then
i2c_SLA_fsm <= S5RA_READ_SDA_ACK;
end if;
check_start_stop;
end if;
when S5RA_READ_SDA_ACK =>
if s_bit_done = '1' then
if s_byte_cnt < s_ctr0.brd then
i2c_SLA_fsm <= S5R_READ_SDA;
else
i2c_SLA_fsm <= S6_WAIT_START_PAUSE;
end if;
end if;
when S5W0_RESTART =>
i2c_SLA_fsm <= S5W1_I2C_ADDR;
when S5W1_I2C_ADDR =>
if s_bit_done = '1' then
if s_bit_cnt = 7 then
if s_DRX_slv(6 downto 0) = "0000000" -- ????????????????
or s_DRX_slv(6 downto 0) =
STD_LOGIC_VECTOR(s_CTR0.I2C_ADDR) then
i2c_SLA_fsm <= S5W1A_I2C_ADDR_ACK;
else
i2c_SLA_fsm <= S5W1NA_I2C_ADDR_NACK;
end if;
end if;
check_start_stop;
end if;
when S5W1A_I2C_ADDR_ACK =>
txsr <= f_ch_endian(pf_wb_data_i);
if s_bit_done = '1' then
i2c_SLA_fsm <= S5W2_WRITE_SDA;
end if;
when S5W1NA_I2C_ADDR_NACK =>
if s_bit_done = '1' then
i2c_SLA_fsm <= S6_WAIT_START_PAUSE;
end if;
when S5W2_WRITE_SDA =>
if s_bit_done = '1' then
txsr <= txsr(30 downto 0) & '0';
if s_bit_cnt = 8 then
i2c_SLA_fsm <= S5W2A_WRITE_SDA_ACK;
end if;
--! It can be removed, never reached
check_start_stop;
end if;
when S5W2A_WRITE_SDA_ACK =>
if s_bit_done = '1' then
if s_rcved_o = '0' then
if s_byte_cnt < s_ctr0.bwr then
i2c_SLA_fsm <= S5W2_WRITE_SDA;
else
i2c_SLA_fsm <= R0_RESET;
end if;
else
i2c_SLA_fsm <= S5W3_NACK;
check_start_stop;
end if;
end if;
when S5W3_NACK =>
i2c_SLA_fsm <= S6_WAIT_START_PAUSE;
when S6_WAIT_START_PAUSE =>
if s_bit_done = '1' then
if s_pause_o = '1' then
i2c_SLA_fsm <= S7_PAUSE_DETECT;
elsif s_start_o = '1' then
i2c_SLA_fsm <= S1_START_DETECT;
else
i2c_SLA_fsm <= R0_RESET;
check_start_stop;
end if;
end if;
when S7_PAUSE_DETECT =>
i2c_SLA_fsm <= R0_RESET;
check_start_stop;
when others =>
i2c_SLA_fsm <= R0_RESET;
end case;
end if;
end if; end if;
end process; end if;
end process p_fsm;
end Behavioral; end Behavioral;
...@@ -26,148 +26,153 @@ use work.i2c_slave_pkg.ALL; ...@@ -26,148 +26,153 @@ use work.i2c_slave_pkg.ALL;
use work.ctdah_pkg.ALL; use work.ctdah_pkg.ALL;
entity i2c_slave_top is entity i2c_slave_top is
generic (g_WB_CLK_PERIOD : TIME := c_WB_CLK_PERIOD); -- Specify in ns generic
(
g_WB_CLK_PERIOD : TIME := c_WB_CLK_PERIOD -- Specify in ns
);
port port
( (
sda_oen : out STD_LOGIC; sda_oen : out STD_LOGIC;
sda_i : in STD_LOGIC; sda_i : in STD_LOGIC;
sda_o : out STD_LOGIC; sda_o : out STD_LOGIC;
scl_oen : out STD_LOGIC; scl_oen : out STD_LOGIC;
scl_i : in STD_LOGIC; scl_i : in STD_LOGIC;
scl_o : out STD_LOGIC; scl_o : out STD_LOGIC;
wb_clk_i : in STD_LOGIC; wb_clk_i : in STD_LOGIC;
wb_rst_i : in STD_LOGIC; wb_rst_i : in STD_LOGIC;
wb_master_stb_o : out STD_LOGIC; wb_master_stb_o : out STD_LOGIC;
wb_master_cyc_o : out STD_LOGIC; wb_master_cyc_o : out STD_LOGIC;
wb_master_sel_o : out STD_LOGIC_VECTOR(3 downto 0); wb_master_sel_o : out STD_LOGIC_VECTOR(3 downto 0);
wb_master_we_o : out STD_LOGIC; wb_master_we_o : out STD_LOGIC;
wb_master_data_i : in STD_LOGIC_VECTOR(31 downto 0); wb_master_data_i : in STD_LOGIC_VECTOR(31 downto 0);
wb_master_data_o : out STD_LOGIC_VECTOR(31 downto 0); wb_master_data_o : out STD_LOGIC_VECTOR(31 downto 0);
wb_master_addr_o : out STD_LOGIC_VECTOR(15 downto 0); wb_master_addr_o : out STD_LOGIC_VECTOR(15 downto 0);
wb_master_ack_i : in STD_LOGIC; wb_master_ack_i : in STD_LOGIC;
wb_master_rty_i : in STD_LOGIC; wb_master_rty_i : in STD_LOGIC;
wb_master_err_i : in STD_LOGIC; wb_master_err_i : in STD_LOGIC;
wb_slave_stb_i : in STD_LOGIC; wb_slave_stb_i : in STD_LOGIC;
wb_slave_cyc_i : in STD_LOGIC; wb_slave_cyc_i : in STD_LOGIC;
wb_slave_sel_i : in STD_LOGIC_VECTOR(3 downto 0); wb_slave_sel_i : in STD_LOGIC_VECTOR(3 downto 0);
wb_slave_we_i : in STD_LOGIC; wb_slave_we_i : in STD_LOGIC;
wb_slave_data_i : in STD_LOGIC_VECTOR(31 downto 0); wb_slave_data_i : in STD_LOGIC_VECTOR(31 downto 0);
wb_slave_data_o : out STD_LOGIC_VECTOR(31 downto 0); wb_slave_data_o : out STD_LOGIC_VECTOR(31 downto 0);
wb_slave_addr_i : in STD_LOGIC_VECTOR(3 downto 0); wb_slave_addr_i : in STD_LOGIC_VECTOR(3 downto 0);
wb_slave_ack_o : out STD_LOGIC; wb_slave_ack_o : out STD_LOGIC;
wb_slave_rty_o : out STD_LOGIC; wb_slave_rty_o : out STD_LOGIC;
wb_slave_err_o : out STD_LOGIC; wb_slave_err_o : out STD_LOGIC;
pf_wb_addr_o : out STD_LOGIC; pf_wb_addr_o : out STD_LOGIC;
rd_done_o : out STD_LOGIC; rd_done_o : out STD_LOGIC;
wr_done_o : out STD_LOGIC; wr_done_o : out STD_LOGIC;
i2c_addr_i : in STD_LOGIC_VECTOR(6 downto 0) i2c_addr_i : in STD_LOGIC_VECTOR(6 downto 0)
); );
end i2c_slave_top; end i2c_slave_top;
architecture Behavioral of i2c_slave_top is architecture Behavioral of i2c_slave_top is
signal s_CTR0_slv : STD_LOGIC_VECTOR(r_CTR0'a_length - 1 downto 0); signal ctr0 : STD_LOGIC_VECTOR(r_CTR0'a_length - 1 downto 0);
signal s_CTR0 : r_CTR0; signal lt : STD_LOGIC_VECTOR(r_LT'a_length - 1 downto 0);
signal s_LT_slv : STD_LOGIC_VECTOR(r_LT'a_length - 1 downto 0);
signal drxa : STD_LOGIC_VECTOR(r_DRX'a_length - 1 downto 0);
signal drxb : STD_LOGIC_VECTOR(r_DRX'a_length - 1 downto 0);
signal s_DRXA : STD_LOGIC_VECTOR(r_DRX'a_length - 1 downto 0); signal pf_wb_addr : STD_LOGIC;
signal s_DRXB : STD_LOGIC_VECTOR(r_DRX'a_length - 1 downto 0); signal pf_wb_data : STD_LOGIC_VECTOR(31 downto 0);
signal rd_done : STD_LOGIC;
signal wr_done : STD_LOGIC;
signal s_pf_wb_addr : STD_LOGIC; signal s_clk_i2c : STD_LOGIC;
signal s_pf_wb_data : STD_LOGIC_VECTOR(31 downto 0); signal rst_i2c : STD_LOGIC;
signal s_rd_done : STD_LOGIC; signal reset_extender: STD_LOGIC_VECTOR(2**c_RST_EXTENSOR - 1 downto 0) := (others => '1');
signal s_wr_done : STD_LOGIC;
signal s_clk_i2c : STD_LOGIC;
signal s_rst_i2c : STD_LOGIC;
signal s_reset_extensor : STD_LOGIC_VECTOR(2**c_RST_EXTENSOR - 1
downto 0) := (others => '1');
begin begin
pf_wb_addr_o <= s_pf_wb_addr; pf_wb_addr_o <= pf_wb_addr;
rd_done_o <= s_rd_done; rd_done_o <= rd_done;
wr_done_o <= s_wr_done; wr_done_o <= wr_done;
--! Added for simulation
s_CTR0 <= f_CTR0(s_CTR0_slv); cmp_i2c_slave_core: i2c_slave_core
port map
inst_i2c_slave_core: i2c_slave_core (
port map(clk_i => wb_clk_i, clk_i => wb_clk_i,
rst_i => wb_rst_i, rst_i => wb_rst_i,
sda_oen => sda_oen, sda_oen => sda_oen,
sda_i => sda_i, sda_i => sda_i,
sda_o => sda_o, sda_o => sda_o,
scl_oen => scl_oen, scl_oen => scl_oen,
scl_i => scl_i, scl_i => scl_i,
scl_o => scl_o, scl_o => scl_o,
CTR0_i => s_CTR0_slv, CTR0_i => ctr0,
LT_o => s_LT_slv, LT_o => lt,
DRXA_o => s_DRXA, DRXA_o => drxa,
DRXB_o => s_DRXB, DRXB_o => drxb,
pf_wb_addr_o => s_pf_wb_addr, pf_wb_addr_o => pf_wb_addr,
pf_wb_data_i => s_pf_wb_data, pf_wb_data_i => pf_wb_data,
rd_done_o => s_rd_done, rd_done_o => rd_done,
wr_done_o => s_wr_done); wr_done_o => wr_done
);
inst_i2c_regs: i2c_regs
port map(pf_wb_addr_i => s_pf_wb_addr, cmp_i2c_regs: i2c_regs
pf_wb_data_o => s_pf_wb_data, port map
rd_done_i => s_rd_done, (
wr_done_i => s_wr_done, pf_wb_addr_i => pf_wb_addr,
pf_wb_data_o => pf_wb_data,
wb_rst_i => wb_rst_i, rd_done_i => rd_done,
wb_clk_i => wb_clk_i, wr_done_i => wr_done,
wb_master_we_o => wb_master_we_o, wb_rst_i => wb_rst_i,
wb_master_stb_o => wb_master_stb_o, wb_clk_i => wb_clk_i,
wb_master_cyc_o => wb_master_cyc_o,
wb_master_sel_o => wb_master_sel_o, wb_master_we_o => wb_master_we_o,
wb_master_data_i => wb_master_data_i, wb_master_stb_o => wb_master_stb_o,
wb_master_data_o => wb_master_data_o, wb_master_cyc_o => wb_master_cyc_o,
wb_master_addr_o => wb_master_addr_o, wb_master_sel_o => wb_master_sel_o,
wb_master_ack_i => wb_master_ack_i, wb_master_data_i => wb_master_data_i,
wb_master_rty_i => wb_master_rty_i, wb_master_data_o => wb_master_data_o,
wb_master_err_i => wb_master_err_i, wb_master_addr_o => wb_master_addr_o,
wb_master_ack_i => wb_master_ack_i,
wb_slave_we_i => wb_slave_we_i, wb_master_rty_i => wb_master_rty_i,
wb_slave_stb_i => wb_slave_stb_i, wb_master_err_i => wb_master_err_i,
wb_slave_cyc_i => wb_slave_cyc_i,
wb_slave_sel_i => wb_slave_sel_i, wb_slave_we_i => wb_slave_we_i,
wb_slave_data_i => wb_slave_data_i, wb_slave_stb_i => wb_slave_stb_i,
wb_slave_data_o => wb_slave_data_o, wb_slave_cyc_i => wb_slave_cyc_i,
wb_slave_addr_i => wb_slave_addr_i, wb_slave_sel_i => wb_slave_sel_i,
wb_slave_ack_o => wb_slave_ack_o, wb_slave_data_i => wb_slave_data_i,
wb_slave_rty_o => wb_slave_rty_o, wb_slave_data_o => wb_slave_data_o,
wb_slave_err_o => wb_slave_err_o, wb_slave_addr_i => wb_slave_addr_i,
wb_slave_ack_o => wb_slave_ack_o,
CTR0_o => s_CTR0_slv, wb_slave_rty_o => wb_slave_rty_o,
LT_i => s_LT_slv, wb_slave_err_o => wb_slave_err_o,
DRXA_i => s_DRXA,
DRXB_i => s_DRXB, CTR0_o => ctr0,
i2c_addr_i => i2c_addr_i); LT_i => lt,
DRXA_i => drxa,
DRXB_i => drxb,
s_rst_i2c <= s_reset_extensor(2**c_RST_EXTENSOR - 1); i2c_addr_i => i2c_addr_i
);
rst_i2c <= reset_extender(2**c_RST_EXTENSOR - 1);
--! A shift with reset, consumes just a few SLICEX in Spartan6. --! A shift with reset, consumes just a few SLICEX in Spartan6.
p_rst_extender : process(wb_clk_i) p_rst_extender : process(wb_clk_i)
begin begin
if rising_edge(wb_clk_i) then if rising_edge(wb_clk_i) then
if wb_rst_i = '1' then if wb_rst_i = '1' then
s_reset_extensor <= (others => '1'); reset_extender <= (others => '1');
else else
s_reset_extensor(0) <= '0'; reset_extender(0) <= '0';
for i in 1 to 2**c_RST_EXTENSOR -1 loop for i in 1 to 2**c_RST_EXTENSOR -1 loop
s_reset_extensor(i) <= s_reset_extensor(i-1); reset_extender(i) <= reset_extender(i-1);
end loop; end loop;
end if;
end if; end if;
end process; end if;
end process;
end Behavioral; end Behavioral;
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