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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.74/] [rtl/] [bplib/] [micron/] [mt45w8mw16b.vhd] - Blame information for rev 34

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

Line No. Rev Author Line
1 34 wfjm
-- $Id: mt45w8mw16b.vhd 718 2015-12-26 15:59:48Z mueller $
2 2 wfjm
--
3 34 wfjm
-- Copyright 2010-2015 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:    mt45w8mw16b - sim
16
-- Description:    Micron MT45W8MW16B CellularRAM model
17
--                 Currently a much simplified model
18
--                 - only async accesses
19
--                 - ignores CLK and CRE
20
--                 - simple model for response of DATA lines, but no
21
--                   check for timing violations of control lines
22
--
23
-- Dependencies:   -
24
-- Test bench:     -
25
-- Target Devices: generic
26 29 wfjm
-- Tool versions:  xst 11.4-14.7; ghdl 0.26-0.31
27 2 wfjm
-- Revision History: 
28
-- Date         Rev Version  Comment
29 34 wfjm
-- 2015-12-26   718   1.3.3  BUGFIX: initialize L_ADDR with all '1', see comment
30 13 wfjm
-- 2011-11-19   427   1.3.2  now numeric_std clean
31 2 wfjm
-- 2010-06-03   299   1.3.1  improved timing model (WE cycle, robust T_apa)
32
-- 2010-06-03   298   1.3    add timing model again
33
-- 2010-05-28   295   1.2    drop timing (was incorrect), pure functional now
34
-- 2010-05-21   293   1.1    add BCR (only read of default so far)
35
-- 2010-05-16   291   1.0    Initial version (inspired by is61lv25616al)
36
------------------------------------------------------------------------------
37
-- Truth table accoring to data sheet:
38
--  
39
-- Asynchronous Mode (BCR(15)=1)
40
--   Operation               CLK ADV_N CE_N OE_N WE_N CRE xB_N WT  DATA
41
--   Read                     L     L    L    L    H   L    L  act data-out
42
--   Write                    L     L    L    X    L   L    L  act data-in
43
--   Standby                  L     X    H    X    X   L    X  'z' 'z'
44
--   CRE write                L     L    L    H    L   H    X  act 'z'
45
--   CRE read                 L     L    L    L    H   H    L  act conf-out
46
--
47
-- Burst Mode (BCR(15)=0)
48
--   Operation               CLK ADV_N CE_N OE_N WE_N CRE xB_N WT  DATA
49
--   Async read               L     L    L    L    H   L    L  act data-out
50
--   Async write              L     L    L    X    L   L    L  act data-in 
51
--   Standby                  L     X    H    X    X   L    X  'z' 'z'
52
--   Initial burst read      0-1    L    L    X    H   L    L  act  X
53
--   Initial burst write     0-1    L    L    H    L   L    X  act  X
54
--   Burst continue          0-1    H    L    X    X   X    X  act data-in/out
55
--   CRE write               0-1    L    L    H    L   H    X  act 'z'
56
--   CRE read                0-1    L    L    L    H   H    L  act conf-out
57
--
58
 
59
library ieee;
60
use ieee.std_logic_1164.all;
61 13 wfjm
use ieee.numeric_std.all;
62 2 wfjm
 
63
use work.slvtypes.all;
64
 
65
entity mt45w8mw16b is                   -- Micron MT45W8MW16B CellularRAM model
66
  port (
67
    CLK : in slbit;                     -- clock for synchonous operation
68
    CE_N : in slbit;                    -- chip enable        (act.low)
69
    OE_N : in slbit;                    -- output enable      (act.low)
70
    WE_N : in slbit;                    -- write enable       (act.low)
71
    UB_N : in slbit;                    -- upper byte enable  (act.low)
72
    LB_N : in slbit;                    -- lower byte enable  (act.low)
73
    ADV_N : in slbit;                   -- address valid      (act.low)
74
    CRE : in slbit;                     -- control register enable
75
    MWAIT : out slbit;                  -- wait (for burst read/write)
76
    ADDR : in slv23;                    -- address lines
77
    DATA : inout slv16                  -- data lines
78
  );
79
end mt45w8mw16b;
80
 
81
 
82
architecture sim of mt45w8mw16b is
83
 
84
  -- timing constants for -701 speed grade (70 ns; 104 MHz)
