diff --git a/Makefile b/Makefile index 2d34627..1b1f714 100644 --- a/Makefile +++ b/Makefile @@ -54,7 +54,7 @@ core_files = decode_types.vhdl common.vhdl wishbone_types.vhdl fetch1.vhdl \ core.vhdl fpu.vhdl soc_files = wishbone_arbiter.vhdl wishbone_bram_wrapper.vhdl sync_fifo.vhdl \ - wishbone_debug_master.vhdl xics.vhdl syscon.vhdl soc.vhdl \ + wishbone_debug_master.vhdl xics.vhdl syscon.vhdl gpio.vhdl soc.vhdl \ spi_rxtx.vhdl spi_flash_ctrl.vhdl uart_files = $(wildcard uart16550/*.v) diff --git a/fpga/arty_a7.xdc b/fpga/arty_a7.xdc index bf8310c..64e0405 100644 --- a/fpga/arty_a7.xdc +++ b/fpga/arty_a7.xdc @@ -9,15 +9,6 @@ set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports { ext_rst_ set_property -dict { PACKAGE_PIN D10 IOSTANDARD LVCMOS33 } [get_ports { uart_main_tx }]; set_property -dict { PACKAGE_PIN A9 IOSTANDARD LVCMOS33 } [get_ports { uart_main_rx }]; -################################################################################ -# Pmod Header JC: UART (bottom) -################################################################################ - -set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { uart_pmod_cts_n }]; -set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { uart_pmod_tx }]; -set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { uart_pmod_rx }]; -set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { uart_pmod_rts_n }]; - ################################################################################ # RGB LEDs ################################################################################ @@ -138,39 +129,39 @@ set_property IOB true [get_cells -hierarchical -filter {NAME =~*.litesdcard/sdca # Arduino/chipKIT shield connector ################################################################################ -#set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { shield_io0 }]; -#set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { shield_io1 }]; -#set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { shield_io2 }]; -#set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 } [get_ports { shield_io3 }]; -#set_property -dict { PACKAGE_PIN R12 IOSTANDARD LVCMOS33 } [get_ports { shield_io4 }]; -#set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 } [get_ports { shield_io5 }]; -#set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 } [get_ports { shield_io6 }]; -#set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 } [get_ports { shield_io7 }]; -#set_property -dict { PACKAGE_PIN N15 IOSTANDARD LVCMOS33 } [get_ports { shield_io8 }]; -#set_property -dict { PACKAGE_PIN M16 IOSTANDARD LVCMOS33 } [get_ports { shield_io9 }]; -#set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { shield_io10 }]; -#set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { shield_io11 }]; -#set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 } [get_ports { shield_io12 }]; -#set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { shield_io13 }]; -#set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 } [get_ports { shield_io26 }]; -#set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { shield_io27 }]; -#set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { shield_io28 }]; -#set_property -dict { PACKAGE_PIN R10 IOSTANDARD LVCMOS33 } [get_ports { shield_io29 }]; -#set_property -dict { PACKAGE_PIN R11 IOSTANDARD LVCMOS33 } [get_ports { shield_io30 }]; -#set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 } [get_ports { shield_io31 }]; -#set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { shield_io32 }]; -#set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 } [get_ports { shield_io33 }]; -#set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 } [get_ports { shield_io34 }]; -#set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 } [get_ports { shield_io35 }]; -#set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { shield_io36 }]; -#set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { shield_io37 }]; -#set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { shield_io38 }]; -#set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports { shield_io39 }]; -#set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { shield_io40 }]; -#set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { shield_io41 }]; -#set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { shield_ioa }]; -#set_property -dict { PACKAGE_PIN L18 IOSTANDARD LVCMOS33 } [get_ports { shield_scl }]; -#set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { shield_sda }]; +set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[0] }]; +set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[1] }]; +set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[2] }]; +set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[3] }]; +set_property -dict { PACKAGE_PIN R12 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[4] }]; +set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[5] }]; +set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[6] }]; +set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[7] }]; +set_property -dict { PACKAGE_PIN N15 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[8] }]; +set_property -dict { PACKAGE_PIN M16 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[9] }]; +set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[10] }]; +set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[11] }]; +set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[12] }]; +set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[13] }]; +set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[26] }]; +set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[27] }]; +set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[28] }]; +set_property -dict { PACKAGE_PIN R10 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[29] }]; +set_property -dict { PACKAGE_PIN R11 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[30] }]; +set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[31] }]; +set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[32] }]; +set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[33] }]; +set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[34] }]; +set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[35] }]; +set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[36] }]; +set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[37] }]; +set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[38] }]; +set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[39] }]; +set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[40] }]; +set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[41] }]; +set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[42] }]; # A +set_property -dict { PACKAGE_PIN L18 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[43] }]; # SCL +set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[44] }]; # SDA #set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports { shield_rst }]; #set_property -dict { PACKAGE_PIN C1 IOSTANDARD LVCMOS33 } [get_ports { spi_hdr_ss }]; diff --git a/fpga/top-arty.vhdl b/fpga/top-arty.vhdl index cb7f781..8e6ff02 100644 --- a/fpga/top-arty.vhdl +++ b/fpga/top-arty.vhdl @@ -27,7 +27,8 @@ entity toplevel is USE_LITEETH : boolean := false; UART_IS_16550 : boolean := false; HAS_UART1 : boolean := true; - USE_LITESDCARD : boolean := false + USE_LITESDCARD : boolean := false; + NGPIO : natural := 32 ); port( ext_clk : in std_ulogic; @@ -37,12 +38,6 @@ entity toplevel is uart_main_tx : out std_ulogic; uart_main_rx : in std_ulogic; - -- UART1 signals: - uart_pmod_tx : out std_ulogic; - uart_pmod_rx : in std_ulogic; - uart_pmod_cts_n : in std_ulogic; - uart_pmod_rts_n : out std_ulogic; - -- LEDs led0_b : out std_ulogic; led0_g : out std_ulogic; @@ -60,6 +55,9 @@ entity toplevel is spi_flash_wp_n : inout std_ulogic; spi_flash_hold_n : inout std_ulogic; + -- GPIO + shield_io : inout std_ulogic_vector(44 downto 0); + -- Ethernet eth_ref_clk : out std_ulogic; eth_clocks_tx : in std_ulogic; @@ -158,6 +156,11 @@ architecture behaviour of toplevel is signal spi_sdat_oe : std_ulogic_vector(3 downto 0); signal spi_sdat_i : std_ulogic_vector(3 downto 0); + -- GPIO + signal gpio_in : std_ulogic_vector(NGPIO - 1 downto 0); + signal gpio_out : std_ulogic_vector(NGPIO - 1 downto 0); + signal gpio_dir : std_ulogic_vector(NGPIO - 1 downto 0); + -- Fixup various memory sizes based on generics function get_bram_size return natural is begin @@ -203,7 +206,8 @@ begin HAS_LITEETH => USE_LITEETH, UART0_IS_16550 => UART_IS_16550, HAS_UART1 => HAS_UART1, - HAS_SD_CARD => USE_LITESDCARD + HAS_SD_CARD => USE_LITESDCARD, + NGPIO => NGPIO ) port map ( -- System signals @@ -215,8 +219,8 @@ begin uart0_rxd => uart_main_rx, -- UART1 signals - uart1_txd => uart_pmod_tx, - uart1_rxd => uart_pmod_rx, + --uart1_txd => uart_pmod_tx, + --uart1_rxd => uart_pmod_rx, -- SPI signals spi_flash_sck => spi_sck, @@ -225,6 +229,11 @@ begin spi_flash_sdat_oe => spi_sdat_oe, spi_flash_sdat_i => spi_sdat_i, + -- GPIO signals + gpio_in => gpio_in, + gpio_out => gpio_out, + gpio_dir => gpio_dir, + -- External interrupts ext_irq_eth => ext_irq_eth, ext_irq_sdcard => ext_irq_sdcard, @@ -248,7 +257,7 @@ begin alt_reset => core_alt_reset ); - uart_pmod_rts_n <= '0'; + --uart_pmod_rts_n <= '0'; -- SPI Flash -- @@ -678,6 +687,72 @@ begin led4 <= system_clk_locked; led5 <= eth_clk_locked; led6 <= not soc_rst; - led7 <= not spi_flash_cs_n; + + -- GPIO + gpio_in(0) <= shield_io(0); + gpio_in(1) <= shield_io(1); + gpio_in(2) <= shield_io(2); + gpio_in(3) <= shield_io(3); + gpio_in(4) <= shield_io(4); + gpio_in(5) <= shield_io(5); + gpio_in(6) <= shield_io(6); + gpio_in(7) <= shield_io(7); + gpio_in(8) <= shield_io(8); + gpio_in(9) <= shield_io(9); + gpio_in(10) <= shield_io(10); + gpio_in(11) <= shield_io(11); + gpio_in(12) <= shield_io(12); + gpio_in(13) <= shield_io(13); + gpio_in(14) <= shield_io(26); + gpio_in(15) <= shield_io(27); + gpio_in(16) <= shield_io(28); + gpio_in(17) <= shield_io(29); + gpio_in(18) <= shield_io(30); + gpio_in(19) <= shield_io(31); + gpio_in(20) <= shield_io(32); + gpio_in(21) <= shield_io(33); + gpio_in(22) <= shield_io(34); + gpio_in(23) <= shield_io(35); + gpio_in(24) <= shield_io(36); + gpio_in(25) <= shield_io(37); + gpio_in(26) <= shield_io(38); + gpio_in(27) <= shield_io(39); + gpio_in(28) <= shield_io(40); + gpio_in(29) <= shield_io(41); + gpio_in(30) <= shield_io(43); + gpio_in(31) <= shield_io(44); + + shield_io(0) <= gpio_out(0) when gpio_dir(0) = '1' else 'Z'; + shield_io(1) <= gpio_out(1) when gpio_dir(1) = '1' else 'Z'; + shield_io(2) <= gpio_out(2) when gpio_dir(2) = '1' else 'Z'; + shield_io(3) <= gpio_out(3) when gpio_dir(3) = '1' else 'Z'; + shield_io(4) <= gpio_out(4) when gpio_dir(4) = '1' else 'Z'; + shield_io(5) <= gpio_out(5) when gpio_dir(5) = '1' else 'Z'; + shield_io(6) <= gpio_out(6) when gpio_dir(6) = '1' else 'Z'; + shield_io(7) <= gpio_out(7) when gpio_dir(7) = '1' else 'Z'; + shield_io(8) <= gpio_out(8) when gpio_dir(8) = '1' else 'Z'; + shield_io(9) <= gpio_out(9) when gpio_dir(9) = '1' else 'Z'; + shield_io(10) <= gpio_out(10) when gpio_dir(10) = '1' else 'Z'; + shield_io(11) <= gpio_out(11) when gpio_dir(11) = '1' else 'Z'; + shield_io(12) <= gpio_out(12) when gpio_dir(12) = '1' else 'Z'; + shield_io(13) <= gpio_out(13) when gpio_dir(13) = '1' else 'Z'; + shield_io(26) <= gpio_out(14) when gpio_dir(14) = '1' else 'Z'; + shield_io(27) <= gpio_out(15) when gpio_dir(15) = '1' else 'Z'; + shield_io(28) <= gpio_out(16) when gpio_dir(16) = '1' else 'Z'; + shield_io(29) <= gpio_out(17) when gpio_dir(17) = '1' else 'Z'; + shield_io(30) <= gpio_out(18) when gpio_dir(18) = '1' else 'Z'; + shield_io(31) <= gpio_out(19) when gpio_dir(19) = '1' else 'Z'; + shield_io(32) <= gpio_out(20) when gpio_dir(20) = '1' else 'Z'; + shield_io(33) <= gpio_out(21) when gpio_dir(21) = '1' else 'Z'; + shield_io(34) <= gpio_out(22) when gpio_dir(22) = '1' else 'Z'; + shield_io(35) <= gpio_out(23) when gpio_dir(23) = '1' else 'Z'; + shield_io(36) <= gpio_out(24) when gpio_dir(24) = '1' else 'Z'; + shield_io(37) <= gpio_out(25) when gpio_dir(25) = '1' else 'Z'; + shield_io(38) <= gpio_out(26) when gpio_dir(26) = '1' else 'Z'; + shield_io(39) <= gpio_out(27) when gpio_dir(27) = '1' else 'Z'; + shield_io(40) <= gpio_out(28) when gpio_dir(28) = '1' else 'Z'; + shield_io(41) <= gpio_out(29) when gpio_dir(29) = '1' else 'Z'; + shield_io(43) <= gpio_out(30) when gpio_dir(30) = '1' else 'Z'; + shield_io(44) <= gpio_out(31) when gpio_dir(31) = '1' else 'Z'; end architecture behaviour; diff --git a/gpio.vhdl b/gpio.vhdl new file mode 100644 index 0000000..bdce519 --- /dev/null +++ b/gpio.vhdl @@ -0,0 +1,99 @@ +-- GPIO module for microwatt +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.wishbone_types.all; + +entity gpio is + generic ( + NGPIO : integer := 32 + ); + port ( + clk : in std_ulogic; + rst : in std_ulogic; + + -- Wishbone + wb_in : in wb_io_master_out; + wb_out : out wb_io_slave_out; + + -- GPIO lines + gpio_in : in std_ulogic_vector(NGPIO - 1 downto 0); + gpio_out : out std_ulogic_vector(NGPIO - 1 downto 0); + -- 1 = output, 0 = input + gpio_dir : out std_ulogic_vector(NGPIO - 1 downto 0); + + -- Interrupt + intr : out std_ulogic + ); +end entity gpio; + +architecture behaviour of gpio is + constant GPIO_REG_BITS : positive := 5; + + -- Register addresses, matching addr downto 2, so 4 bytes per reg + constant GPIO_REG_DATA_OUT : std_ulogic_vector(GPIO_REG_BITS-1 downto 0) := "00000"; + constant GPIO_REG_DATA_IN : std_ulogic_vector(GPIO_REG_BITS-1 downto 0) := "00001"; + constant GPIO_REG_DIR : std_ulogic_vector(GPIO_REG_BITS-1 downto 0) := "00010"; + constant GPIO_REG_DATA_SET : std_ulogic_vector(GPIO_REG_BITS-1 downto 0) := "00100"; + constant GPIO_REG_DATA_CLR : std_ulogic_vector(GPIO_REG_BITS-1 downto 0) := "00101"; + + -- Current output value and direction + signal reg_data : std_ulogic_vector(NGPIO - 1 downto 0) := (others => '0'); + signal reg_dirn : std_ulogic_vector(NGPIO - 1 downto 0) := (others => '0'); + signal reg_in1 : std_ulogic_vector(NGPIO - 1 downto 0); + signal reg_in2 : std_ulogic_vector(NGPIO - 1 downto 0); + + signal wb_rsp : wb_io_slave_out; + signal reg_out : std_ulogic_vector(NGPIO - 1 downto 0); + +begin + + -- No interrupt facility for now + intr <= '0'; + + gpio_out <= reg_data; + gpio_dir <= reg_dirn; + + -- Wishbone response + wb_rsp.ack <= wb_in.cyc and wb_in.stb; + with wb_in.adr(GPIO_REG_BITS + 1 downto 2) select reg_out <= + reg_data when GPIO_REG_DATA_OUT, + reg_in2 when GPIO_REG_DATA_IN, + reg_dirn when GPIO_REG_DIR, + (others => '0') when others; + wb_rsp.dat(wb_rsp.dat'left downto NGPIO) <= (others => '0'); + wb_rsp.dat(NGPIO - 1 downto 0) <= reg_out; + wb_rsp.stall <= '0'; + + regs_rw: process(clk) + begin + if rising_edge(clk) then + wb_out <= wb_rsp; + reg_in2 <= reg_in1; + reg_in1 <= gpio_in; + if rst = '1' then + reg_data <= (others => '0'); + reg_dirn <= (others => '0'); + wb_out.ack <= '0'; + else + if wb_in.cyc = '1' and wb_in.stb = '1' and wb_in.we = '1' then + case wb_in.adr(GPIO_REG_BITS + 1 downto 2) is + when GPIO_REG_DATA_OUT => + reg_data <= wb_in.dat(NGPIO - 1 downto 0); + when GPIO_REG_DIR => + reg_dirn <= wb_in.dat(NGPIO - 1 downto 0); + when GPIO_REG_DATA_SET => + reg_data <= reg_data or wb_in.dat(NGPIO - 1 downto 0); + when GPIO_REG_DATA_CLR => + reg_data <= reg_data and not wb_in.dat(NGPIO - 1 downto 0); + when others => + end case; + end if; + end if; + end if; + end process; + +end architecture behaviour; + diff --git a/microwatt.core b/microwatt.core index 4911809..a21ba3e 100644 --- a/microwatt.core +++ b/microwatt.core @@ -44,6 +44,7 @@ filesets: - wishbone_bram_wrapper.vhdl - soc.vhdl - xics.vhdl + - gpio.vhdl - syscon.vhdl - sync_fifo.vhdl - spi_rxtx.vhdl diff --git a/soc.vhdl b/soc.vhdl index cee4753..8c0401a 100644 --- a/soc.vhdl +++ b/soc.vhdl @@ -24,6 +24,7 @@ use work.wishbone_types.all; -- 0xc0004000: XICS ICP -- 0xc0005000: XICS ICS -- 0xc0006000: SPI Flash controller +-- 0xc0007000: GPIO controller -- 0xc8nnnnnn: External IO bus -- 0xf0000000: Flash "ROM" mapping -- 0xff000000: DRAM init code (if any) or flash ROM (**) @@ -48,6 +49,7 @@ use work.wishbone_types.all; -- 1 : Ethernet -- 2 : UART1 -- 3 : SD card +-- 4 : GPIO entity soc is generic ( @@ -78,7 +80,8 @@ entity soc is DCACHE_NUM_WAYS : natural := 2; DCACHE_TLB_SET_SIZE : natural := 64; DCACHE_TLB_NUM_WAYS : natural := 2; - HAS_SD_CARD : boolean := false + HAS_SD_CARD : boolean := false; + NGPIO : natural := 0 ); port( rst : in std_ulogic; @@ -119,6 +122,11 @@ entity soc is spi_flash_sdat_oe : out std_ulogic_vector(SPI_FLASH_DLINES-1 downto 0); spi_flash_sdat_i : in std_ulogic_vector(SPI_FLASH_DLINES-1 downto 0) := (others => '1'); + -- GPIO signals + gpio_out : out std_ulogic_vector(NGPIO - 1 downto 0); + gpio_dir : out std_ulogic_vector(NGPIO - 1 downto 0); + gpio_in : in std_ulogic_vector(NGPIO - 1 downto 0) := (others => '0'); + -- DRAM controller signals alt_reset : in std_ulogic := '0' ); @@ -186,6 +194,11 @@ architecture behaviour of soc is signal ics_to_icp : ics_to_icp_t; signal core_ext_irq : std_ulogic; + -- GPIO signals: + signal wb_gpio_in : wb_io_master_out; + signal wb_gpio_out : wb_io_slave_out; + signal gpio_intr : std_ulogic := '0'; + -- Main memory signals: signal wb_bram_in : wishbone_master_out; signal wb_bram_out : wishbone_slave_out; @@ -211,6 +224,7 @@ architecture behaviour of soc is signal rst_uart : std_ulogic := '1'; signal rst_xics : std_ulogic := '1'; signal rst_spi : std_ulogic := '1'; + signal rst_gpio : std_ulogic := '1'; signal rst_bram : std_ulogic := '1'; signal rst_dtm : std_ulogic := '1'; signal rst_wbar : std_ulogic := '1'; @@ -225,6 +239,7 @@ architecture behaviour of soc is SLAVE_IO_UART1, SLAVE_IO_SPI_FLASH_REG, SLAVE_IO_SPI_FLASH_MAP, + SLAVE_IO_GPIO, SLAVE_IO_EXTERNAL, SLAVE_IO_NONE); signal slave_io_dbg : slave_io_type; @@ -294,6 +309,7 @@ begin rst_uart <= rst; rst_spi <= rst; rst_xics <= rst; + rst_gpio <= rst; rst_bram <= rst; rst_dtm <= rst; rst_wbar <= rst; @@ -603,6 +619,8 @@ begin slave_io := SLAVE_IO_ICS; elsif std_match(match, x"C0006") then slave_io := SLAVE_IO_SPI_FLASH_REG; + elsif std_match(match, x"C0007") then + slave_io := SLAVE_IO_GPIO; end if; slave_io_dbg <= slave_io; wb_uart0_in <= wb_sio_out; @@ -613,6 +631,8 @@ begin wb_spiflash_in.cyc <= '0'; wb_spiflash_is_reg <= '0'; wb_spiflash_is_map <= '0'; + wb_gpio_in <= wb_sio_out; + wb_gpio_in.cyc <= '0'; -- Only give xics 8 bits of wb addr (for now...) wb_xics_icp_in <= wb_sio_out; @@ -696,6 +716,9 @@ begin wb_spiflash_in.cyc <= wb_sio_out.cyc; wb_sio_in <= wb_spiflash_out; wb_spiflash_is_reg <= '1'; + when SLAVE_IO_GPIO => + wb_gpio_in.cyc <= wb_sio_out.cyc; + wb_sio_in <= wb_gpio_out; when others => end case; @@ -890,6 +913,21 @@ begin icp_out => ics_to_icp ); + gpio : entity work.gpio + generic map( + NGPIO => NGPIO + ) + port map( + clk => system_clk, + rst => rst_gpio, + wb_in => wb_gpio_in, + wb_out => wb_gpio_out, + gpio_in => gpio_in, + gpio_out => gpio_out, + gpio_dir => gpio_dir, + intr => gpio_intr + ); + -- Assign external interrupts interrupts: process(all) begin @@ -898,6 +936,7 @@ begin int_level_in(1) <= ext_irq_eth; int_level_in(2) <= uart1_irq; int_level_in(3) <= ext_irq_sdcard; + int_level_in(4) <= gpio_intr; end process; -- BRAM Memory slave