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

Subversion Repositories w11

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

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

Line No. Rev Author Line
1 37 wfjm
-- $Id: nx_cram_memctl_as.vhd 789 2016-07-17 08:26:55Z mueller $
2 2 wfjm
--
3 36 wfjm
-- Copyright 2010-2016 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 36 wfjm
-- Description:    nexys2/3/4: 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 37 wfjm
--                 sys_gen/tst_sram/nexys3/tb/tb_tst_sram_n3
24
--                 sys_gen/tst_sram/nexys4/tb/tb_tst_sram_n4
25 2 wfjm
-- Target Devices: generic
26 37 wfjm
-- Tool versions:  ise 11.4-14.7; viv 2014.4-2016.2; ghdl 0.26-0.33
27 2 wfjm
--
28 37 wfjm
-- Synthesized:
29
-- Date         Rev  viv    Target       flop  lutl  lutm  bram  slic    
30
-- 2016-07-03   783 2016.3  xc7a100t-1     91    87     0     0    43
31
-- 
32 2 wfjm
-- Synthesized (xst):
33
-- Date         Rev  ise         Target      flop lutl lutm slic t peri
34 37 wfjm
-- Date         Rev  ise         Target      flop lutl lutm slic t peri
35
-- 2016-07-03   767 14.7 131013  xc6slx16-2   100  134    0   60 s  4.2
36
-- 2010-06-03   299 11.4    L68  xc3s1200e-4   91  100    0   96 s  6.7
37
-- 2010-05-24   294 11.4    L68  xc3s1200e-4   91   99    0   95 s  6.7
38
-- 2010-05-23   293 11.4    L68  xc3s1200e-4   91  139    0   99 s  6.7
39 2 wfjm
--
40
-- Revision History: 
41
-- Date         Rev Version  Comment
42 37 wfjm
-- 2016-07-16   788   2.1    change *DELAY generics, now absolute delay cycles
43
--                           add s_init1; drop "KEEP" for data (better for dbg)
44
-- 2016-07-10   786   2.0    add page mode support
45
-- 2016-05-22   767   1.2.2  don't init N_REGS (vivado fix for fsm inference)
46 34 wfjm
-- 2015-12-26   718   1.2.1  BUGFIX: do_dispatch(): always define imem_oe
47 15 wfjm
-- 2011-11-26   433   1.2    renamed from n2_cram_memctl_as
48
-- 2011-11-19   432   1.1    remove O_FLA_CE_N port
49 13 wfjm
-- 2011-11-19   427   1.0.5  now numeric_std clean
50 8 wfjm
-- 2010-11-22   339   1.0.4  cntdly now 3 bit; add assert for DELAY generics
51 2 wfjm
-- 2010-06-03   299   1.0.3  add "KEEP" for data iob; MEM_OE='1' on first read
52
--                           cycle;
53
-- 2010-05-30   297   1.0.2  use READ(0|1)DELAY generic
54
-- 2010-05-24   294   1.0.1  more compact n.memdi logic; extra wait in s_rdwait1
55
-- 2010-05-23   293   1.0    Initial version 
56
--
57
-- Notes:
58 37 wfjm
--  1. There is no 'bus-turn-around' cycle needed for a write->read change
59 2 wfjm
--     FPGA_OE goes 1->0 and MEM_OE goes 0->1 on the s_wrput1->s_rdinit
60
--     transition simultaneously. The FPGA will go high-Z quickly, the memory
61
--     low-Z delay by the IOB and internal memory delays. No clash.
62 37 wfjm
--  2. There is a hidden 'bus-turn-around' cycle for a read->write change.
63 2 wfjm
--     MEM_OE goes 1->0 on s_rdget1->s_wrinit and the memory will go high-z with
64 25 wfjm
--     some delay. FPGA_OE goes 0->1 in the next cycle at s_wrinit->s_wrwait0.
65 2 wfjm
--     Again no clash due to the 1 cycle delay.
66
--
67 8 wfjm
-- Nominal timings:
68 37 wfjm
--     READ0   = (T_aa + ext_read_delay)  in cycles
69
--     READ1   = (T_pa + ext_read_delay)  in cycles
70
--     WRITE   = (T_aa + ext_write_delay) in cycles
71
--   with
72
--     ext_read_delay:  output_IOB + 2*PCB_delay + input_IOB + skew
73
--     ext_write_delay: skew
74 8 wfjm
--
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 15 wfjm
entity nx_cram_memctl_as is             -- CRAM driver (async+page mode)
121 2 wfjm
  generic (
122 37 wfjm
    READ0DELAY : positive := 4;         -- read word 0 delay in clock cycles
123 2 wfjm
    READ1DELAY : positive := 2;         -- read word 1 delay in clock cycles
124 37 wfjm
    WRITEDELAY : positive := 4);        -- write delay in clock cycles
