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