forked from antonblanchard/microwatt
-
Notifications
You must be signed in to change notification settings - Fork 0
/
syscon.vhdl
254 lines (224 loc) · 9.87 KB
/
syscon.vhdl
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
-- syscon module, a bunch of misc global system control MMIO registers
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.git.all;
use work.wishbone_types.all;
entity syscon is
generic (
SIG_VALUE : std_ulogic_vector(63 downto 0) := x"f00daa5500010001";
CLK_FREQ : integer;
HAS_UART : boolean;
HAS_DRAM : boolean;
BRAM_SIZE : integer;
DRAM_SIZE : integer;
DRAM_INIT_SIZE : integer;
HAS_SPI_FLASH : boolean;
SPI_FLASH_OFFSET : integer;
HAS_LITEETH : boolean;
HAS_SD_CARD : boolean;
UART0_IS_16550 : boolean;
HAS_UART1 : boolean
);
port (
clk : in std_ulogic;
rst : in std_ulogic;
-- Wishbone ports:
wishbone_in : in wb_io_master_out;
wishbone_out : out wb_io_slave_out;
-- System control ports
dram_at_0 : out std_ulogic;
core_reset : out std_ulogic;
soc_reset : out std_ulogic;
alt_reset : out std_ulogic
);
end entity syscon;
architecture behaviour of syscon is
-- Register address bits
constant SYS_REG_BITS : positive := 6;
-- Register addresses (matches wishbone addr downto 3, ie, 8 bytes per reg)
constant SYS_REG_SIG : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "000000";
constant SYS_REG_INFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "000001";
constant SYS_REG_BRAMINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "000010";
constant SYS_REG_DRAMINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "000011";
constant SYS_REG_CLKINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "000100";
constant SYS_REG_CTRL : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "000101";
constant SYS_REG_DRAMINITINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "000110";
constant SYS_REG_SPIFLASHINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "000111";
constant SYS_REG_UART0_INFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "001000";
constant SYS_REG_UART1_INFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "001001";
constant SYS_REG_GIT_INFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "001010";
-- Muxed reg read signal
signal reg_out : std_ulogic_vector(63 downto 0);
-- INFO register bits
constant SYS_REG_INFO_HAS_UART : integer := 0; -- Has a UART (always set)
constant SYS_REG_INFO_HAS_DRAM : integer := 1; -- Has DRAM
constant SYS_REG_INFO_HAS_BRAM : integer := 2; -- Has "main" BRAM
constant SYS_REG_INFO_HAS_SPIF : integer := 3; -- Has SPI flash
constant SYS_REG_INFO_HAS_LETH : integer := 4; -- Has LiteEth ethernet
constant SYS_REG_INFO_HAS_LSYS : integer := 5; -- Has 6-bit address syscon
constant SYS_REG_INFO_HAS_URT1 : integer := 6; -- Has second UART
constant SYS_REG_INFO_HAS_ARTB : integer := 7; -- Has architected TB frequency
constant SYS_REG_INFO_HAS_SDCARD : integer := 8; -- Has LiteSDCard SD-card interface
-- BRAMINFO contains the BRAM size in the bottom 52 bits
-- DRAMINFO contains the DRAM size if any in the bottom 52 bits
-- (both have reserved top bits for future use)
-- CLKINFO contains the CLK frequency is HZ in the bottom 40 bits
-- CTRL register bits
constant SYS_REG_CTRL_BITS : positive := 4;
constant SYS_REG_CTRL_DRAM_AT_0 : integer := 0;
constant SYS_REG_CTRL_CORE_RESET : integer := 1;
constant SYS_REG_CTRL_SOC_RESET : integer := 2;
constant SYS_REG_CTRL_ALT_RESET : integer := 3;
-- SPI Info register bits
--
-- Top 32-bit is flash offset which is the amount of flash
-- reserved for the FPGA bitfile if any
constant SYS_REG_SPI_INFO_IS_FLASH : integer := 0;
-- UART0/1 info registers bits
--
-- 0 ..31 : UART clock freq (in HZ)
-- 32 : UART is 16550 (otherwise pp)
--
-- GIT info register bits
--
-- 0 ..55 : git hash (14 chars = 56 bits)
-- 63 : dirty flag
--
-- Ctrl register
signal reg_ctrl : std_ulogic_vector(SYS_REG_CTRL_BITS-1 downto 0);
signal reg_ctrl_out : std_ulogic_vector(63 downto 0);
signal ctrl_init_alt_reset : std_ulogic;
-- Others
signal reg_info : std_ulogic_vector(63 downto 0);
signal reg_braminfo : std_ulogic_vector(63 downto 0);
signal reg_draminfo : std_ulogic_vector(63 downto 0);
signal reg_dramiinfo : std_ulogic_vector(63 downto 0);
signal reg_clkinfo : std_ulogic_vector(63 downto 0);
signal reg_spiinfo : std_ulogic_vector(63 downto 0);
signal reg_uart0info : std_ulogic_vector(63 downto 0);
signal reg_uart1info : std_ulogic_vector(63 downto 0);
signal reg_gitinfo : std_ulogic_vector(63 downto 0);
signal info_has_dram : std_ulogic;
signal info_has_bram : std_ulogic;
signal info_has_uart : std_ulogic;
signal info_has_spif : std_ulogic;
signal info_has_leth : std_ulogic;
signal info_has_lsdc : std_ulogic;
signal info_has_urt1 : std_ulogic;
signal info_clk : std_ulogic_vector(39 downto 0);
signal info_fl_off : std_ulogic_vector(31 downto 0);
signal uinfo_16550 : std_ulogic;
signal uinfo_freq : std_ulogic_vector(31 downto 0);
-- Wishbone response latch
signal wb_rsp : wb_io_slave_out;
begin
-- Generated output signals
dram_at_0 <= '1' when BRAM_SIZE = 0 else reg_ctrl(SYS_REG_CTRL_DRAM_AT_0);
soc_reset <= reg_ctrl(SYS_REG_CTRL_SOC_RESET);
core_reset <= reg_ctrl(SYS_REG_CTRL_CORE_RESET);
alt_reset <= reg_ctrl(SYS_REG_CTRL_ALT_RESET);
-- Info register is hard wired
info_has_uart <= '1' when HAS_UART else '0';
info_has_dram <= '1' when HAS_DRAM else '0';
info_has_bram <= '1' when BRAM_SIZE /= 0 else '0';
info_has_spif <= '1' when HAS_SPI_FLASH else '0';
info_has_leth <= '1' when HAS_LITEETH else '0';
info_has_lsdc <= '1' when HAS_SD_CARD else '0';
info_has_urt1 <= '1' when HAS_UART1 else '0';
info_clk <= std_ulogic_vector(to_unsigned(CLK_FREQ, 40));
reg_info <= (SYS_REG_INFO_HAS_UART => info_has_uart,
SYS_REG_INFO_HAS_DRAM => info_has_dram,
SYS_REG_INFO_HAS_BRAM => info_has_bram,
SYS_REG_INFO_HAS_SPIF => info_has_spif,
SYS_REG_INFO_HAS_LETH => info_has_leth,
SYS_REG_INFO_HAS_SDCARD => info_has_lsdc,
SYS_REG_INFO_HAS_LSYS => '1',
SYS_REG_INFO_HAS_URT1 => info_has_urt1,
others => '0');
reg_braminfo <= x"000" & std_ulogic_vector(to_unsigned(BRAM_SIZE, 52));
reg_draminfo <= x"000" & std_ulogic_vector(to_unsigned(DRAM_SIZE, 52)) when HAS_DRAM
else (others => '0');
reg_dramiinfo <= x"000" & std_ulogic_vector(to_unsigned(DRAM_INIT_SIZE, 52)) when HAS_DRAM
else (others => '0');
reg_clkinfo <= (39 downto 0 => info_clk,
others => '0');
info_fl_off <= std_ulogic_vector(to_unsigned(SPI_FLASH_OFFSET, 32));
reg_spiinfo <= (31 downto 0 => info_fl_off,
others => '0');
-- Control register read composition
reg_ctrl_out <= (63 downto SYS_REG_CTRL_BITS => '0',
SYS_REG_CTRL_BITS-1 downto 0 => reg_ctrl);
-- UART info registers read composition
uinfo_16550 <= '1' when UART0_IS_16550 else '0';
uinfo_freq <= std_ulogic_vector(to_unsigned(CLK_FREQ, 32));
reg_uart0info <= (32 => uinfo_16550,
31 downto 0 => uinfo_freq,
others => '0');
reg_uart1info <= (32 => '1',
31 downto 0 => uinfo_freq,
others => '0');
-- GIT info register composition
reg_gitinfo <= (63 => GIT_DIRTY,
55 downto 0 => GIT_HASH,
others => '0');
-- Wishbone response
wb_rsp.ack <= wishbone_in.cyc and wishbone_in.stb;
with wishbone_in.adr(SYS_REG_BITS downto 1) select reg_out <=
SIG_VALUE when SYS_REG_SIG,
reg_info when SYS_REG_INFO,
reg_braminfo when SYS_REG_BRAMINFO,
reg_draminfo when SYS_REG_DRAMINFO,
reg_dramiinfo when SYS_REG_DRAMINITINFO,
reg_clkinfo when SYS_REG_CLKINFO,
reg_ctrl_out when SYS_REG_CTRL,
reg_spiinfo when SYS_REG_SPIFLASHINFO,
reg_uart0info when SYS_REG_UART0_INFO,
reg_uart1info when SYS_REG_UART1_INFO,
reg_gitinfo when SYS_REG_GIT_INFO,
(others => '0') when others;
wb_rsp.dat <= reg_out(63 downto 32) when wishbone_in.adr(0) = '1' else
reg_out(31 downto 0);
wb_rsp.stall <= '0';
-- Wishbone response latch
regs_read: process(clk)
begin
if rising_edge(clk) then
-- Send response from latch
wishbone_out <= wb_rsp;
end if;
end process;
-- Initial state
ctrl_init_alt_reset <= '1' when HAS_DRAM else '0';
-- Register writes
regs_write: process(clk)
begin
if rising_edge(clk) then
if (rst) then
reg_ctrl <= (SYS_REG_CTRL_ALT_RESET => ctrl_init_alt_reset,
others => '0');
else
if wishbone_in.cyc and wishbone_in.stb and wishbone_in.we then
-- Change this if CTRL ever has more than 32 bits
if wishbone_in.adr(SYS_REG_BITS downto 1) = SYS_REG_CTRL and
wishbone_in.adr(0) = '0' then
reg_ctrl(SYS_REG_CTRL_BITS-1 downto 0) <=
wishbone_in.dat(SYS_REG_CTRL_BITS-1 downto 0);
end if;
end if;
-- Reset auto-clear
if reg_ctrl(SYS_REG_CTRL_SOC_RESET) = '1' then
reg_ctrl(SYS_REG_CTRL_SOC_RESET) <= '0';
end if;
if reg_ctrl(SYS_REG_CTRL_CORE_RESET) = '1' then
reg_ctrl(SYS_REG_CTRL_CORE_RESET) <= '0';
end if;
-- If BRAM doesn't exist, force DRAM at 0
if BRAM_SIZE = 0 then
reg_ctrl(SYS_REG_CTRL_DRAM_AT_0) <= '1';
end if;
end if;
end if;
end process;
end architecture behaviour;