1 --------------------------------------------------------------------------
2 --
3 -- Copyright (C) 1993, Peter J. Ashenden
4 -- Mail: Dept. Computer Science
5 -- University of Adelaide, SA 5005, Australia
6 -- e-mail: petera@cs.adelaide.edu.au
7 --
8 -- This program is free software; you can redistribute it and/or modify
9 -- it under the terms of the GNU General Public License as published by
10 -- the Free Software Foundation; either version 1, or (at your option)
11 -- any later version.
12 --
13 -- This program is distributed in the hope that it will be useful,
14 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
15 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 -- GNU General Public License for more details.
17 --
18 -- You should have received a copy of the GNU General Public License
19 -- along with this program; if not, write to the Free Software
20 -- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 --
22 --------------------------------------------------------------------------
23 --
24 -- $RCSfile: memory-behaviour.vhdl,v $ $Revision: 1.1 $ $Date: 2000/05/08 14:36:48 $
25 --
26 --------------------------------------------------------------------------
27 --
28 -- Behavioural architecture for memory model
29 --
30
31
32 use work.bv_arithmetic.bv_to_natural,
33 work.bv_arithmetic.natural_to_bv,
34 work.images.image_hex,
35 std.textio.all;
36
37
38 architecture behaviour of memory is
39
40 begin
41
42 mem : process
43
44 constant low_address : natural := 0;
45 constant high_address : natural := mem_size - 1;
46
47 subtype byte is bit_vector(0 to 7);
48 subtype ls_2_bits is bit_vector(1 downto 0);
49
50 type memory_array is
51 array (natural range low_address to high_address) of byte;
52
53 variable mem : memory_array;
54 variable aligned_a : dlx_address;
55 variable address : natural;
56
57 variable L : line;
58
59
60 procedure load(mem : out memory_array) is
61
62 file binary_file : text is in "dlx.out";
63 variable L : line;
64 variable addr : natural;
65 variable word : dlx_word;
66
67 procedure read_hex_natural(L : inout line; addr : out natural) is
68 variable result : natural := 0;
69 variable ch : character;
70 begin
71 for i in 1 to 8 loop
72 read(L, ch);
73 if ('0' <= ch and ch <= '9') then
74 result := result*16 + character'pos(ch) - character'pos('0');
75 else
76 result := result*16 + character'pos(ch) - character'pos('a') + 10;
77 end if;
78 end loop;
79 addr := result;
80 end read_hex_natural;
81
82 procedure read_hex_word(L : inout line; word : out dlx_word) is
83 variable result : dlx_word;
84 variable digit, r : natural := 0;
85 variable ch : character;
86 begin
87 read(L, ch); -- the space between addr and data
88 for i in 10 to 17 loop
89 read(L, ch);
90 if ('0' <= ch and ch <= '9') then
91 digit := character'pos(ch) - character'pos('0');
92 else
93 digit := character'pos(ch) - character'pos('a') + 10;
94 end if;
95 result(r to r+3) := natural_to_bv(digit, 4);
96 r := r + 4;
97 end loop;
98 word := result;
99 end read_hex_word;
100
101 begin
102 while not endfile(binary_file) loop
103 readline(binary_file, L);
104 read_hex_natural(L, addr);
105 read_hex_word(L, word);
106 --
107 write(L, addr);
108 write(L, ' ');
109 write(L, image_hex(word));
110 writeline(output, L);
111 --
112 mem(addr) := word(0 to 7);
113 mem(addr+1) := word(8 to 15);
114 mem(addr+2) := word(16 to 23);
115 mem(addr+3) := word(24 to 31);
116 end loop;
117 end load;
118
119
120 procedure do_write is
121 begin
122 --
123 -- align address to accessed unit
124 --
125 aligned_a := a;
126 case width is
127 when width_word =>
128 aligned_a(1 downto 0) := b"00";
129 when width_halfword =>
130 aligned_a(0) := '0';
131 when width_byte =>
132 null;
133 end case;
134 address := bv_to_natural(aligned_a);
135 case width is
136 when width_word =>
137 mem(address) := d(0 to 7);
138 mem(address+1) := d(8 to 15);
139 mem(address+2) := d(16 to 23);
140 mem(address+3) := d(24 to 31);
141 when width_halfword =>
142 if a(1) = '0' then -- ms half word
143 mem(address) := d(0 to 7);
144 mem(address+1) := d(8 to 15);
145 else -- ls half word
146 mem(address) := d(16 to 23);
147 mem(address+1) := d(24 to 31);
148 end if;
149 when width_byte =>
150 case ls_2_bits'(a(1 downto 0)) is
151 when b"00" =>
152 mem(address) := d(0 to 7);
153 when b"01" =>
154 mem(address) := d(8 to 15);
155 when b"10" =>
156 mem(address) := d(16 to 23);
157 when b"11" =>
158 mem(address) := d(24 to 31);
159 end case;
160 end case;
161 end do_write;
162
163 procedure do_read is
164 begin
165 aligned_a := a;
166 aligned_a(1 downto 0) := b"00";
167 address := bv_to_natural(aligned_a);
168 d <= mem(address) & mem(address+1) & mem(address+2) & mem(address+3);
169 end do_read;
170
171
172 procedure disp_snapshot
173 is
174 variable l : line;
175 begin
176 for i in 0 to 15 loop
177 write (l, i);
178 write (l, string'(": "));
179 write (l, image_hex (mem (i)));
180 writeline (output, l);
181 end loop;
182 end disp_snapshot;
183
184 begin
185 load(mem);
186
187 --disp_snapshot;
188
189 -- initialize outputs
190 --
191 d <= null;
192 ready <= '0';
193 --
194 -- process memory cycles
195 --
196 loop
197 --
198 -- wait for a command, valid on leading edge of phi2
199 --
200 wait until phi2 = '1' and mem_enable = '1';
201 --
202 -- decode address and perform command if selected
203 --
204 address := bv_to_natural(a);
205 if address >= low_address and address <= high_address then
206 if write_enable = '1' then -- write cycle
207 do_write;
208 wait for Tac1; -- write access time, 1st cycle
209 else -- read cycle
210 wait for Tac1; -- read access time, 1st cycle
211 do_read;
212 end if;
213 -- ready synchronous with phi2
214 wait until phi2 = '1';
215 ready <= '1' after Tpd_clk_out;
216 wait until phi2 = '0';
217 ready <= '0' after Tpd_clk_out;
218 -- do subsequent cycles in burst
219 while burst = '1' loop
220 wait until phi2 = '1';
221 if write_enable = '1' then -- write cycle
222 do_write;
223 wait for Tacb; -- write access time, burst cycle
224 else -- read cycle
225 wait for Tacb; -- read access time, burst cycle
226 do_read;
227 end if;
228 -- ready synchronous with phi2
229 wait until phi2 = '1';
230 ready <= '1' after Tpd_clk_out;
231 wait until phi2 = '0';
232 ready <= '0' after Tpd_clk_out;
233 end loop;
234 if write_enable = '0' then -- was read
235 d <= null after Tpd_clk_out;
236 end if;
237 end if;
238 end loop;
239 end process;
240
241 end behaviour;
242
This page was generated using GHDL 0.14 (20040829) [Sokcho edition], a program written by Tristan Gingold