w11 - vhd 0.794
W11 CPU core and support modules
Loading...
Searching...
No Matches
s3_sram_memctl.vhd
Go to the documentation of this file.
1-- $Id: s3_sram_memctl.vhd 1181 2019-07-08 17:00:50Z mueller $
2-- SPDX-License-Identifier: GPL-3.0-or-later
3-- Copyright 2007-2017 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4--
5------------------------------------------------------------------------------
6-- Module Name: s3_sram_memctl - syn
7-- Description: s3board: SRAM controller
8--
9-- Dependencies: vlib/xlib/iob_reg_o
10-- vlib/xlib/iob_reg_o_gen
11-- vlib/xlib/iob_reg_io_gen
12-- Test bench: tb/tb_s3_sram_memctl
13-- fw_gen/tst_sram/s3board/tb/tb_tst_sram_s3
14-- Target Devices: generic
15-- Tool versions: xst 8.2-14.7; ghdl 0.18-0.31
16--
17-- Synthesized (xst):
18-- Date Rev ise Target flop lutl lutm slic t peri
19-- 2010-05-23 293 11.4 L68 xc3s1000-4 7 22 0 14 s 8.5
20-- 2008-02-16 116 8.2.03 I34 xc3s1000-4 5 30 0 17 s 7.0
21--
22-- Revision History:
23-- Date Rev Version Comment
24-- 2017-06-11 912 1.0.8 drop superfluous idata_cei=1 in s_write2
25-- 2016-07-23 793 1.0.7 drop "KEEP" for data (better for dbg)
26-- 2011-11-19 427 1.0.6 now numeric_std clean
27-- 2010-06-03 299 1.0.5 add "KEEP" for data iob;
28-- 2010-05-16 291 1.0.4 rename memctl_s3sram -> s3_sram_memctl
29-- 2008-02-17 117 1.0.3 use req,we rather req_r,req_w interface
30-- 2008-01-20 113 1.0.2 rename memdrv -> memctl_s3sram
31-- 2007-12-15 101 1.0.1 use _N for active low; get ce/we clocking right
32-- 2007-12-08 100 1.0 Initial version
33--
34-- Timing of some signals:
35--
36-- single read request:
37--
38-- state |_idle |_read |_idle |
39--
40-- CLK __|^^^|___|^^^|___|^^^|___|^
41--
42-- REQ _______|^^^^^|______________
43-- WE ____________________________
44--
45-- IOB_CE __________|^^^^^^^|_________
46-- IOB_OE __________|^^^^^^^|_________
47--
48-- DO oooooooooooooooooo|ddddddd|d
49-- BUSY ____________________________
50-- ACK_R __________________|^^^^^^^|_
51--
52-- single write request:
53--
54-- state |_idle |_write1|_write2|_idle |
55--
56-- CLK __|^^^|___|^^^|___|^^^|___|^^^|___|^
57--
58-- REQ _______|^^^^^|______________
59-- WE _______|^^^^^|______________
60--
61-- IOB_CE __________|^^^^^^^^^^^^^^^|_________
62-- IOB_BE __________|^^^^^^^^^^^^^^^|_________
63-- IOB_OE ____________________________________
64-- IOB_WE ______________|^^^^^^^|_____________
65--
66-- BUSY __________|^^^^^^^|_________________
67-- ACK_W __________________|^^^^^^^|_________
68--
69------------------------------------------------------------------------------
70
71library ieee;
72use ieee.std_logic_1164.all;
73use ieee.numeric_std.all;
74
75use work.slvtypes.all;
76use work.xlib.all;
77
78entity s3_sram_memctl is -- SRAM controller for S3BOARD
79 port (
80 CLK : in slbit; -- clock
81 RESET : in slbit; -- reset
82 REQ : in slbit; -- request
83 WE : in slbit; -- write enable
84 BUSY : out slbit; -- controller busy
85 ACK_R : out slbit; -- acknowledge read
86 ACK_W : out slbit; -- acknowledge write
87 ACT_R : out slbit; -- signal active read
88 ACT_W : out slbit; -- signal active write
89 ADDR : in slv18; -- address
90 BE : in slv4; -- byte enable
91 DI : in slv32; -- data in (memory view)
92 DO : out slv32; -- data out (memory view)
93 O_MEM_CE_N : out slv2; -- sram: chip enables (act.low)
94 O_MEM_BE_N : out slv4; -- sram: byte enables (act.low)
95 O_MEM_WE_N : out slbit; -- sram: write enable (act.low)
96 O_MEM_OE_N : out slbit; -- sram: output enable (act.low)
97 O_MEM_ADDR : out slv18; -- sram: address lines
98 IO_MEM_DATA : inout slv32 -- sram: data lines
99 );
101
102
103architecture syn of s3_sram_memctl is
104
105 type state_type is (
106 s_idle, -- s_idle: wait for req
107 s_read, -- s_read: read cycle
108 s_write1, -- s_write1: write cycle, 1st half
109 s_write2, -- s_write2: write cycle, 2nd half
110 s_bta_r2w, -- s_bta_r2w: bus turn around: r->w
111 s_bta_w2r -- s_bta_w2r: bus turn around: w->r
112 );
113
114 type regs_type is record
115 state : state_type; -- state
116 ackr : slbit; -- signal ack_r
117 end record regs_type;
118
119 constant regs_init : regs_type := (
120 s_idle, -- state
121 '0' -- ackr
122 );
123
124 signal R_REGS : regs_type := regs_init; -- state registers
125 signal N_REGS : regs_type := regs_init; -- next value state regs
126
127 signal CLK_180 : slbit := '0';
128 signal MEM_CE_N : slv2 := "00";
129 signal MEM_BE_N : slv4 := "0000";
130 signal MEM_WE_N : slbit := '0';
131 signal MEM_OE_N : slbit := '0';
132 signal ADDR_CE : slbit := '0';
133 signal DATA_CEI : slbit := '0';
134 signal DATA_CEO : slbit := '0';
135 signal DATA_OE : slbit := '0';
136
137begin
138
139 CLK_180 <= not CLK;
140
141 IOB_MEM_CE : iob_reg_o_gen
142 generic map (
143 DWIDTH => 2,
144 INIT => '1')
145 port map (
146 CLK => CLK,
147 CE => '1',
148 DO => MEM_CE_N,
149 PAD => O_MEM_CE_N
150 );
151
152 IOB_MEM_BE : iob_reg_o_gen
153 generic map (
154 DWIDTH => 4,
155 INIT => '1')
156 port map (
157 CLK => CLK,
158 CE => ADDR_CE,
159 DO => MEM_BE_N,
160 PAD => O_MEM_BE_N
161 );
162
163 IOB_MEM_WE : iob_reg_o
164 generic map (
165 INIT => '1')
166 port map (
167 CLK => CLK_180,
168 CE => '1',
169 DO => MEM_WE_N,
170 PAD => O_MEM_WE_N
171 );
172
173 IOB_MEM_OE : iob_reg_o
174 generic map (
175 INIT => '1')
176 port map (
177 CLK => CLK,
178 CE => '1',
179 DO => MEM_OE_N,
180 PAD => O_MEM_OE_N
181 );
182
183 IOB_MEM_ADDR : iob_reg_o_gen
184 generic map (
185 DWIDTH => 18)
186 port map (
187 CLK => CLK,
188 CE => ADDR_CE,
189 DO => ADDR,
190 PAD => O_MEM_ADDR
191 );
192
193 IOB_MEM_DATA : iob_reg_io_gen
194 generic map (
195 DWIDTH => 32,
196 PULL => "NONE")
197 port map (
198 CLK => CLK,
199 CEI => DATA_CEI,
200 CEO => DATA_CEO,
201 OE => DATA_OE,
202 DI => DO,
203 DO => DI,
205 );
206
207 proc_regs: process (CLK)
208 begin
209
210 if rising_edge(CLK) then
211 if RESET = '1' then
212 R_REGS <= regs_init;
213 else
214 R_REGS <= N_REGS;
215 end if;
216 end if;
217
218 end process proc_regs;
219
220 proc_next: process (R_REGS, REQ, WE, BE)
221
222 variable r : regs_type := regs_init;
223 variable n : regs_type := regs_init;
224 variable ibusy : slbit := '0';
225 variable iackw : slbit := '0';
226 variable iactr : slbit := '0';
227 variable iactw : slbit := '0';
228 variable imem_ce : slv2 := "00";
229 variable imem_be : slv4 := "0000";
230 variable imem_we : slbit := '0';
231 variable imem_oe : slbit := '0';
232 variable iaddr_ce : slbit := '0';
233 variable idata_cei : slbit := '0';
234 variable idata_ceo : slbit := '0';
235 variable idata_oe : slbit := '0';
236
237 begin
238
239 r := R_REGS;
240 n := R_REGS;
241 n.ackr := '0';
242
243 ibusy := '0';
244 iackw := '0';
245 iactr := '0';
246 iactw := '0';
247
248 imem_ce := "00";
249 imem_be := "1111";
250 imem_we := '0';
251 imem_oe := '0';
252 iaddr_ce := '0';
253 idata_cei := '0';
254 idata_ceo := '0';
255 idata_oe := '0';
256
257 case r.state is
258 when s_idle => -- s_idle: wait for req
259 if REQ = '1' then -- if IO requested
260 if WE = '0' then -- if READ requested
261 iaddr_ce := '1'; -- latch address and be's
262 imem_ce := "11"; -- ce SRAM next cycle
263 imem_oe := '1'; -- oe SRAM next cycle
264 n.state := s_read; -- next: read
265 else -- if WRITE requested
266 iaddr_ce := '1'; -- latch address and be's
267 idata_ceo := '1'; -- latch output data
268 idata_oe := '1'; -- oe FPGA next cycle
269 imem_ce := "11"; -- ce SRAM next cycle
270 imem_be := BE; -- use request BE's
271 n.state := s_write1; -- next: write 1st part
272 end if;
273 end if;
274
275 when s_read => -- s_read: read cycle
276 idata_cei := '1'; -- latch input data
277 iactr := '1'; -- signal mem read
278 n.ackr := '1'; -- ACK_R next cycle
279 if REQ = '1' then -- if IO requested
280 if WE = '0' then -- if READ requested
281 iaddr_ce := '1'; -- latch address and be's
282 imem_ce := "11"; -- ce SRAM next cycle
283 imem_oe := '1'; -- oe SRAM next cycle
284 n.state := s_read; -- next: continue read
285 else -- if WRITE requested
286 iaddr_ce := '1'; -- latch address and be's
287 idata_ceo := '1'; -- latch output data
288 imem_be := BE; -- use request BE's
289 n.state := s_bta_r2w; -- next: bus turn around cycle
290 end if;
291 else
292 n.state := s_idle; -- next: idle if nothing to do
293 end if;
294
295 when s_write1 => -- s_write1: write cycle, 1st half
296 ibusy := '1'; -- signal busy, unable to handle req
297 iactw := '1'; -- signal mem write
298 idata_oe := '1'; -- oe FPGA next cycle
299 imem_ce := "11"; -- ce SRAM next cycle
300 imem_we := '1'; -- we SRAM next shifted cycle
301 n.state := s_write2; -- next: write cycle, 2nd half
302
303 when s_write2 => -- s_write2: write cycle, 2nd half
304 iactw := '1'; -- signal mem write
305 iackw := '1'; -- signal write acknowledge
306 if REQ = '1' then -- if IO requested
307 if WE = '1' then -- if WRITE requested
308 iaddr_ce := '1'; -- latch address and be's
309 idata_ceo := '1'; -- latch output data
310 idata_oe := '1'; -- oe FPGA next cycle
311 imem_ce := "11"; -- ce SRAM next cycle
312 imem_be := BE; -- use request BE's
313 n.state := s_write1; -- next: continue read
314 else -- if READ requested
315 iaddr_ce := '1'; -- latch address and be's
316 n.state := s_bta_w2r; -- next: bus turn around cycle
317 end if;
318 else
319 n.state := s_idle; -- next: idle if nothing to do
320 end if;
321
322 when s_bta_r2w => -- s_bta_r2w: bus turn around: r->w
323 ibusy := '1'; -- signal busy, unable to handle req
324 iactw := '1'; -- signal mem write
325 imem_ce := "11"; -- ce SRAM next cycle
326 idata_oe := '1'; -- oe FPGA next cycle
327 n.state := s_write1; -- next: start write
328
329 when s_bta_w2r => -- s_bta_w2r: bus turn around: w->r
330 ibusy := '1'; -- signal busy, unable to handle req
331 iactr := '1'; -- signal mem read
332 imem_ce := "11"; -- ce SRAM next cycle
333 imem_oe := '1'; -- oe SRAM next cycle
334 n.state := s_read; -- next: start read
335
336 when others => null;
337 end case;
338
339 N_REGS <= n;
340
341 MEM_CE_N <= not imem_ce;
342 MEM_WE_N <= not imem_we;
343 MEM_BE_N <= not imem_be;
344 MEM_OE_N <= not imem_oe;
345 ADDR_CE <= iaddr_ce;
346 DATA_CEI <= idata_cei;
347 DATA_CEO <= idata_ceo;
348 DATA_OE <= idata_oe;
349
350 BUSY <= ibusy;
351 ACK_R <= r.ackr;
352 ACK_W <= iackw;
353 ACT_R <= iactr;
354 ACT_W <= iactw;
355
356 end process proc_next;
357
358end syn;
in CEO slbit := '1'
in CEI slbit := '1'
PULL string := "NONE"
inout PAD slv( DWIDTH- 1 downto 0)
in DO slv( DWIDTH- 1 downto 0)
out DI slv( DWIDTH- 1 downto 0)
DWIDTH positive := 16
in CE slbit := '1'
out PAD slv( DWIDTH- 1 downto 0)
INIT slbit := '0'
in CLK slbit
in DO slv( DWIDTH- 1 downto 0)
DWIDTH positive := 16
in CE slbit := '1'
Definition: iob_reg_o.vhd:30
out PAD slbit
Definition: iob_reg_o.vhd:33
INIT slbit := '0'
Definition: iob_reg_o.vhd:27
in CLK slbit
Definition: iob_reg_o.vhd:29
in DO slbit
Definition: iob_reg_o.vhd:31
slbit := '0' CLK_180
regs_type := regs_init N_REGS
slbit := '0' MEM_OE_N
slv4 := "0000" MEM_BE_N
slbit := '0' DATA_OE
(s_idle,s_read,s_write1,s_write2,s_bta_r2w,s_bta_w2r) state_type
regs_type := regs_init R_REGS
slbit := '0' ADDR_CE
slbit := '0' DATA_CEO
regs_type :=( s_idle, '0') regs_init
slbit := '0' MEM_WE_N
slv2 := "00" MEM_CE_N
slbit := '0' DATA_CEI
inout IO_MEM_DATA slv32
out O_MEM_CE_N slv2
out ACT_W slbit
out O_MEM_WE_N slbit
out ACK_R slbit
out BUSY slbit
out O_MEM_ADDR slv18
out ACT_R slbit
out O_MEM_BE_N slv4
out ACK_W slbit
out O_MEM_OE_N slbit
std_logic_vector( 3 downto 0) slv4
Definition: slvtypes.vhd:36
std_logic_vector( 17 downto 0) slv18
Definition: slvtypes.vhd:51
std_logic_vector( 31 downto 0) slv32
Definition: slvtypes.vhd:59
std_logic slbit
Definition: slvtypes.vhd:30
std_logic_vector( 1 downto 0) slv2
Definition: slvtypes.vhd:34
Definition: xlib.vhd:35