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
|
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
library work;
use work.zpu_config.all;
use work.zpupkg.all;
entity zpuio is
port ( areset : in std_logic;
cpu_clk : in std_logic;
clk_status : in std_logic_vector(2 downto 0);
cpu_din : in std_logic_vector(15 downto 0);
cpu_a : in std_logic_vector(20 downto 0);
cpu_we : in std_logic_vector(1 downto 0);
cpu_re : in std_logic;
cpu_dout : inout std_logic_vector(15 downto 0));
end zpuio;
architecture behave of zpuio is
signal timer_read : std_logic_vector(7 downto 0);
--signal timer_write : std_logic_vector(7 downto 0);
signal timer_we : std_logic;
signal io_busy : std_logic;
signal io_read : std_logic_vector(7 downto 0);
--signal io_write : std_logic_vector(7 downto 0);
signal io_addr : std_logic_vector(maxAddrBit downto minAddrBit);
signal io_writeEnable : std_logic;
signal Enable : std_logic;
signal din : std_logic_vector(7 downto 0);
signal dout : std_logic_vector(7 downto 0);
signal adr : std_logic_vector(15 downto 0);
signal break : std_logic;
signal we : std_logic;
signal re : std_logic;
-- uart forwarding...
signal uartTXPending : std_logic;
signal uartTXCleared : std_logic;
signal uartData : std_logic_vector(7 downto 0);
signal readingTimer : std_logic;
signal mem_busy : std_logic;
signal mem_read : std_logic_vector(wordSize-1 downto 0);
signal mem_write : std_logic_vector(wordSize-1 downto 0);
signal mem_addr : std_logic_vector(maxAddrBitIncIO downto 0);
signal mem_writeEnable : std_logic;
signal mem_readEnable : std_logic;
signal mem_writeMask: std_logic_vector(wordBytes-1 downto 0);
signal dram_mem_busy : std_logic;
signal dram_mem_read : std_logic_vector(wordSize-1 downto 0);
signal dram_mem_write : std_logic_vector(wordSize-1 downto 0);
signal dram_mem_writeEnable : std_logic;
signal dram_mem_readEnable : std_logic;
signal dram_mem_writeMask: std_logic_vector(wordBytes-1 downto 0);
--signal io_mem_read : std_logic_vector(7 downto 0);
--signal io_mem_writeEnable : std_logic;
--signal io_mem_readEnable : std_logic;
signal io_readEnable : std_logic;
signal dram_read : std_logic;
begin
io_addr <= mem_addr(maxAddrBit downto minAddrBit);
timerinst: timer port map (
clk => cpu_clk,
areset => areset,
we => timer_we,
din => mem_write(7 downto 0),
adr => io_addr(4 downto 2),
dout => timer_read);
zpu: zpu_core port map (
clk => cpu_clk ,
areset => areset,
in_mem_busy => mem_busy,
mem_read => mem_read,
mem_write => mem_write,
out_mem_addr => mem_addr,
out_mem_writeEnable => mem_writeEnable,
out_mem_readEnable => mem_readEnable,
mem_writeMask => mem_writeMask,
interrupt => '0',
break => break);
ram_imp: dram port map (
clk => cpu_clk ,
areset => areset,
mem_busy => dram_mem_busy,
mem_read => dram_mem_read,
mem_write => mem_write,
mem_addr => mem_addr(maxAddrBit downto 0),
mem_writeEnable => dram_mem_writeEnable,
mem_readEnable => dram_mem_readEnable,
mem_writeMask => mem_writeMask);
fauxUart:
process(cpu_clk, areset)
begin
if areset = '1' then
io_busy <= '0';
uartTXPending <= '0';
timer_we <= '0';
io_busy <= '0';
uartData <= x"58"; -- 'X'
readingTimer <= '0';
elsif (cpu_clk'event and cpu_clk = '1') then
timer_we <= '0';
io_busy <= '0';
if uartTXCleared = '1' then
uartTXPending <= '0';
end if;
if io_writeEnable = '1' then
if io_addr=x"2028003" then
-- Write to UART
uartData <= mem_write(7 downto 0);
uartTXPending <= '1';
io_busy <= '1';
elsif io_addr(12)='1' then
timer_we <= '1';
io_busy <= '1';
else
-- report "Illegal IO write" severity failure;
end if;
end if;
if (io_readEnable = '1') then
if io_addr=x"2028003" then
io_read <= (0=>'1', -- recieve empty
1 => uartTXPending, -- tx full
others => '0');
io_busy <= '1';
elsif io_addr(12)='1' then
readingTimer <= '1';
io_busy <= '1';
elsif io_addr(11)='1' then
io_read <= ZPU_Frequency;
io_busy <= '1';
else
-- report "Illegal IO read" severity failure;
end if;
else
if (readingTimer = '1') then
readingTimer <= '0';
io_read <= timer_read;
io_busy <= '0';
else
io_read <= (others => '1');
end if;
end if;
end if;
end process;
forwardUARTOutputToARM:
process(cpu_clk, areset)
begin
if areset = '1' then
uartTXCleared <= '0';
elsif (cpu_clk = '1' and cpu_clk'event) then
if cpu_we(0) = '1' and cpu_a(3 downto 1) = "000" then
uartTXCleared <= cpu_din(0);
else
uartTXCleared <= uartTXCleared;
end if;
end if;
end process;
cpu_dout(7 downto 0) <= uartData when (cpu_re = '1' and cpu_a(3 downto 1) = "001") else (others => 'Z');
cpu_dout <= (0 => uartTXPending, others => '0') when (cpu_re = '1' and cpu_a(3 downto 1) = "000") else (others => 'Z');
dram_mem_writeEnable <= mem_writeEnable and not mem_addr(ioBit);
dram_mem_readEnable <= mem_readEnable and not mem_addr(ioBit);
io_writeEnable <= mem_writeEnable and mem_addr(ioBit);
-- io_readEnable <= mem_readEnable and mem_addr(ioBit);
mem_busy <= io_busy or dram_mem_busy or dram_read or io_readEnable;
-- Memory reads either come from IO or DRAM. We need to pick the right one.
memorycontrol:
process(cpu_clk, areset)
begin
if areset = '1' then
dram_read <= '0';
io_readEnable <= '0';
elsif (cpu_clk'event and cpu_clk = '1') then
mem_read <= (others => '0');
if mem_addr(ioBit)='0' and mem_readEnable='1' then
dram_read <= '1';
end if;
if dram_read='1' and dram_mem_busy='0' then
dram_read <= '0';
mem_read <= dram_mem_read;
end if;
if mem_addr(ioBit)='1' and mem_readEnable='1' then
io_readEnable <= '1';
end if;
if io_readEnable='1' and io_busy='0' then
io_readEnable <= '0';
mem_read(7 downto 0) <= io_read;
end if;
end if;
end process;
end behave;
|