vme_data_bus.vhd 35 KB
Newer Older
Michael Munch's avatar
Michael Munch committed
1
2
library ieee;
use ieee.std_logic_1164.all;
Michael Munch's avatar
Michael Munch committed
3
4
library vme;
use vme.vme_pkg.all;
Michael Munch's avatar
Michael Munch committed
5

Michael Munch's avatar
Michael Munch committed
6
entity vme_data_bus is
Michael Munch's avatar
Michael Munch committed
7
  generic (
Michael Munch's avatar
Michael Munch committed
8
9
    CLOCK_PERIOD  : integer := 10;
    FORMAL        : boolean := true
Michael Munch's avatar
Michael Munch committed
10
    );
Michael Munch's avatar
Michael Munch committed
11
12
  port (
    signal clk      : in std_logic; -- CLOCK with period CLOCK_PERIOD
Michael Munch's avatar
Michael Munch committed
13

Michael Munch's avatar
Michael Munch committed
14
    -- _n indicate active low (inverted) signals
Michael Munch's avatar
Michael Munch committed
15

Michael Munch's avatar
Michael Munch committed
16
17
    signal vme_addr_i		: in std_logic_vector(31 downto 0);
    signal vme_addr_o		: out std_logic_vector(31 downto 0);
Michael Munch's avatar
Michael Munch committed
18
    signal vme_addr_dir		: out std_logic := c_PIN_IN;
Michael Munch's avatar
Michael Munch committed
19
    signal vme_addr_oe_n	: out std_logic := c_OE_OFF;
Michael Munch's avatar
Michael Munch committed
20

Michael Munch's avatar
Michael Munch committed
21
22
    signal vme_am_i		: in am_vec_t;
    signal vme_am_o		: out am_vec_t;
Michael Munch's avatar
Michael Munch committed
23
    signal vme_am_dir		: out std_logic := c_PIN_IN;
Michael Munch's avatar
Michael Munch committed
24
25
26
27
--    signal vme_am_oe_n	: out std_logic -- Shared with addr
    signal vme_write_n_i        : in std_logic;
    signal vme_write_n_o        : out std_logic;
    -- write shares DIR and OE with AM
Michael Munch's avatar
Michael Munch committed
28

Michael Munch's avatar
Michael Munch committed
29
30
    signal vme_data_i		: in std_logic_vector(31 downto 0);
    signal vme_data_o		: out std_logic_vector(31 downto 0);
Michael Munch's avatar
Michael Munch committed
31
    signal vme_data_dir		: out std_logic := c_PIN_IN;
Michael Munch's avatar
Michael Munch committed
32
    signal vme_data_oe_n	: out std_logic := c_OE_OFF;
Michael Munch's avatar
Michael Munch committed
33

Michael Munch's avatar
Michael Munch committed
34
35
    signal vme_as_n_i		: in std_logic;
    signal vme_as_n_o		: out std_logic;
Michael Munch's avatar
Michael Munch committed
36
    signal vme_as_n_dir		: out std_logic := c_PIN_IN;
Michael Munch's avatar
Michael Munch committed
37

Michael Munch's avatar
Michael Munch committed
38
39
    signal vme_iack_n_i		: in std_logic;
    signal vme_iack_n_o		: out std_logic;
Michael Munch's avatar
Michael Munch committed
40
    signal vme_iack_n_dir	: out std_logic := c_PIN_IN;
Michael Munch's avatar
Michael Munch committed
41
42
43
44

    -- Always enabled, always input
    signal vme_iackin_n		: in std_logic;

Michael Munch's avatar
Michael Munch committed
45
46
    -- Enable IACKOUT_n. Will be pulled low
    signal vme_iackout_n_oe_n	: out std_logic := c_OE_OFF;
Michael Munch's avatar
Michael Munch committed
47
48

    signal vme_dtack_n_i	: in std_logic;
Michael Munch's avatar
Michael Munch committed
49
--    signal vme_dtack_n_o	: out std_logic;
Michael Munch's avatar
Michael Munch committed
50
    signal vme_dtack_n_dir	: out std_logic := c_PIN_IN;
Michael Munch's avatar
Michael Munch committed
51

Michael Munch's avatar
Michael Munch committed
52
--    signal vme_retry_i	        : in std_logic;
Michael Munch's avatar
Michael Munch committed
53
--    signal vme_retry_o	        : out std_logic;
Michael Munch's avatar
Michael Munch committed
54
--    signal vme_retry_dir	: out std_logic := c_PIN_IN;
Michael Munch's avatar
Michael Munch committed
55
56
57

    signal vme_ds_n_i	        : in std_logic_vector(1 downto 0);
    signal vme_ds_n_o	        : out std_logic_vector(1 downto 0);
Michael Munch's avatar
Michael Munch committed
58
    signal vme_ds_n_dir	        : out std_logic := c_PIN_IN;
Michael Munch's avatar
Michael Munch committed
59
60

    signal vme_berr_n_i         : in std_logic;
Michael Munch's avatar
Michael Munch committed
61
62
    signal vme_berr_n_o         : out std_logic;
    signal vme_berr_n_dir       : out std_logic;
Michael Munch's avatar
Michael Munch committed
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82


    ---------------------------------
    -- SYS CONTROL START           --
    ---------------------------------

    -- signal vme_sysreset_n_i     : in std_logic;
    -- signal vme_sysreset_n_o     : out std_logic;
    -- signal vme_sysreset_n_dir   : out std_logic

    -- signal vme_sysfail_n_i     : in std_logic;
    -- signal vme_sysfail_n_o     : out std_logic;
    -- signal vme_sysfail_n_dir   : out std_logic

    -- signal vme_sysclk_i     : in std_logic;
    -- signal vme_sysclk_o     : out std_logic;
    -- signal vme_sysclk_dir   : out std_logic

    ---------------------------------
    -- SYS CONTROL END             --
Michael Munch's avatar
Michael Munch committed
83
    ---------------------------------
Michael Munch's avatar
Michael Munch committed
84
85
86
87


    ---------------------------------
    -- BUS REQUEST START           --
Michael Munch's avatar
Michael Munch committed
88
    ---------------------------------
Michael Munch's avatar
Michael Munch committed
89

Michael Munch's avatar
Bugfix    
Michael Munch committed
90
91
92
93
    -- signal vme_br_n_i		: in std_logic_vector(3 downto 0);
    -- signal vme_br_n_o		: out std_logic_vector(3 downto 0);
    -- signal vme_br_n_dir		: out std_logic;
    -- signal vme_br_n_oe_n	: out std_logic;
Michael Munch's avatar
Michael Munch committed
94

Michael Munch's avatar
Michael Munch committed
95
    -- -- Fixed DIR = input
Michael Munch's avatar
Bugfix    
Michael Munch committed
96
97
    -- signal vme_bgin_n_i		: in std_logic_vector(3 downto 0);
    -- signal vme_bgin_n_oe_n	: out std_logic;
Michael Munch's avatar
Michael Munch committed
98

Michael Munch's avatar
Bugfix    
Michael Munch committed
99
100
101
    -- -- Fixed DIR = output
    -- signal vme_bgout_n_o	: out std_logic_vector(3 downto 0);
    -- signal vme_bgout_n_oe_n	: out std_logic;
Michael Munch's avatar
Michael Munch committed
102

Michael Munch's avatar
Bugfix    
Michael Munch committed
103
104
105
106
107
108
109
110
111
112
    -- signal vme_bbsy_n_i         : in std_logic;
    -- signal vme_bbsy_n_o         : out std_logic;
    -- signal vme_bbsy_n_dir       : out std_logic;

    -- signal vme_bclr_n_i         : in std_logic;
    -- signal vme_bclr_n_o         : out std_logic;
    -- signal vme_bclr_n_dir       : out std_logic

    ---------------------------------
    -- BUS REQUEST END           --
Michael Munch's avatar
Michael Munch committed
113
    ---------------------------------
Michael Munch's avatar
Michael Munch committed
114
115


Michael Munch's avatar
Bugfix    
Michael Munch committed
116
117
118
    ---------------------------------
    -- Mini BUS REQUEST START      --
    ---------------------------------
Michael Munch's avatar
Michael Munch committed
119
    -- Request bus
Michael Munch's avatar
Michael Munch committed
120
    signal vme_br_n_o		: out std_logic_vector(3 downto 0);
Michael Munch's avatar
Michael Munch committed
121
122
123
    -- Receive bus grant
    signal vme_bgin_n_i		: in std_logic_vector(3 downto 0);
    -- Output bus grant
124
    signal vme_bgout_n_o	: out std_logic_vector(3 downto 0);
Michael Munch's avatar
Michael Munch committed
125
    -- Signal bus ownership
126
    signal vme_bbsy_n_o         : out std_logic;
Michael Munch's avatar
Michael Munch committed
127
    -- Signal the we should clear bus
Michael Munch's avatar
Michael Munch committed
128
    signal vme_bclr_n_i         : in std_logic;
Michael Munch's avatar
Michael Munch committed
129
130

    ---------------------------------
Michael Munch's avatar
Bugfix    
Michael Munch committed
131
132
133
    -- Mini BUS REQUEST END        --
    ---------------------------------

Michael Munch's avatar
Michael Munch committed
134

Michael Munch's avatar
Michael Munch committed
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
    ---------------------------------
    -- Serial data interface START --
    ---------------------------------

    -- signal vme_serdat_n_i         : in std_logic;
    -- signal vme_serdat_n_o         : out std_logic;
    -- signal vme_serdat_n_dir       : out std_logic

    -- signal vme_serclk_i         : in std_logic;
    -- signal vme_serclk_o         : out std_logic;
    -- signal vme_serclk_dir       : out std_logic

    -------------------------------
    -- Serial data interface END --
    -------------------------------

Michael Munch's avatar
Michael Munch committed
151
    -- This is asserted when not IDLE.
Michael Munch's avatar
Michael Munch committed
152
    signal busy                 : out std_logic := '0';
Michael Munch's avatar
Michael Munch committed
153
    
Michael Munch's avatar
Michael Munch committed
154
155
    -- Latched from last VME read operation.
    -- This is valid when int_data_strobe is high.
156
    signal int_data_read           : out vme_vec_64_t;
Michael Munch's avatar
Michael Munch committed
157

158
    -- Strobe that indicates new data in int_data_read
Michael Munch's avatar
Michael Munch committed
159
160
    signal int_data_strobe      : out std_logic := c_DATA_CLEAR;

Michael Munch's avatar
Michael Munch committed
161
162
163
164
    -- Strobe that indicates that the current value of
    -- int_vme_go have been consumed.
    signal int_go_consumed_strobe : out std_logic := '0';

Michael Munch's avatar
Michael Munch committed
165
166
    -- Strobe that indicates when a BLT decision is needed.
    -- See int_blt_decided and int_blt_continue
167
    signal int_blt_decision : out std_logic := '0';
Michael Munch's avatar
Michael Munch committed
168

Michael Munch's avatar
Michael Munch committed
169
170
171
    -- Error code.
    -- Consult vme_pkg.ERR_CODE for valid values.
    -- Will be vme_pkg.ERR_CODE.OK if no problems.
172
    signal int_err_code         : out err_vec_t := c_ERR_OK;    
Michael Munch's avatar
Michael Munch committed
173
   
Michael Munch's avatar
Michael Munch committed
174
    signal int_addr             : in vme_addr_t;
175
    signal int_data_write           : in vme_vec_64_t;
Michael Munch's avatar
Michael Munch committed
176

Michael Munch's avatar
Michael Munch committed
177
    signal int_am_i             : in am_vec_t;
178
    -- signal int_vme_op           : in VME_OP;
Michael Munch's avatar
Michael Munch committed
179
    signal int_vme_write           : in std_logic;
180
    signal int_vme_go           : in std_logic;
Michael Munch's avatar
Michael Munch committed
181

182
183

    signal int_blt_decided      : in std_logic;
Michael Munch's avatar
Michael Munch committed
184
    signal int_blt_continue     : in std_logic;
Michael Munch's avatar
Michael Munch committed
185
    signal int_timeout_n        : in std_logic
186

Michael Munch's avatar
Michael Munch committed
187
188
189
    );
