-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathsimm_controller.vhd
executable file
·130 lines (115 loc) · 3.1 KB
/
simm_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
-- SIMM entity
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use work.P_CORE.ALL;
entity simm_controller is
port ( reset : in STD_LOGIC;
clock : in STD_LOGIC;
simm : in STD_LOGIC;
as : in STD_LOGIC;
ds : in STD_LOGIC;
rn_w : in STD_LOGIC;
bank_addr : in STD_LOGIC;
byte_selects : in STD_LOGIC_VECTOR (3 downto 0);
write : out STD_LOGIC;
ras : out STD_LOGIC_VECTOR (3 downto 0);
cas : out STD_LOGIC_VECTOR (3 downto 0);
waitstate : out STD_LOGIC;
mux_select : out STD_LOGIC);
end entity;
architecture behavioral of simm_controller is
type DRAM_STATE is (IDLE, MEMRW1, MEMRW2, REFRESH1, REFRESH2, REFRESH3, REFRESH4); -- Define the states
begin
process (reset, clock)
variable refresh_count : INTEGER range 0 to 250 := 0;
variable state : DRAM_STATE := IDLE;
variable needs_refresh : STD_LOGIC := '0';
begin
if (reset = '1') then
write <= '0';
mux_select <= '1';
ras <= "0000";
cas <= "0000";
waitstate <= '1';
state := IDLE;
elsif (clock'event and clock = '1') then
refresh_count := refresh_count + 1;
if (refresh_count = 250) then
refresh_count := 0;
needs_refresh := '1';
end if;
case state is
when IDLE =>
write <= '0';
mux_select <= '0';
ras <= "0000";
cas <= "0000";
waitstate <= '1';
if (needs_refresh = '1') then
needs_refresh := '0';
state := REFRESH1;
elsif (simm = '1' and ds = '1' and as = '1') then
write <= not rn_w;
if (bank_addr = '0') then
ras <= "0101";
else
ras <= "1010";
end if;
state := MEMRW1;
else
state := IDLE;
end if;
when MEMRW1 =>
mux_select <= '1';
state := MEMRW2;
when MEMRW2 =>
if (rn_w = '0') then
-- Writing? Select only needed bytes
cas <= byte_selects;
else
-- Reading? Select them all, needed for cache
cas <= "1111";
end if;
waitstate <= '0';
if (as = '1') then
state := MEMRW2;
else
state := IDLE;
end if;
when REFRESH1 =>
cas <= "1111";
state := REFRESH2;
when REFRESH2 =>
ras <= "1111";
state := REFRESH3;
when REFRESH3 =>
cas <= "0000";
state := REFRESH4;
when REFRESH4 =>
ras <= "0000";
state := IDLE;
end case;
end if;
end process;
end architecture;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity simm_mux is
port ( mux_select : in STD_LOGIC;
addr_in : in STD_LOGIC_VECTOR (31 downto 0);
addr_out : out STD_LOGIC_VECTOR (11 downto 0)
);
end entity;
architecture behavioral of simm_mux is
begin
-- 8 MB
-- addr_out (9 downto 0) <= addr_in (9 + 3 downto 3) when mux_select = '0' else
-- addr_in (9 + 10 + 3 downto 10 + 3);
-- addr_out (11 downto 10) <= (others => '0');
-- 32 MB
addr_out (10 downto 0) <= addr_in (10 + 2 downto 2) when mux_select = '0' else
addr_in (10 + 11 + 2 downto 11 + 2);
addr_out (11) <= '0';
end architecture;