OpenCores
URL https://opencores.org/ocsvn/w11/w11/trunk

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.6/] [rtl/] [bplib/] [nxcramlib/] [nx_cram_memctl_as.vhd] - Blame information for rev 13

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 13 wfjm
-- $Id: n2_cram_memctl_as.vhd 427 2011-11-19 21:04:11Z mueller $
2 2 wfjm
--
3 13 wfjm
-- Copyright 2010-2011 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4 2 wfjm
--
5
-- This program is free software; you may redistribute and/or modify it under
6
-- the terms of the GNU General Public License as published by the Free
7
-- Software Foundation, either version 2, or at your option any later version.
8
--
9
-- This program is distributed in the hope that it will be useful, but
10
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
11
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
-- for complete details.
13
-- 
14
------------------------------------------------------------------------------
15
-- Module Name:    n2_cram_memctl_as - syn
16
-- Description:    nexys2: CRAM driver - async and page mode
17
--
18
-- Dependencies:   vlib/xlib/iob_reg_o
19
--                 vlib/xlib/iob_reg_o_gen
20
--                 vlib/xlib/iob_reg_io_gen
21
-- Test bench:     tb/tb_n2_cram_memctl
22
--                 fw_gen/tst_sram/nexys2/tb/tb_tst_sram_n2
23
-- Target Devices: generic
24 13 wfjm
-- Tool versions:  xst 11.4, 13.1; ghdl 0.26
25 2 wfjm
--
26
-- Synthesized (xst):
27
-- Date         Rev  ise         Target      flop lutl lutm slic t peri
28
-- 2010-06-03   299  11.4   L68  xc3s1200e-4   91  100    0   96 s  6.7
29
-- 2010-05-24   294  11.4   L68  xc3s1200e-4   91   99    0   95 s  6.7
30
-- 2010-05-23   293  11.4   L68  xc3s1200e-4   91  139    0   99 s  6.7
31
--
32
-- Revision History: 
33
-- Date         Rev Version  Comment
34 13 wfjm
-- 2011-11-19   427   1.0.5  now numeric_std clean
35 8 wfjm
-- 2010-11-22   339   1.0.4  cntdly now 3 bit; add assert for DELAY generics
36 2 wfjm
-- 2010-06-03   299   1.0.3  add "KEEP" for data iob; MEM_OE='1' on first read
37
--                           cycle;
38
-- 2010-05-30   297   1.0.2  use READ(0|1)DELAY generic
39
-- 2010-05-24   294   1.0.1  more compact n.memdi logic; extra wait in s_rdwait1
40
-- 2010-05-23   293   1.0    Initial version 
41
--
42
-- Notes:
43
--  1. READ1DELAY of 2 is needed even though the timing of the memory suggests
44
--     that 1 cycle is enough (T_apa is 20 ns, so 40 ns round trip is ok). A
45
--     short READ1 delay works in sim, but not on fpga where the data od the
46
--     ADDR(0)=0 cycle is re-read (see notes_tst_sram_n2.txt).
47
--     tb_n2_cram_memctl_as_ISim_tsim works with full sdf even when T_apa is
48
--     40ns or 50 ns, only T_apa 60 ns fails !
49
--     Unclear what is wrong here, the timing of the memory model seems ok.
50
--  2. There is no 'bus-turn-around' cycle needed for a write->read change
51
--     FPGA_OE goes 1->0 and MEM_OE goes 0->1 on the s_wrput1->s_rdinit
52
--     transition simultaneously. The FPGA will go high-Z quickly, the memory
53
--     low-Z delay by the IOB and internal memory delays. No clash.
54
--  3. There is a hidden 'bus-turn-around' cycle for a read->write change.
55
--     MEM_OE goes 1->0 on s_rdget1->s_wrinit and the memory will go high-z with
56
--     some dekal. FPGA_OE goes 0->1 in the next cycle at s_wrinit->s_wrwait0.
57
--     Again no clash due to the 1 cycle delay.
58
--
59 8 wfjm
-- Nominal timings:
60
--     READ0/1 = N_rd_cycle - 2
61
--     WRITE   = N_wr_cycle - 1
62
--
63
-- from notes_nexys2.txt (Rev 339):
64
--         clksys        RD  WR     < use for >               Test case
65
--                                                            MHz div mul
66
--        <51.20          2   3     <-- 50                     50   1   1
67
--         51.20- 54.80   3   3     <-- 52,54                  54  25  27
68
--         54.80- 64.10   3   4     <-- 55,56,58,60,62,64      64  25  32
69
--         64.10- 68.50   4   4     <-- 65                     65  10  13
70
--         68.50- 76.92   4   5     <-- 70,75                  75   2   3
71
--         76.92- 82.19   5   5     <-- 80                     80   5   8
72
--         82.19- 89.74   5   6     <-- 85                     85  10  17
73
--         89.74- 95.89   6   6     <-- 90,95                  95  10  19
74
--         95.89-102.56   6   7     <-- 100                   100   1   2
75
--
76 2 wfjm
-- Timing of some signals:
77
--
78
-- single read request:
79
--
80
-- state      |_idle  |_rdinit|_rdwt0 |_rdwt0 |_rdget0|_rdwt1 |_rdget1|
81
--                      0      20      40      60      80      100     120
82
-- CLK      __|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|
83
-- 
84
-- REQ      _______|^^^^^|_____________________________________________
85
-- WE       ___________________________________________________________
86
-- 
87
-- IOB_CE   __________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|_
88
-- IOB_OE    _________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|_
89
-- 
90
-- DO       oooooooooooooooooooooooooooooooooooooooooo|lllllll|lllllll|h
91
-- BUSY     __________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|________________
92
-- ACK_R   ___________________________________________________________|^^^^^^^|_
93
-- 
94
-- single write request:
95
-- 
96
-- state       |_idle  |_wrinit|_wrwt0 |_wrwt0 |_wrwt0 |_wrput0|_idle  |
97
--                       0      20      40      60      80      100     120
98
-- CLK       __|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|
99
-- 
100
-- REQ       _______|^^^^^|______________________________________
101
-- WE        _______|^^^^^|______________________________________
102
-- 
103
-- IOB_CE    __________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|_
104
-- IOB_BE    __________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|_
105
-- IOB_OE    ____________________________________________________
106
-- IOB_WE    ______________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|_____
107
-- 
108
-- BUSY      __________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|_________
109
-- ACK_W     __________________________________________|^^^^^^^|_
110
-- 
111
------------------------------------------------------------------------------
112
 