end entity;

Michael Munch's avatar
Michael Munch committed
190
191
192
193


architecture rtl of vme_data_bus is
  type vme_data_state is (
Michael Munch's avatar
Michael Munch committed
194
195
196
197
198
199
200
201
202
    IDLE,               -- 0
    DTACK_HIGH_WAIT,    -- 1
    DTACK_LOW_WAIT,     -- 2
    AS_DELAY,           -- 3
    DS_DELAY,           -- 4
    IACK_HIGH_WAIT,     -- 5
    LATCH_DATA,         -- 6
    BLT_READ_WAIT,      -- 7
    BLT_WRITE_WAIT,     -- 8
Michael Munch's avatar
Michael Munch committed
203
204
    IDLE_DELAY,         -- 9
    TIMEOUT,            -- 10
205
206
    TIMEOUT_WAIT,       -- 11
    BERR_HIGH_WAIT      -- 12
Michael Munch's avatar
Michael Munch committed
207
208
209
    );

  type addr_type_t is (
Michael Munch's avatar
Michael Munch committed
210
    A16,
Michael Munch's avatar
Michael Munch committed
211
212
213
214
215
216
    A24,
    A32,
    ADDR_ERR
    );

  type transfer_type_t is (
217
218
219
220
    SINGLE,             -- 0
    BLT,                -- 1
    MBLT,               -- 2
    TRANSFER_ERR        -- 3
221
    );
Michael Munch's avatar
Michael Munch committed
222

