Add Nexys Video support
[microwatt.git] / fpga / toplevel.vhd
1 -- The Potato Processor - SoC design for the Arty FPGA board
2 -- (c) Kristian Klomsten Skordal 2016 <kristian.skordal@wafflemail.net>
3
4 library ieee;
5 use ieee.std_logic_1164.all;
6 use ieee.math_real.all;
7
8 library work;
9 use work.wishbone_types.all;
10
11
12 -- 0x00000000: Main memory (1 MB)
13 -- 0xc0002000: UART0 (for host communication)
14 entity toplevel is
15 generic (
16 MEMORY_SIZE : positive := 1048576;
17 RAM_INIT_FILE : string := "firmware.hex");
18 port(
19 clk : in std_logic;
20 reset_n : in std_logic;
21
22 -- UART0 signals:
23 uart0_txd : out std_logic;
24 uart0_rxd : in std_logic
25 );
26 end entity toplevel;
27
28 architecture behaviour of toplevel is
29
30 -- Reset signals:
31 signal reset : std_logic;
32
33 -- Internal clock signals:
34 signal system_clk : std_logic;
35 signal timer_clk : std_logic;
36 signal system_clk_locked : std_logic;
37
38 -- wishbone signals:
39 signal wishbone_proc_out: wishbone_master_out;
40 signal wishbone_proc_in: wishbone_slave_out;
41
42 -- Processor signals:
43 signal processor_adr_out : std_logic_vector(63 downto 0);
44 signal processor_sel_out : std_logic_vector(7 downto 0);
45 signal processor_cyc_out : std_logic;
46 signal processor_stb_out : std_logic;
47 signal processor_we_out : std_logic;
48 signal processor_dat_out : std_logic_vector(63 downto 0);
49 signal processor_dat_in : std_logic_vector(63 downto 0);
50 signal processor_ack_in : std_logic;
51
52 -- UART0 signals:
53 signal uart0_adr_in : std_logic_vector(11 downto 0);
54 signal uart0_dat_in : std_logic_vector( 7 downto 0);
55 signal uart0_dat_out : std_logic_vector( 7 downto 0);
56 signal uart0_cyc_in : std_logic;
57 signal uart0_stb_in : std_logic;
58 signal uart0_we_in : std_logic;
59 signal uart0_ack_out : std_logic;
60
61 -- Main memory signals:
62 signal main_memory_adr_in : std_logic_vector(positive(ceil(log2(real(MEMORY_SIZE))))-1 downto 0);
63 signal main_memory_dat_in : std_logic_vector(63 downto 0);
64 signal main_memory_dat_out : std_logic_vector(63 downto 0);
65 signal main_memory_cyc_in : std_logic;
66 signal main_memory_stb_in : std_logic;
67 signal main_memory_sel_in : std_logic_vector(7 downto 0);
68 signal main_memory_we_in : std_logic;
69 signal main_memory_ack_out : std_logic;
70
71 -- Selected peripheral on the interconnect:
72 type intercon_peripheral_type is (
73 PERIPHERAL_UART0, PERIPHERAL_MAIN_MEMORY, PERIPHERAL_ERROR,
74 PERIPHERAL_NONE);
75 signal intercon_peripheral : intercon_peripheral_type := PERIPHERAL_NONE;
76
77 -- Interconnect address decoder state:
78 signal intercon_busy : boolean := false;
79
80 -- disable for now
81 signal gpio_pins : std_logic_vector(11 downto 0);
82 signal uart1_txd : std_logic;
83 signal uart1_rxd : std_logic;
84 begin
85
86 address_decoder: process(system_clk)
87 begin
88 if rising_edge(system_clk) then
89 if reset = '1' then
90 intercon_peripheral <= PERIPHERAL_NONE;
91 intercon_busy <= false;
92 else
93 if not intercon_busy then
94 if processor_cyc_out = '1' then
95 intercon_busy <= true;
96
97 if processor_adr_out(31 downto 24) = x"00" then -- Main memory space
98 intercon_peripheral <= PERIPHERAL_MAIN_MEMORY;
99 elsif processor_adr_out(31 downto 24) = x"c0" then -- Peripheral memory space
100 case processor_adr_out(15 downto 12) is
101 when x"2" =>
102 intercon_peripheral <= PERIPHERAL_UART0;
103 when others => -- Invalid address - delegated to the error peripheral
104 intercon_peripheral <= PERIPHERAL_ERROR;
105 end case;
106 else
107 intercon_peripheral <= PERIPHERAL_ERROR;
108 end if;
109 else
110 intercon_peripheral <= PERIPHERAL_NONE;
111 end if;
112 else
113 if processor_cyc_out = '0' then
114 intercon_busy <= false;
115 intercon_peripheral <= PERIPHERAL_NONE;
116 end if;
117 end if;
118 end if;
119 end if;
120 end process address_decoder;
121
122 processor_intercon: process(all)
123 begin
124 case intercon_peripheral is
125 when PERIPHERAL_UART0 =>
126 processor_ack_in <= uart0_ack_out;
127 processor_dat_in <= x"00000000000000" & uart0_dat_out;
128 when PERIPHERAL_MAIN_MEMORY =>
129 processor_ack_in <= main_memory_ack_out;
130 processor_dat_in <= main_memory_dat_out;
131 when PERIPHERAL_NONE =>
132 processor_ack_in <= '0';
133 processor_dat_in <= (others => '0');
134 when others =>
135 processor_ack_in <= '0';
136 processor_dat_in <= (others => '0');
137 end case;
138 end process processor_intercon;
139
140 reset_controller: entity work.pp_soc_reset
141 port map(
142 clk => system_clk,
143 reset_n => reset_n,
144 reset_out => reset,
145 system_clk => system_clk,
146 system_clk_locked => system_clk_locked
147 );
148
149 clkgen: entity work.clock_generator
150 port map(
151 clk => clk,
152 resetn => reset_n,
153 system_clk => system_clk,
154 locked => system_clk_locked
155 );
156
157 processor: entity work.core
158 port map(
159 clk => system_clk,
160 rst => reset,
161
162 wishbone_out => wishbone_proc_out,
163 wishbone_in => wishbone_proc_in
164 );
165 processor_adr_out <= wishbone_proc_out.adr;
166 processor_dat_out <= wishbone_proc_out.dat;
167 processor_sel_out <= wishbone_proc_out.sel;
168 processor_cyc_out <= wishbone_proc_out.cyc;
169 processor_stb_out <= wishbone_proc_out.stb;
170 processor_we_out <= wishbone_proc_out.we;
171 wishbone_proc_in.dat <= processor_dat_in;
172 wishbone_proc_in.ack <= processor_ack_in;
173
174 uart0: entity work.pp_soc_uart
175 generic map(
176 FIFO_DEPTH => 32
177 ) port map(
178 clk => system_clk,
179 reset => reset,
180 txd => uart0_txd,
181 rxd => uart0_rxd,
182 wb_adr_in => uart0_adr_in,
183 wb_dat_in => uart0_dat_in,
184 wb_dat_out => uart0_dat_out,
185 wb_cyc_in => uart0_cyc_in,
186 wb_stb_in => uart0_stb_in,
187 wb_we_in => uart0_we_in,
188 wb_ack_out => uart0_ack_out
189 );
190 uart0_adr_in <= processor_adr_out(uart0_adr_in'range);
191 uart0_dat_in <= processor_dat_out(7 downto 0);
192 uart0_we_in <= processor_we_out;
193 uart0_cyc_in <= processor_cyc_out when intercon_peripheral = PERIPHERAL_UART0 else '0';
194 uart0_stb_in <= processor_stb_out when intercon_peripheral = PERIPHERAL_UART0 else '0';
195
196 main_memory: entity work.pp_soc_memory
197 generic map(
198 MEMORY_SIZE => MEMORY_SIZE,
199 RAM_INIT_FILE => RAM_INIT_FILE
200 ) port map(
201 clk => system_clk,
202 reset => reset,
203 wb_adr_in => main_memory_adr_in,
204 wb_dat_in => main_memory_dat_in,
205 wb_dat_out => main_memory_dat_out,
206 wb_cyc_in => main_memory_cyc_in,
207 wb_stb_in => main_memory_stb_in,
208 wb_sel_in => main_memory_sel_in,
209 wb_we_in => main_memory_we_in,
210 wb_ack_out => main_memory_ack_out
211 );
212 main_memory_adr_in <= processor_adr_out(main_memory_adr_in'range);
213 main_memory_dat_in <= processor_dat_out;
214 main_memory_we_in <= processor_we_out;
215 main_memory_sel_in <= processor_sel_out;
216 main_memory_cyc_in <= processor_cyc_out when intercon_peripheral = PERIPHERAL_MAIN_MEMORY else '0';
217 main_memory_stb_in <= processor_stb_out when intercon_peripheral = PERIPHERAL_MAIN_MEMORY else '0';
218
219 end architecture behaviour;