85
  constant T_aa   : time := 70 ns;      -- address access time             (max)
86
  constant T_apa  : time := 20 ns;      -- page acess time                 (max)
87
  constant T_oh   : time :=  5 ns;      -- output hold from addr change    (max)
88
  constant T_oe   : time := 20 ns;      -- output enable to valid output   (max)
89
  constant T_ohz  : time :=  8 ns;      -- output disable to high-z output (max)
90
  constant T_olz  : time :=  3 ns;      -- output enable to low-z output   (min)
91
  constant T_lz   : time := 10 ns;      -- chip enable to low-z output     (min)
92
  constant T_hz   : time :=  8 ns;      -- chip disable to high-z output   (max)
93
 
94
  constant memsize : positive := 2**(ADDR'length);
95
  constant datzero : slv(DATA'range) := (others=>'0');
96
  type ram_type is array (0 to memsize-1) of slv(DATA'range);
97
 
98
  constant bcr_f_mode   : integer := 15;              -- operating mode 
99
  constant bcr_f_ilat   : integer := 14;              -- initial latency
100
  subtype  bcr_f_lc    is integer range 13 downto 11; -- latency counter
101
  constant bcr_f_wp     : integer := 10;              -- wait polarity
102
  constant bcr_f_wc     : integer :=  8;              -- wait configuration
103
  subtype  bcr_f_drive is integer range  5 downto  4; -- drive strength
104
  constant bcr_f_bw     : integer :=  3;              -- burst wrap
105
  subtype  bcr_f_bl    is integer range  2 downto  0; -- burst length
106
 
107
  subtype  f_byte1       is integer range 15 downto 8;
108
  subtype  f_byte0       is integer range  7 downto 0;
109
 
110
  signal CE : slbit := '0';
111
  signal OE : slbit := '0';
112
  signal WE : slbit := '0';
113
  signal BE_L : slbit := '0';
114
  signal BE_U : slbit := '0';
115
  signal ADV : slbit := '0';
116
  signal WE_L_EFF : slbit := '0';
117
  signal WE_U_EFF : slbit := '0';
118
 
119
  signal R_BCR_MODE  : slbit := '1';    -- mode: def: async
120
  signal R_BCR_ILAT  : slbit := '0';    -- ilat: def: variable
121
  signal R_BCR_LC    : slv3  := "011";  -- lc:   def: code 3
122
  signal R_BCR_WP    : slbit := '1';    -- wp:   def: active high
123
  signal R_BCR_WC    : slbit := '1';    -- wc:   def: assert one before
124
  signal R_BCR_DRIVE : slv2  := "01";   -- drive:def: 1/2
125
  signal R_BCR_BW    : slbit := '1';    -- bw:   def: no wrap
126
  signal R_BCR_BL    : slv3  := "111";  -- bl:   def: continuous
127
 
128 34 wfjm
  signal L_ADDR : slv23 := (others=>'1'); -- all '1' for propper 1st access
129 2 wfjm
  signal DOUT_VAL_EN : slbit := '0';
130
  signal DOUT_VAL_AA : slbit := '0';
131
  signal DOUT_VAL_PA : slbit := '0';
132
  signal DOUT_VAL_OE : slbit := '0';
133
  signal DOUT_LZ_CE  : slbit := '0';
134
  signal DOUT_LZ_OE  : slbit := '0';
135
 
136
  signal OEWE : slbit := '0';
137
  signal DOUT : slv16 := (others=>'0');
138
begin
139
 
140
  CE   <= not CE_N;
141
  OE   <= not OE_N;
142
  WE   <= not WE_N;
143
  BE_L <= not LB_N;
144
  BE_U <= not UB_N;
145
  ADV  <= not ADV_N;
146
 
147
  WE_L_EFF <= CE and WE and BE_L;
148
  WE_U_EFF <= CE and WE and BE_U;
149
 
150
  -- address valid logic, latch ADDR when ADV true
151
  proc_adv: process (ADV, ADDR)
152
  begin
153
    if ADV = '1' then
154
      L_ADDR <= ADDR;
155
    end if;
156
  end process proc_adv;
157
 
158 34 wfjm
  -- Notes:
159
  --  1. the row change (t_aa) and column change (t_apa) timing depends on the
160
  --     recognition of address changes and of page changes. To keep the logic
161
  --     simple L_ADDR and addr_last are initialized with all '1'. This gives
162
  --     proper behaviour unless the very first access uses the very last
163
  --     address. In w11a systems, with use only 4 MB, this can't happen, in
164
  --     most other use cases this is very unlikely.
165
 
166 2 wfjm
  proc_dout_val: process (CE, OE, WE, BE_L, BE_U, ADV, L_ADDR)
167 34 wfjm
    variable addr_last : slv23 := (others=>'1');-- all '1' for propper 1st access
168 2 wfjm
  begin
169
    if (CE'event   and CE='1') or
170
       (BE_L'event and BE_L='1') or
171
       (BE_U'event and BE_U='1') or
172
       (WE'event   and WE='0') or
173
       (ADV'event  and ADV='1') then
174
      DOUT_VAL_EN <= '0', '1' after T_aa;
175
    end if;
176
    if L_ADDR'event then
177
      DOUT_VAL_PA <= '0', '1' after T_apa;
178
      if L_ADDR(22 downto 4) /= addr_last(22 downto 4) then
179
        DOUT_VAL_AA <= '0', '1' after T_aa;
180
      end if;
181
      addr_last := L_ADDR;
182
    end if;
183 13 wfjm
    if rising_edge(OE) then
184 2 wfjm
      DOUT_VAL_OE <= '0', '1' after T_oe;
185
    end if;
186
  end process proc_dout_val;
187
 
188
  -- to simplify things assume that OE and (not WE) have same effect on output
189
  -- drivers. The timing rules are very similar indeed...
190
  OEWE <= OE and (not WE);
191
 
192
  proc_dout_lz: process (CE, OEWE)
193
  begin
194
    if (CE'event) then
195
      if CE = '1' then
196
        DOUT_LZ_CE <= '1' after T_lz;
197
      else
198
        DOUT_LZ_CE <= '0' after T_hz;
199
      end if;
200
    end if;
201
    if (OEwe'event) then
202
      if OEWE = '1' then
203
        DOUT_LZ_OE <= '1' after T_olz;
204
      else
205
        DOUT_LZ_OE <= '0' after T_ohz;
206
      end if;
207
    end if;
208
  end process proc_dout_lz;
209
 
210
  proc_cram: process (CE, OE, WE, WE_L_EFF, WE_U_EFF, L_ADDR, DATA)
211
    variable ram : ram_type := (others=>datzero);
212
  begin
213
 
214
    -- end of write cycle
215
    -- note: to_x01 used below to prevent that 'z' a written into mem.
216 13 wfjm
    if falling_edge(WE_L_EFF) then
217
      ram(to_integer(unsigned(L_ADDR)))(f_byte0) := to_x01(DATA(f_byte0));
218 2 wfjm
    end if;
219 13 wfjm
    if falling_edge(WE_U_EFF) then
220
      ram(to_integer(unsigned(L_ADDR)))(f_byte1) := to_x01(DATA(f_byte1));
221 2 wfjm
    end if;
222
 
223 13 wfjm
    DOUT <= ram(to_integer(unsigned(L_ADDR)));
224 2 wfjm
 
225
  end process proc_cram;
226
 
227
  proc_data: process (DOUT, DOUT_VAL_EN, DOUT_VAL_AA, DOUT_VAL_PA, DOUT_VAL_OE,
228
                      DOUT_LZ_CE, DOUT_LZ_OE)
229
    variable idout : slv16 := (others=>'0');
230
  begin
231
    idout := DOUT;
232
    if DOUT_VAL_EN='0' or DOUT_VAL_AA='0' or
233
       DOUT_VAL_PA='0' or DOUT_VAL_OE='0' then
234
      idout := (others=>'X');
235
    end if;
236
    if DOUT_LZ_CE='0' or DOUT_LZ_OE='0' then
237
      idout := (others=>'Z');
238
    end if;
239
    DATA <= idout;
240
  end process proc_data;
241
 
242
  proc_mwait: process (CE)
243
  begin
244
    -- WT driver (just a dummy)
245
    if CE = '1' then
246
      MWAIT <= '1';
247
    else
248
      MWAIT <= 'Z';
249
    end if;
250
  end process proc_mwait;
251
 
252
end sim;

powered by: WebSVN 2.1.0

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