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

Subversion Repositories w11

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

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

Line No. Rev Author Line
1 29 wfjm
-- $Id: nx_cram_memctl_as.vhd 644 2015-02-08 22:56:54Z 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 15 wfjm
-- Module Name:    nx_cram_memctl_as - syn
16
-- Description:    nexys2/3: CRAM driver - async and page mode
17 2 wfjm
--
18
-- Dependencies:   vlib/xlib/iob_reg_o
19
--                 vlib/xlib/iob_reg_o_gen
20
--                 vlib/xlib/iob_reg_io_gen
21 15 wfjm
-- Test bench:     tb/tb_nx_cram_memctl_as
22
--                 sys_gen/tst_sram/nexys2/tb/tb_tst_sram_n2
23 2 wfjm
-- Target Devices: generic
24 29 wfjm
-- Tool versions:  ise 11.4-14.7; viv 2014.4; ghdl 0.26-0.31
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 15 wfjm
-- 2011-11-26   433   1.2    renamed from n2_cram_memctl_as
35
-- 2011-11-19   432   1.1    remove O_FLA_CE_N port
36 13 wfjm
-- 2011-11-19   427   1.0.5  now numeric_std clean
37 8 wfjm
-- 2010-11-22   339   1.0.4  cntdly now 3 bit; add assert for DELAY generics
38 2 wfjm
-- 2010-06-03   299   1.0.3  add "KEEP" for data iob; MEM_OE='1' on first read
39
--                           cycle;
40
-- 2010-05-30   297   1.0.2  use READ(0|1)DELAY generic
41
-- 2010-05-24   294   1.0.1  more compact n.memdi logic; extra wait in s_rdwait1
42
-- 2010-05-23   293   1.0    Initial version 
43
--
44
-- Notes:
45
--  1. READ1DELAY of 2 is needed even though the timing of the memory suggests
46
--     that 1 cycle is enough (T_apa is 20 ns, so 40 ns round trip is ok). A
47 25 wfjm
--     short READ1 delay works in sim, but not on fpga where the data of the
48 2 wfjm
--     ADDR(0)=0 cycle is re-read (see notes_tst_sram_n2.txt).
49
--     tb_n2_cram_memctl_as_ISim_tsim works with full sdf even when T_apa is
50
--     40ns or 50 ns, only T_apa 60 ns fails !
51
--     Unclear what is wrong here, the timing of the memory model seems ok.
52
--  2. There is no 'bus-turn-around' cycle needed for a write->read change
53
--     FPGA_OE goes 1->0 and MEM_OE goes 0->1 on the s_wrput1->s_rdinit
54
--     transition simultaneously. The FPGA will go high-Z quickly, the memory
55
--     low-Z delay by the IOB and internal memory delays. No clash.
56
--  3. There is a hidden 'bus-turn-around' cycle for a read->write change.
57
--     MEM_OE goes 1->0 on s_rdget1->s_wrinit and the memory will go high-z with
58 25 wfjm
--     some delay. FPGA_OE goes 0->1 in the next cycle at s_wrinit->s_wrwait0.
59 2 wfjm
--     Again no clash due to the 1 cycle delay.
60
--
61 8 wfjm
-- Nominal timings:
62
--     READ0/1 = N_rd_cycle - 2
63
--     WRITE   = N_wr_cycle - 1
64
--
65
-- from notes_nexys2.txt (Rev 339):
66
--         clksys        RD  WR     < use for >               Test case
67
--                                                            MHz div mul
68
--        <51.20          2   3     <-- 50                     50   1   1
69
--         51.20- 54.80   3   3     <-- 52,54                  54  25  27
70
--         54.80- 64.10   3   4     <-- 55,56,58,60,62,64      64  25  32
71
--         64.10- 68.50   4   4     <-- 65                     65  10  13
72
--         68.50- 76.92   4   5     <-- 70,75                  75   2   3
73
--         76.92- 82.19   5   5     <-- 80                     80   5   8
74
--         82.19- 89.74   5   6     <-- 85                     85  10  17
75
--         89.74- 95.89   6   6     <-- 90,95                  95  10  19
76
--         95.89-102.56   6   7     <-- 100                   100   1   2
77
--
78 2 wfjm
-- Timing of some signals:
79
--
80
-- single read request:
81
--
82
-- state      |_idle  |_rdinit|_rdwt0 |_rdwt0 |_rdget0|_rdwt1 |_rdget1|
83
--                      0      20      40      60      80      100     120
84
-- CLK      __|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|
85
-- 
86
-- REQ      _______|^^^^^|_____________________________________________
87
-- WE       ___________________________________________________________
88
-- 
89
-- IOB_CE   __________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|_
90
-- IOB_OE    _________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|_
91
-- 
92
-- DO       oooooooooooooooooooooooooooooooooooooooooo|lllllll|lllllll|h
93
-- BUSY     __________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|________________
94
-- ACK_R   ___________________________________________________________|^^^^^^^|_
95
-- 
96
-- single write request:
97
-- 
98
-- state       |_idle  |_wrinit|_wrwt0 |_wrwt0 |_wrwt0 |_wrput0|_idle  |
99
--                       0      20      40      60      80      100     120
100
-- CLK       __|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|
101
-- 
102
-- REQ       _______|^^^^^|______________________________________
103
-- WE        _______|^^^^^|______________________________________
104
-- 
105
-- IOB_CE    __________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|_
106
-- IOB_BE    __________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|_
107
-- IOB_OE    ____________________________________________________
108
-- IOB_WE    ______________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|_____
109
-- 
110
-- BUSY      __________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|_________
111
-- ACK_W     __________________________________________|^^^^^^^|_
112
-- 
113
------------------------------------------------------------------------------
114
 