113
library ieee;
114
use ieee.std_logic_1164.all;
115 13 wfjm
use ieee.numeric_std.all;
116 2 wfjm
 
117
use work.slvtypes.all;
118
use work.xlib.all;
119
 
120
entity n2_cram_memctl_as is             -- CRAM driver (async+page mode)
121
  generic (
122
    READ0DELAY : positive := 2;         -- read word 0 delay in clock cycles
123
    READ1DELAY : positive := 2;         -- read word 1 delay in clock cycles
124
    WRITEDELAY : positive := 3);        -- write delay in clock cycles
125
  port (
126
    CLK : in slbit;                     -- clock
127
    RESET : in slbit;                   -- reset
128
    REQ   : in slbit;                   -- request
129
    WE    : in slbit;                   -- write enable
130
    BUSY : out slbit;                   -- controller busy
131
    ACK_R : out slbit;                  -- acknowledge read
132
    ACK_W : out slbit;                  -- acknowledge write
133
    ACT_R : out slbit;                  -- signal active read
134
    ACT_W : out slbit;                  -- signal active write
135
    ADDR : in slv22;                    -- address  (32 bit word address)
136
    BE : in slv4;                       -- byte enable
137
    DI : in slv32;                      -- data in  (memory view)
138
    DO : out slv32;                     -- data out (memory view)
139
    O_MEM_CE_N : out slbit;             -- cram: chip enable   (act.low)
140
    O_MEM_BE_N : out slv2;              -- cram: byte enables  (act.low)
141
    O_MEM_WE_N : out slbit;             -- cram: write enable  (act.low)
142
    O_MEM_OE_N : out slbit;             -- cram: output enable (act.low)
143
    O_MEM_ADV_N : out slbit;            -- cram: address valid (act.low)
144
    O_MEM_CLK : out slbit;              -- cram: clock
145
    O_MEM_CRE : out slbit;              -- cram: command register enable
146
    I_MEM_WAIT : in slbit;              -- cram: mem wait
147
    O_FLA_CE_N : out slbit;             -- flash ce..          (act.low)
148
    O_MEM_ADDR  : out slv23;            -- cram: address lines
149
    IO_MEM_DATA : inout slv16           -- cram: data lines
150
  );