Michael Munch's avatar
Michael Munch committed
223
  signal state          : vme_data_state := IDLE;
Michael Munch's avatar
Michael Munch committed
224
225
  signal addr_mode      : addr_type_t;
  signal transfer_mode  : transfer_type_t;
226
  signal data_placed    : std_logic := '0';
Michael Munch's avatar
Michael Munch committed
227

Michael Munch's avatar
Michael Munch committed
228
  signal n_wait      : natural range 0 to 8 := 0;
Michael Munch's avatar
Michael Munch committed
229
  constant c_N_AS_DELAY  : natural range 1 to 8 :=
Michael Munch's avatar
Michael Munch committed
230
    (35 / CLOCK_PERIOD);
Michael Munch's avatar
Michael Munch committed
231
  constant c_N_DS_DELAY  : natural range 1 to 8 :=
Michael Munch's avatar
Michael Munch committed
232
233
234
    (35 / CLOCK_PERIOD);
  constant c_N_DS_SPACING  : natural range 1 to 8 :=
    (35 / CLOCK_PERIOD);  
Michael Munch's avatar
Michael Munch committed
235
  constant c_N_DATA_WAIT  : natural range 1 to 8 :=
Michael Munch's avatar
Michael Munch committed
236
237
238
239
    (25 / CLOCK_PERIOD);
  constant c_N_TIMEOUT_WAIT  : natural range 1 to 8 :=
    (30 / CLOCK_PERIOD);

Michael Munch's avatar
Michael Munch committed
240
241
242

  -- Latched signals
  signal l_addr                 : vme_addr_t;
243
  signal l_rw                   : std_logic;
Michael Munch's avatar
Michael Munch committed
244
245
246
247
  signal l_am                   : am_vec_t;
  signal l_addr_mode            : addr_type_t;
  signal l_transfer_mode        : transfer_type_t;

248
249
250
251
252
  -- Latched data
  -- If READ_OP it stores the data read from slave.
  -- If WRITE_OP it stores the data to write to slave.
  signal l_data             : std_logic_vector(63 downto 0) := (others => '0');

Michael Munch's avatar
Michael Munch committed
253
  signal first_cycle                  : std_logic := '1';
Michael Munch's avatar
Michael Munch committed
254
255
256
257
258

  -- Timeout of operations, in order to never get stuck.
  constant TIMEOUT_CNT_MAX : integer := 255;
  signal timeout_cnt : integer range 0 to 255 := TIMEOUT_CNT_MAX;

Michael Munch's avatar
Michael Munch committed
259
260
  signal last_ds_n	        : std_logic_vector(1 downto 0);
  signal last_berr_n              : std_logic;
Michael Munch's avatar
Michael Munch committed
261
  
Michael Munch's avatar
Michael Munch committed
262
begin
Michael Munch's avatar
Michael Munch committed
263

Michael Munch's avatar
Michael Munch committed
264
265
  -- Determine addressing mode
  with int_am_i select addr_mode <=
Michael Munch's avatar
Michael Munch committed
266
    A16 when c_AM_A16 | c_AM_A16_LOCK | c_AM_A16_SUP,
Michael Munch's avatar
Michael Munch committed
267
268
269
270
271
    A24 when c_AM_A24_SUP_BLT | c_AM_A24_SUP_MBLT |
    	c_AM_A24_BLT | c_AM_A24_MBLT |
    	c_AM_A24_SUP_PROG | c_AM_A24_SUP_DATA |
	c_AM_A24_PROG | c_AM_A24_DATA |
	c_AM_A24_LOCK, -- In principle correct ADDR mode
272

Michael Munch's avatar
Michael Munch committed
273
274
275
276
277
    A32 when c_AM_A32_BLT | c_AM_A32_MBLT |
    	c_AM_A32_PROG | c_AM_A32_DATA |
	c_AM_A32_LOCK, -- In principle correct ADDR mode
    ADDR_ERR when others;

278

Michael Munch's avatar
Michael Munch committed
279
280
281
  with int_am_i select transfer_mode <=
    SINGLE when c_AM_A32_PROG | c_AM_A32_DATA |
    	        c_AM_A24_SUP_PROG | c_AM_A24_SUP_DATA |
Michael Munch's avatar
Michael Munch committed
282
283
	        c_AM_A24_PROG | c_AM_A24_DATA |
                c_AM_A16 | c_AM_A16_SUP,
Michael Munch's avatar
Michael Munch committed
284
285
286
    BLT when c_AM_A32_BLT | c_AM_A24_SUP_BLT |
             c_AM_A24_BLT,
    MBLT when c_AM_A32_MBLT | c_AM_A24_SUP_MBLT |
287
288
289
    	     c_AM_A24_MBLT,
    TRANSFER_ERR when others;

Michael Munch's avatar
Michael Munch committed
290
  process (clk)
291
      variable cur_data             : std_logic_vector(63 downto 0) := (others => '0');
Michael Munch's avatar
Michael Munch committed
292
293
  begin
    if (rising_edge(clk)) then
294
295
296
297
298

      -- Common delay counter
      if (n_wait /= 0) then
        n_wait <= n_wait - 1;
      end if;
299
  
300
      
Michael Munch's avatar
Michael Munch committed
301
302
303
304
305
306
307
308
309
310
      case state is
        when IDLE =>
          -- Revert to well defined state.
          vme_addr_oe_n <= c_OE_ON;
          vme_data_oe_n <= c_OE_ON;
          vme_iackout_n_oe_n <= c_OE_OFF;
          vme_addr_dir <= c_PIN_IN;
          vme_am_dir <= c_PIN_IN;
          vme_data_dir <= c_PIN_IN;
          vme_as_n_dir <= c_PIN_IN;
Michael Munch's avatar
Michael Munch committed
311
312
313
          vme_as_n_o <= '1';
          vme_berr_n_dir <= c_PIN_IN;
          vme_berr_n_o <= '1';
Michael Munch's avatar
Michael Munch committed
314
315
316
          vme_iack_n_dir <= c_PIN_IN;
          vme_dtack_n_dir <= c_PIN_IN;
          vme_ds_n_dir <= c_PIN_IN;
Michael Munch's avatar
Michael Munch committed
317
          vme_ds_n_o <= "11";
318
          int_data_strobe <= c_DATA_CLEAR;
Michael Munch's avatar
Michael Munch committed
319

320
321
          -- Munk: Retain error code until starting next cycle
          -- int_err_code <= c_ERR_OK;
Michael Munch's avatar
Michael Munch committed
322
323
          
          n_wait <= 0;
Michael Munch's avatar
Michael Munch committed
324
          first_cycle <= '1';
Michael Munch's avatar
Michael Munch committed
325
          busy <= '0';
Michael Munch's avatar
Michael Munch committed
326
327

          -- READ requested
Michael Munch's avatar
Michael Munch committed
328
          if vme_iack_n_i = '0' then