115
library ieee;
116
use ieee.std_logic_1164.all;
117 13 wfjm
use ieee.numeric_std.all;
118 2 wfjm
 
119
use work.slvtypes.all;
120
use work.xlib.all;
121
 
122 15 wfjm
entity nx_cram_memctl_as is             -- CRAM driver (async+page mode)
123 2 wfjm
  generic (
124
    READ0DELAY : positive := 2;         -- read word 0 delay in clock cycles
125
    READ1DELAY : positive := 2;         -- read word 1 delay in clock cycles
126
    WRITEDELAY : positive := 3);        -- write delay in clock cycles
127
  port (
128
    CLK : in slbit;                     -- clock
129
    RESET : in slbit;                   -- reset
130
    REQ   : in slbit;                   -- request
131
    WE    : in slbit;                   -- write enable
132
    BUSY : out slbit;                   -- controller busy
133
    ACK_R : out slbit;                  -- acknowledge read
134
    ACK_W : out slbit;                  -- acknowledge write
135
    ACT_R : out slbit;                  -- signal active read
136
    ACT_W : out slbit;                  -- signal active write
137
    ADDR : in slv22;                    -- address  (32 bit word address)
138
    BE : in slv4;                       -- byte enable
139
    DI : in slv32;                      -- data in  (memory view)
140
    DO : out slv32;                     -- data out (memory view)
141
    O_MEM_CE_N : out slbit;             -- cram: chip enable   (act.low)
142
    O_MEM_BE_N : out slv2;              -- cram: byte enables  (act.low)
143
    O_MEM_WE_N : out slbit;             -- cram: write enable  (act.low)
144
    O_MEM_OE_N : out slbit;             -- cram: output enable (act.low)
145
    O_MEM_ADV_N : out slbit;            -- cram: address valid (act.low)
146
    O_MEM_CLK : out slbit;              -- cram: clock
147
    O_MEM_CRE : out slbit;              -- cram: command register enable
148
    I_MEM_WAIT : in slbit;              -- cram: mem wait
149
    O_MEM_ADDR  : out slv23;            -- cram: address lines
150
    IO_MEM_DATA : inout slv16           -- cram: data lines
151
  );
152 15 wfjm
end nx_cram_memctl_as;
153 2 wfjm
 
154
 
155 15 wfjm
architecture syn of nx_cram_memctl_as is
156 2 wfjm
 
157
  type state_type is (
158
    s_idle,                             -- s_idle: wait for req
159
    s_rdinit,                           -- s_rdinit:  read init cycle
160
    s_rdwait0,                          -- s_rdwait0: read wait low word
161
    s_rdget0,                           -- s_rdget0:  read get low word
162
    s_rdwait1,                          -- s_rdwait1: read wait high word
163
    s_rdget1,                           -- s_rdget1:  read get high word
164
    s_wrinit,                           -- s_wrinit:  write init cycle
165
    s_wrwait0,                          -- s_rdwait0: write wait 1st word
166
    s_wrput0,                           -- s_rdput0:  write put 1st word
167
    s_wrini1,                           -- s_wrini1:  write init 2nd word
168
    s_wrwait1,                          -- s_wrwait1: write wait 2nd word
169
    s_wrput1                            -- s_wrput1:  write put 2nd word
170
  );
171
 
172
  type regs_type is record
173
    state : state_type;                 -- state
174
    ackr : slbit;                       -- signal ack_r
175
    addr0 : slbit;                      -- current addr0
176
    be2nd : slv2;                       -- be's of 2nd write cycle
177 8 wfjm
    cntdly : slv3;                      -- wait delay counter
178 2 wfjm
    cntce : slv7;                       -- ce counter