151
end n2_cram_memctl_as;
152
 
153
 
154
architecture syn of n2_cram_memctl_as is
155
 
156
  type state_type is (
157
    s_idle,                             -- s_idle: wait for req
158
    s_rdinit,                           -- s_rdinit:  read init cycle
159
    s_rdwait0,                          -- s_rdwait0: read wait low word
160
    s_rdget0,                           -- s_rdget0:  read get low word
161
    s_rdwait1,                          -- s_rdwait1: read wait high word
162
    s_rdget1,                           -- s_rdget1:  read get high word
163
    s_wrinit,                           -- s_wrinit:  write init cycle
164
    s_wrwait0,                          -- s_rdwait0: write wait 1st word
165
    s_wrput0,                           -- s_rdput0:  write put 1st word
166
    s_wrini1,                           -- s_wrini1:  write init 2nd word
167
    s_wrwait1,                          -- s_wrwait1: write wait 2nd word
168
    s_wrput1                            -- s_wrput1:  write put 2nd word
169
  );
170
 
171
  type regs_type is record
172
    state : state_type;                 -- state
173
    ackr : slbit;                       -- signal ack_r
174
    addr0 : slbit;                      -- current addr0
175
    be2nd : slv2;                       -- be's of 2nd write cycle
176 8 wfjm
    cntdly : slv3;                      -- wait delay counter
177 2 wfjm
    cntce : slv7;                       -- ce counter
178
    fidle : slbit;                      -- force idle flag
179
    memdo0 : slv16;                     -- mem data out, low word
180
    memdi : slv32;                      -- mem data in
181
  end record regs_type;
182
 
183
  constant regs_init : regs_type := (
184
    s_idle,                             --
185
    '0',                                -- ackr
186
    '0',                                -- addr0
187
    "00",                               -- be2nd
188
    (others=>'0'),                      -- cntdly
189
    (others=>'0'),                      -- cntce
190
    '0',                                -- fidle
191
    (others=>'0'),                      -- memdo0
192
    (others=>'0')                       -- memdi
193
  );
194
 
195
  signal R_REGS : regs_type := regs_init;  -- state registers
196
  signal N_REGS : regs_type := regs_init;  -- next value state regs
197
 
198
  signal CLK_180  : slbit := '0';
199
  signal MEM_CE_N : slbit := '1';
200
  signal MEM_BE_N : slv2  := "11";
201
  signal MEM_WE_N : slbit := '1';
202
  signal MEM_OE_N : slbit := '1';
203
  signal BE_CE    : slbit := '0';
204
  signal ADDRH_CE : slbit := '0';
205
  signal ADDR0_CE : slbit := '0';
206
  signal ADDR0    : slbit := '0';
207
  signal DATA_CEI : slbit := '0';
208
  signal DATA_CEO : slbit := '0';
209
  signal DATA_OE  : slbit := '0';
210
  signal MEM_DO   : slv16 := (others=>'0');
211
  signal MEM_DI   : slv16 := (others=>'0');
212
 
213
-- these attributes aren't accepted by ghdl 0.26
214
--  attribute s : string;
215
--  attribute s of I_MEM_WAIT : signal is "true";
216
 
217
begin
218
 
219 8 wfjm
  assert READ0DELAY<=2**R_REGS.cntdly'length and
220
         READ1DELAY<=2**R_REGS.cntdly'length and
221
         WRITEDELAY<=2**R_REGS.cntdly'length
222
    report "assert(READ0,READ1,WRITEDELAY <= 2**cntdly'length)"
223
    severity failure;
224
 