329
                state <= IACK_HIGH_WAIT;            
330
          elsif (int_vme_go = '1') then
331
332
333
334
335
336
337
338
339
340
            -- Signal that we have seen the GO
            int_go_consumed_strobe <= '1';

            if addr_mode = ADDR_ERR then
              int_err_code <= c_ERR_ADDR_MODE;
              state <= IDLE_DELAY;
            elsif transfer_mode = TRANSFER_ERR then
              int_err_code <= c_ERR_TRANSFER_MODE;
              state <= IDLE_DELAY;
            else                 
Michael Munch's avatar
Michael Munch committed
341
342
343
344
345
346
347
348
              -- Table 2-4 and Table 2-29
              -- A[0] = LWORD*
              -- B(i) = Byte(i)
              --     | A[31-24] A[23-16] A[15-8] A[7-0] D[31-24] D[23-16] D[15-8] D[7-0]
              --   ---------------------------------------------------------------------
              -- D16 |                                                      B(0)   B(1)
              -- D32 |                                    B(0)     B(1)     B(2)   B(3)
              -- D64 |   B(0)     B(1)     B(2)   B(3)    B(4)     B(5)     B(6)   B(7)
349
              l_addr <= int_addr;              
350
              l_data <= int_data_write;
Michael Munch's avatar
Michael Munch committed
351
              l_am <= int_am_i;
Michael Munch's avatar
Michael Munch committed
352
              l_rw <= int_vme_write;
Michael Munch's avatar
Michael Munch committed
353
              l_transfer_mode <= transfer_mode;
Michael Munch's avatar
Michael Munch committed
354
              l_addr_mode <= addr_mode;
Michael Munch's avatar
Michael Munch committed
355
              busy <= '1';
356
              int_err_code <= c_ERR_OK;
Michael Munch's avatar
Michael Munch committed
357
358
              -- Rule 2.30:
              -- The Master MUST NOT drive AS* low until IACK* has been high
Michael Munch's avatar
Michael Munch committed
359

360
361
362
363
364
              vme_addr_o <= int_addr;
              vme_addr_dir <= c_PIN_OUT;
              vme_am_o <= int_am_i;
              vme_am_dir <= c_PIN_OUT;

Michael Munch's avatar
Michael Munch committed
365
              vme_write_n_o <=  not int_vme_write;
366
367
              
              
368
369
370
371
372
373
              vme_iack_n_o <= '1'; -- We pull IACK* high
              vme_iack_n_dir <= c_PIN_OUT;

              -- If data lines are free then place data on them
              -- We also do this in MBLT mode.
              if (--transfer_mode /= MBLT and
Michael Munch's avatar
Michael Munch committed
374
                int_vme_write = c_VME_WRITE and
375
376
                vme_dtack_n_i = '1')
              then
377
                vme_data_o <= int_data_write(31 downto 0);
378
379
                vme_data_dir <= c_PIN_OUT;
                data_placed <= '1';
Michael Munch's avatar
Michael Munch committed
380
              end if;
381
382
383

              n_wait <= c_N_AS_DELAY;
              state <= AS_DELAY;
384
            end if;
Michael Munch's avatar
Michael Munch committed
385
386
387
388
389
390
          end if;

        -- Rule 2.30:
        -- The Master MUST NOT drive AS* low until IACK* has been high
        -- and the required lines among A[31..1], AM[5..0], and LWORD*
        -- have been valid for this minimum time.
Michael Munch's avatar
Michael Munch committed
391
        when AS_DELAY =>
392
          if (n_wait = 0) then 
393
            -- Signal valid address
394
            vme_as_n_o <= '0';
Michael Munch's avatar
Michael Munch committed
395
            vme_as_n_dir <= c_PIN_OUT;
Michael Munch's avatar
Michael Munch committed
396
            int_go_consumed_strobe <= '0';
Michael Munch's avatar
Michael Munch committed
397

Michael Munch's avatar
Michael Munch committed
398
399
            -- Rule 2.36:
            -- The Master MUST NOT drive DSA* low until it has driven AS* low.
400

Michael Munch's avatar
Michael Munch committed
401
402
403
            -- Rule 2.35:
            -- The Master MUST NOT drive DSA* low until both DTACK*
            -- and BERR* are high.
404

Michael Munch's avatar
Michael Munch committed
405
406
            -- Data lines free.
            if (vme_dtack_n_i & vme_berr_n_i = "11") then
407
              if (l_rw = c_VME_READ) then
408
                vme_ds_n_o <= "00";
409
410
411
412
413
                vme_ds_n_dir <= c_PIN_OUT;

                -- Wait for slave ACK.
                state <= DTACK_LOW_WAIT;
              else
Michael Munch's avatar
Michael Munch committed
414
415
416
417
418
419
                if (data_placed = '1') then
                  -- Data already together with addr.
                  -- We have waited enough.
                  vme_ds_n_o <= "00";
                  vme_ds_n_dir <= c_PIN_OUT;
                  data_placed <= '1';
420

Michael Munch's avatar
Michael Munch committed
421
422
423
                  -- Wait for slave ACK.
                  state <= DTACK_LOW_WAIT;
                else
Michael Munch's avatar
Michael Munch committed
424
425
426
                  -- Still in addressing phase.
                  -- We can only place data on D lines
                  vme_data_o <= l_data(31 downto 0);
427
428
429
430
431
432
                  vme_data_dir <= c_PIN_OUT;

                  -- Rule 2.34a
                  -- During write cycles [...] the Master MUST NOT drive DSA*
                  -- low until the required lines among D[31..0] have been
                  -- valid for this minimum time.
Michael Munch's avatar
Michael Munch committed
433
434
435
                  n_wait <= c_N_DS_DELAY;
                  state <= DS_DELAY;
                end if;              
436
              end if;
Michael Munch's avatar
Michael Munch committed
437
438
439
            else
              -- Data lines not free. We must wait.
              state <= DTACK_HIGH_WAIT;
440
            end if;
441
442
          end if;

443
444
445
        -- Data bus occupied. Wait for release.
        when DTACK_HIGH_WAIT =>
          if (vme_dtack_n_i & vme_berr_n_i = "11") then
446
            if (l_rw = c_VME_READ) then
Michael Munch's avatar
Michael Munch committed
447
448
449
450
              -- Read cycle. 
              if (n_wait = 0) then
                vme_ds_n_o <= "00";
                vme_ds_n_dir <= c_PIN_OUT;
Michael Munch's avatar
Michael Munch committed
451
                state <= DTACK_LOW_WAIT;
Michael Munch's avatar
Michael Munch committed
452
              else
Michael Munch's avatar
Michael Munch committed
453
                state <= DS_DELAY;
Michael Munch's avatar
Michael Munch committed
454
              end if;              
Michael Munch's avatar
Michael Munch committed
455
            else
456
              -- Write cycle. Place data and wait
