-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsram_controller.vhd
384 lines (323 loc) · 11.1 KB
/
sram_controller.vhd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
----------------------------------------------------------------------------------
-- Company:
-- Engineer: M.M. Cheraghi
--
-- Create Date: 20:27:18 03/10/2024
-- Design Name:
-- Module Name: sram_controller - Behavioral
-- Project Name:
-- Target Devices: IS61WV5128BLL-10TI
-- Tool versions: 1.0
-- Description: This module is intented to work on Posedge development board with Spartan-6 FPGA working in 24 MHz.
-- 1- There are Four states for wrinting and Four states for reading. Each write/read state takes two cycles
-- to fullfill SRAM timing constraints (The delay_signal is used to delay state machine in each write/read state).
-- 2- The target SRAM is byte accessible and we should devide word access to byte access. Master specifies required bytes
-- with 4-bit xbus_sel_i signal. The machine state traverses states based on this select signal.
-- 3- This module hardwires xbus_err_o to '0' and further improvement should handle error situations.
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity sram_controller is
-- SRAM Controller
port
(
-- Wishbone bus interface (available if MEM_EXT_EN = true) --
xbus_adr_i : in std_ulogic_vector(18 downto 0); -- address
xbus_dat_i : in std_ulogic_vector(31 downto 0); -- write data
xbus_we_i : in std_ulogic; -- read/write
xbus_sel_i : in std_ulogic_vector(03 downto 0); -- byte enable
xbus_stb_i : in std_ulogic; -- strobe
xbus_cyc_i : in std_ulogic; -- valid cycle
xbus_dat_o : out std_ulogic_vector(31 downto 0) := (others => '0'); -- read data
xbus_ack_o : out std_ulogic := '0'; -- transfer acknowledge
xbus_err_o : out std_ulogic := '0'; -- transfer errors
-- SRAM signals --
ADDR_out : out std_ulogic_vector(18 downto 0) := (others => 'X');
DATApin : inout std_ulogic_vector(7 downto 0);
Sram_ce : out std_logic;
Sram_oe : out std_logic;
Sram_we : out std_logic;
-- General signals --
clk_i : in std_logic; -- global clock, rising edge
rstn_i : in std_logic -- global reset, low-active, async
);
end entity;
architecture Behavioral of sram_controller is
type controller_State is (IDLE, D_READ1, D_READ2, D_READ3, D_WRITE1, D_WRITE2, D_WRITE3);
signal state : controller_State := IDLE;
signal xbus_dat_i_reg : std_ulogic_vector(31 downto 0) := (others => '0'); -- write data
signal xbus_adr_i_reg : unsigned(18 downto 0) := (others => '0'); -- write data address
signal delay_signal : std_logic := '0'; -- write data address
signal xbus_dat_o_tmp : std_ulogic_vector(31 downto 00) := (others => '0'); -- write data address
signal DATApin_TX : std_ulogic_vector(07 downto 00) := (others => 'Z');
signal Tri_en : std_logic := '0'; -- write data address
signal sel_reg : std_ulogic_vector(03 downto 00) := (others => '0');
-------- Sram => signals --------
signal srd :std_logic:='0';
signal wrt :std_logic:='0';
signal Done :std_logic:='0';
signal ADDR_in :std_ulogic_vector(18 downto 0);
signal DATA_in :std_ulogic_vector(7 downto 0);
signal DATAout :std_ulogic_vector(7 downto 0);
signal d_out :std_ulogic_vector(7 downto 0);
-- ### SRAM controller core
component Sram is
port ( clk :in STD_LOGIC;
rd :in STD_LOGIC;
wrt :in STD_LOGIC;
DATApin :inout std_ulogic_vector(7 downto 0);
DATAin :in std_ulogic_vector(7 downto 0):=x"00";
DATAout :out std_ulogic_vector(7 downto 0):=x"00";
ADDR_out :out std_ulogic_vector(18 downto 0);
ADDR_in :in std_ulogic_vector(18 downto 0);
Done :out STD_LOGIC;
Sram_ce :out std_logic;
Sram_oe :out std_logic;
sram_we :out std_logic;
rstn_i : in std_logic -- global reset, low-active, async
);
end component;
begin
Inst_sram: sram PORT MAP(
DATAout => DATAout,
DATApin => DATApin,
DATAin => DATA_in,
clk => clk_i,
rd => srd,
wrt => wrt,
ADDR_out => ADDR_out,
ADDR_in => ADDR_in ,
Done => Done,
Sram_ce => Sram_ce,
Sram_oe => Sram_oe,
Sram_we => Sram_we,
rstn_i => rstn_i
);
process (clk_i, rstn_i)
begin
if(rstn_i = '0') then
state <= IDLE;
sel_reg <= B"0000";
xbus_ack_o <= '0';
xbus_err_o <= '0';
ADDR_in <= (others=>'0');
DATA_in <= (others=>'0');
xbus_dat_o(7 downto 0) <= (others=>'0');
elsif (clk_i'event and clk_i = '1') then
ADDR_in <= (others=>'0');
DATA_in <= (others=>'0');
xbus_dat_o(7 downto 0) <= (others=>'0');
xbus_ack_o <= '0';
xbus_err_o <= '0';
case state is
-- IDLE state --
when IDLE =>
sel_reg <= xbus_sel_i;
wrt <= '0';
srd <= '0';
if ((xbus_cyc_i and xbus_stb_i and xbus_we_i) = '1') then -- valid write access
state <= D_WRITE1;
elsif ((xbus_cyc_i and xbus_stb_i) = '1') then -- valid read access
state <= D_READ1;
else
state <= IDLE;
end if;
-- WRITE1 state --
when D_WRITE1 =>
if(sel_reg(3)='1')then
ADDR_in <= xbus_adr_i(18 downto 02) & B"11";
DATA_in <= xbus_dat_i(31 downto 24);
elsif(sel_reg(2)='1')then
ADDR_in <= xbus_adr_i(18 downto 02) & B"10";
DATA_in <= xbus_dat_i(23 downto 16);
elsif(sel_reg(1)='1')then
ADDR_in <= xbus_adr_i(18 downto 02) & B"01";
DATA_in <= xbus_dat_i(15 downto 08);
elsif(sel_reg(0)='1')then
ADDR_in <= xbus_adr_i(18 downto 02) & B"00";
DATA_in <= xbus_dat_i(07 downto 00);
end if;
xbus_dat_o <= (others=>'0');
state <= D_WRITE1;
wrt <= '1';
xbus_err_o <= '0';
xbus_ack_o <= '0';
if (Done = '1')then
wrt <= '0';
state <= D_WRITE2;
-- xbus_ack_o <= '1';
end if;
-- WRITE2 state --
when D_WRITE2 =>
state <= D_WRITE3;
wrt <= '0';
if(sel_reg(3)='1')then
sel_reg <= B"0" & sel_reg(2 downto 0);
elsif(sel_reg(2)='1')then
sel_reg <= B"00" & sel_reg(1 downto 0);
elsif(sel_reg(1)='1')then
sel_reg <= B"000" & sel_reg(0);
elsif(sel_reg(0)='1')then
sel_reg <= B"0000";
xbus_ack_o <= '1';
state <= IDLE;
else
xbus_ack_o <= '1';
state <= IDLE;
end if;
-- WRITE3 state --
when D_WRITE3 =>
state <= D_WRITE1;
-- READ1 state --
when D_READ1 =>
if(sel_reg(3)='1')then
ADDR_in <= xbus_adr_i(18 downto 2) & B"11";
elsif(sel_reg(2)='1')then
ADDR_in <= xbus_adr_i(18 downto 2) & B"10";
elsif(sel_reg(1)='1')then
ADDR_in <= xbus_adr_i(18 downto 2) & B"01";
elsif(sel_reg(0)='1')then
ADDR_in <= xbus_adr_i(18 downto 2) & B"00";
end if;
DATA_in <= (others=>'0');
state <= D_READ1;
srd <= '1';
xbus_err_o <= '0';
xbus_ack_o <= '0';
if (Done = '1')then
srd <= '0';
state <= D_READ2;
-- xbus_ack_o <= '1';
end if;
-- READ2 state --
when D_READ2 =>
state <= D_READ3;
srd <= '0';
if(sel_reg(3)='1')then
xbus_dat_o(31 downto 24) <= DATAout;
sel_reg <= B"0" & sel_reg(2 downto 0);
elsif(sel_reg(2)='1')then
xbus_dat_o(23 downto 16) <= DATAout;
sel_reg <= B"00" & sel_reg(1 downto 0);
elsif(sel_reg(1)='1')then
xbus_dat_o(15 downto 08) <= DATAout;
sel_reg <= B"000" & sel_reg(0);
elsif(sel_reg(0)='1')then
xbus_dat_o(07 downto 00) <= DATAout;
sel_reg <= B"0000";
xbus_ack_o <= '1';
state <= IDLE;
else
xbus_ack_o <= '1';
state <= IDLE;
end if;
-- READ3 state --
when D_READ3 =>
state <= D_READ1;
end case;
end if;
end process;
end Behavioral;
----------------------------------------------------------------------------------
-- Mohsen Sadeghi Moghaddam
-- Sram Component
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Sram is
port ( clk :in STD_LOGIC;
rd :in STD_LOGIC;
wrt :in STD_LOGIC;
DATApin :inout std_ulogic_vector(7 downto 0);
DATAin :in std_ulogic_vector(7 downto 0):=x"00";
DATAout :out std_ulogic_vector(7 downto 0):=x"00";
ADDR_out :out std_ulogic_vector(18 downto 0);
ADDR_in :in std_ulogic_vector(18 downto 0);
Done :out STD_LOGIC;
Sram_ce :out std_logic;
Sram_oe :out std_logic;
Sram_we :out std_logic;
rstn_i : in std_logic -- global reset, low-active, async
);
end Sram;
------------------------------------------------------------------------
architecture Behavioral of Sram is
type Sram_State is (S_start,S_Read,S_write,S_wrt_done,S_get,S_finish);
signal pr_state :Sram_State := S_start;
begin
ADDR_out <= ADDR_in;
process (clk, rstn_i)
begin
if(rstn_i = '0') then
pr_state <= S_start;
Done <= '0';
Sram_ce <= '1';
Sram_we <= '1';
Sram_oe <= '1';
DATAout <= X"00";
elsif (clk'event and clk = '1') then
case pr_state is
when S_start =>
Done <= '0';
if (wrt = '1') then
DATApin <= DATAin;
Sram_ce <= '0';
Sram_we <= '0';
Sram_oe <= '1';
pr_state <= S_write;
elsif (rd = '1') then
DATApin<=(others => 'Z');
Sram_ce <= '0';
Sram_we <= '1';
Sram_oe <= '0';
pr_state <= S_Read;
end if;
--------------------------------------
when S_Read =>
Sram_ce <= '0';
Sram_we <= '1';
Sram_oe <= '0';
pr_state <= S_get;
--------------------------------------
when S_get =>
Done <= '1';
DATAout <=DATApin;
pr_state <= S_finish;
--------------------------------------
when S_write =>
DATApin<=DATAin;
Sram_ce <= '0';
Sram_we <= '0';
Sram_oe <= '1';
pr_state <= S_wrt_done;
--------------------------------------
when S_wrt_done =>
Done <= '1';
pr_state <= S_finish;
--------------------------------------
when S_finish =>
Sram_ce <= '0';
Sram_oe <= '1';
Sram_we <= '1';
if(rd='0' and wrt='0') then
pr_state <= S_start;
end if;
end case;
end if;
end process;
end Behavioral;