225 2 wfjm
  CLK_180 <= not CLK;
226
 
227
  IOB_MEM_CE : iob_reg_o
228
    generic map (
229
      INIT   => '1')
230
    port map (
231
      CLK => CLK,
232
      CE  => '1',
233
      DO  => MEM_CE_N,
234
      PAD => O_MEM_CE_N
235
    );
236
 
237
  IOB_MEM_BE : iob_reg_o_gen
238
    generic map (
239
      DWIDTH => 2,
240
      INIT   => '1')
241
    port map (
242
      CLK => CLK,
243
      CE  => BE_CE,
244
      DO  => MEM_BE_N,
245
      PAD => O_MEM_BE_N
246
    );
247
 
248
  IOB_MEM_WE : iob_reg_o
249
    generic map (
250
      INIT   => '1')
251
    port map (
252
      CLK => CLK_180,
253
      CE  => '1',
254
      DO  => MEM_WE_N,
255
      PAD => O_MEM_WE_N
256
    );
257
 
258
  IOB_MEM_OE : iob_reg_o
259
    generic map (
260
      INIT   => '1')
261
    port map (
262
      CLK => CLK,
263
      CE  => '1',
264
      DO  => MEM_OE_N,
265
      PAD => O_MEM_OE_N
266
    );
267
 
268
  IOB_MEM_ADDRH : iob_reg_o_gen
269
    generic map (
270
      DWIDTH => 22)
271
    port map (
272
      CLK => CLK,
273
      CE  => ADDRH_CE,
274
      DO  => ADDR,
275
      PAD => O_MEM_ADDR(22 downto 1)
276
    );
277
 
278
  IOB_MEM_ADDR0 : iob_reg_o
279
    port map (
280
      CLK => CLK,
281
      CE  => ADDR0_CE,
282
      DO  => ADDR0,
283
      PAD => O_MEM_ADDR(0)
284
    );
285
 
286
  IOB_MEM_DATA : iob_reg_io_gen
287
    generic map (
288
      DWIDTH => 16,
289
      PULL   => "KEEP")
290
    port map (
291
      CLK => CLK,
292
      CEI => DATA_CEI,
293
      CEO => DATA_CEO,
294
      OE  => DATA_OE,
295
      DI  => MEM_DO,
296
      DO  => MEM_DI,
297
      PAD => IO_MEM_DATA
298
    );
299
 
300
  O_MEM_ADV_N <= '0';
301
  O_MEM_CLK   <= '0';
302
  O_MEM_CRE   <= '0';
303
  O_FLA_CE_N  <= '1';
304
 
305
  proc_regs: process (CLK)
306
  begin
307
 
308 13 wfjm
    if rising_edge(CLK) then
309 2 wfjm
      if RESET = '1' then
310
        R_REGS <= regs_init;
311
      else
312
        R_REGS <= N_REGS;
313
      end if;
314
    end if;
315
 
316
  end process proc_regs;
317
 
318
  proc_next: process (R_REGS, REQ, WE, BE, DI, MEM_DO)
319
 
320
    variable r : regs_type := regs_init;
321
    variable n : regs_type := regs_init;
322
    variable ibusy : slbit := '0';
323
    variable iackw : slbit := '0';
324
    variable iactr : slbit := '0';
325
    variable iactw : slbit := '0';
326
    variable imem_ce : slbit := '0';
327
    variable imem_be : slv2  := "00";
328
    variable imem_we : slbit := '0';
329
    variable imem_oe : slbit := '0';
330
    variable ibe_ce    : slbit := '0';
331
    variable iaddrh_ce : slbit := '0';
332
    variable iaddr0_ce : slbit := '0';
333
    variable iaddr0    : slbit := '0';
334
    variable idata_cei : slbit := '0';
335
    variable idata_ceo : slbit := '0';
336
    variable idata_oe  : slbit := '0';
337
 
338
    procedure do_dispatch(nstate  : out state_type;
339
                          iaddrh_ce : out slbit;
340
                          iaddr0_ce : out slbit;
341
                          iaddr0  : out slbit;
342
                          ibe_ce  : out slbit;
343
                          imem_be : out slv2;
344
                          imem_ce : out slbit;
345
                          imem_oe : out slbit;
346
                          nbe2nd  : out slv2) is