125 2 wfjm
  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_MEM_ADDR  : out slv23;            -- cram: address lines
148
    IO_MEM_DATA : inout slv16           -- cram: data lines
149
  );
150 15 wfjm
end nx_cram_memctl_as;
151 2 wfjm
 
152
 
153 15 wfjm
architecture syn of nx_cram_memctl_as is
154 2 wfjm
 
155
  type state_type is (
156 37 wfjm
    s_init,                             -- s_init: startup state
157
    s_init1,                            -- s_init1: reset released
158
    s_wcinit,                           -- s_wcinit: write rcr init
159
    s_wcwait,                           -- s_wcwait: write rcr wait
160
    s_wcput,                            -- s_wcput: write rcr done
161
    s_rainit,                           -- s_rainit: read array init
162
    s_rawait,                           -- s_rawait: wait read array
163 2 wfjm
    s_idle,                             -- s_idle: wait for req
164
    s_rdinit,                           -- s_rdinit:  read init cycle
165
    s_rdwait0,                          -- s_rdwait0: read wait low word
166
    s_rdget0,                           -- s_rdget0:  read get low word
167
    s_rdwait1,                          -- s_rdwait1: read wait high word
168
    s_rdget1,                           -- s_rdget1:  read get high word
169
    s_wrinit,                           -- s_wrinit:  write init cycle
170
    s_wrwait0,                          -- s_rdwait0: write wait 1st word
171
    s_wrput0,                           -- s_rdput0:  write put 1st word
172
    s_wrini1,                           -- s_wrini1:  write init 2nd word
173
    s_wrwait1,                          -- s_wrwait1: write wait 2nd word
174
    s_wrput1                            -- s_wrput1:  write put 2nd word
175
  );
176
 
177
  type regs_type is record
178
    state : state_type;                 -- state
179
    ackr : slbit;                       -- signal ack_r
180
    addr0 : slbit;                      -- current addr0
181
    be2nd : slv2;                       -- be's of 2nd write cycle
182 8 wfjm
    cntdly : slv3;                      -- wait delay counter
183 2 wfjm
    cntce : slv7;                       -- ce counter
184
    fidle : slbit;                      -- force idle flag
185
    memdo0 : slv16;                     -- mem data out, low word
186
    memdi : slv32;                      -- mem data in
187
  end record regs_type;
188
 
189
  constant regs_init : regs_type := (
190 37 wfjm
    s_init,                             -- state
191 2 wfjm
    '0',                                -- ackr
192
    '0',                                -- addr0
193
    "00",                               -- be2nd
194
    (others=>'0'),                      -- cntdly
195
    (others=>'0'),                      -- cntce
196
    '0',                                -- fidle
197
    (others=>'0'),                      -- memdo0
198
    (others=>'0')                       -- memdi
199
  );
200 37 wfjm
 
201
  constant c_addrh_rcr_setup : slv22 :=
202
    "000" &             -- 22:20 reserved MBZ
203
    "00"  &             -- 19:18 reg sel 00=RCR
204
    "0000000000"  &     -- 17: 8 reserved MBZ
205
    '1' &               --     7 page mode enable (1=enable)
206
    "00" &              --  6: 5 reserved MBZ
207
    '1' &               --     4 dpd disaable (1=disable)
208
    "000";              --  3: 1 rest is reserved or PAR, which should be 0
209
 
210 36 wfjm
  signal R_REGS : regs_type := regs_init;
211
  signal N_REGS : regs_type;            -- don't init (vivado fix for fsm infer)
212 2 wfjm
 
213
  signal CLK_180  : slbit := '0';
214
  signal MEM_CE_N : slbit := '1';
215
  signal MEM_BE_N : slv2  := "11";
216
  signal MEM_WE_N : slbit := '1';
217
  signal MEM_OE_N : slbit := '1';
218 37 wfjm
  signal MEM_CRE  : slbit := '0';