179
    fidle : slbit;                      -- force idle flag
180
    memdo0 : slv16;                     -- mem data out, low word
181
    memdi : slv32;                      -- mem data in
182
  end record regs_type;
183
 
184
  constant regs_init : regs_type := (
185 29 wfjm
    s_idle,                             -- state
186 2 wfjm
    '0',                                -- ackr
187
    '0',                                -- addr0
188
    "00",                               -- be2nd
189
    (others=>'0'),                      -- cntdly
190
    (others=>'0'),                      -- cntce
191
    '0',                                -- fidle
192
    (others=>'0'),                      -- memdo0
193
    (others=>'0')                       -- memdi
194
  );
195
 
196
  signal R_REGS : regs_type := regs_init;  -- state registers
197
  signal N_REGS : regs_type := regs_init;  -- next value state regs
198
 
199
  signal CLK_180  : slbit := '0';
200
  signal MEM_CE_N : slbit := '1';
201
  signal MEM_BE_N : slv2  := "11";
202
  signal MEM_WE_N : slbit := '1';
203
  signal MEM_OE_N : slbit := '1';
204
  signal BE_CE    : slbit := '0';
205
  signal ADDRH_CE : slbit := '0';
206
  signal ADDR0_CE : slbit := '0';
207
  signal ADDR0    : slbit := '0';
208
  signal DATA_CEI : slbit := '0';
209
  signal DATA_CEO : slbit := '0';
210
  signal DATA_OE  : slbit := '0';
211
  signal MEM_DO   : slv16 := (others=>'0');
212
  signal MEM_DI   : slv16 := (others=>'0');
213
 
214
-- these attributes aren't accepted by ghdl 0.26
215
--  attribute s : string;
216
--  attribute s of I_MEM_WAIT : signal is "true";
217
 
218
begin
219
 
220 8 wfjm
  assert READ0DELAY<=2**R_REGS.cntdly'length and
221
         READ1DELAY<=2**R_REGS.cntdly'length and
222
         WRITEDELAY<=2**R_REGS.cntdly'length
223
    report "assert(READ0,READ1,WRITEDELAY <= 2**cntdly'length)"
224
    severity failure;
225
 
226 2 wfjm
  CLK_180 <= not CLK;
227
 
228
  IOB_MEM_CE : iob_reg_o
229
    generic map (
230
      INIT   => '1')
231
    port map (
232
      CLK => CLK,
233
      CE  => '1',
234
      DO  => MEM_CE_N,
235
      PAD => O_MEM_CE_N
236
    );
237
 
238
  IOB_MEM_BE : iob_reg_o_gen
239
    generic map (
240
      DWIDTH => 2,
241
      INIT   => '1')
242
    port map (
243
      CLK => CLK,
244
      CE  => BE_CE,
245
      DO  => MEM_BE_N,
246
      PAD => O_MEM_BE_N
247
    );
248
 
249
  IOB_MEM_WE : iob_reg_o
250
    generic map (
251
      INIT   => '1')
252
    port map (
253
      CLK => CLK_180,
254
      CE  => '1',
255
      DO  => MEM_WE_N,
256
      PAD => O_MEM_WE_N
257
    );
258
 
259
  IOB_MEM_OE : iob_reg_o
260
    generic map (
261
      INIT   => '1')
262
    port map (
263
      CLK => CLK,
264
      CE  => '1',
265
      DO  => MEM_OE_N,
266
      PAD => O_MEM_OE_N
267
    );
268
 
269
  IOB_MEM_ADDRH : iob_reg_o_gen
270
    generic map (
271
      DWIDTH => 22)
272
    port map (
273
      CLK => CLK,
274
      CE  => ADDRH_CE,
275
      DO  => ADDR,
276
      PAD => O_MEM_ADDR(22 downto 1)
277
    );
278
 
279
  IOB_MEM_ADDR0 : iob_reg_o
280
    port map (
281
      CLK => CLK,
282
      CE  => ADDR0_CE,
283
      DO  => ADDR0,
284
      PAD => O_MEM_ADDR(0)
285
    );
286
 
287
  IOB_MEM_DATA : iob_reg_io_gen
288
    generic map (
289
      DWIDTH => 16,
290
      PULL   => "KEEP")
291
    port map (
292
      CLK => CLK,
293
      CEI => DATA_CEI,
294
      CEO => DATA_CEO,
295
      OE  => DATA_OE,
296
      DI  => MEM_DO,
297
      DO  => MEM_DI,
298
      PAD => IO_MEM_DATA
299
    );
300
 
301
  O_MEM_ADV_N <= '0';
302
  O_MEM_CLK   <= '0';
303
  O_MEM_CRE   <= '0';
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.