347
    begin
348
      iaddrh_ce := '1';                 -- latch address (high part)
349
      iaddr0_ce := '1';                 -- latch address 0 bit
350
      ibe_ce    := '1';                 -- latch be's
351
      imem_ce   := '1';                 -- ce CRAM next cycle
352
      nbe2nd    := "00";                -- assume no 2nd write cycle
353
      if WE = '0' then                  -- if READ requested
354
        iaddr0  := '0';                   -- go first for low word
355
        imem_be := "11";                  -- on read always on
356
        imem_oe := '1';                   -- oe CRAM next cycle
357
        nstate  := s_rdinit;              -- next: read init part
358
      else                              -- if WRITE requested
359
        if BE(1 downto 0) /= "00" then    -- low word write
360
          iaddr0  := '0';                   -- access word 0 
361
          imem_be := BE(1 downto 0);        -- set be's for 1st cycle
362
          nbe2nd  := BE(3 downto 2);        -- keep be's for 2nd cycle
363
        else                              -- high word write
364
          iaddr0  := '1';                   -- access word 1 
365
          imem_be := BE(3 downto 2);        -- set be's for 1st cycle
366
        end if;
367
        nstate := s_wrinit;               -- next: write init part
368
      end if;
369
    end procedure do_dispatch;
370
 
371
  begin
372
 
373
    r := R_REGS;
374
    n := R_REGS;
375
    n.ackr := '0';
376
 
377
    ibusy := '0';
378
    iackw := '0';
379
    iactr := '0';
380
    iactw := '0';
381
 
382
    imem_ce := '0';
383
    imem_be := "11";
384
    imem_we := '0';
385
    imem_oe := '0';
386
    ibe_ce    := '0';
387
    iaddrh_ce := '0';
388
    iaddr0_ce := '0';
389
    iaddr0    := '0';
390
    idata_cei := '0';
391
    idata_ceo := '0';
392
    idata_oe  := '0';
393
 
394
    if unsigned(r.cntdly) /= 0 then
395 13 wfjm
      n.cntdly := slv(unsigned(r.cntdly) - 1);
396 2 wfjm
    end if;
397
 
398
    case r.state is
399
      when s_idle =>                    -- s_idle: wait for req
400
        if REQ = '1' then                 -- if IO requested
401
          do_dispatch(n.state, iaddrh_ce, iaddr0_ce, iaddr0,
402
                               ibe_ce, imem_be, imem_ce, imem_oe, n.be2nd);
403
        end if;
404
 
405
      when s_rdinit =>                  -- s_rdinit:  read init cycle
406
        ibusy   := '1';                   -- signal busy, unable to handle req
407
        iactr   := '1';                   -- signal mem read
408
        imem_ce := '1';                   -- ce CRAM next cycle
409
        imem_oe := '1';                   -- oe CRAM next cycle