219 2 wfjm
  signal BE_CE    : slbit := '0';
220
  signal ADDRH_CE : slbit := '0';
221
  signal ADDR0_CE : slbit := '0';
222 37 wfjm
  signal ADDRH    : slv22 := (others=>'0');
223 2 wfjm
  signal ADDR0    : slbit := '0';
224
  signal DATA_CEI : slbit := '0';
225
  signal DATA_CEO : slbit := '0';
226
  signal DATA_OE  : slbit := '0';
227
  signal MEM_DO   : slv16 := (others=>'0');
228
  signal MEM_DI   : slv16 := (others=>'0');
229
 
230
begin
231
 
232 37 wfjm
  -- Notes:
233
  --   used READ0DELAY-2 and READ0DELAY-3
234
  --   used READ1DELAY-2
235
  --   used WRITEDELAY-2
236
 
237
  assert READ0DELAY-2 < 2**R_REGS.cntdly'length and
238
         READ1DELAY-2 < 2**R_REGS.cntdly'length and
239
         WRITEDELAY-2 < 2**R_REGS.cntdly'length
240
    report "assert( (READ0,READ1,WRITE)DELAY-2 < 2**cntdly'length)"
241 8 wfjm
    severity failure;
242 37 wfjm
  assert READ0DELAY >= 3 and
243
         READ1DELAY >= 2 and
244
         WRITEDELAY >= 2
245
    report "assert( (READ0,READ1,WRITE)DELAY-2 >= 2 or 3)"
246
    severity failure;
247 8 wfjm
 
248 2 wfjm
  CLK_180 <= not CLK;
249
 
250
  IOB_MEM_CE : iob_reg_o
251
    generic map (
252
      INIT   => '1')
253
    port map (
254
      CLK => CLK,
255
      CE  => '1',
256
      DO  => MEM_CE_N,
257
      PAD => O_MEM_CE_N
258
    );
259
 
260
  IOB_MEM_BE : iob_reg_o_gen
261
    generic map (
262
      DWIDTH => 2,
263
      INIT   => '1')
264
    port map (
265
      CLK => CLK,
266
      CE  => BE_CE,
267
      DO  => MEM_BE_N,
268
      PAD => O_MEM_BE_N
269
    );
270
 
271
  IOB_MEM_WE : iob_reg_o
272
    generic map (
273
      INIT   => '1')
274
    port map (
275
      CLK => CLK_180,
276
      CE  => '1',
277
      DO  => MEM_WE_N,
278
      PAD => O_MEM_WE_N
279
    );
280
 
281
  IOB_MEM_OE : iob_reg_o
282
    generic map (
283
      INIT   => '1')
284
    port map (
285
      CLK => CLK,
286
      CE  => '1',
287
      DO  => MEM_OE_N,
288
      PAD => O_MEM_OE_N
289
    );
290
 
291 37 wfjm
  IOB_MEM_CRE : iob_reg_o
292
    generic map (
293
      INIT   => '0')
294
    port map (
295
      CLK => CLK,
296
      CE  => '1',
297
      DO  => MEM_CRE,
298
      PAD => O_MEM_CRE
299
    );
300
 
301 2 wfjm
  IOB_MEM_ADDRH : iob_reg_o_gen
302
    generic map (
303
      DWIDTH => 22)
304
    port map (
305
      CLK => CLK,
306
      CE  => ADDRH_CE,
307 37 wfjm
      DO  => ADDRH,
308 2 wfjm
      PAD => O_MEM_ADDR(22 downto 1)
309
    );
310
 
311
  IOB_MEM_ADDR0 : iob_reg_o
312
    port map (
313
      CLK => CLK,
314
      CE  => ADDR0_CE,
315
      DO  => ADDR0,
316
      PAD => O_MEM_ADDR(0)
317
    );
318
 
319
  IOB_MEM_DATA : iob_reg_io_gen
320
    generic map (
321
      DWIDTH => 16,
322 37 wfjm
      PULL   => "NONE")
323 2 wfjm
    port map (
324
      CLK => CLK,
325
      CEI => DATA_CEI,
326
      CEO => DATA_CEO,
327
      OE  => DATA_OE,
328
      DI  => MEM_DO,
329
      DO  => MEM_DI,
330
      PAD => IO_MEM_DATA
331
    );
332
 
333
  O_MEM_ADV_N <= '0';
