CMX
CMX firmware code in-line documentation
 All Classes Namespaces Files Functions Variables
CMX_generic_module_spy_mem_control_FSM.vhd
Go to the documentation of this file.
1 ---------------------------------------
10 
11 library IEEE;
12 use IEEE.STD_LOGIC_1164.ALL;
13 use IEEE.NUMERIC_STD.ALL;
14 use IEEE.MATH_REAL.ALL;
15 
16 library UNISIM;
17 use UNISIM.VComponents.all;
18 
19 library work;
20 use work.CMXpackage.all;
22 
24  generic(
28  num_external_RAMS : positive := 1 --this defines how many outside memories
29  --there are so that we can parametrize the
30  --width of the mem_select_address port
31  );
32  port (
33  clk : in std_logic;
34 
35  ncs : in std_logic; --vme ports
36  rd_nwr : in std_logic;
37  ds : in std_logic;
38  addr_vme : in std_logic_vector (15 downto 0);
39  data_vme_in : in std_logic_vector (15 downto 0);
40  data_vme_out : out std_logic_vector (15 downto 0);
41  bus_drive : out std_logic;
42 
43  mode_control : out std_logic_vector(3 downto 0); --controls the mode of
44  --running; modes can be
45  --CONST_DPR_CONTROL_SPY,
46  --CONST_DPR_CONTROL_PLAYBACK,
47  --CONST_DPR_CONTROL_VERIFY
48  --forwarded form the
49  --control register
50  --will be interpreted by
51  --the outside
52  --generic to
53  --determine the data flow
54 
55  --memory steering ports
56  ena : out std_logic;
57  wea : out std_logic;
58  addra : out std_logic_vector(7 DOWNTO 0);
59 
60  mem_select_address : out std_logic_vector(addr_port_width(num_external_RAMS)-1 downto 0); --
61 
62  --unspecified length
63  dina : out std_logic_vector;
64  douta : in std_logic_vector;
65 
66  --this should be used to inhibit enb web when memory is being written to or
67  --read from vme on port a, high->inhibit, low->mode_control operation
68  port_b_master_inhibit : out std_logic);
69 
70 end CMX_generic_spy_mem_control_FSM;
71 
72 architecture multi_seg of CMX_generic_spy_mem_control_FSM is
73 
74  --width of the memory port
75  constant data_length : integer := dina'length; --how big is the data port
76 
77 
78  --we need to take the ceiling of the division so that a whole extra word is
79  --allocated to the VME space if the memory port width does not divide neatly
80  --into 16-bit words
81  constant num_words : integer := integer(ceil(real(data_length)/real(16)));
82 
83  --the number of reminder bits
84  constant num_rem_bits : integer := data_length rem 16;
85 
86  --this is the width of the memory select address which is uncorrected
87  --it is 0 if we have just one external RAM
88  constant mem_select_width_uncorr : natural := ceil_log_2(num_external_RAMS);
89 
90  --as above maxed out at 5 (to use in the status word as width of the portion
91  --of the global address repoted on the VME)
93 
94  --the maximum value of the global counter plus one.
95  --Note that we need that extra bit for the FSM opperation
96  constant global_addr_counter_limit : unsigned := to_unsigned(256*num_external_RAMS,mem_select_width_uncorr+1+8);
97 
98  --FSM states
99  type state_spy_mem_control_type is (s_standby, --the normal running mode, ihibit is
100  --released, no reads or writes from vme
101  s_inhibit_init, --after r/w request we
102  --need to raise the
103  --inhibit for 2 cycles
104  --so it can be propagated to
105  --the port B domain
106  s_wait_for_vme_write, -- write has been
107  -- requested, FSM waits
108  -- for data writes from VME
109  s_writing_ram, --all data words have been
110  --written to VME, uploading to RAM
111  s_reading_ram, --read has been requested,
112  --reading RAM
113  s_wait_for_vme_read --data has been read from
114  --RAM and presented to VME,
115  --waiting for SW to read it
116  --all out from VME.
117  );
119 
120  signal wea_sig,ena_sig : std_logic;
121  signal dina_sig : std_logic_vector(data_length-1 downto 0);
122 
123 
124  component vme_local_switch is
125  port (
126  data_vme_up : out std_logic_vector (15 downto 0);
127  data_vme_from_below : in arr_16;
128  bus_drive_up : out std_logic;
129  bus_drive_from_below : in std_logic_vector);
130  end component vme_local_switch;
131 
132 
133  signal data_vme_from_below : arr_16(num_words+1 downto 0);
134  signal bus_drive_from_below : std_logic_vector(num_words+1 downto 0);
135 
136 
137  component vme_outreg_notri is
138  generic (
139  ia_vme : integer;
140  width : integer);
141  port (
142  clk : in std_logic;
143  ncs : in std_logic;
144  rd_nwr : in std_logic;
145  ds : in std_logic;
146  addr_vme : in std_logic_vector (15 downto 0);
147  data_vme : out std_logic_vector (15 downto 0);
148  bus_drive : out std_logic;
149  data_to_vme : in std_logic_vector (width-1 downto 0);
150  read_detect : out std_logic);
151  end component vme_outreg_notri;
152 
154  generic (
155  ia_vme : integer;
156  width : integer);
157  port (
158  ncs : in std_logic;
159  rd_nwr : in std_logic;
160  ds : in std_logic;
161  addr_vme : in std_logic_vector (15 downto 0);
162  data_vme : out std_logic_vector (15 downto 0);
163  bus_drive : out std_logic;
164  data_to_vme : in std_logic_vector (width-1 downto 0));
165  end component vme_outreg_notri_async;
166 
167  component vme_inreg_notri is
168  generic (
169  ia_vme : integer;
170  width : integer);
171  port (
172  clk : in std_logic;
173  ncs : in std_logic;
174  rd_nwr : in std_logic;
175  ds : in std_logic;
176  addr_vme : in std_logic_vector (15 downto 0);
177  data_vme_in : in std_logic_vector (15 downto 0);
178  data_vme_out : out std_logic_vector (15 downto 0);
179  bus_drive : out std_logic;
180  data_from_vme : out std_logic_vector (width-1 downto 0);
181  data_to_vme : in std_logic_vector (width-1 downto 0);
182  read_detect : out std_logic;
183  write_detect : out std_logic);
184  end component vme_inreg_notri;
185 
187  generic (
188  ia_vme : integer;
189  width : integer);
190  port (
191  ncs : in std_logic;
192  rd_nwr : in std_logic;
193  ds : in std_logic;
194  addr_vme : in std_logic_vector (15 downto 0);
195  data_vme_in : in std_logic_vector (15 downto 0);
196  data_vme_out : out std_logic_vector (15 downto 0);
197  bus_drive : out std_logic;
198  data_from_vme : out std_logic_vector (width-1 downto 0);
199  data_to_vme : in std_logic_vector (width-1 downto 0));
200  end component vme_inreg_notri_async;
201 
202 
203  --six sets of signals for the data registers
205  signal data_to_vme_REG_RW_GENERIC_SPY_MEM_WORD : arr_16(num_words - 1 downto 0);
206  signal read_detect_REG_RW_GENERIC_SPY_MEM_WORD : std_logic_vector(num_words - 1 downto 0);
207  signal write_detect_REG_RW_GENERIC_SPY_MEM_WORD : std_logic_vector(num_words - 1 downto 0);
208 
209  --control register signals
210  signal data_from_vme_REG_RW_GENERIC_SPY_MEM_CONTROL : std_logic_vector (15 downto 0);
211  signal data_to_vme_REG_RW_GENERIC_SPY_MEM_CONTROL : std_logic_vector (15 downto 0);
214 
215  signal data_to_vme_REG_RO_GENERIC_SPY_MEM_STATUS : std_logic_vector (15 downto 0);
216  --signal read_detect_REG_RO_GENERIC_SPY_MEM_STATUS : std_logic;
217 
218  signal status_summary: std_logic_vector(2 downto 0); --included as part of
219  --the status register
220 
221 
222  --counter specifying the memory that will be written to (upper bits) and the address
223  --(lower 8 bits)
224  --all spy memories store 256 events (so address width is 8)
225  -- +bits needed to address the external memories
226  -- +extra bit needed for the FSM logic
227  signal global_addr_counter: unsigned(8+mem_select_width_uncorr downto 0);
228 
229  signal global_addr_counter_next: unsigned(8+mem_select_width_uncorr downto 0);
230 
231  signal inhibit_init_counter: unsigned(0 downto 0);
232 
233  signal op_request: std_logic; --bit signalling operation is requested
234  --taken from
235  signal rw_request: std_logic; --0 for read, 1 for write
236  --
237 
238  signal port_b_master_inhibit_sig : std_logic;
239 
240  --component chipscope_icon_u2_c1
241  -- port (
242  -- CONTROL0 : inout std_logic_vector(35 downto 0));
243  --end component;
244  --
245  --signal CONTROL0 : std_logic_vector(35 downto 0);
246  --
247  --component chipscope_ila_CMX_generic_spy_mem_control_FSM
248  -- port (
249  -- CONTROL : inout std_logic_vector(35 downto 0);
250  -- CLK : in std_logic;
251  -- DATA : in std_logic_vector(260 downto 0);
252  -- TRIG0 : in std_logic_vector(15 downto 0));
253  --end component;
254  --
255  --
256  --signal DATA_chipscope_ila_CMX_generic_spy_mem_control_FSM : std_logic_vector(260 downto 0);
257  --signal TRIG0_chipscope_ila_CMX_generic_spy_mem_control_FSM : std_logic_vector(15 downto 0);
258 
259 begin -- multi_seg
260 
261  --XST should give an error if we supplied vectors of different lengths
262  assert (dina'length = douta'length ) report "memory port lengths not equal" severity failure;
263 
264 
265 
266  --instantiate VME registers
267 
268 
269  vme_local_switch_inst: entity work.vme_local_switch
270  port map (
275 
276  ena<=ena_sig;
277  wea<=wea_sig;
278  dina<=dina_sig;
279 
281 
282  vme_data_word_reg_gen: for word_i in 0 to num_words-1 generate
283 
285  generic map (
286  ia_vme => ADDR_REG_RW_GENERIC_SPY_MEM_WORD+(2*word_i),
287  width => 16)
288  port map (
289  clk => clk,
290  ncs => ncs,
291  rd_nwr => rd_nwr,
292  ds => ds,
293  addr_vme => addr_vme,
295  data_vme_out => data_vme_from_below (word_i),
296  bus_drive => bus_drive_from_below (word_i),
301 
302  --connect the output from RAM to VME for reading by SW
303  full_register: if num_rem_bits = 0 generate --the width of the data breaks
304  --cleanly into 16 bit words
305  -- simply assign memory output to VME
306  data_to_vme_REG_RW_GENERIC_SPY_MEM_WORD(word_i) <= douta( (word_i+1)*16 - 1 downto word_i*16);
307  dina_sig( (word_i+1)*16 - 1 downto word_i*16)<=data_from_vme_REG_RW_GENERIC_SPY_MEM_WORD(word_i);
308  end generate full_register;
309  partial_register: if num_rem_bits /= 0 generate --the memory width does not
310  --divide by 16
311  lower_words: if word_i < (num_words-1) generate
312  --lower words - just assign a range of data to register as above
313  data_to_vme_REG_RW_GENERIC_SPY_MEM_WORD(word_i) <= douta( (word_i+1)*16 - 1 downto word_i*16);
314  dina_sig( (word_i+1)*16 - 1 downto word_i*16)<=data_from_vme_REG_RW_GENERIC_SPY_MEM_WORD(word_i);
315  end generate lower_words;
316  upper_words: if word_i = (num_words-1) generate
317  --last word fill lower bits with whatsever is left from the data port
318  --and pre-pad with 0
319  --for input just ignore the upper bits
320  data_to_vme_REG_RW_GENERIC_SPY_MEM_WORD(word_i)(num_rem_bits-1 downto 0) <= douta(word_i*16+num_rem_bits-1 downto word_i*16);
321  data_to_vme_REG_RW_GENERIC_SPY_MEM_WORD(word_i)(15 downto num_rem_bits) <= (others => '0');
322  dina_sig(word_i*16+num_rem_bits-1 downto word_i*16)<=data_from_vme_REG_RW_GENERIC_SPY_MEM_WORD(word_i)(num_rem_bits-1 downto 0);
323  end generate upper_words;
324  end generate partial_register;
325 
326  end generate vme_data_word_reg_gen;
327 
329  generic map (
331  width => 16)
332  port map (
333  clk => clk,
334  ncs => ncs,
335  rd_nwr => rd_nwr,
336  ds => ds,
337  addr_vme => addr_vme,
345 
346 
348  generic map (
350  width => 16)
351  port map (
352  ncs => ncs,
353  rd_nwr => rd_nwr,
354  ds => ds,
355  addr_vme => addr_vme,
356  data_vme => data_vme_from_below (num_words+1),
357  bus_drive => bus_drive_from_below (num_words+1),
359  --read_detect => read_detect_REG_RO_GENERIC_SPY_MEM_STATUS);
360 
361 
362  --interpretation of portions of VME registers and connection to output ports
363  --status register: top 3 bits is the status
365  --remaining bits is the global address counter. If we are controlling more
366  --than 32 RAMS (unlikely) only the lower 5 bits will be presented on the
367  --status register
369  --
370  gen_vme_status_word_padding: if mem_select_width_uncorr_trunc < 5 generate
372  end generate gen_vme_status_word_padding;
373 
374 
375  gen_mem_select_addr_dummy: if mem_select_width_uncorr = 0 generate
376  mem_select_address(0)<='1'; --assign a constant. If there is only one RAM
377  --the value of the port should be ignored
378  end generate gen_mem_select_addr_dummy;
379  gen_mem_select_addr_proper: if mem_select_width_uncorr > 0 generate
380  mem_select_address<=std_logic_vector( global_addr_counter(global_addr_counter'length-1-1 downto 8) ); --we have two or
381  --more RAMs to control; note that the 'extra' -1 is there since the width
382  --of the global address is extended by one bit for the FSM control so we
383  --need to subtract this here
384 
385  end generate gen_mem_select_addr_proper;
386  addra<=std_logic_vector(global_addr_counter(7 downto 0));
387 
391 
392  --for the control register data to read is simply the data written
394 
395  -- -- --data to/from vme is connected to data from/to RAM
396  -- -- dina_sig<=data_from_vme_REG_RW_GENERIC_SPY_MEM_WORD(5) & data_from_vme_REG_RW_GENERIC_SPY_MEM_WORD(4) &
397  -- -- data_from_vme_REG_RW_GENERIC_SPY_MEM_WORD(3) & data_from_vme_REG_RW_GENERIC_SPY_MEM_WORD(2) &
398  -- -- data_from_vme_REG_RW_GENERIC_SPY_MEM_WORD(1) & data_from_vme_REG_RW_GENERIC_SPY_MEM_WORD(0);
399  -- -- --data_to_vme... was constructed in the generate loop above
400 
401  --update state on clock edge
402  process (clk)
403  begin -- process
404  if rising_edge(clk) then
405  --if state_next=s_writing_ram or (state_next=s_wait_for_vme_read and state_reg=s_reading_ram) then
406  -- if global_addr_counter=to_unsigned(256*numactchan,13) then
407  -- global_addr_counter<=to_unsigned(0,13);
408  -- else
409  -- global_addr_counter<=global_addr_counter_next;
410  -- end if;
411  --else
412  -- global_addr_counter<=global_addr_counter;--to_unsigned(0,13);
413  --end if;
415  -- start klm mod
417  end if;
418  end process;
419 
420 
421  --next state logic
423  begin
424  -- default values
427  ena_sig<='0';
428  wea_sig<='0';
429  --addra<=(others=>'0');
430  --global_addr_counter<=(others=>'0');
431  status_summary<=(others=>'0');
432 
433  case state_reg is
434  when s_standby =>
435  status_summary<=CONST_DPR_STATUS_NORMAL;
438  state_next<=s_inhibit_init;
440  else
441  state_next<=s_standby;
442  end if;
443  when s_inhibit_init =>
445  status_summary<=CONST_DPR_STATUS_WAIT_INHIBIT;
446  if ( rw_request='1') then
447  state_next<=s_wait_for_vme_write;
448  else
449  state_next<=s_reading_ram;
450  end if;
451  when s_wait_for_vme_write =>
453  status_summary<=CONST_DPR_STATUS_WRITE;
455  state_next<=s_writing_ram;
457  ena_sig<='1';
458  wea_sig<='1';
459  else
460  state_next<=s_wait_for_vme_write;
462  end if;
463  when s_writing_ram =>
465  status_summary<=CONST_DPR_STATUS_WAIT_WRITE;
466  if global_addr_counter=global_addr_counter_limit then --to_unsigned(256*numactchan,13) then
468  state_next<=s_standby;
469  else
470  state_next<=s_wait_for_vme_write;
472  end if;
473  when s_reading_ram =>
475  status_summary<=CONST_DPR_STATUS_WAIT_READ;
476  ena_sig<='1';
478  state_next<=s_wait_for_vme_read;
479  when s_wait_for_vme_read =>
481  status_summary<=CONST_DPR_STATUS_READ;
483  if global_addr_counter=(global_addr_counter_limit-1) then --to_unsigned(256*numactchan-1,13) then
484  state_next<=s_standby;
485  else
487  state_next<=s_reading_ram;
488  end if;
489  else
491  state_next<=s_wait_for_vme_read;
492  end if;
493  when others =>
494  state_next<=s_standby;
495  end case;
496 
497  end process;
498 
499 -- --Moore output
500 -- process (state_reg)
501 -- begin
502 -- counter_enable<='0';
503 -- case state_reg is
504 -- when s_counter_running =>
505 -- counter_enable<='1';
506 -- when s_counter_stopped =>
507 -- counter_enable<='0';
508 -- when others => null;
509 -- end case;
510 -- end process;
511 --
512 
513 
514  --chipscope_ila_CMX_generic_spy_mem_control_FSM_inst: chipscope_ila_CMX_generic_spy_mem_control_FSM
515  -- port map (
516  -- CONTROL => CONTROL0,
517  -- CLK => clk,
518  -- DATA => DATA_chipscope_ila_CMX_generic_spy_mem_control_FSM,
519  -- TRIG0 => TRIG0_chipscope_ila_CMX_generic_spy_mem_control_FSM);
520  --
521  --
522  --chipscope_icon_u2_c1_inst: chipscope_icon_u2_c1
523  -- port map (
524  -- CONTROL0 => CONTROL0);
525  --
526  --TRIG0_chipscope_ila_CMX_generic_spy_mem_control_FSM(0)<=op_request;
527  --TRIG0_chipscope_ila_CMX_generic_spy_mem_control_FSM(1)<=rw_request;
528  --TRIG0_chipscope_ila_CMX_generic_spy_mem_control_FSM(2)<=write_detect_REG_RW_GENERIC_SPY_MEM_CONTROL;
529  --TRIG0_chipscope_ila_CMX_generic_spy_mem_control_FSM(8 downto 3)<=read_detect_REG_RW_GENERIC_SPY_MEM_WORD;
530  --TRIG0_chipscope_ila_CMX_generic_spy_mem_control_FSM(14 downto 9)<=write_detect_REG_RW_GENERIC_SPY_MEM_WORD;
531  --TRIG0_chipscope_ila_CMX_generic_spy_mem_control_FSM(15)<=ds;
532  --
533  --
534  --DATA_chipscope_ila_CMX_generic_spy_mem_control_FSM(0)<=op_request;
535  --DATA_chipscope_ila_CMX_generic_spy_mem_control_FSM(1)<=rw_request;
536  --DATA_chipscope_ila_CMX_generic_spy_mem_control_FSM(2)<=write_detect_REG_RW_GENERIC_SPY_MEM_CONTROL;
537  --DATA_chipscope_ila_CMX_generic_spy_mem_control_FSM(8 downto 3)<=read_detect_REG_RW_GENERIC_SPY_MEM_WORD;
538  --DATA_chipscope_ila_CMX_generic_spy_mem_control_FSM(14 downto 9)<=write_detect_REG_RW_GENERIC_SPY_MEM_WORD;
539  --DATA_chipscope_ila_CMX_generic_spy_mem_control_FSM(27 downto 15)<=std_logic_vector(global_addr_counter);
540  --DATA_chipscope_ila_CMX_generic_spy_mem_control_FSM(31 downto 28)<=status_summary;
541  --DATA_chipscope_ila_CMX_generic_spy_mem_control_FSM(32)<=ena_sig;
542  --DATA_chipscope_ila_CMX_generic_spy_mem_control_FSM(33)<=wea_sig;
543  --DATA_chipscope_ila_CMX_generic_spy_mem_control_FSM(129 downto 34)<=douta;
544  --DATA_chipscope_ila_CMX_generic_spy_mem_control_FSM(225 downto 130)<=dina_sig;
545  --DATA_chipscope_ila_CMX_generic_spy_mem_control_FSM(226)<=ds;
546  --DATA_chipscope_ila_CMX_generic_spy_mem_control_FSM(227)<=rd_nwr;
547  --DATA_chipscope_ila_CMX_generic_spy_mem_control_FSM(243 downto 228)<=addr_vme;
548  --DATA_chipscope_ila_CMX_generic_spy_mem_control_FSM(259 downto 244)<=data_vme;
549  --DATA_chipscope_ila_CMX_generic_spy_mem_control_FSM(260)<=port_b_master_inhibit_sig;
550 
551 
552 
553 
554 
555 
556 end multi_seg;
vme_inreg_notri vme_inreg_reg_rw_generic_spy_mem_wordvme_inreg_reg_rw_generic_spy_mem_word
std_logic_vector (num_words - 1 downto 0) write_detect_REG_RW_GENERIC_SPY_MEM_WORD
out read_detectstd_logic
in addr_vmestd_logic_vector (15 downto 0)
out data_vmestd_logic_vector (15 downto 0)
out data_vme_outstd_logic_vector (15 downto 0)
out data_from_vmestd_logic_vector (width - 1 downto 0)
natural :=imin (5 ,mem_select_width_uncorr) mem_select_width_uncorr_trunc
in data_vme_from_belowarr_16
--! inputs from local registers and from
out data_from_vmestd_logic_vector (width - 1 downto 0)
unsigned (8 + mem_select_width_uncorr downto 0) global_addr_counter
out data_vmestd_logic_vector (15 downto 0)
in data_vme_instd_logic_vector (15 downto 0)
out write_detectstd_logic
unsigned (8 + mem_select_width_uncorr downto 0) global_addr_counter_next
natural :=ceil_log_2 (num_external_RAMS) mem_select_width_uncorr
( s_standby ,s_inhibit_init ,s_wait_for_vme_write ,s_writing_ram ,s_reading_ram ,s_wait_for_vme_read ) state_spy_mem_control_type
std_logic_vector (data_length - 1 downto 0) dina_sig
in data_to_vmestd_logic_vector (width - 1 downto 0)
out data_vme_upstd_logic_vector (15 downto 0)
--! connect this to
vme_inreg_notri vme_inreg_reg_rw_generic_spy_mem_controlvme_inreg_reg_rw_generic_spy_mem_control
in addr_vmestd_logic_vector (15 downto 0)
in data_to_vmestd_logic_vector (width - 1 downto 0)
out bus_drive_upstd_logic
or of all bus drive requests from below
out mem_select_addressstd_logic_vector (addr_port_width (num_external_RAMS) - 1 downto 0)
unsigned :=to_unsigned (256 * num_external_RAMS ,mem_select_width_uncorr + 1 + 8 global_addr_counter_limit)
in addr_vmestd_logic_vector (15 downto 0)
vme_outreg_notri_async vme_outreg_reg_ro_generic_spy_mem_statusvme_outreg_reg_ro_generic_spy_mem_status
in data_to_vmestd_logic_vector (width - 1 downto 0)
out data_vme_outstd_logic_vector (15 downto 0)
out bus_drivestd_logic
in addr_vmestd_logic_vector (15 downto 0)
test registers
in data_vme_instd_logic_vector (15 downto 0)
integer :=integer (ceil (real (data_length) / real (16))) num_words
out read_detectstd_logic
in data_to_vmestd_logic_vector (width - 1 downto 0)
std_logic_vector (num_words - 1 downto 0) read_detect_REG_RW_GENERIC_SPY_MEM_WORD
std_logic_vector (num_words + 1 downto 0) bus_drive_from_below
in bus_drive_from_belowstd_logic_vector