Michael Munch's avatar
Michael Munch committed
457
458
459
460
              vme_data_o <= l_data(31 downto 0);
              if (l_transfer_mode = MBLT) then
                vme_addr_o <= l_data(63 downto 32);
              end if;
461
462
463
464
465
466
              vme_data_dir <= c_PIN_OUT;

              -- Rule 2.34a
              -- During write cycles [...] the Master MUST NOT drive DSA*
              -- low until the required lines among D[31..0] have been
              -- valid for this minimum time.
Michael Munch's avatar
Michael Munch committed
467
468
              n_wait <= c_N_DS_DELAY;
              state <= DS_DELAY;
469
470
471
472
473
474
475
            end if;
          end if;

        -- Rule 2.34a
        -- During write cycles [...] the Master MUST NOT drive DSA*
        -- low until the required lines among D[31..0] have been
        -- valid for this minimum time.
Michael Munch's avatar
Michael Munch committed
476
        when DS_DELAY =>
477
478
479
480
481
          -- Data has been placed. Wait to drive DS.
          if (n_wait = 0) then
              vme_ds_n_o <= "00";
              vme_ds_n_dir <= c_PIN_OUT;
              state <= DTACK_LOW_WAIT;
Michael Munch's avatar
Michael Munch committed
482
          end if;
483

Michael Munch's avatar
Michael Munch committed
484
485
        -- Wait for slave to ack transfer
        when DTACK_LOW_WAIT =>
Michael Munch's avatar
Michael Munch committed
486
487
488
489
490
          -- OBSERVATION 2.48:
          -- The Master is guaranteed that neither DTACK* nor BERR* will go low
          -- until this minimum time after it drives DSA* low.
          -- [30 ns]
          --
Michael Munch's avatar
Michael Munch committed
491
          -- Munk: Thus we can only catch BERR* here.
Michael Munch's avatar
Docs    
Michael Munch committed
492
493
          -- Munk (17/8/2020) : Always catch BERR*.
          --   There might be bad modules or a bug in this code.
Michael Munch's avatar
Michael Munch committed
494
            
Michael Munch's avatar
Michael Munch committed
495
          if (vme_dtack_n_i = '0') then
Michael Munch's avatar
Michael Munch committed
496
497
498
499

            -- RULE 2.40:
            -- During all data transfer cycles, excluding A16, A24 and A32
            -- Read-Modify-Write and Retry cycles, the Master MUST drive A[31..1] and LWORD*
Michael Munch's avatar
Michael Munch committed
500
            -- with valid addressing information until it detects the first_cycle falling edge
Michael Munch's avatar
Michael Munch committed
501
502
            -- on DTACK* or BERR*.

503
            if (l_rw = c_VME_READ) then
504
505
506
              -- Munk: We can thus always flip dir on ADDR pins.
              -- This simplifies MBLT logic
              vme_addr_dir <= c_PIN_IN;
Michael Munch's avatar
Michael Munch committed
507
              if l_transfer_mode = MBLT and first_cycle = '1' then
Michael Munch's avatar
Michael Munch committed
508
509
510
                vme_ds_n_o <= "11";
                n_wait <= c_N_DS_SPACING; -- 40ns cooldown of DS*               
                state <= DTACK_HIGH_WAIT;
Michael Munch's avatar
Michael Munch committed
511
              else                
Michael Munch's avatar
Michael Munch committed
512
                n_wait <= c_N_DATA_WAIT;
Michael Munch's avatar
Michael Munch committed
513
                state <= LATCH_DATA;
Michael Munch's avatar
Michael Munch committed
514
              end if;
515
   
Michael Munch's avatar
Michael Munch committed
516
            else
Michael Munch's avatar
Michael Munch committed
517
518
519
520
521
522
523
              -- Rescind DS*
              vme_ds_n_o <= "11";
              case l_transfer_mode is
                when SINGLE =>
                  -- We are done. Terminate cycle and IDLE.
                  vme_as_n_o <= '1';
                  state <= IDLE;
524
                  busy <= '0';
525
                  int_data_strobe <= c_DATA_PRESENT;
526
                  int_err_code <= c_ERR_OK;
Michael Munch's avatar
Michael Munch committed
527
528
529
                when BLT =>
                  -- Per Rule 2.34a there must be 40ns delay
                  -- between DS* transistions. Handle this in next cycle
530
                  int_blt_decision <= '1';
531
                  int_data_strobe <= c_DATA_PRESENT;
Michael Munch's avatar
Michael Munch committed
532
                  state <= BLT_WRITE_WAIT;
Michael Munch's avatar
Michael Munch committed
533
534
                when MBLT =>
                  if first_cycle = '0' then
535
                    int_blt_decision <= '1';
536
                    int_data_strobe <= c_DATA_PRESENT;
Michael Munch's avatar
Michael Munch committed
537
538
539
540
541
542
                    state <= BLT_WRITE_WAIT;
                  else
                    -- ADDR broadcast. Now write data.
                    n_wait <= c_N_DS_SPACING; -- 40ns cooldown of DS*               
                    state <= DTACK_HIGH_WAIT;
                  end if;                  
Michael Munch's avatar
Michael Munch committed
543
544
545
                when others =>
                  assert false report "not implemented!";
              end case;              
546
547
            end if;
            first_cycle <= '0';
Michael Munch's avatar
Michael Munch committed
548
          end if;
549
550


Michael Munch's avatar
Michael Munch committed
551
552
553
554
555
556
557
        -- OBSERVATION 2.47a:
        -- During read cycles, the Master is guaranteed that D[31..0] will be
        -- valid within 25 nanoseconds after DTACK* goes low. In addition, during
        -- MBLT, A40BLT, and MD32 read cycles, the Master is guaranteed that A[31..1]
        -- and LWORD* will be valid within 25 nanoseconds after DTACK* goes low.
        -- This time does not apply to cycles where the Slave drives BERR* low instead
        -- of DTACK*.          
Michael Munch's avatar
Michael Munch committed
558
        when LATCH_DATA =>
Michael Munch's avatar
Michael Munch committed
559
560
561
          -- Table 2-4 and Table 2-29
          -- A[0] = LWORD*
          -- B(i) = Byte(i)
Michael Munch's avatar
Michael Munch committed
562
563
          -- B(0) is the most significant byte
          --
Michael Munch's avatar
Michael Munch committed
564
565
566
567
568
569
          --     | A[31-24] A[23-16] A[15-8] A[7-0] D[31-24] D[23-16] D[15-8] D[7-0]
          --   ---------------------------------------------------------------------
          -- D16 |                                                      B(0)   B(1)
          -- D32 |                                    B(0)     B(1)     B(2)   B(3)
          -- D64 |   B(0)     B(1)     B(2)   B(3)    B(4)     B(5)     B(6)   B(7)
          --
Michael Munch's avatar
Michael Munch committed
570
571
572
          -- Conclusion:
          -- The D lines always carry the least significant bits.
          -- If we run MBLT then the A lines with carry the MSB.