334
  O_MEM_CLK   <= '0';
335
 
336
  proc_regs: process (CLK)
337
  begin
338
 
339 13 wfjm
    if rising_edge(CLK) then
340 2 wfjm
      if RESET = '1' then
341
        R_REGS <= regs_init;
342
      else
343
        R_REGS <= N_REGS;
344
      end if;
345
    end if;
346
 
347
  end process proc_regs;
348
 
349 37 wfjm
  proc_next: process (R_REGS, REQ, WE, BE, DI, ADDR, MEM_DO)
350 2 wfjm
 
351
    variable r : regs_type := regs_init;
352
    variable n : regs_type := regs_init;
353
    variable ibusy : slbit := '0';
354
    variable iackw : slbit := '0';
355
    variable iactr : slbit := '0';
356
    variable iactw : slbit := '0';
357 37 wfjm
    variable imem_ce   : slbit := '0';
358
    variable imem_be   : slv2  := "00";
359
    variable imem_we   : slbit := '0';
360
    variable imem_oe   : slbit := '0';
361
    variable imem_cre  : slbit := '0';
362 2 wfjm
    variable ibe_ce    : slbit := '0';
363
    variable iaddrh_ce : slbit := '0';
364
    variable iaddr0_ce : slbit := '0';
365 37 wfjm
    variable iaddrh    : slv22 := (others=>'0');
366 2 wfjm
    variable iaddr0    : slbit := '0';
367
    variable idata_cei : slbit := '0';
368
    variable idata_ceo : slbit := '0';
369
    variable idata_oe  : slbit := '0';
370
 
371
    procedure do_dispatch(nstate  : out state_type;
372
                          iaddrh_ce : out slbit;
373
                          iaddr0_ce : out slbit;
374
                          iaddr0  : out slbit;
375
                          ibe_ce  : out slbit;
376
                          imem_be : out slv2;
377
                          imem_ce : out slbit;
378
                          imem_oe : out slbit;
379
                          nbe2nd  : out slv2) is
380
    begin
381
      iaddrh_ce := '1';                 -- latch address (high part)
382
      iaddr0_ce := '1';                 -- latch address 0 bit
383
      ibe_ce    := '1';                 -- latch be's
384
      imem_ce   := '1';                 -- ce CRAM next cycle
385
      nbe2nd    := "00";                -- assume no 2nd write cycle
386
      if WE = '0' then                  -- if READ requested
387
        iaddr0  := '0';                   -- go first for low word
388
        imem_be := "11";                  -- on read always on
389
        imem_oe := '1';                   -- oe CRAM next cycle
390
        nstate  := s_rdinit;              -- next: read init part
391
      else                              -- if WRITE requested
392
        if BE(1 downto 0) /= "00" then    -- low word write
393
          iaddr0  := '0';                   -- access word 0 
394
          imem_be := BE(1 downto 0);        -- set be's for 1st cycle
395
          nbe2nd  := BE(3 downto 2);        -- keep be's for 2nd cycle
396
        else                              -- high word write
397
          iaddr0  := '1';                   -- access word 1 
398
          imem_be := BE(3 downto 2);        -- set be's for 1st cycle
399
        end if;
400 34 wfjm
        imem_oe := '0';                   -- oe=0
401 2 wfjm
        nstate := s_wrinit;               -- next: write init part
402
      end if;
403
    end procedure do_dispatch;
404
 
405
  begin
406
 
407
    r := R_REGS;
408
    n := R_REGS;
409
    n.ackr := '0';
410
 
411
    ibusy := '0';
412
    iackw := '0';
413
    iactr := '0';
414
    iactw := '0';
415
 
416 37 wfjm
    imem_ce   := '0';
417
    imem_be   := "11";
418
    imem_we   := '0';
419
    imem_oe   := '0';
420
    imem_cre  := '0';
421 2 wfjm
    ibe_ce    := '0';
422
    iaddrh_ce := '0';
423
    iaddr0_ce := '0';
424 37 wfjm
    iaddrh    := ADDR;
425 2 wfjm
    iaddr0    := '0';
426
    idata_cei := '0';
427
    idata_ceo := '0';
428
    idata_oe  := '0';
429
 
430
    if unsigned(r.cntdly) /= 0 then
431 13 wfjm
      n.cntdly := slv(unsigned(r.cntdly) - 1);
