summaryrefslogtreecommitdiffstats
path: root/sdram_ctrl.vhd
blob: b0b4a1f9f5d908c45560a785010cc781b836072f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

library work;
use work.sdram_util.ALL;

-- a simple dram controller (no pipelineing)
-- that looks like a slow static ram

entity sdram_ctrl is
  port
  (  
    clock_100  :  in std_logic;
    reset_n    :  in std_logic;

    bus_cs_n    :  in std_logic;
    bus_rnw    :  in std_logic;

    bus_wait_n  :  out std_logic;

    bus_addr    :  in addr_t;
    bus_data_in    :  in data_t;
    bus_data_out    :  out data_t;

    sdram_clk  :  out std_logic;
    sdram_cke  :  out std_logic;

    sdram_cs_n  :  out std_logic;

    sdram_cas_n  :  out std_logic;
    sdram_ras_n  :  out std_logic;
    sdram_we_n  :  out std_logic;

    sdram_addr  :  out std_logic_vector(12 downto 0);
    sdram_ba  :  out std_logic_vector(1 downto 0);

    sdram_dq  :  inout data_t;
    sdram_dqm  :  out dqm_t;

    debug : out std_logic_vector(7 downto 0)
  );
end entity;


architecture rtl of sdram_ctrl is


  signal clock : std_logic;


  constant DEBUG_0 : std_logic_vector(6 downto 0) := std_logic_vector(to_unsigned(16#3F#,7));
  constant DEBUG_1 : std_logic_vector(6 downto 0) := std_logic_vector(to_unsigned(16#06#,7));
  constant DEBUG_2 : std_logic_vector(6 downto 0) := std_logic_vector(to_unsigned(16#5B#,7));
  constant DEBUG_3 : std_logic_vector(6 downto 0) := std_logic_vector(to_unsigned(16#4F#,7));
  constant DEBUG_4 : std_logic_vector(6 downto 0) := std_logic_vector(to_unsigned(16#66#,7));
  constant DEBUG_5 : std_logic_vector(6 downto 0) := std_logic_vector(to_unsigned(16#6D#,7));
  constant DEBUG_6 : std_logic_vector(6 downto 0) := std_logic_vector(to_unsigned(16#7D#,7));
  constant DEBUG_7 : std_logic_vector(6 downto 0) := std_logic_vector(to_unsigned(16#07#,7));
  constant DEBUG_8 : std_logic_vector(6 downto 0) := std_logic_vector(to_unsigned(16#7F#,7));
  constant DEBUG_9 : std_logic_vector(6 downto 0) := std_logic_vector(to_unsigned(16#6F#,7));

  -- bits in the MEM_CMD register RAS_N CAS_N WE_N

  constant MEM_CMD_NOP : std_logic_vector(2 downto 0 ):="111";
  constant MEM_CMD_READ : std_logic_vector(2 downto 0 ):="101";
  constant MEM_CMD_WRIT : std_logic_vector(2 downto 0 ):="100";
  constant MEM_CMD_ACTV : std_logic_vector(2 downto 0 ):="011";
  constant MEM_CMD_PRE : std_logic_vector(2 downto 0 ):="010";
  constant MEM_CMD_REF : std_logic_vector(2 downto 0 ):="001";
  constant MEM_CMD_MRS : std_logic_vector(2 downto 0 ):="000";

  constant MEM_CS_N_ALL : cs_n_t := "0";
  constant MEM_CS_N_NONE : cs_n_t := "1";

  -- refresh logic

  signal need_refresh : std_logic;
  signal refresh_counter : uint13_t;

  -- init logic

  signal init_done : std_logic;
  signal      i_addr : std_logic_vector(12 downto 0);
  signal      i_cs_n: cs_n_t;
  signal      i_cmd : std_logic_vector(2 downto 0);
  signal      i_count : uint4_t;
  signal      i_next : uint3_t;
  signal      i_refs : uint3_t;

  -- debuging
  signal      i_debug : std_logic_vector(6 downto 0);
  signal      m_debug : std_logic_vector(7 downto 0);
  signal      b_debug : std_logic_vector(7 downto 0);

  -- init fsm
  signal      i_state :uint3_t;

  constant I_ST_RESET_WAIT : uint3_t:=0;
  constant I_ST_PRECHARGE : uint3_t :=1;
  constant I_ST_REFRESH : uint3_t :=2;
  constant I_ST_WAIT_COUNT : uint3_t :=3;
  constant I_ST_SET_MODE : uint3_t :=4;
  constant I_ST_DONE : uint3_t :=5;

  -- memory interface wires
  signal mem_cs_n : cs_n_t;
  signal mem_bank : std_logic_vector(1 downto 0);
  signal mem_cmd : std_logic_vector(2 downto 0);
  signal mem_addr : std_logic_vector(12 downto 0);
  signal mem_data_out : data_t;
  signal mem_data_in : data_t;
  signal mem_dqm : dqm_t;
  signal mem_oe: std_logic;

  -- main logic
  signal ack_refresh : std_logic;
  signal ack_request : std_logic;
  signal m_count: uint3_t; 

  signal active_cs_n : cs_n_t;
  signal active_addr : addr_t;
  signal active_data : data_t;
  signal active_rnw : std_logic;
  signal active_dqm : dqm_t;

  -- main fsm 
  signal m_state : std_logic_vector(9 downto 0);
  signal m_next : std_logic_vector(9 downto 0);

  constant M_ST_WAITING_INIT       : std_logic_vector(9 downto 0 ):="0000000001";
  constant M_ST_IDLE               : std_logic_vector(9 downto 0 ):="0000000010";
  constant M_ST_RAS                : std_logic_vector(9 downto 0 ):="0000000100";
  constant M_ST_NOP_COUNT          : std_logic_vector(9 downto 0 ):="0000001000";
  constant M_ST_READ               : std_logic_vector(9 downto 0 ):="0000010000";
  constant M_ST_WRITE              : std_logic_vector(9 downto 0 ):="0000100000";
  constant M_ST_ACTIVE             : std_logic_vector(9 downto 0 ):="0001000000";
  constant M_ST_WAIT_FOR_PRECHARGE : std_logic_vector(9 downto 0 ):="0010000000";
  constant M_ST_PRECHARGE          : std_logic_vector(9 downto 0 ):="0100000000";
  constant M_ST_REFRESH            : std_logic_vector(9 downto 0 ):="1000000000";


  -- request logic
  signal request_pending: std_logic;
  signal request_cs_n : cs_n_t;
  signal request_addr : addr_t;
  signal request_data : data_t;
  signal request_rnw : std_logic;
  signal request_dqm : dqm_t;

  -- read state logic
  signal r_data_valid: std_logic_vector(3 downto 0);

  -- bus logic
  signal post_request: std_logic;

  -- bus fsm
  signal b_state : std_logic_vector(4 downto 0);

  constant B_ST_WAIT_CS_N_LOW  : std_logic_vector(4 downto 0):="00001";
  constant B_ST_LODGE_REQUEST  : std_logic_vector(4 downto 0):="00010";
  constant B_ST_WAIT_ACK       : std_logic_vector(4 downto 0):="00100";
  constant B_ST_WAIT_DATA      : std_logic_vector(4 downto 0):="01000";
  constant B_ST_WAIT_CS_N_HIGH : std_logic_vector(4 downto 0):="10000";

  -- convert boolean to active high logic 
  function b2l_ah(constant val : in boolean) return std_logic is begin
    if val then
      return '1';
    else
      return '0';
    end if;
  end function; 


  -- convert active high logic to boolean value
  function l2b_ah(constant val : in std_logic) return boolean is begin
    return val='1';
  end function; 

  function l2b_al(constant val : in std_logic) return boolean is begin
    return val='0';
  end function; 


  function same_bank_and_row ( 	constant a1: in addr_t; constant a2: in addr_t ) return boolean is begin 
    return a1(23 downto 9) = a2(23 downto 9); 
  end function;

begin

  clock<=clock_100;

  refresh_counter_process: process(reset_n,clock) begin
    if l2b_al(reset_n) then
      refresh_counter <= 8000;
    elsif rising_edge(clock) then
      if refresh_counter = 0 then
	refresh_counter <= 624;
      else
	refresh_counter <= refresh_counter - 1;  
      end if;
    end if; 
  end process;


  need_refresh_process: process(reset_n,clock,refresh_counter,need_refresh,init_done,ack_refresh) begin
    if l2b_al(reset_n)  then
      need_refresh <= '0';
    elsif rising_edge(clock) then
      need_refresh <= (b2l_ah(refresh_counter = 0) or need_refresh) and init_done and not ack_refresh;
    end if;
  end process;

  request_pending_process: process(reset_n, clock, post_request, request_pending,ack_request,refresh_counter) begin
    if l2b_al(reset_n)  then
      request_pending <= '0';
    elsif rising_edge(clock) then
      --request_pending <= post_request or (request_pending and not b2l_ah(refresh_counter = 0 ));
      request_pending <= post_request or (request_pending and not ack_request);
    end if;
  end process;
 

  init_done_process: process (reset_n,clock,i_state)  begin
    if l2b_al(reset_n) then 
      init_done <= '0';
    elsif rising_edge(clock) then
      init_done <= init_done or b2l_ah(i_state = I_ST_DONE );
    end if;
  end process;

  init_fsm: process (reset_n,clock,i_state,i_count,i_next,refresh_counter) begin
    if l2b_al(reset_n) then
      i_state <= I_ST_RESET_WAIT;
      i_next <= I_ST_RESET_WAIT;
      i_cs_n <=MEM_CS_N_NONE;
      i_cmd <= MEM_CMD_NOP;
      i_addr <= (others => '1');
      i_count <= 0;
      i_debug <= DEBUG_0;
    elsif rising_edge(clock) then

      if i_state = I_ST_RESET_WAIT then
        i_debug <= DEBUG_1;
      -- after reset wait until the refresh_counter ticks over for RAM to stabalize
	i_cs_n <=MEM_CS_N_NONE;
	i_cmd <= MEM_CMD_NOP;
	i_refs <= 0;
	if refresh_counter=0 then
	  i_state <= I_ST_PRECHARGE;
	end if;
      elsif i_state = I_ST_PRECHARGE then
        i_debug <= DEBUG_2;
      -- precharge all banks, wait one clock, then go to refresh
	i_cs_n <=MEM_CS_N_ALL;
	i_cmd <=MEM_CMD_PRE;
	i_state <= I_ST_WAIT_COUNT;
	i_count <= 1;
	i_next <= I_ST_REFRESH;
      elsif i_state =I_ST_REFRESH then
        i_debug <= DEBUG_3;
      -- repeat 7 times { refresh, wait 5 counts }
	i_cs_n <=MEM_CS_N_ALL;
	i_cmd <=MEM_CMD_REF;
	i_refs <= i_refs + 1;

	i_state <= I_ST_WAIT_COUNT;
	i_count <= 5;

	if i_refs = 7 then
	  i_next <= I_ST_SET_MODE;
	else
	  i_next <= I_ST_REFRESH;
	end if;
      elsif i_state = I_ST_WAIT_COUNT then
        i_debug <= DEBUG_4;
      -- wait i_count ticks then goto state i_next
	i_cs_n <=MEM_CS_N_ALL;
	i_cmd <= MEM_CMD_NOP;
	if (i_count > 1) then
	  i_count <= i_count -1;
	else
	  i_state <= i_next;
	end if;

      elsif i_state=I_ST_SET_MODE then
        i_debug <= DEBUG_5;
      -- set mode, wait 3 ticks then goto done
	i_cs_n <=MEM_CS_N_ALL;
	i_cmd <= MEM_CMD_MRS;

      -- reserverd      000
      -- opcode burst read/write  0
      -- reserved       00
      -- cas latency 3    011
      -- sequential burst    0
      -- burst length 1     000

	i_addr <= "0000000110000";
	i_count <= 3;
	i_next <= I_ST_DONE;
	i_state <= I_ST_WAIT_COUNT;

      elsif i_state=I_ST_DONE then
        i_debug <= DEBUG_6;
	i_state <= I_ST_DONE;
      else
	i_state <= I_ST_RESET_WAIT;      
      end if;
    end if;
  end process;

  main_fsm: process (reset_n,clock,m_state,need_refresh,request_pending,request_addr,request_data,request_cs_n,request_rnw,request_dqm,i_debug) begin

    if reset_n ='0' then
      m_state <= M_ST_WAITING_INIT;
      m_next <= M_ST_WAITING_INIT;
      mem_cmd  <= MEM_CMD_NOP;
      mem_cs_n <= MEM_CS_N_NONE;
      mem_bank <= (others => '0');
      mem_addr <= (others => '0');
      mem_data_out <= (others => '0');
      mem_dqm <= (others => '0');
      m_count <= 0;
      ack_refresh <= '0';
      ack_request <= '0';
      mem_oe <= '0';
      m_debug(6 downto 0) <=(others =>'0');
      m_debug(7) <='1';
    elsif rising_edge(clock) then
      if m_state =M_ST_WAITING_INIT then
      	m_debug(6 downto 0) <= i_debug;
        m_debug(7) <='1';
	mem_addr <= i_addr;
	mem_cmd <= i_cmd;
	mem_cs_n <= i_cs_n;

	if l2b_ah(init_done) then
	  m_state <= M_ST_IDLE;
	end if;
      elsif m_state = M_ST_IDLE then
      	m_debug(6 downto 0) <= DEBUG_1;
        m_debug(7) <='0';
	mem_cmd <= MEM_CMD_NOP;

	ack_refresh <='0';

	if l2b_ah(need_refresh) then
	    -- If we got here needing a refresh
	    -- we may have come straight from a 
	    -- read so leave CS on so we get
	    -- that data

	  mem_cs_n<=MEM_CS_N_ALL;

	    -- precharge everyone (putting back 
	    -- the open row if we did come from a read
	    -- or write) then refresh everyone.

	  m_state <= M_ST_PRECHARGE;
	  m_next <= M_ST_REFRESH;
	else 
	  -- idle to all chips (MEM_CMD_IGN)
	  mem_cs_n<=MEM_CS_N_NONE; 

	  -- find out if anyone wants us 
	  if l2b_ah(request_pending) then
	    active_cs_n <= request_cs_n;
	    active_rnw <= request_rnw;
	    active_addr <= request_addr;
	    active_data <= request_data;
	    active_dqm <= request_dqm;
	    m_state <= M_ST_RAS;
	    ack_request <='1';
	  end if;
	end if;
      elsif m_state = M_ST_RAS then
      	m_debug(6 downto 0) <= DEBUG_2;
	  -- activate the relevant ROW, wait 3 clocks, then go and do the read or write

	ack_request <='0';

	mem_cs_n <= active_cs_n;
	mem_cmd  <= MEM_CMD_ACTV;
	mem_bank(1) <= active_addr(23);
	mem_bank(0) <= active_addr(9);
	mem_addr <= active_addr(22 downto 10);
	mem_data_out <= active_data;
	mem_dqm  <= active_dqm;

	m_state <= M_ST_NOP_COUNT;
	m_count <= 2; --t  3 clocks : FIXME
	if l2b_ah(active_rnw) then
	  m_next <= M_ST_READ;
	else
	  m_next <= M_ST_WRITE;
	end if;
      elsif m_state = M_ST_NOP_COUNT then
      	m_debug(6 downto 0) <= DEBUG_3;
	  -- send nops for m_count, then go to state m_next
	mem_cmd <=MEM_CMD_NOP;
	if m_count > 1 then
	  m_count <= m_count - 1;
	else
	  m_state <= m_next;
	end if;
      elsif m_state = M_ST_READ then
      	m_debug(6 downto 0) <= DEBUG_4;
	ack_request <='0';

	mem_cmd <=MEM_CMD_READ;

	mem_addr(12 downto 9) <= (others => '0');
	mem_addr(8 downto 0) <= active_addr(8 downto 0);

	m_state <= M_ST_ACTIVE;
      elsif m_state = M_ST_WRITE then
      	m_debug(6 downto 0) <= DEBUG_5;
	ack_request <='0';

	mem_cmd<=MEM_CMD_WRIT;

	mem_addr(12 downto 9) <= (others => '0');
	mem_addr(8 downto 0) <= active_addr(8 downto 0);

	mem_oe <= '1';
	mem_data_out <= active_data;

	m_state <=M_ST_ACTIVE;
      elsif m_state = M_ST_ACTIVE then
      	m_debug(6 downto 0) <= DEBUG_6;
	  -- turn off drivers (we might have come from a write)
	mem_oe <= '0';

	  -- sit doing NOPS on this row until either we get a new request
	  -- or we need a refresh
	mem_cmd <= MEM_CMD_NOP;

	if l2b_ah(need_refresh) then
	    -- the refresh will first precharge everything, so no need to precharge
	    -- just this row. 
	  m_state <= M_ST_NOP_COUNT;
	  m_next <= M_ST_IDLE;
	  m_count <= 1;
	elsif l2b_ah(request_pending) then
	  if (active_cs_n = request_cs_n) and (active_rnw = request_rnw) and same_bank_and_row(active_addr,request_addr) then
	      -- this request matches our currently active row
	      -- we can process it 

	    active_addr <= request_addr;
	    active_data <= request_data;
	    active_dqm <= request_dqm;

	    ack_request <='1';

	    if l2b_ah(request_rnw) then
	      m_state <= M_ST_READ;
	    else
	      m_state <= M_ST_WRITE;
	    end if;
	  else
	      -- new request doesn't match, precharge and go to idle
	    m_state <= M_ST_WAIT_FOR_PRECHARGE;
	    m_next <= M_ST_IDLE;
	  end if;
	end if;

      elsif m_state = M_ST_WAIT_FOR_PRECHARGE then
      	m_debug(6 downto 0) <= DEBUG_7;
	  -- wait count then do a precharge
	mem_cmd <= MEM_CMD_NOP;
	if m_count > 1 then
	  m_count <= m_count -1;
	else
	  m_state<=M_ST_PRECHARGE;
	end if;
      elsif m_state = M_ST_PRECHARGE then
      	m_debug(6 downto 0) <= DEBUG_8;
	-- do a precharge, wait two clocks, then goto m_next
	mem_addr <= (others => '1');
	mem_cmd <= MEM_CMD_PRE;
	m_count <= 1;
	m_state <= M_ST_NOP_COUNT;
      elsif m_state=M_ST_REFRESH then
      	m_debug(6 downto 0) <= DEBUG_9;
	-- do a refresh, wait six clocks, return to idle

	mem_cmd <= MEM_CMD_REF;
	m_count <=5;
	m_next <=M_ST_IDLE;
	m_state <= M_ST_NOP_COUNT;

	-- tell the gubbins we did the refresh
	ack_refresh <= '1';
      else  
	-- shouldn't be here - crash
        m_debug(7) <='1';
      	m_debug(6 downto 0) <= DEBUG_9;
	mem_cmd <=MEM_CMD_NOP;
	mem_cs_n <= MEM_CS_N_NONE;
	mem_oe <= '0';
      end if;
    end if;

  end process;

  -- drive the memory lines
  sdram_clk <= clock;
  sdram_cke <= '1';
  sdram_cs_n  <= mem_cs_n(0);
  sdram_ras_n <= mem_cmd(2);
  sdram_cas_n <= mem_cmd(1);
  sdram_we_n  <= mem_cmd(0);
  sdram_addr  <= mem_addr;
  sdram_ba    <= mem_bank;

  sdram_dq_tristate: process(mem_oe,mem_data_out)  begin
  if l2b_ah(mem_oe) then
	sdram_dq <= mem_data_out;
  else
	sdram_dq <= (others => 'Z' );
  end if;
  end process;

  mem_data_in <= sdram_dq;

  sdram_dqm <= mem_dqm;

  -- a shift register to track the reads
  read_process: process(reset_n,clock, mem_cmd) begin
    if l2b_al(reset_n) then
	r_data_valid <= (others => '0');
    elsif rising_edge(clock) then
	r_data_valid(2 downto 0)<=r_data_valid(3 downto 1);
	r_data_valid(3) <= b2l_ah(mem_cmd = MEM_CMD_READ);
    end if;
  end process;
	

  bus_fsm: process (reset_n,clock,b_state,bus_cs_n,bus_rnw,bus_addr,bus_data_in,ack_request,r_data_valid) begin
    if l2b_al(reset_n) then
	bus_data_out <= (others => '0');
	request_data <= (others => '0');
	request_addr <= (others => '0');
	request_rnw <= '0';
  	request_cs_n <= MEM_CS_N_NONE;
  	request_dqm <= "00";
	b_state <= B_ST_WAIT_CS_N_LOW;
	b_debug(6 downto 0) <= DEBUG_0;
	b_debug(7) <='0';
	bus_wait_n <= '0';
   elsif rising_edge(clock) then
	if b_state = B_ST_WAIT_CS_N_LOW then
		b_debug(6 downto 0) <= DEBUG_1;
		bus_wait_n <= '0';
		if l2b_al(bus_cs_n) then
			-- new request ship it to the main state machine
			post_request <='1';
			request_addr <= bus_addr;
			request_rnw <= bus_rnw;
			request_data <= bus_data_in;

			-- send to first chip and all bytes
  			request_cs_n <= "0"; -- (others => '1');
  			request_dqm <= "00";

			b_state <= B_ST_LODGE_REQUEST;
		end if;
	elsif b_state =B_ST_LODGE_REQUEST then
	b_debug(6 downto 0) <= DEBUG_2;
		post_request <='0';
		b_state <= B_ST_WAIT_ACK;
	elsif b_state =B_ST_WAIT_ACK then
	b_debug(6 downto 0) <= DEBUG_3;
		if not l2b_ah(request_pending) then
			-- the logic has pushed the request to the ram
			if l2b_al(request_rnw) then
				-- if it's a write we're all done
				b_state <= B_ST_WAIT_CS_N_HIGH;
			else
				-- if it's a read we have to wait for the data
				b_state <= B_ST_WAIT_DATA;
			end if;
		end if;
	elsif b_state = B_ST_WAIT_DATA then
		b_debug(6 downto 0) <= DEBUG_4;
		if l2b_ah(r_data_valid(0)) then
			bus_data_out <= mem_data_in;
--			bus_data_out <= request_addr(15 downto 0);
			b_state <= B_ST_WAIT_CS_N_HIGH;
		end if;
	elsif b_state = B_ST_WAIT_CS_N_HIGH then
	b_debug(6 downto 0) <= DEBUG_5;
	b_debug(7) <='1';
			bus_wait_n <= '1'; 
		if not l2b_al(bus_cs_n) then
			b_state <=B_ST_WAIT_CS_N_LOW;
		end if;
	else
		b_state <=B_ST_WAIT_CS_N_LOW;
	end if;
 end if;

   end process;
--   debug <=b_debug;
    debug <= m_debug;


end;