Michael Munch's avatar
Michael Munch committed
573
          -- 
574
          cur_data(31 downto 0) := vme_data_i;
Michael Munch's avatar
Michael Munch committed
575
576
          case l_transfer_mode is
            when SINGLE | BLT =>
577
578
              -- l_data(31 downto 0) => vme_data_i;
              cur_data(63 downto 32) := (others => '0');
Michael Munch's avatar
Michael Munch committed
579
            when MBLT =>
580
              -- l_data(31 downto 0) => vme_addr_i;
Michael Munch's avatar
Michael Munch committed
581
              cur_data(63 downto 32) := vme_addr_i;
Michael Munch's avatar
Michael Munch committed
582
583
584
            when others =>
              assert false report "Logic error!";
          end case;
Michael Munch's avatar
Michael Munch committed
585
          
Michael Munch's avatar
Michael Munch committed
586
587
588
589
590
          -- Munk: In principle we can have cur_data = l_data,
          -- first time n_wait = 0.
          -- In this case l_data is latched when n_wait = 1.
          -- Howver, according to observation 2.47a, then data is
          -- valid WITHIN 25ns. 
Michael Munch's avatar
Michael Munch committed
591
592
          if (n_wait = 0) then
            -- Latched data stable
593
594
595
            if (cur_data = l_data) then
              -- Slave only maintains data lines while
              -- DS* asserted. They can be deasserted now. 
Michael Munch's avatar
Michael Munch committed
596
597
              vme_ds_n_o <= "11";
              vme_ds_n_dir <= c_PIN_OUT;
598
              int_data_read <= cur_data;
Michael Munch's avatar
Michael Munch committed
599
600
601
602
603
              int_data_strobe <= c_DATA_PRESENT;

              case l_transfer_mode is
                when SINGLE =>
                  vme_as_n_o <= '1';
604
                  
Michael Munch's avatar
Michael Munch committed
605
                  state <= IDLE;
606
607
                  busy <= '0';
                  int_err_code <= c_ERR_OK;
Michael Munch's avatar
Michael Munch committed
608
                when BLT | MBLT =>
Michael Munch's avatar
Michael Munch committed
609
                  n_wait <= c_N_DS_SPACING;
610
                  int_blt_decision <= '1';
Michael Munch's avatar
Michael Munch committed
611
                  state <= BLT_READ_WAIT;
Michael Munch's avatar
Michael Munch committed
612
613
                when others =>
                  assert false report "Logic error!";
614
              end case;              
Michael Munch's avatar
Michael Munch committed
615
616
617
618
            else -- Unstable data. Try again
              n_wait <= 1;
            end if;
          end if;
619
620
          l_data <= cur_data;

Michael Munch's avatar
Michael Munch committed
621
        when BLT_WRITE_WAIT =>
622
          int_data_strobe <= c_DATA_CLEAR;
623
          if int_blt_decided = '1' then
624
            int_blt_decision <= '0';
625
            
626
            if int_blt_continue = '1' then
627
              l_data <= int_data_write; -- Latch new data
628
629
              state <= DTACK_HIGH_WAIT; -- Wait for slave to rescind DTACK
            else
Michael Munch's avatar
Michael Munch committed
630
631
632
              -- Terminate cycle
              vme_as_n_o <= '1';
              state <= IDLE;
633
634
              busy <= '0';
              int_err_code <= c_ERR_OK;
635
636
            end if;
          end if;                    
Michael Munch's avatar
Michael Munch committed
637

Michael Munch's avatar
Michael Munch committed
638
        when BLT_READ_WAIT =>
Michael Munch's avatar
Michael Munch committed
639
640
          int_data_strobe <= c_DATA_CLEAR;
          if int_blt_decided = '1' then            
641
            int_blt_decision <= '0';
642
643
644
645
646
647
648
            if int_blt_continue = '1' then          
              state <= DTACK_HIGH_WAIT;
            else
              -- Block transfer is terminated by AS* high.
              vme_as_n_o <= '1';
              n_wait <= 0;
              state <= IDLE;
649
650
              busy <= '0';
              int_err_code <= c_ERR_OK;
651
652
            end if;
          end if;
Michael Munch's avatar
Michael Munch committed
653
          
Michael Munch's avatar
Michael Munch committed
654
        when IACK_HIGH_WAIT =>
Michael Munch's avatar
Michael Munch committed
655
656
          if vme_iack_n_i = '1' then
            state <= IDLE;
657
          end if;
Håkan Johansson's avatar
A note.    
Håkan Johansson committed
658
659
          -- Note: this state does not assert busy, since we
          -- are not working on behalf of the client.
660

Michael Munch's avatar
Michael Munch committed
661

662
663
664
665
        -- Delay return to IDLE.          
        when IDLE_DELAY =>
          state <= IDLE;
          busy <= '0';
Michael Munch's avatar
Michael Munch committed
666

667
        when BERR_HIGH_WAIT =>
668
          --if (last_berr_n = '1' and vme_berr_n_i = '1') then
669
670
671
          if (vme_berr_n_i = '1') then
            state <= IDLE;
          end if;          
Michael Munch's avatar
Michael Munch committed
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687

        -- Timeout!  Something is preventing the state machine
        -- from completing.  Either an external error (e.g. a
        -- non-responding module), or a bug in this code.

        -- BERR is issued and we stop driving signals.
        when TIMEOUT =>
          vme_berr_n_dir <= c_PIN_OUT;
          vme_berr_n_o <= '0';
          
          vme_ds_n_dir <= c_PIN_IN;
          vme_ds_n_o <= "11";
          
          vme_as_n_dir <= c_PIN_IN;
          vme_as_n_o <= '1';

688
689
          vme_dtack_n_dir <= c_PIN_IN;

Michael Munch's avatar
Michael Munch committed
690
691
          -- Data present (error)
          int_data_strobe <= c_DATA_PRESENT;
692
          int_go_consumed_strobe <= '1';
Michael Munch's avatar
Michael Munch committed
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
          int_err_code <= (
            c_ERR_BERR_I => not vme_berr_n_i,
            c_ERR_TIMEOUT_I => '1',
            others => '0'
            );
          busy <= '0';
          -- Attempt to leave the TIMEOUT state
          n_wait <= c_N_TIMEOUT_WAIT;
          state <= TIMEOUT_WAIT;


        -- We stay here and wait 
        when TIMEOUT_WAIT =>
          -- Make sure that also noone else is driving
          -- AS, DS or DTACK before we consider leaving
          -- TIMEOUT state.

710
711
712
          if (vme_ds_n_i = "00" or
              vme_as_n_i = '0' or
              vme_dtack_n_i = '0') then
Michael Munch's avatar
Michael Munch committed
713
714
715
            -- Someone is still holding a strobe.
            n_wait <= c_N_TIMEOUT_WAIT;
          elsif (n_wait = 0) then
