eFEX firmware  1.7.3
ATLAS l1-calo - electron and tau feature extraction firmware for eFEX boards

Back to eFEX documentation
ipbus_watchdog.vhd
Go to the documentation of this file.
1 
7 
8 library IEEE;
9 use IEEE.STD_LOGIC_1164.ALL;
10 use ieee.numeric_std.all;
11 library ipbus_lib;
12 use ipbus_lib.ipbus.all;
13 use ipbus_lib.ipbus_reg_types.all;
14 
15 -- TIMEBASE and DEFAULT_TIMEOUT defined here.
16 -- Implementation and simulation use separate files with different values
17 use work.watchdog.all;
19 entity ipbus_watchdog is
20  generic(
21  TIMER_WIDTH: natural := 10
22  -- = Width in bits of watchdog timer
23  );
24  port(
26  ipbus_clk: in STD_LOGIC;
28  reset: in STD_LOGIC;
30  ipbus_in: in ipb_wbus;
32  ipbus_out: out ipb_rbus
33  );
34 
35 end ipbus_watchdog;
37 architecture rtl of ipbus_watchdog is
38 
39  signal addr: natural range 0 to 7;
40  signal ack: std_logic := '0';
41 
42  signal timeout_value: std_logic_vector(TIMER_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(DEFAULT_TIMEOUT,TIMER_WIDTH));
43  constant timer_padding: std_logic_vector(31 downto TIMER_WIDTH) := (others => '0');
44 
45  signal access_key: unsigned(29 downto 0) := (others => '0');
46  signal lock, previous_lock: std_logic := '0';
47  signal poslock, neglock: std_logic := '0';
48 
49  signal tick1ms: std_logic;
50 
51  signal wr_timer, wr_error: std_logic := '0';
52  signal timer_running, previous_timer_running: std_logic := '0';
53  signal timeout, t_error:std_logic := '0';
54 
55 begin
56 
57 -------------------------------------------------------------------------------
58 -- IPBus Control register
59 -- Addr(0) = Arbitration register = 30 bit Key & Lock & Timeout_error
60 -- Addr(1) = Programmable timeout delay in ms ticks. Default is 1 second.
61 --
62 -- Timer starts when Lock goes True ie '0' -> '1'. Timer refreshed when Timeout value (re)written.
63 -- Watchdog = '1' indicates the timer is running.
64 -- A timeout clears the Lock bit , sets T_error and sets the timeout delay register back to a default value.
65 -- The Key value is incremented whenever Lock goes False ie '1' -> '0'.
66 
67 
68  addr <= to_integer(unsigned(ipbus_in.ipb_addr(2 downto 0)));
69 
70 transitions: process(ipbus_clk, lock, previous_lock)
71  begin
72  if rising_edge(ipbus_clk) then
73  previous_lock <= lock;
74  poslock <= lock and not previous_lock; -- lock being applied
75  neglock <= not lock and previous_lock; -- lock being removed
76  previous_timer_running <= timer_running;
77  timeout <= not timer_running and previous_timer_running; -- a single pulse on timer reaching zero
78  end if;
79  end process;
80 
81 key_op: process(ipbus_clk, access_key, lock, previous_lock)
82  begin
83  if rising_edge(ipbus_clk) then
84  if reset = '1' then
85  access_key <= (others => '0');
86  elsif neglock = '1' then
87  access_key <= access_key + 1;
88  end if;
89  end if;
90  end process;
91 
92 -- Control register
93 writeop: process(ipbus_clk,addr,ipbus_in.ipb_wdata,ipbus_in.ipb_strobe,ipbus_in.ipb_write,ack)
94  begin
95  if rising_edge(ipbus_clk) then
96  if ( reset = '1' or timeout = '1' ) then
97  timeout_value <= std_logic_vector(to_unsigned(DEFAULT_TIMEOUT,TIMER_WIDTH));
98  lock <= '0';
99  elsif (ipbus_in.ipb_strobe='1' and ipbus_in.ipb_write = '1') then
100  if addr = 0 then lock <= ipbus_in.ipb_wdata(1); end if;
101  if addr = 1 then timeout_value <= ipbus_in.ipb_wdata(TIMER_WIDTH-1 downto 0); end if;
102  end if;
103  ack <= ipbus_in.ipb_strobe and not ack;
104  end if;
105  end process;
106 
107 timeout_flag: process(ipbus_clk,timeout,lock,ipbus_in.ipb_wdata(0))
108  begin
109  if rising_edge(ipbus_clk) then
110  if timeout = '1' then
111  t_error <= lock;-- a timeout with lock is an error
112  elsif wr_error = '1' then
113  t_error <= ipbus_in.ipb_wdata(0);-- clear error if needbe
114  end if;
115  end if;
116  end process;
117 
118 
119 
120 pulseop: process(ipbus_clk,addr,ipbus_in.ipb_wdata,ipbus_in.ipb_strobe,ipbus_in.ipb_write)
121  begin
122  if rising_edge(ipbus_clk) then
123  wr_timer <= '0'; wr_error <= '0';
124  if (ipbus_in.ipb_strobe='1' and ipbus_in.ipb_write = '1' and addr = 0) then
125  wr_error <= '1';
126  end if;
127  if (ipbus_in.ipb_strobe='1' and ipbus_in.ipb_write = '1' and addr = 1) then
128  wr_timer <= '1';
129  end if;
130  end if;
131  end process;
132 
133  ipbus_out.ipb_ack <= ack;
134  ipbus_out.ipb_err <= '0';
135 
136 -- Status register
137  ipbus_out.ipb_rdata <= std_logic_vector(access_key) & lock & t_error when addr = 0 else
138  timer_padding & timeout_value when addr = 1 else
139  x"00000000";
140 
141 
142 -- generate 1ms clock
143 ticker: process(reset, ipbus_clk)
144  variable cnt : natural range 0 to 32767 := 0;
145  begin
146  if rising_edge(ipbus_clk) then -- 32ns clock
147  if cnt < TIMEBASE then
148  cnt:= cnt+1;
149  tick1ms <= '0';
150  else
151  cnt:= 0;
152  tick1ms <= '1';
153  end if;
154  end if;
155  end process;
156 
157 
158 watchdog_timer: process(ipbus_clk, tick1ms)
159  variable timer : natural := 0;
160  begin
161  if rising_edge(ipbus_clk) then
162  if (wr_timer = '1' or poslock = '1' ) then
163  timer := to_integer(unsigned(timeout_value));
164  timer_running <= '1';
165  else -- count down to zero and stop
166  if tick1ms = '1' then
167  if timer = 0 then
168  timer := 0;
169  timer_running <= '0';
170  else
171  timer := timer - 1;
172  timer_running <= '1';
173  end if;
174  end if;
175  end if;
176  end if;
177  end process;
178 
179 end rtl;
ipbus watchdog
ipbus watchdog
in ipbus_clk STD_LOGIC
IPBus clock of 31.25MHz.
out ipbus_out ipb_rbus
IPBus output bus going from slaves to master.
in reset STD_LOGIC
reset
in ipbus_in ipb_wbus
IPBus input bus going from master to slaves.