432 2 wfjm
    end if;
433 34 wfjm
 
434 2 wfjm
    case r.state is
435 37 wfjm
      when s_init =>                    -- s_init: startup state
436
        ibusy   := '1';                   -- signal busy, unable to handle req
437
        n.state := s_init1;
438
 
439
      when s_init1 =>                   -- s_init1: reset released
440
        ibusy   := '1';                   -- signal busy, unable to handle req
441
        iaddrh  := c_addrh_rcr_setup;
442
        iaddr0  := '0';
443
        iaddrh_ce := '1';
444
        iaddr0_ce := '1';
445
        imem_ce  := '1';                  -- ce  CRAM next cycle
446
        imem_cre := '1';                  -- cre CRAM next cycle
447
        n.state := s_wcinit;
448
 
449
      when s_wcinit =>                  -- s_wcinit: write rcr init
450
        ibusy    := '1';                  -- signal busy, unable to handle req
451
        imem_ce  := '1';                  -- ce  CRAM next cycle
452
        imem_cre := '1';                  -- cre CRAM next cycle
453
        imem_we  := '1';                  -- we  CRAM next cycle
454
        n.cntdly := slv(to_unsigned(WRITEDELAY-2, n.cntdly'length));
455
        n.state  := s_wcwait;
456
 
457
      when s_wcwait =>                  -- s_wcinit: write rcr wait
458
        ibusy    := '1';                  -- signal busy, unable to handle req
459
        imem_ce  := '1';                  -- ce  CRAM next cycle
460
        imem_we  := '1';                  -- we  CRAM next cycle
461
        imem_cre := '1';                  -- cre CRAM next cycle
462
        if unsigned(r.cntdly) = 0 then    -- wait expired ?
463
          n.state := s_wcput;             -- next: write rcr done
464
        end if;
465
 
466
      when s_wcput =>                   -- s_wcput: write rcr done
467
        ibusy    := '1';                  -- signal busy, unable to handle req
468
        n.state  := s_rainit;             -- next: read array init
469
 
470
      when s_rainit =>                  -- s_rainit: read array init
471
        ibusy   := '1';                   -- signal busy, unable to handle req
472
        imem_ce := '1';                   -- ce CRAM next cycle
473
        n.cntdly:= slv(to_unsigned(READ0DELAY-2, n.cntdly'length));
474
        n.state := s_rawait ;             -- next: wait read array
475
 
476
      when s_rawait =>                  -- s_rawait: wait read array
477
        ibusy   := '1';                   -- signal busy, unable to handle req
478
        imem_ce := '1';                   -- ce CRAM next cycle
479
        if unsigned(r.cntdly) = 0 then    -- wait expired ?
480
          n.state := s_idle;              -- next: wait for req
481
        end if;
482
 
483 2 wfjm
      when s_idle =>                    -- s_idle: wait for req
484
        if REQ = '1' then                 -- if IO requested
485
          do_dispatch(n.state, iaddrh_ce, iaddr0_ce, iaddr0,
486
                               ibe_ce, imem_be, imem_ce, imem_oe, n.be2nd);
487
        end if;
488
 
489
      when s_rdinit =>                  -- s_rdinit:  read init cycle
490
        ibusy   := '1';                   -- signal busy, unable to handle req
491
        iactr   := '1';                   -- signal mem read
492
        imem_ce := '1';                   -- ce CRAM next cycle
493
        imem_oe := '1';                   -- oe CRAM next cycle
494 37 wfjm
        n.cntdly:= slv(to_unsigned(READ0DELAY-3, n.cntdly'length));
495
        n.state := s_rdwait0;             -- next: wait low word
496 2 wfjm
 
497
      when s_rdwait0 =>                  -- s_rdwait0: read wait low word
498
        ibusy   := '1';                   -- signal busy, unable to handle req
499
        iactr   := '1';                   -- signal mem read
500
        imem_ce := '1';                   -- ce CRAM next cycle
501
        imem_oe := '1';                   -- oe CRAM next cycle
502
        if unsigned(r.cntdly) = 0 then    -- wait expired ?
503
          n.state := s_rdget0;              -- next: get low word
504
        end if;
505
 
506
      when s_rdget0 =>                  -- s_rdget0: read get low word
507
        ibusy   := '1';                   -- signal busy, unable to handle req
508
        iactr   := '1';                   -- signal mem read
509
        imem_ce := '1';                   -- ce CRAM next cycle
510
        imem_oe := '1';                   -- oe CRAM next cycle
511
        idata_cei := '1';                 -- latch input data
512
        iaddr0_ce := '1';                 -- latch address 0 bit
513
        iaddr0    := '1';                 -- now go for high word
514 37 wfjm
        n.cntdly:= slv(to_unsigned(READ1DELAY-2, n.cntdly'length));
515 2 wfjm
        n.state := s_rdwait1;             -- next: wait high word
516
 
517
      when s_rdwait1 =>                 -- s_rdwait1: read wait high word
518
        ibusy   := '1';                   -- signal busy, unable to handle req
519
        iactr   := '1';                   -- signal mem read
520
        imem_ce := '1';                   -- ce CRAM next cycle
521
        imem_oe := '1';                   -- oe CRAM next cycle
522
        if unsigned(r.cntdly) = 0 then    -- wait expired ?
523 37 wfjm
          n.state := s_rdget1;              -- next: get high word
524 2 wfjm
        end if;                             --
525
 
526
      when s_rdget1 =>                  -- s_rdget1: read get high word
527
        iactr   := '1';                   -- signal mem read
528
        n.memdo0:= MEM_DO;                -- save low word data
529
        idata_cei := '1';                 -- latch input data
530
        n.ackr  := '1';                   -- ACK_R next cycle
531
        n.state := s_idle;                -- next: wait next request
532
        if r.fidle = '1' then             -- forced idle cycle
533
          ibusy   := '1';                   -- signal busy, unable to handle req
534
        else
535
          if REQ = '1' then                 -- if IO requested            
536
            do_dispatch(n.state, iaddrh_ce, iaddr0_ce, iaddr0,
537
                                 ibe_ce, imem_be, imem_ce, imem_oe, n.be2nd);
538
          end if;
539
        end if;
540
 
541
      when s_wrinit =>                  -- s_wrinit:  write init cycle
542
        ibusy := '1';                     -- signal busy, unable to handle req
543
        iactw := '1';                     -- signal mem write
544
        iackw := '1';                     -- signal write done (all latched)
545
        idata_ceo:= '1';                  -- latch output data
546
        idata_oe := '1';                  -- oe FPGA next cycle
547
        imem_ce  := '1';                  -- ce CRAM next cycle
548
        imem_we  := '1';                  -- we CRAM in half cycle
549 37 wfjm
        n.cntdly:= slv(to_unsigned(WRITEDELAY-2, n.cntdly'length));
550 2 wfjm
        n.state := s_wrwait0;             -- next: wait
551
 
552
      when s_wrwait0 =>                 -- s_rdput0:  write wait 1st word
553
        ibusy := '1';                     -- signal busy, unable to handle req
554
        iactw := '1';                     -- signal mem write
555
        idata_oe := '1';                  -- oe FPGA next cycle
556
        imem_ce  := '1';                  -- ce CRAM next cycle
557
        imem_we  := '1';                  -- we CRAM next cycle
558
        if unsigned(r.cntdly) = 0 then    -- wait expired ?
559
          n.state := s_wrput0;            -- next: put 1st word
560
        end if;
561
 
562
      when s_wrput0 =>                  -- s_rdput0:  write put 1st word
563
        iactw := '1';                     -- signal mem write
564
        imem_we  := '0';                  -- deassert we CRAM in half cycle
565
        if r.be2nd /= "00" then
566
          ibusy := '1';                     -- signal busy, unable to handle req
567
          imem_ce  := '1';                  -- ce CRAM next cycle
568
          iaddr0_ce := '1';                 -- latch address 0 bit
569
          iaddr0    := '1';                 -- now go for high word
570
          ibe_ce    := '1';                 -- latch be's
571
          imem_be   := r.be2nd;             -- now be's of high word
572
          n.state := s_wrini1;              -- next: start 2nd write
573
        else
574
          n.state := s_idle;                -- next: wait next request
575
          if r.fidle = '1' then             -- forced idle cycle
576
            ibusy   := '1';                   -- signal busy
577
          else
578
            if REQ = '1' then                 -- if IO requested            
579
              do_dispatch(n.state, iaddrh_ce, iaddr0_ce, iaddr0,
580
                                   ibe_ce, imem_be, imem_ce, imem_oe, n.be2nd);
581
            end if;
582
          end if;
583
        end if;
584
 
585
      when s_wrini1 =>                  -- s_wrini1:  write init 2nd word
586
        ibusy := '1';                     -- signal busy, unable to handle req
587
        iactw := '1';                     -- signal mem write
588
        idata_ceo:= '1';                  -- latch output data
589
        idata_oe := '1';                  -- oe FPGA next cycle
590
        imem_ce  := '1';                  -- ce CRAM next cycle
591
        imem_we  := '1';                  -- we CRAM in half cycle
592 37 wfjm
        n.cntdly:= slv(to_unsigned(WRITEDELAY-2, n.cntdly'length));
593 2 wfjm
        n.state := s_wrwait1;             -- next: wait
594
 
595
      when s_wrwait1 =>                 -- s_wrwait1: write wait 2nd word
596
        ibusy := '1';                     -- signal busy, unable to handle req
597
        iactw := '1';                     -- signal mem write
598
        idata_oe := '1';                  -- oe FPGA next cycle
599
        imem_ce  := '1';                  -- ce CRAM next cycle
600
        imem_we  := '1';                  -- we CRAM next cycle
601
        if unsigned(r.cntdly) = 0 then    -- wait expired ?
602
          n.state := s_wrput1;            -- next: put 2nd word
603
        end if;
604
 
605
      when s_wrput1 =>                  -- s_wrput1:  write put 2nd word
606
        iactw := '1';                     -- signal mem write
607
        imem_we  := '0';                  -- deassert we CRAM in half cycle
608
        n.state := s_idle;                -- next: wait next request
609
        if r.fidle = '1' then             -- forced idle cycle
610
          ibusy   := '1';                   -- signal busy, unable to handle req
611
        else
612
          if REQ = '1' then                 -- if IO requested            
613
            do_dispatch(n.state, iaddrh_ce, iaddr0_ce, iaddr0,
614
                                 ibe_ce, imem_be, imem_ce, imem_oe, n.be2nd);
615
          end if;
616
        end if;
617
 
618
      when others => null;
619
    end case;
620
 
621
    if imem_ce = '0' then               -- if cmem not active
622
      n.cntce := (others=>'0');           -- clear counter 
623
      n.fidle := '0';                     -- clear force idle flag
624
    else                                -- if cmem active
625
      if unsigned(r.cntce) >= 127 then    -- if max ce count expired
626
        n.fidle := '1';                     -- set forced idle flag
627
      else                                -- if max ce count not yet reached
628 13 wfjm
        n.cntce := slv(unsigned(r.cntce) + 1);   -- increment counter
629 2 wfjm
      end if;
630
    end if;
631
 
632
    if iaddrh_ce = '1' then             -- if addresses are latched
633
      n.memdi := DI;                      -- latch data too...
634
    end if;
635
 
636
    if iaddr0_ce = '1' then             -- if address bit 0 changed
637
      n.addr0 := iaddr0;                  -- mirror it in state regs
638
    end if;
639
 
640
    N_REGS <= n;
641
 
642
    MEM_CE_N <= not imem_ce;
643
    MEM_WE_N <= not imem_we;
644
    MEM_BE_N <= not imem_be;
645
    MEM_OE_N <= not imem_oe;
646 37 wfjm
    MEM_CRE  <=     imem_cre;
647 2 wfjm
 
648
    if r.addr0 = '0' then
649
      MEM_DI <= r.memdi(15 downto 0);
650
    else
651
      MEM_DI <= r.memdi(31 downto 16);
652
    end if;
653
 
654
    BE_CE    <= ibe_ce;
655
    ADDRH_CE <= iaddrh_ce;
656
    ADDR0_CE <= iaddr0_ce;
657 37 wfjm
    ADDRH    <= iaddrh;
658 2 wfjm
    ADDR0    <= iaddr0;
659
    DATA_CEI <= idata_cei;
660
    DATA_CEO <= idata_ceo;
661
    DATA_OE  <= idata_oe;
662
 
663
    BUSY  <= ibusy;
664
    ACK_R <= r.ackr;
665
    ACK_W <= iackw;
666
    ACT_R <= iactr;
667
    ACT_W <= iactw;
668
 
669
    DO    <= MEM_DO & r.memdo0;
670
 
671
  end process proc_next;
672
 
673
end syn;

powered by: WebSVN 2.1.0

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