Michael Munch's avatar
Michael Munch committed
716
717
718
            -- Release BERR line
            vme_berr_n_o <= '1';
            vme_berr_n_dir <= c_PIN_IN;
719
            state <= BERR_HIGH_WAIT;
Michael Munch's avatar
Michael Munch committed
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
          end if;
      end case;

      -- This is after state machine, such that it can force
      -- into TIMEOUT state, no matter what happens.
      -- Also an seemingly indefinate wait in IACK_HIGH_WAIT
      -- will be cut short, such that we report failure to
      -- perform the access to our superiors.

      -- VME spec 2.37:
      -- [...]
      -- The Master, upon completing the first data transfer,
      -- (that is, driving the data strobes high) does not allow
      -- the address strobe to go high. Instead, it repeatedly
      -- drives the data strobe(s) low in response to data transfer
      -- acknowledgments from the Slave
Michael Munch's avatar
Michael Munch committed
736

737
738
      
      if (last_ds_n /= vme_ds_n_i or -- 
Michael Munch's avatar
Michael Munch committed
739
740
741
742
743
744
          state    = IDLE or
          state    = IDLE_DELAY or
          state    = TIMEOUT or
          state    = TIMEOUT_WAIT) then
        -- Things are good, or we have fired (no need to fire again).
        timeout_cnt <= TIMEOUT_CNT_MAX;
745
746
      elsif ((state /= BERR_HIGH_WAIT and vme_berr_n_i = '0') or
             int_timeout_n = '0')
747
        state <= TIMEOUT;
Michael Munch's avatar
Michael Munch committed
748
749
750
751
752
753
      elsif (timeout_cnt = 0) then
        -- We have been operating for too long, timeout.
        state <= TIMEOUT;
      else
        timeout_cnt <= timeout_cnt - 1;
      end if;
754
755
756
757


      last_ds_n <= vme_ds_n_i;
      last_berr_n <= vme_berr_n_i
Michael Munch's avatar
Michael Munch committed
758
759
760
761
    end if;
  end process;


Michael Munch's avatar
Michael Munch committed
762
763
764
  FormalG : if Formal generate

    -- VHDL helper vars
Michael Munch's avatar
Docs    
Michael Munch committed
765
766
767
768
769
770
771
772
    signal f_addr               : std_logic_vector(31 downto 0) := (others => 'U');
    signal f_data               : std_logic_vector(63 downto 0) := (others => 'U');        
    signal f_latch_data2        : std_logic_vector(63 downto 0) := (others => 'U');    
    signal f_latch_data         : std_logic_vector(63 downto 0) := (others => 'U');
    signal f_blt_data           : std_logic_vector(63 downto 0) := (others => 'U');    
    signal f_am                 : am_vec_t := (others => 'U');
    signal f_berr_ok            : std_logic := 'U';
    signal f_vme_rw             : std_logic := 'U';
Michael Munch's avatar
Michael Munch committed
773
    
774
    signal f_blt_cycle          : integer := 0;
Michael Munch's avatar
Michael Munch committed
775
776
777
778
779
    
  begin

    process (clk) begin
      if (rising_edge(clk)) then
Michael Munch's avatar
Michael Munch committed
780
781
        if (state = IDLE and int_vme_go = '1') then
          f_addr <= int_addr;
Michael Munch's avatar
Michael Munch committed
782
          f_am <= int_am_i;
Michael Munch's avatar
Michael Munch committed
783
          f_vme_rw <= int_vme_write;
784
          f_data <= int_data_write;
Michael Munch's avatar
Michael Munch committed
785
786
787
        end if;

        if (state = LATCH_DATA) then
Michael Munch's avatar
Docs    
Michael Munch committed
788
789
790
          f_latch_data2 <= f_latch_data;
          f_latch_data(31 downto 0) <= vme_data_i;
          f_latch_data(63 downto 32) <= vme_addr_i;
Michael Munch's avatar
Michael Munch committed
791
792
793
794
795
796
797
        end if;
        
        
        -- Data latched during BLT continue op
        if (state = BLT_WRITE_WAIT
            and int_blt_decided = '1' and int_blt_continue = '1')
        then
798
          f_blt_data <= int_data_write;
Michael Munch's avatar
Michael Munch committed
799
800
        end if;

801
802
803
804
805
806
807
        if (state = IDLE) then
          f_blt_cycle <= 0;
        elsif (state = BLT_WRITE_WAIT) then
          f_blt_cycle <= f_blt_cycle + 1;
        end if;
        

Michael Munch's avatar
Michael Munch committed
808
809
810
      end if;
    end process;

Michael Munch's avatar
Michael Munch committed
811
    -- psl default clock is rising_edge(clk);