410 13 wfjm
        n.cntdly:= slv(to_unsigned(READ0DELAY-1, n.cntdly'length));
411 2 wfjm
        n.state := s_rdwait0;             -- next: wait
412
 
413
      when s_rdwait0 =>                  -- s_rdwait0: read wait low word
414
        ibusy   := '1';                   -- signal busy, unable to handle req
415
        iactr   := '1';                   -- signal mem read
416
        imem_ce := '1';                   -- ce CRAM next cycle
417
        imem_oe := '1';                   -- oe CRAM next cycle
418
        if unsigned(r.cntdly) = 0 then    -- wait expired ?
419
          n.state := s_rdget0;              -- next: get low word
420
        end if;
421
 
422
      when s_rdget0 =>                  -- s_rdget0: read get low word
423
        ibusy   := '1';                   -- signal busy, unable to handle req
424
        iactr   := '1';                   -- signal mem read
425
        imem_ce := '1';                   -- ce CRAM next cycle
426
        imem_oe := '1';                   -- oe CRAM next cycle
427
        idata_cei := '1';                 -- latch input data
428
        iaddr0_ce := '1';                 -- latch address 0 bit
429
        iaddr0    := '1';                 -- now go for high word
430 13 wfjm
        n.cntdly:= slv(to_unsigned(READ1DELAY-1, n.cntdly'length));
431 2 wfjm
        n.state := s_rdwait1;             -- next: wait high word
432
 
433
      when s_rdwait1 =>                 -- s_rdwait1: read wait high word
434
        ibusy   := '1';                   -- signal busy, unable to handle req
435
        iactr   := '1';                   -- signal mem read
436
        imem_ce := '1';                   -- ce CRAM next cycle
437
        imem_oe := '1';                   -- oe CRAM next cycle
438
        if unsigned(r.cntdly) = 0 then    -- wait expired ?
439
          n.state := s_rdget1;              -- next: get low word
440
        end if;                             --
441
 
442
      when s_rdget1 =>                  -- s_rdget1: read get high word
443
        iactr   := '1';                   -- signal mem read
444
        n.memdo0:= MEM_DO;                -- save low word data
445
        idata_cei := '1';                 -- latch input data
446
        n.ackr  := '1';                   -- ACK_R next cycle
447
        n.state := s_idle;                -- next: wait next request
448
        if r.fidle = '1' then             -- forced idle cycle
449
          ibusy   := '1';                   -- signal busy, unable to handle req
450
        else
451
          if REQ = '1' then                 -- if IO requested            
452
            do_dispatch(n.state, iaddrh_ce, iaddr0_ce, iaddr0,
453
                                 ibe_ce, imem_be, imem_ce, imem_oe, n.be2nd);
454
          end if;
455
        end if;
456
 
457
      when s_wrinit =>                  -- s_wrinit:  write init cycle
458
        ibusy := '1';                     -- signal busy, unable to handle req
459
        iactw := '1';                     -- signal mem write
460
        iackw := '1';                     -- signal write done (all latched)
461
        idata_ceo:= '1';                  -- latch output data
462
        idata_oe := '1';                  -- oe FPGA next cycle
463
        imem_ce  := '1';                  -- ce CRAM next cycle
464
        imem_we  := '1';                  -- we CRAM in half cycle
465 13 wfjm
        n.cntdly:= slv(to_unsigned(WRITEDELAY-1, n.cntdly'length));
466 2 wfjm
        n.state := s_wrwait0;             -- next: wait
467
 
468
      when s_wrwait0 =>                 -- s_rdput0:  write wait 1st word
469
        ibusy := '1';                     -- signal busy, unable to handle req
470
        iactw := '1';                     -- signal mem write
471
        idata_oe := '1';                  -- oe FPGA next cycle
472
        imem_ce  := '1';                  -- ce CRAM next cycle
473
        imem_we  := '1';                  -- we CRAM next cycle
474
        if unsigned(r.cntdly) = 0 then    -- wait expired ?
475
          n.state := s_wrput0;            -- next: put 1st word
476
        end if;
477
 
478
      when s_wrput0 =>                  -- s_rdput0:  write put 1st word
479
        iactw := '1';                     -- signal mem write
480
        imem_we  := '0';                  -- deassert we CRAM in half cycle
481
        if r.be2nd /= "00" then
482
          ibusy := '1';                     -- signal busy, unable to handle req
483
          imem_ce  := '1';                  -- ce CRAM next cycle
484
          iaddr0_ce := '1';                 -- latch address 0 bit
485
          iaddr0    := '1';                 -- now go for high word
486
          ibe_ce    := '1';                 -- latch be's
487
          imem_be   := r.be2nd;             -- now be's of high word
488
          n.state := s_wrini1;              -- next: start 2nd write
489
        else
490
          n.state := s_idle;                -- next: wait next request
491
          if r.fidle = '1' then             -- forced idle cycle
492
            ibusy   := '1';                   -- signal busy
493
          else
494
            if REQ = '1' then                 -- if IO requested            
495
              do_dispatch(n.state, iaddrh_ce, iaddr0_ce, iaddr0,
496
                                   ibe_ce, imem_be, imem_ce, imem_oe, n.be2nd);
497
            end if;
498
          end if;
499
        end if;
500
 
501
      when s_wrini1 =>                  -- s_wrini1:  write init 2nd word
502
        ibusy := '1';                     -- signal busy, unable to handle req
503
        iactw := '1';                     -- signal mem write
504
        idata_ceo:= '1';                  -- latch output data
505
        idata_oe := '1';                  -- oe FPGA next cycle
506
        imem_ce  := '1';                  -- ce CRAM next cycle
507
        imem_we  := '1';                  -- we CRAM in half cycle
508 13 wfjm
        n.cntdly:= slv(to_unsigned(WRITEDELAY-1, n.cntdly'length));
509 2 wfjm
        n.state := s_wrwait1;             -- next: wait
510
 
511
      when s_wrwait1 =>                 -- s_wrwait1: write wait 2nd word
512
        ibusy := '1';                     -- signal busy, unable to handle req
513
        iactw := '1';                     -- signal mem write
514
        idata_oe := '1';                  -- oe FPGA next cycle
515
        imem_ce  := '1';                  -- ce CRAM next cycle
516
        imem_we  := '1';                  -- we CRAM next cycle
517
        if unsigned(r.cntdly) = 0 then    -- wait expired ?
518
          n.state := s_wrput1;            -- next: put 2nd word
519
        end if;
520
 
521
      when s_wrput1 =>                  -- s_wrput1:  write put 2nd word
522
        iactw := '1';                     -- signal mem write
523
        imem_we  := '0';                  -- deassert we CRAM in half cycle
524
        n.state := s_idle;                -- next: wait next request
525
        if r.fidle = '1' then             -- forced idle cycle
526
          ibusy   := '1';                   -- signal busy, unable to handle req
527
        else
528
          if REQ = '1' then                 -- if IO requested            
529
            do_dispatch(n.state, iaddrh_ce, iaddr0_ce, iaddr0,
530
                                 ibe_ce, imem_be, imem_ce, imem_oe, n.be2nd);
531
          end if;
532
        end if;
533
 
534
      when others => null;
535
    end case;
536
 
537
    if imem_ce = '0' then               -- if cmem not active
538
      n.cntce := (others=>'0');           -- clear counter 
539
      n.fidle := '0';                     -- clear force idle flag
540
    else                                -- if cmem active
541
      if unsigned(r.cntce) >= 127 then    -- if max ce count expired
542
        n.fidle := '1';                     -- set forced idle flag
543
      else                                -- if max ce count not yet reached
544 13 wfjm
        n.cntce := slv(unsigned(r.cntce) + 1);   -- increment counter
545 2 wfjm
      end if;
546
    end if;
547
 
548
    if iaddrh_ce = '1' then             -- if addresses are latched
549
      n.memdi := DI;                      -- latch data too...
550
    end if;
551
 
552
    if iaddr0_ce = '1' then             -- if address bit 0 changed
553
      n.addr0 := iaddr0;                  -- mirror it in state regs
554
    end if;
555
 
556
    N_REGS <= n;
557
 
558
    MEM_CE_N <= not imem_ce;
559
    MEM_WE_N <= not imem_we;
560
    MEM_BE_N <= not imem_be;
561
    MEM_OE_N <= not imem_oe;
562
 
563
    if r.addr0 = '0' then
564
      MEM_DI <= r.memdi(15 downto 0);
565
    else
566
      MEM_DI <= r.memdi(31 downto 16);
567
    end if;
568
 
569
    BE_CE    <= ibe_ce;
570
    ADDRH_CE <= iaddrh_ce;
571
    ADDR0_CE <= iaddr0_ce;
572
    ADDR0    <= iaddr0;
573
    DATA_CEI <= idata_cei;
574
    DATA_CEO <= idata_ceo;
575
    DATA_OE  <= idata_oe;
576
 
577
    BUSY  <= ibusy;
578
    ACK_R <= r.ackr;
579
    ACK_W <= iackw;
580
    ACT_R <= iactr;
581
    ACT_W <= iactw;
582
 
583
    DO    <= MEM_DO & r.memdo0;
584
 
585
  end process proc_next;
586
 
587
end syn;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.