syscon: Add syscon registers
[microwatt.git] / fpga / top-arty.vhdl
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
4
5 library unisim;
6 use unisim.vcomponents.all;
7
8 library work;
9 use work.wishbone_types.all;
10
11 entity toplevel is
12 generic (
13 MEMORY_SIZE : positive := 16384;
14 RAM_INIT_FILE : string := "firmware.hex";
15 RESET_LOW : boolean := true;
16 CLK_FREQUENCY : positive := 100000000;
17 USE_LITEDRAM : boolean := false;
18 DISABLE_FLATTEN_CORE : boolean := false
19 );
20 port(
21 ext_clk : in std_ulogic;
22 ext_rst : in std_ulogic;
23
24 -- UART0 signals:
25 uart_main_tx : out std_ulogic;
26 uart_main_rx : in std_ulogic;
27
28 -- DRAM UART signals (PMOD)
29 uart_pmod_tx : out std_ulogic;
30 uart_pmod_rx : in std_ulogic;
31 uart_pmod_cts_n : in std_ulogic;
32 uart_pmod_rts_n : out std_ulogic;
33
34 -- LEDs
35 led0_b : out std_ulogic;
36 led0_g : out std_ulogic;
37 led0_r : out std_ulogic;
38
39 -- DRAM wires
40 ddram_a : out std_ulogic_vector(13 downto 0);
41 ddram_ba : out std_ulogic_vector(2 downto 0);
42 ddram_ras_n : out std_ulogic;
43 ddram_cas_n : out std_ulogic;
44 ddram_we_n : out std_ulogic;
45 ddram_cs_n : out std_ulogic;
46 ddram_dm : out std_ulogic_vector(1 downto 0);
47 ddram_dq : inout std_ulogic_vector(15 downto 0);
48 ddram_dqs_p : inout std_ulogic_vector(1 downto 0);
49 ddram_dqs_n : inout std_ulogic_vector(1 downto 0);
50 ddram_clk_p : out std_ulogic;
51 ddram_clk_n : out std_ulogic;
52 ddram_cke : out std_ulogic;
53 ddram_odt : out std_ulogic;
54 ddram_reset_n : out std_ulogic
55 );
56 end entity toplevel;
57
58 architecture behaviour of toplevel is
59
60 -- Reset signals:
61 signal soc_rst : std_ulogic;
62 signal pll_rst : std_ulogic;
63
64 -- Internal clock signals:
65 signal system_clk : std_ulogic;
66 signal system_clk_locked : std_ulogic;
67
68 -- DRAM wishbone connection
69 signal wb_dram_in : wishbone_master_out;
70 signal wb_dram_out : wishbone_slave_out;
71 signal wb_dram_csr : std_ulogic;
72 signal wb_dram_init : std_ulogic;
73
74 -- Control/status
75 signal core_alt_reset : std_ulogic;
76
77 -- Status LED
78 signal led0_b_pwm : std_ulogic;
79 signal led0_r_pwm : std_ulogic;
80 signal led0_g_pwm : std_ulogic;
81
82 -- Dumb PWM for the LEDs, those RGB LEDs are too bright otherwise
83 signal pwm_counter : std_ulogic_vector(8 downto 0);
84 begin
85
86 uart_pmod_rts_n <= '0';
87
88 -- Main SoC
89 soc0: entity work.soc
90 generic map(
91 MEMORY_SIZE => MEMORY_SIZE,
92 RAM_INIT_FILE => RAM_INIT_FILE,
93 RESET_LOW => RESET_LOW,
94 SIM => false,
95 CLK_FREQ => CLK_FREQUENCY,
96 HAS_DRAM => USE_LITEDRAM,
97 DRAM_SIZE => 256 * 1024 * 1024,
98 DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE
99 )
100 port map (
101 system_clk => system_clk,
102 rst => soc_rst,
103 uart0_txd => uart_main_tx,
104 uart0_rxd => uart_main_rx,
105 wb_dram_in => wb_dram_in,
106 wb_dram_out => wb_dram_out,
107 wb_dram_csr => wb_dram_csr,
108 wb_dram_init => wb_dram_init,
109 alt_reset => core_alt_reset
110 );
111
112 nodram: if not USE_LITEDRAM generate
113 signal ddram_clk_dummy : std_ulogic;
114 begin
115 reset_controller: entity work.soc_reset
116 generic map(
117 RESET_LOW => RESET_LOW
118 )
119 port map(
120 ext_clk => ext_clk,
121 pll_clk => system_clk,
122 pll_locked_in => system_clk_locked,
123 ext_rst_in => ext_rst,
124 pll_rst_out => pll_rst,
125 rst_out => soc_rst
126 );
127
128 clkgen: entity work.clock_generator
129 generic map(
130 CLK_INPUT_HZ => 100000000,
131 CLK_OUTPUT_HZ => CLK_FREQUENCY
132 )
133 port map(
134 ext_clk => ext_clk,
135 pll_rst_in => pll_rst,
136 pll_clk_out => system_clk,
137 pll_locked_out => system_clk_locked
138 );
139
140 led0_b_pwm <= '1';
141 led0_r_pwm <= '1';
142 led0_g_pwm <= '0';
143 core_alt_reset <= '0';
144
145 -- Vivado barfs on those differential signals if left
146 -- unconnected. So instanciate a diff. buffer and feed
147 -- it a constant '0'.
148 dummy_dram_clk: OBUFDS
149 port map (
150 O => ddram_clk_p,
151 OB => ddram_clk_n,
152 I => ddram_clk_dummy
153 );
154 ddram_clk_dummy <= '0';
155
156 end generate;
157
158 has_dram: if USE_LITEDRAM generate
159 signal dram_init_done : std_ulogic;
160 signal dram_init_error : std_ulogic;
161 signal soc_rst_0 : std_ulogic;
162 signal soc_rst_1 : std_ulogic;
163 begin
164
165 -- Eventually dig out the frequency from the generator
166 -- but for now, assert it's 100Mhz
167 assert CLK_FREQUENCY = 100000000;
168
169 reset_controller: entity work.soc_reset
170 generic map(
171 RESET_LOW => RESET_LOW
172 )
173 port map(
174 ext_clk => ext_clk,
175 pll_clk => system_clk,
176 pll_locked_in => system_clk_locked,
177 ext_rst_in => ext_rst,
178 pll_rst_out => pll_rst,
179 rst_out => soc_rst_0
180 );
181
182 dram: entity work.litedram_wrapper
183 generic map(
184 DRAM_ABITS => 24,
185 DRAM_ALINES => 14
186 )
187 port map(
188 clk_in => ext_clk,
189 rst => pll_rst,
190 system_clk => system_clk,
191 system_reset => soc_rst_1,
192 core_alt_reset => core_alt_reset,
193 pll_locked => system_clk_locked,
194
195 wb_in => wb_dram_in,
196 wb_out => wb_dram_out,
197 wb_is_csr => wb_dram_csr,
198 wb_is_init => wb_dram_init,
199
200 serial_tx => uart_pmod_tx,
201 serial_rx => uart_pmod_rx,
202
203 init_done => dram_init_done,
204 init_error => dram_init_error,
205
206 ddram_a => ddram_a,
207 ddram_ba => ddram_ba,
208 ddram_ras_n => ddram_ras_n,
209 ddram_cas_n => ddram_cas_n,
210 ddram_we_n => ddram_we_n,
211 ddram_cs_n => ddram_cs_n,
212 ddram_dm => ddram_dm,
213 ddram_dq => ddram_dq,
214 ddram_dqs_p => ddram_dqs_p,
215 ddram_dqs_n => ddram_dqs_n,
216 ddram_clk_p => ddram_clk_p,
217 ddram_clk_n => ddram_clk_n,
218 ddram_cke => ddram_cke,
219 ddram_odt => ddram_odt,
220 ddram_reset_n => ddram_reset_n
221 );
222
223 led0_b_pwm <= not dram_init_done;
224 led0_r_pwm <= dram_init_error;
225 led0_g_pwm <= dram_init_done and not dram_init_error;
226 soc_rst <= soc_rst_0 or soc_rst_1;
227
228 end generate;
229
230 leds_pwm : process(system_clk)
231 begin
232 if rising_edge(system_clk) then
233 pwm_counter <= std_ulogic_vector(signed(pwm_counter) + 1);
234 if pwm_counter(8 downto 4) = "00000" then
235 led0_b <= led0_b_pwm;
236 led0_r <= led0_r_pwm;
237 led0_g <= led0_g_pwm;
238 else
239 led0_b <= '0';
240 led0_r <= '0';
241 led0_g <= '0';
242 end if;
243 end if;
244 end process;
245
246 end architecture behaviour;