Michael Munch's avatar
Michael Munch committed
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
    -- psl restrict {{vme_iack_n_i = '1' and vme_berr_n_i = '1'}[+]};

    -- -- Check that client input is latched
    -- psl when_go_addr_is_latched:
    --   assert always {int_vme_go = '1'
    --                  and transfer_mode /= TRANSFER_ERR
    --                  and addr_mode /= ADDR_ERR}
    --     |=> l_addr = f_addr until busy = '0';

    -- psl when_go_am_is_latched:
    --   assert always {int_vme_go = '1'
    --                  and transfer_mode /= TRANSFER_ERR
    --                  and addr_mode /= ADDR_ERR}
    --     |=> l_am = f_am until busy = '0';

    -- psl when_go_rw_is_latched:
    --   assert always {int_vme_go = '1'
    --                  and transfer_mode /= TRANSFER_ERR
    --                  and addr_mode /= ADDR_ERR}
    --     |=> l_rw = f_vme_rw until busy = '0';

    -- -- We only check data next cycle.
    -- -- This might be relatched
    -- psl when_go_data_is_latch:
    --   assert always {state = IDLE and int_vme_go = '1'
    --                  and transfer_mode /= TRANSFER_ERR
    --                  and addr_mode /= ADDR_ERR}
    --     |=> l_data = f_data;    

    -- -- Maintain BUSY until back in IDLE
    -- psl core_is_busy_until_idle:
    --   assert always {state = IDLE; int_vme_go = '1'
    --                  and transfer_mode /= TRANSFER_ERR
    --                  and addr_mode /= ADDR_ERR}
    --     |=> busy = '1' until state = IDLE;

    -- psl when_unsupported_addr_mode_issue_error_code:
    --   assert always {state = IDLE and int_vme_go = '1' and addr_mode = ADDR_ERR}
    --     |=> int_err_code = c_ERR_ADDR_MODE
    --     and state = IDLE_DELAY;

    -- psl when_unsupported_transfer_mode_issue_error_code:
    --   assert always {state = IDLE and int_vme_go = '1'
    --                  and transfer_mode = TRANSFER_ERR
    --                  and addr_mode /= ADDR_ERR}
    --     |=> int_err_code = c_ERR_TRANSFER_MODE
    --     and state = IDLE_DELAY;        

    -- -- If DTACK* is LOW after AS_DELAY,
    -- -- then we must wait for data lines to clear.
    -- psl core_will_not_start_until_dtack_high:
    --   assert always {vme_dtack_n_i = '0' and state = AS_DELAY and n_wait=0}
    --     |=> state = DTACK_HIGH_WAIT until vme_dtack_n_i = '1';

    -- -- We maintain go_consumed high until end of AS_DELAY
    -- psl go_consumed_is_signalled_until_as_delay:
    --   assert always {state = IDLE and int_vme_go = '1'}
    --     |=> int_go_consumed_strobe = '1' until state /= AS_DELAY;

    -- -- Don't fire AS* during AS_DELAY
    -- psl addr_strobe_are_not_fired_during_as_delay:
    --   assert always {state = AS_DELAY}
    --     |=> vme_as_n_o = '1' and vme_as_n_dir = c_PIN_IN
    --     until state /= AS_DELAY;

    -- -- AS* fires after we leave AS_DELAY
    -- psl addr_strobe_are_fired_after_as_delay:
    --   assert always {state = AS_DELAY and n_wait = 0}
    --     |=> vme_as_n_o = '0' and vme_as_n_dir = c_PIN_OUT;

    -- -- AS* fires after we leave AS_DELAY
    -- psl if_dtack_is_asserted_in_as_then_we_wait_until_deasserted:
    --   assert always {state = AS_DELAY and n_wait = 0 and vme_dtack_n_i = '0'}
    --     |=> state = DTACK_HIGH_WAIT and vme_ds_n_o = "11"
    --     until vme_dtack_n_i = '1';    

    -- -- Don't fire DS* during AS_DELAY
    -- psl data_strobes_are_not_fired_during_as_delay:
    --   assert always {state = AS_DELAY}
    --     |=> vme_ds_n_o = "11" and vme_ds_n_dir = c_PIN_IN
    --     until state /= AS_DELAY;

    -- psl data_strobe_are_fired_with_as_when_data_placed:
    --   assert always {vme_dtack_n_i = '1' and
    --                  state = AS_DELAY and l_rw = c_VME_WRITE
    --                  and data_placed = '1' and n_wait = 0}
    --     |=> vme_ds_n_o = "00";

    -- -- If writing and waiting for DTACK* HIGH,
    -- -- then data is placed when satisfied.
    -- psl when_writing_and_dtack_fires_place_data:
    --   assert always {l_transfer_mode = SINGLE
    --                  and l_rw = c_VME_WRITE
    --                  and state = DTACK_HIGH_WAIT; vme_dtack_n_i = '1'}
    --     |=> vme_data_o = l_data(31 downto 0);

    -- -- If IDLE and GO given
    -- -- and data lines are free (DTACK* = 1)
    -- -- and we are writing.
    -- -- Then place low 32 bits immideately 
    -- psl when_writing_and_dtack_is_high_then_data_is_placed:
    --   assert always {int_vme_go = '1' and state = IDLE
Michael Munch's avatar
Michael Munch committed
914
    --                  and int_vme_write = c_VME_WRITE and vme_dtack_n_i = '1'
Michael Munch's avatar
Michael Munch committed
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
    --                  and int_am_i = c_AM_A24_DATA}
    --     |=> vme_data_o = l_data(31 downto 0)
    --     until state = DTACK_LOW_WAIT or state = IDLE;

    -- -- When writing MBLT the data will be placed on the bus
    -- psl mblt_writing_data_is_placed_on_bus:
    --   assert always {state = DTACK_HIGH_WAIT and l_transfer_mode = MBLT
    --                  and first_cycle = '1' and vme_dtack_n_i = '1'
    --                  and l_rw = c_VME_WRITE}
    --     |=> vme_data_o = l_data(31 downto 0)
    --     and vme_addr_o = l_data(63 downto 32);

    -- -- When writing MBLT the data latched during BLT_WRITE_WAIT
    -- -- is written to both addr and data pins
    -- psl mblt_writing_data_is_placed_on_bus_second_time:
    --   assert always {state = DTACK_HIGH_WAIT and l_transfer_mode = MBLT
    --                  and first_cycle = '0' and vme_dtack_n_i = '1'
    --                  and l_rw = c_VME_WRITE and f_blt_cycle > 0}
    --     |=> vme_data_o = f_blt_data(31 downto 0)
    --     and vme_addr_o = f_blt_data(63 downto 32);            

    -- -- If stopping BLT write transaction,
    -- -- then return to IDLE
    -- psl return_to_idle_if_stopping_blt_write:
    --   assert always {state = BLT_WRITE_WAIT
    --                  and int_blt_decided = '1' and int_blt_continue = '0'}
    --     |=> state = IDLE;

    -- -- If stopping BLT read transaction,
    -- -- then return to IDLE
    -- psl return_to_idle_if_stopping_blt_read:
    --   assert always {state = BLT_READ_WAIT
    --                  and int_blt_decided = '1' and int_blt_continue = '0'}
    --     |=> state = IDLE;

    -- -- When latching 32 or 16 bit data,
    -- -- then low 32 bits are from data lines
    -- -- and high 32 bits are set to 0.
    -- psl data_is_latched_when_stable:
    --   assert always {state = LATCH_DATA and n_wait = 0
    --                  and f_latch_data = f_latch_data2 and l_transfer_mode /= MBLT}
    --     |-> l_data(31 downto 0) = f_latch_data(31 downto 0)
    --     and l_data(63 downto 32) = "00000000000000000000000000000000";

    -- -- When latching 64 bit data,
    -- -- then low 32 bits are from data lines
    -- -- and high 32 bits are from addr lines.    
    -- psl mblt_data_is_latched_when_stable:
    --   assert always {state = LATCH_DATA
    --                  and f_latch_data = f_latch_data2 and l_transfer_mode = MBLT;
    --                  n_wait = 0}
    --     |-> l_data(31 downto 0) = f_latch_data(31 downto 0)
    --     and l_data(63 downto 32) = f_latch_data(63 downto 32); 
Michael Munch's avatar
Michael Munch committed
968
    
Michael Munch's avatar
Michael Munch committed
969

Michael Munch's avatar
Michael Munch committed
970
971
972
973
974
975
    -- -- If BLT write is continued,
    -- -- then new data is latched.
    -- psl if_continueing_blt_write_then_latch_new_data:
    --   assert always {state = BLT_WRITE_WAIT
    --                  and int_blt_decided = '1' and int_blt_continue = '1'}
    --     |=> l_data = f_blt_data;    
Michael Munch's avatar
Michael Munch committed
976
    
Michael Munch's avatar
Michael Munch committed
977
978
979
980

  end generate FormalG;
  
  
Michael Munch's avatar
Michael Munch committed
981
end architecture;
Michael Munch's avatar
Michael Munch committed
982
983
984