Merge pull request #461 from paulusmack/master

Improvements for the Arty A7 board
master
Paul Mackerras 2 days ago committed by GitHub
commit efd0571b5f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,331 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library unisim;
use unisim.vcomponents.all;

library work;
use work.wishbone_types.all;

-- Interface for LCD/touchscreen connected to Arduino-compatible socket on Arty A7
entity lcd_touchscreen is
port (
clk : in std_ulogic;
rst : in std_ulogic;
wb_in : in wb_io_master_out;
wb_out : out wb_io_slave_out;
wb_sel : in std_ulogic;
tp : out std_ulogic;

lcd_din : in std_ulogic_vector(7 downto 0);
lcd_dout : out std_ulogic_vector(7 downto 0);
lcd_doe : out std_ulogic;
lcd_doe0 : out std_ulogic;
lcd_doe1 : out std_ulogic;
lcd_rd : out std_ulogic; -- note active low
lcd_wr : out std_ulogic; -- note active low
lcd_rs : out std_ulogic;
lcd_rsoe : out std_ulogic;
lcd_cs : out std_ulogic; -- note active low
lcd_csoe : out std_ulogic;
lcd_rst : out std_ulogic; -- note active low

-- Differential analog inputs from touchscreen
a2_p : in std_ulogic;
a2_n : in std_ulogic;
a3_p : in std_ulogic;
a3_n : in std_ulogic;
a4_p : in std_ulogic;
a4_n : in std_ulogic;
a5_p : in std_ulogic;
a5_n : in std_ulogic
);
end entity lcd_touchscreen;

architecture rtl of lcd_touchscreen is

type state_t is (idle, prep1, prep2, writing, wr_pause, reading, rd_recovery,
drp_lo, drp_hi);

signal state : state_t;
signal delay : unsigned(5 downto 0);
signal ack : std_ulogic;
signal idle1 : std_ulogic;
signal idle2 : std_ulogic;

signal rs : std_ulogic;
signal rsoe : std_ulogic;
signal cs : std_ulogic;
signal csoe : std_ulogic;
signal d0 : std_ulogic;
signal doe0 : std_ulogic;
signal doe1 : std_ulogic;
signal d1 : std_ulogic;
signal tsctrl : std_ulogic;

signal wr_data : std_ulogic_vector(31 downto 0);
signal rd_data : std_ulogic_vector(31 downto 0);
signal wr_sel : std_ulogic_vector(3 downto 0);
signal req_wr : std_ulogic;

signal xadc_di : std_ulogic_vector(15 downto 0);
signal xadc_do : std_ulogic_vector(15 downto 0);
signal xadc_addr : std_ulogic_vector(6 downto 0);
signal xadc_en : std_ulogic;
signal xadc_we : std_ulogic;
signal xadc_rdy : std_ulogic;
signal xadc_eoc : std_ulogic;
signal xadc_eos : std_ulogic;
signal xadc_busy : std_ulogic;
signal eoc_stat : std_ulogic;
signal eos_stat : std_ulogic;

-- Assume touchscreen is connected to the A2 - A5 analog inputs

begin

-- The connection of the analog A0 - A5 pins on the Arty
-- to FPGA pins is as follows:
-- A0 connects to AD4P/AD4N
-- A1 connects to AD5P/AD5N
-- A2 connects to AD6P/AD6N
-- A3 connects to AD7P/AD7N
-- A4 connects to AD15P/AD15N
-- A5 connects to AD0P/AD0N
xadc_0 : XADC
generic map (
init_42 => x"0400" -- adcclk = dclk / 4, i.e. 25MHz
)
port map (
di => xadc_di,
do => xadc_do,
daddr => xadc_addr,
den => xadc_en,
dwe => xadc_we,
dclk => clk,
drdy => xadc_rdy,
reset => rst,
convst => '0',
convstclk => '0',
vp => '0',
vn => '0',
vauxp => a4_p & "0000000" & a3_p & a2_p & "00000" & a5_p,
vauxn => a4_n & "0000000" & a3_n & a2_n & "00000" & a5_n,
eoc => xadc_eoc,
eos => xadc_eos,
busy => xadc_busy
);

-- for now; should make sure it is at least 10us wide
lcd_rst <= not rst;

wb_out.dat <= rd_data;
wb_out.ack <= ack;
wb_out.stall <= '0' when state = idle else '1';

lcd_doe0 <= doe0;
lcd_doe1 <= doe1;
lcd_rs <= rs;
lcd_rsoe <= rsoe;
lcd_cs <= cs;
lcd_csoe <= csoe;

tp <= tsctrl;

process (clk)
variable rdat : std_ulogic_vector(7 downto 0);
begin
if rising_edge(clk) then
ack <= '0';
xadc_en <= '0';
idle2 <= idle1;
if xadc_eoc = '1' then
eoc_stat <= '1';
end if;
if xadc_eos = '1' then
eos_stat <= '1';
end if;
if rst = '1' then
state <= idle;
delay <= to_unsigned(0, 6);
rd_data <= (others => '0');
lcd_rd <= '1';
lcd_wr <= '1';
cs <= '1';
csoe <= '1';
rs <= '0';
rsoe <= '1';
lcd_doe <= '0';
doe0 <= '0';
doe1 <= '0';
d0 <= '0';
d1 <= '0';
idle1 <= '0';
idle2 <= '0';
tsctrl <= '0';
xadc_en <= '0';
eoc_stat <= '0';
eos_stat <= '0';
elsif delay /= "000000" then
delay <= delay - 1;
else
case state is
when idle =>
req_wr <= wb_in.we;
wr_data <= wb_in.dat;
wr_sel <= wb_in.sel;
if idle2 = '1' then
-- delay this one cycle after entering idle
lcd_doe <= '0';
doe0 <= '0';
doe1 <= '0';
end if;
idle1 <= '0';
if wb_in.cyc = '1' and wb_in.stb = '1' and wb_sel = '1' then
if wb_in.sel = "0000" then
ack <= '1';
elsif wb_in.adr(6) = '0' then
if wb_in.we = '1' or wb_in.adr(2) = '1' then
ack <= '1';
end if;
if wb_in.adr(2) = '0' then
-- c8050000 or 8, access LCD controller chip
tsctrl <= '0';
csoe <= '1';
cs <= '0'; -- active low
rsoe <= '1';
rs <= wb_in.adr(1);
doe0 <= '0';
doe1 <= '0';
state <= prep1;
elsif wb_in.adr(1) = '0' then
-- c8050010, touchscreen drive register
tsctrl <= '1';
idle2 <= '0';
rdat := rsoe & rs & doe0 & d0 & doe1 & d1 & csoe & cs;
rd_data <= rdat & rdat & rdat & rdat;
if wb_in.we = '1' and wb_in.sel(0) = '1' then
rsoe <= wb_in.dat(7);
rs <= wb_in.dat(6);
doe0 <= wb_in.dat(5);
d0 <= wb_in.dat(4);
lcd_dout(0) <= wb_in.dat(4);
doe1 <= wb_in.dat(3);
d1 <= wb_in.dat(2);
lcd_dout(1) <= wb_in.dat(2);
csoe <= wb_in.dat(1);
cs <= wb_in.dat(0);
end if;
else
-- c8050018, touchscreen status register
rdat := 4x"0" & xadc_busy & eoc_stat & eos_stat & tsctrl;
rd_data <= rdat & rdat & rdat & rdat;
if wb_in.we = '1' and wb_in.sel(0) = '1' then
-- for eoc_stat and eos_state, write 0 to clear
if wb_in.dat(2) = '0' then
eoc_stat <= '0';
end if;
if wb_in.dat(1) = '0' then
eos_stat <= '0';
end if;
end if;
end if;
else
-- c80501xx, access to the XADC DRP port
xadc_en <= '1';
xadc_we <= wb_in.we;
xadc_addr(6 downto 1) <= wb_in.adr(5 downto 0);
if wb_in.sel(1 downto 0) = "00" then
xadc_di <= wb_in.dat(31 downto 16);
xadc_addr(0) <= '1';
state <= drp_hi;
else
xadc_di <= wb_in.dat(15 downto 0);
xadc_addr(0) <= '0';
state <= drp_lo;
end if;
end if;
else
if tsctrl = '0' then
cs <= '1';
end if;
end if;
when prep1 =>
lcd_doe <= req_wr;
doe0 <= req_wr;
doe1 <= req_wr;
if req_wr = '1' then
if wr_sel(1 downto 0) /= "00" then
if wr_sel(1) = '1' then
lcd_dout <= wr_data(15 downto 8);
wr_sel(1) <= '0';
else
lcd_dout <= wr_data(7 downto 0);
wr_sel(0) <= '0';
end if;
else
if wr_sel(3) = '1' then
lcd_dout <= wr_data(31 downto 24);
wr_sel(3) <= '0';
else
lcd_dout <= wr_data(23 downto 16);
wr_sel(2) <= '0';
end if;
end if;
end if;
state <= prep2;
when prep2 =>
if req_wr = '1' then
lcd_wr <= '0'; -- active low
state <= writing;
delay <= to_unsigned(1, 6);
else
lcd_rd <= '0';
state <= reading;
delay <= to_unsigned(35, 6);
end if;
when writing =>
-- last cycle of writing state
lcd_wr <= '1';
if wr_sel = "0000" then
state <= idle;
idle1 <= '1';
else
state <= wr_pause;
end if;
when wr_pause =>
state <= prep1;
when reading =>
-- last cycle of reading state
lcd_rd <= '1';
rd_data <= lcd_din & lcd_din & lcd_din & lcd_din;
ack <= '1';
state <= rd_recovery;
delay <= to_unsigned(6, 6);
when rd_recovery =>
state <= idle;
when drp_lo =>
if xadc_rdy = '1' then
rd_data(15 downto 0) <= xadc_do;
if wr_sel(3 downto 2) = "00" then
ack <= '1';
state <= idle;
else
xadc_di <= wr_data(31 downto 16);
xadc_addr(0) <= '1';
state <= drp_hi;
end if;
end if;
when drp_hi =>
if xadc_rdy = '1' then
rd_data(31 downto 16) <= xadc_do;
ack <= '1';
state <= idle;
end if;
end case;
end if;
end if;
end process;

end architecture;

@ -82,14 +82,14 @@ set_property IOB true [get_cells -hierarchical -filter {NAME =~*/spi_rxtx/input_
#set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { pmod_ja_10 }];

# connection to Digilent PmodSD on JA
set_property -dict { PACKAGE_PIN G13 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[3] }];
set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_cmd }];
set_property -dict { PACKAGE_PIN A11 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[0] }];
set_property -dict { PACKAGE_PIN D12 IOSTANDARD LVCMOS33 SLEW FAST } [get_ports { sdcard_clk }];
set_property -dict { PACKAGE_PIN D13 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[1] }];
set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[2] }];
set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVCMOS33 } [get_ports { sdcard_cd }];
#set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { sdcard_wp }];
set_property -dict { PACKAGE_PIN G13 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { ja_sdcard_data[3] }];
set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { ja_sdcard_cmd }];
set_property -dict { PACKAGE_PIN A11 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { ja_sdcard_data[0] }];
set_property -dict { PACKAGE_PIN D12 IOSTANDARD LVCMOS33 SLEW FAST } [get_ports { ja_sdcard_clk }];
set_property -dict { PACKAGE_PIN D13 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { ja_sdcard_data[1] }];
set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { ja_sdcard_data[2] }];
set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVCMOS33 } [get_ports { ja_sdcard_cd }];
#set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { ja_sdcard_wp }];

# Put registers into IOBs to improve timing
set_property IOB true [get_cells -hierarchical -filter {NAME =~*.litesdcard/sdpads_data_i_reg*}]
@ -101,14 +101,14 @@ set_property IOB true [get_cells -hierarchical -filter {NAME =~*.litesdcard/sdpa
# PMOD header JB (high-speed, no protection resisters)
################################################################################

#set_property -dict { PACKAGE_PIN E15 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_1 }];
#set_property -dict { PACKAGE_PIN E16 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_2 }];
#set_property -dict { PACKAGE_PIN D15 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_3 }];
#set_property -dict { PACKAGE_PIN C15 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_4 }];
#set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_7 }];
#set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_8 }];
#set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_9 }];
#set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_10 }];
set_property -dict { PACKAGE_PIN E15 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_1 }];
set_property -dict { PACKAGE_PIN E16 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_2 }];
set_property -dict { PACKAGE_PIN D15 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_3 }];
set_property -dict { PACKAGE_PIN C15 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_4 }];
set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_7 }];
set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_8 }];
set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_9 }];
set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_10 }];

# connection to Digilent PmodSD on JB
#set_property -dict { PACKAGE_PIN E15 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[3] }];
@ -133,6 +133,22 @@ set_property IOB true [get_cells -hierarchical -filter {NAME =~*.litesdcard/sdpa
#set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { pmod_jc_9 }];
#set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { pmod_jc_10 }];

# connection to second Digilent PmodSD on JC
set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard2_data[3] }];
set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard2_cmd }];
set_property -dict { PACKAGE_PIN V10 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard2_data[0] }];
set_property -dict { PACKAGE_PIN V11 IOSTANDARD LVCMOS33 SLEW FAST } [get_ports { sdcard2_clk }];
set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard2_data[1] }];
set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard2_data[2] }];
set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { sdcard2_cd }];
#set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { sdcard2_wp }];

# Put registers into IOBs to improve timing
set_property IOB true [get_cells -hierarchical -filter {NAME =~*.litesdcard2/sdpads_data_i_reg*}]
set_property IOB true [get_cells -hierarchical -filter {NAME =~*.litesdcard2/xilinxsdrtristateimpl*_o_reg}]
set_property IOB true [get_cells -hierarchical -filter {NAME =~*.litesdcard2/sdcard_clk_reg}]
set_property IOB true [get_cells -hierarchical -filter {NAME =~*.litesdcard2/sdpads_cmd_i_reg}]

################################################################################
# PMOD header JD (standard, 200 ohm protection resisters)
################################################################################
@ -146,43 +162,91 @@ set_property IOB true [get_cells -hierarchical -filter {NAME =~*.litesdcard/sdpa
#set_property -dict { PACKAGE_PIN H2 IOSTANDARD LVCMOS33 } [get_ports { pmod_jd_9 }];
#set_property -dict { PACKAGE_PIN G2 IOSTANDARD LVCMOS33 } [get_ports { pmod_jd_10 }];

# connection to i2c RTC chip (Dallas DS3231) on JD
set_property -dict { PACKAGE_PIN D2 IOSTANDARD LVCMOS33 PULLUP TRUE } [get_ports { i2c_rtc_d }];
set_property -dict { PACKAGE_PIN H2 IOSTANDARD LVCMOS33 PULLUP TRUE } [get_ports { i2c_rtc_c }];

################################################################################
# TFT LCD shield (arduino-compatible)
# hacked to swap the LCD_RST and LCD_D0 lines, and put LCD_D1 on A5
################################################################################

set_property -dict { PACKAGE_PIN N15 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { lcd_rst }];
#set_property -dict { PACKAGE_PIN M16 IOSTANDARD LVCMOS33 } [get_ports { lcd_tp }];
set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { lcd_d[2] }];
set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 } [get_ports { lcd_d[3] }];
set_property -dict { PACKAGE_PIN R12 IOSTANDARD LVCMOS33 } [get_ports { lcd_d[4] }];
set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 } [get_ports { lcd_d[5] }];
set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 } [get_ports { lcd_d[6] }];
set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 } [get_ports { lcd_d[7] }];
set_property -dict { PACKAGE_PIN F5 IOSTANDARD LVCMOS33 PULLUP TRUE } [get_ports { lcd_rd }]; # A0
set_property -dict { PACKAGE_PIN D8 IOSTANDARD LVCMOS33 PULLUP TRUE } [get_ports { lcd_wr }]; # A1
set_property -dict { PACKAGE_PIN C7 IOSTANDARD LVCMOS33 } [get_ports { lcd_rs }]; # A2
set_property -dict { PACKAGE_PIN E7 IOSTANDARD LVCMOS33 } [get_ports { lcd_cs }]; # A3
set_property -dict { PACKAGE_PIN D7 IOSTANDARD LVCMOS33 } [get_ports { lcd_d[0] }]; # A4
set_property -dict { PACKAGE_PIN D5 IOSTANDARD LVCMOS33 } [get_ports { lcd_d[1] }]; # A5

################################################################################
# Analog inputs (connected to touchscreen)
################################################################################
set_property -dict { PACKAGE_PIN C4 IOSTANDARD LVCMOS33 } [get_ports { a2_p }];
set_property -dict { PACKAGE_PIN B4 IOSTANDARD LVCMOS33 } [get_ports { a2_n }];
set_property -dict { PACKAGE_PIN B1 IOSTANDARD LVCMOS33 } [get_ports { a3_p }];
set_property -dict { PACKAGE_PIN A1 IOSTANDARD LVCMOS33 } [get_ports { a3_n }];
set_property -dict { PACKAGE_PIN B3 IOSTANDARD LVCMOS33 } [get_ports { a4_p }];
set_property -dict { PACKAGE_PIN B2 IOSTANDARD LVCMOS33 } [get_ports { a4_n }];
set_property -dict { PACKAGE_PIN D14 IOSTANDARD LVCMOS33 } [get_ports { a5_p }];
set_property -dict { PACKAGE_PIN C14 IOSTANDARD LVCMOS33 } [get_ports { a5_n }];

################################################################################
# connection to micro SD card socket on touchscreen board
################################################################################
set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { ts_sdcard_data[3] }];
set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { ts_sdcard_cmd }];
set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { ts_sdcard_data[0] }];
set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 SLEW FAST } [get_ports { ts_sdcard_clk }];
set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { ts_sdcard_data[1] }];
set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { ts_sdcard_data[2] }];
set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 PULLUP TRUE } [get_ports { ts_sdcard_cd }];
#set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { ts_sdcard_wp }];

################################################################################
# Arduino/chipKIT shield connector
################################################################################

set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io0 }];
set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io1 }];
set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io2 }];
set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io3 }];
set_property -dict { PACKAGE_PIN R12 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io4 }];
set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io5 }];
set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io6 }];
set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io7 }];
set_property -dict { PACKAGE_PIN N15 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io8 }];
#set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io0 }];
#set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io1 }];
#set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io2 }];
#set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io3 }];
#set_property -dict { PACKAGE_PIN R12 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io4 }];
#set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io5 }];
#set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io6 }];
#set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io7 }];
#set_property -dict { PACKAGE_PIN N15 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io8 }];
set_property -dict { PACKAGE_PIN M16 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io9 }];
set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io10 }];
set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io11 }];
set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io12 }];
set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io13 }];
set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io26 }];
set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io27 }];
set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io28 }];
set_property -dict { PACKAGE_PIN R10 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io29 }];
#set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io10 }];
#set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io11 }];
#set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io12 }];
#set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io13 }];
#set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io26 }];
#set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io27 }];
#set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io28 }];
#set_property -dict { PACKAGE_PIN R10 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io29 }];
set_property -dict { PACKAGE_PIN R11 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io30 }];
set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io31 }];
set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io32 }];
set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io33 }];
set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io34 }];
set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io35 }];
set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io36 }];
set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io37 }];
set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io38 }];
set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io39 }];
set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io40 }];
set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io41 }];
#set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io34 }];
#set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io35 }];
#set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io36 }];
#set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io37 }];
#set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io38 }];
#set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io39 }];
#set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io40 }];
#set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io41 }];
#set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io42 }]; # A
set_property -dict { PACKAGE_PIN L18 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io43 }]; # SCL
set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io44 }]; # SDA
#set_property -dict { PACKAGE_PIN L18 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io43 }]; # SCL
#set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io44 }]; # 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 }];

@ -30,6 +30,7 @@ entity toplevel is
HAS_UART1 : boolean := true;
USE_LITESDCARD : boolean := false;
HAS_GPIO : boolean := true;
USE_LCD : boolean := true;
NGPIO : natural := 32
);
port(
@ -68,38 +69,46 @@ entity toplevel is
sw3 : in std_ulogic;

-- GPIO
shield_io0 : inout std_ulogic;
shield_io1 : inout std_ulogic;
shield_io2 : inout std_ulogic;
shield_io3 : inout std_ulogic;
shield_io4 : inout std_ulogic;
shield_io5 : inout std_ulogic;
shield_io6 : inout std_ulogic;
shield_io7 : inout std_ulogic;
shield_io8 : inout std_ulogic;
--shield_io0 : inout std_ulogic;
--shield_io1 : inout std_ulogic;
--shield_io2 : inout std_ulogic;
--shield_io3 : inout std_ulogic;
--shield_io4 : inout std_ulogic;
--shield_io5 : inout std_ulogic;
--shield_io6 : inout std_ulogic;
--shield_io7 : inout std_ulogic;
--shield_io8 : inout std_ulogic;
shield_io9 : inout std_ulogic;
shield_io10 : inout std_ulogic;
shield_io11 : inout std_ulogic;
shield_io12 : inout std_ulogic;
shield_io13 : inout std_ulogic;
shield_io26 : inout std_ulogic;
shield_io27 : inout std_ulogic;
shield_io28 : inout std_ulogic;
shield_io29 : inout std_ulogic;
--shield_io10 : inout std_ulogic;
--shield_io11 : inout std_ulogic;
--shield_io12 : inout std_ulogic;
--shield_io13 : inout std_ulogic;
--shield_io26 : inout std_ulogic;
--shield_io27 : inout std_ulogic;
--shield_io28 : inout std_ulogic;
--shield_io29 : inout std_ulogic;
shield_io30 : inout std_ulogic;
shield_io31 : inout std_ulogic;
shield_io32 : inout std_ulogic;
shield_io33 : inout std_ulogic;
shield_io34 : inout std_ulogic;
shield_io35 : inout std_ulogic;
shield_io36 : inout std_ulogic;
shield_io37 : inout std_ulogic;
shield_io38 : inout std_ulogic;
shield_io39 : inout std_ulogic;
shield_io40 : inout std_ulogic;
shield_io41 : inout std_ulogic;
shield_io43 : inout std_ulogic;
shield_io44 : inout std_ulogic;
--shield_io34 : inout std_ulogic;
--shield_io35 : inout std_ulogic;
--shield_io36 : inout std_ulogic;
--shield_io37 : inout std_ulogic;
--shield_io38 : inout std_ulogic;
--shield_io39 : inout std_ulogic;
--shield_io40 : inout std_ulogic;
--shield_io41 : inout std_ulogic;
--shield_io43 : inout std_ulogic;
--shield_io44 : inout std_ulogic;
pmod_jb_1 : inout std_ulogic;
pmod_jb_2 : inout std_ulogic;
pmod_jb_3 : inout std_ulogic;
pmod_jb_4 : inout std_ulogic;
pmod_jb_7 : inout std_ulogic;
pmod_jb_8 : inout std_ulogic;
pmod_jb_9 : inout std_ulogic;
pmod_jb_10 : inout std_ulogic;

-- Ethernet
eth_ref_clk : out std_ulogic;
@ -116,11 +125,45 @@ entity toplevel is
eth_col : in std_ulogic;
eth_crs : in std_ulogic;

-- SD card
sdcard_data : inout std_ulogic_vector(3 downto 0);
sdcard_cmd : inout std_ulogic;
sdcard_clk : out std_ulogic;
sdcard_cd : in std_ulogic;
-- SD card pmod on JA
ja_sdcard_data : inout std_ulogic_vector(3 downto 0);
ja_sdcard_cmd : inout std_ulogic;
ja_sdcard_clk : out std_ulogic;
ja_sdcard_cd : in std_ulogic;

-- SD card slot on touchscreen/LCD board
ts_sdcard_data : inout std_ulogic_vector(3 downto 0);
ts_sdcard_cmd : inout std_ulogic;
ts_sdcard_clk : out std_ulogic;
ts_sdcard_cd : in std_ulogic;

-- Second SD card
sdcard2_data : inout std_ulogic_vector(3 downto 0);
sdcard2_cmd : inout std_ulogic;
sdcard2_clk : out std_ulogic;
sdcard2_cd : in std_ulogic;

-- I2C RTC chip
i2c_rtc_d : inout std_ulogic;
i2c_rtc_c : inout std_ulogic;

-- LCD display interface
lcd_d : inout std_ulogic_vector(7 downto 0);
lcd_rs : out std_ulogic;
lcd_cs : out std_ulogic;
lcd_rd : out std_ulogic;
lcd_wr : out std_ulogic;
lcd_rst : out std_ulogic;

-- Differential analog inputs from touchscreen
a2_p : in std_ulogic;
a2_n : in std_ulogic;
a3_p : in std_ulogic;
a3_n : in std_ulogic;
a4_p : in std_ulogic;
a4_n : in std_ulogic;
a5_p : in std_ulogic;
a5_n : in std_ulogic;

-- DRAM wires
ddram_a : out std_ulogic_vector(13 downto 0);
@ -146,6 +189,8 @@ architecture behaviour of toplevel is
-- Status
signal run_out : std_ulogic;
signal run_outs : std_ulogic_vector(CPUS-1 downto 0);
signal init_done : std_ulogic;
signal init_err : std_ulogic;

-- Reset signals:
signal soc_rst : std_ulogic;
@ -165,6 +210,7 @@ architecture behaviour of toplevel is
signal wb_ext_is_dram_init : std_ulogic;
signal wb_ext_is_eth : std_ulogic;
signal wb_ext_is_sdcard : std_ulogic;
signal wb_ext_is_lcd : std_ulogic;

-- DRAM main data wishbone connection
signal wb_dram_in : wishbone_master_out;
@ -179,18 +225,28 @@ architecture behaviour of toplevel is

-- LiteSDCard connection
signal ext_irq_sdcard : std_ulogic := '0';
signal ext_irq_sdcard2 : std_ulogic := '0';
signal wb_sdcard_out : wb_io_slave_out := wb_io_slave_out_init;
signal wb_sdcard2_out : wb_io_slave_out := wb_io_slave_out_init;
signal wb_sddma_out : wb_io_master_out := wb_io_master_out_init;
signal wb_sddma_in : wb_io_slave_out;
signal wb_sddma_nr : wb_io_master_out;
signal wb_sddma1_nr : wb_io_master_out;
signal wb_sddma2_nr : wb_io_master_out;
signal wb_sddma_ir : wb_io_slave_out;
signal wb_sddma1_ack : std_ulogic;
signal wb_sddma2_ack : std_ulogic;
-- for conversion from non-pipelined wishbone to pipelined
signal wb_sddma_stb_sent : std_ulogic;

-- LCD touchscreen connection
signal wb_lcd_out : wb_io_slave_out := wb_io_slave_out_init;

-- Status LED
signal led_b_pwm : std_ulogic_vector(3 downto 0);
signal led_r_pwm : std_ulogic_vector(3 downto 0);
signal led_g_pwm : std_ulogic_vector(3 downto 0);
signal led_b_pwm : std_ulogic_vector(3 downto 0) := (others => '0');
signal led_r_pwm : std_ulogic_vector(3 downto 0) := (others => '0');
signal led_g_pwm : std_ulogic_vector(3 downto 0) := (others => '0');
signal disk_activity : std_ulogic := '0';

-- Dumb PWM for the LEDs, those RGB LEDs are too bright otherwise
signal pwm_counter : std_ulogic_vector(8 downto 0);
@ -261,6 +317,8 @@ begin
UART0_IS_16550 => UART_IS_16550,
HAS_UART1 => HAS_UART1,
HAS_SD_CARD => USE_LITESDCARD,
HAS_SD_CARD2 => USE_LITESDCARD,
HAS_LCD => USE_LCD,
HAS_GPIO => HAS_GPIO,
NGPIO => NGPIO
)
@ -295,6 +353,7 @@ begin
-- External interrupts
ext_irq_eth => ext_irq_eth,
ext_irq_sdcard => ext_irq_sdcard,
ext_irq_sdcard2 => ext_irq_sdcard2,

-- DRAM wishbone
wb_dram_in => wb_dram_in,
@ -307,6 +366,7 @@ begin
wb_ext_is_dram_init => wb_ext_is_dram_init,
wb_ext_is_eth => wb_ext_is_eth,
wb_ext_is_sdcard => wb_ext_is_sdcard,
wb_ext_is_lcd => wb_ext_is_lcd,

-- DMA wishbone
wishbone_dma_in => wb_sddma_in,
@ -383,9 +443,8 @@ begin
pll_locked_out => system_clk_locked
);

led_b_pwm <= "1111";
led_r_pwm <= "1111";
led_g_pwm <= "0000";
init_done <= '1';
init_err <= '0';

-- Vivado barfs on those differential signals if left
-- unconnected. So instanciate a diff. buffer and feed
@ -483,9 +542,8 @@ begin
ddram_reset_n => ddram_reset_n
);

led_b_pwm(0) <= not dram_init_done;
led_r_pwm(0) <= dram_init_error;
led_g_pwm(0) <= dram_init_done and not dram_init_error;
init_done <= dram_init_done;
init_err <= dram_init_error;

end generate;

@ -623,7 +681,7 @@ begin
ext_irq_eth <= '0';
end generate;

-- SD card pmod
-- SD card pmod, two interfaces
has_sdcard : if USE_LITESDCARD generate
component litesdcard_core port (
clk : in std_ulogic;
@ -662,49 +720,133 @@ begin
end component;

signal wb_sdcard_cyc : std_ulogic;
signal wb_sdcard2_cyc : std_ulogic;
signal wb_sdcard_adr : std_ulogic_vector(29 downto 0);
signal dma_msel : std_ulogic;
signal other_cyc : std_ulogic;
signal sdc0_activity : std_ulogic := '0';
signal sdc1_activity : std_ulogic := '0';

begin
litesdcard : litesdcard_core
sdcard_ja: if not USE_LCD generate
litesdcard : litesdcard_core
port map (
clk => system_clk,
rst => periph_rst,
wb_ctrl_adr => wb_sdcard_adr,
wb_ctrl_dat_w => wb_ext_io_in.dat,
wb_ctrl_dat_r => wb_sdcard_out.dat,
wb_ctrl_sel => wb_ext_io_in.sel,
wb_ctrl_cyc => wb_sdcard_cyc,
wb_ctrl_stb => wb_ext_io_in.stb,
wb_ctrl_ack => wb_sdcard_out.ack,
wb_ctrl_we => wb_ext_io_in.we,
wb_ctrl_cti => "000",
wb_ctrl_bte => "00",
wb_ctrl_err => open,
wb_dma_adr => wb_sddma1_nr.adr,
wb_dma_dat_w => wb_sddma1_nr.dat,
wb_dma_dat_r => wb_sddma_ir.dat,
wb_dma_sel => wb_sddma1_nr.sel,
wb_dma_cyc => wb_sddma1_nr.cyc,
wb_dma_stb => wb_sddma1_nr.stb,
wb_dma_ack => wb_sddma1_ack,
wb_dma_we => wb_sddma1_nr.we,
wb_dma_cti => open,
wb_dma_bte => open,
wb_dma_err => '0',
sdcard_data => ja_sdcard_data,
sdcard_cmd => ja_sdcard_cmd,
sdcard_clk => ja_sdcard_clk,
sdcard_cd => ja_sdcard_cd,
irq => ext_irq_sdcard
);
end generate;

sdcard_ts: if USE_LCD generate
litesdcard : litesdcard_core
port map (
clk => system_clk,
rst => periph_rst,
wb_ctrl_adr => wb_sdcard_adr,
wb_ctrl_dat_w => wb_ext_io_in.dat,
wb_ctrl_dat_r => wb_sdcard_out.dat,
wb_ctrl_sel => wb_ext_io_in.sel,
wb_ctrl_cyc => wb_sdcard_cyc,
wb_ctrl_stb => wb_ext_io_in.stb,
wb_ctrl_ack => wb_sdcard_out.ack,
wb_ctrl_we => wb_ext_io_in.we,
wb_ctrl_cti => "000",
wb_ctrl_bte => "00",
wb_ctrl_err => open,
wb_dma_adr => wb_sddma1_nr.adr,
wb_dma_dat_w => wb_sddma1_nr.dat,
wb_dma_dat_r => wb_sddma_ir.dat,
wb_dma_sel => wb_sddma1_nr.sel,
wb_dma_cyc => wb_sddma1_nr.cyc,
wb_dma_stb => wb_sddma1_nr.stb,
wb_dma_ack => wb_sddma1_ack,
wb_dma_we => wb_sddma1_nr.we,
wb_dma_cti => open,
wb_dma_bte => open,
wb_dma_err => '0',
sdcard_data => ts_sdcard_data,
sdcard_cmd => ts_sdcard_cmd,
sdcard_clk => ts_sdcard_clk,
sdcard_cd => ts_sdcard_cd,
irq => ext_irq_sdcard
);
end generate;

litesdcard2 : litesdcard_core
port map (
clk => system_clk,
rst => periph_rst,
wb_ctrl_adr => wb_sdcard_adr,
wb_ctrl_dat_w => wb_ext_io_in.dat,
wb_ctrl_dat_r => wb_sdcard_out.dat,
wb_ctrl_dat_r => wb_sdcard2_out.dat,
wb_ctrl_sel => wb_ext_io_in.sel,
wb_ctrl_cyc => wb_sdcard_cyc,
wb_ctrl_cyc => wb_sdcard2_cyc,
wb_ctrl_stb => wb_ext_io_in.stb,
wb_ctrl_ack => wb_sdcard_out.ack,
wb_ctrl_ack => wb_sdcard2_out.ack,
wb_ctrl_we => wb_ext_io_in.we,
wb_ctrl_cti => "000",
wb_ctrl_bte => "00",
wb_ctrl_err => open,
wb_dma_adr => wb_sddma_nr.adr,
wb_dma_dat_w => wb_sddma_nr.dat,
wb_dma_adr => wb_sddma2_nr.adr,
wb_dma_dat_w => wb_sddma2_nr.dat,
wb_dma_dat_r => wb_sddma_ir.dat,
wb_dma_sel => wb_sddma_nr.sel,
wb_dma_cyc => wb_sddma_nr.cyc,
wb_dma_stb => wb_sddma_nr.stb,
wb_dma_ack => wb_sddma_ir.ack,
wb_dma_we => wb_sddma_nr.we,
wb_dma_sel => wb_sddma2_nr.sel,
wb_dma_cyc => wb_sddma2_nr.cyc,
wb_dma_stb => wb_sddma2_nr.stb,
wb_dma_ack => wb_sddma2_ack,
wb_dma_we => wb_sddma2_nr.we,
wb_dma_cti => open,
wb_dma_bte => open,
wb_dma_err => '0',
sdcard_data => sdcard_data,
sdcard_cmd => sdcard_cmd,
sdcard_clk => sdcard_clk,
sdcard_cd => sdcard_cd,
irq => ext_irq_sdcard
sdcard_data => sdcard2_data,
sdcard_cmd => sdcard2_cmd,
sdcard_clk => sdcard2_clk,
sdcard_cd => sdcard2_cd,
irq => ext_irq_sdcard2
);

-- Gate cyc with chip select from SoC
wb_sdcard_cyc <= wb_ext_io_in.cyc and wb_ext_is_sdcard;
-- Gate cyc with chip selects from SoC
-- Select first or second interface based on real address bit 15
wb_sdcard_cyc <= wb_ext_io_in.cyc and wb_ext_is_sdcard and not wb_ext_io_in.adr(13);
wb_sdcard2_cyc <= wb_ext_io_in.cyc and wb_ext_is_sdcard and wb_ext_io_in.adr(13);

wb_sdcard_adr <= x"0000" & wb_ext_io_in.adr(13 downto 0);
wb_sdcard_adr <= 17x"0" & wb_ext_io_in.adr(12 downto 0);

wb_sdcard_out.stall <= not wb_sdcard_out.ack;

wb_sdcard2_out.stall <= not wb_sdcard2_out.ack;

-- Simple arbiter to multiplex the two DMA wishbones
wb_sddma_nr <= wb_sddma1_nr when dma_msel = '0' else wb_sddma2_nr;
wb_sddma1_ack <= wb_sddma_ir.ack and not dma_msel;
wb_sddma2_ack <= wb_sddma_ir.ack and dma_msel;
other_cyc <= wb_sddma2_nr.cyc when dma_msel = '0' else wb_sddma1_nr.cyc;
-- Convert non-pipelined DMA wishbone to pipelined by suppressing
-- non-acknowledged strobes
process(system_clk)
@ -721,16 +863,113 @@ begin
wb_sddma_stb_sent <= wb_sddma_nr.stb;
end if;
wb_sddma_ir <= wb_sddma_in;

-- Decide which wishbone to use next cycle
if periph_rst = '1' then
dma_msel <= '0';
elsif wb_sddma_nr.cyc = '0' and other_cyc = '1' then
dma_msel <= not dma_msel;
end if;
end if;
end process;

-- Capture writes to the interrupt enable registers, and record
-- the state of the command-done interrupt enable bit to use
-- as an activity indicator.
process(system_clk)
begin
if rising_edge(system_clk) then
if periph_rst = '1' then
sdc0_activity <= '0';
sdc1_activity <= '0';
elsif wb_sdcard_adr(11 downto 0) = x"602"
and wb_ext_io_in.stb = '1' and wb_ext_io_in.we = '1' then
if wb_sdcard_cyc = '1' then
sdc0_activity <= wb_ext_io_in.dat(3);
end if;
if wb_sdcard2_cyc = '1' then
sdc1_activity <= wb_ext_io_in.dat(3);
end if;
end if;
end if;
end process;
disk_activity <= sdc0_activity or sdc1_activity;
end generate;

-- LCD touchscreen on arduino-compatible pins
has_lcd : if USE_LCD generate
signal lcd_dout : std_ulogic_vector(7 downto 0);
signal lcd_doe : std_ulogic;
signal lcd_doe0 : std_ulogic;
signal lcd_doe1 : std_ulogic;
signal lcd_rso : std_ulogic;
signal lcd_rsoe : std_ulogic;
signal lcd_cso : std_ulogic;
signal lcd_csoe : std_ulogic;
signal tp : std_ulogic;
begin
lcd0 : entity work.lcd_touchscreen
port map (
clk => system_clk,
rst => soc_rst,
wb_in => wb_ext_io_in,
wb_out => wb_lcd_out,
wb_sel => wb_ext_is_lcd,
tp => tp,

lcd_din => lcd_d,
lcd_dout => lcd_dout,
lcd_doe => lcd_doe,
lcd_doe0 => lcd_doe0,
lcd_doe1 => lcd_doe1,
lcd_rd => lcd_rd,
lcd_wr => lcd_wr,
lcd_rs => lcd_rso,
lcd_rsoe => lcd_rsoe,
lcd_cs => lcd_cso,
lcd_csoe => lcd_csoe,
lcd_rst => lcd_rst,

a2_p => a2_p,
a2_n => a2_n,
a3_p => a3_p,
a3_n => a3_n,
a4_p => a4_p,
a4_n => a4_n,
a5_p => a5_p,
a5_n => a5_n
);
-- lcd_d(0), lcd_d(1), lcd_rs, lcd_cs are used for the touchscreen
-- interface and hence have individual output enables.
lcd_d(0) <= lcd_dout(0) when lcd_doe0 = '1' else 'Z';
lcd_d(1) <= lcd_dout(1) when lcd_doe1 = '1' else 'Z';
lcd_d(7 downto 2) <= lcd_dout(7 downto 2) when lcd_doe = '1' else (others => 'Z');
lcd_rs <= lcd_rso when lcd_rsoe = '1' else 'Z';
lcd_cs <= lcd_cso when lcd_csoe = '1' else 'Z';
end generate;

-- Mux WB response on the IO bus
wb_ext_io_out <= wb_eth_out when wb_ext_is_eth = '1' else
wb_sdcard_out when wb_ext_is_sdcard = '1' else
wb_sdcard_out when wb_ext_is_sdcard = '1' and wb_ext_io_in.adr(13) = '0' else
wb_sdcard2_out when wb_ext_is_sdcard = '1' and wb_ext_io_in.adr(13) = '1' else
wb_lcd_out when wb_ext_is_lcd = '1' else
wb_dram_ctrl_out;

status_led_colour : process(all)
variable rgb : std_ulogic_vector(2 downto 0);
begin
if soc_rst = '1' then
rgb := "000";
elsif system_clk_locked = '0' then
rgb := "110";
else
rgb := init_err & (init_done and not init_err) & (not init_done);
end if;
led_r_pwm(0) <= rgb(2);
led_g_pwm(0) <= rgb(1);
led_b_pwm(0) <= rgb(0);
end process;

leds_pwm : process(system_clk)
begin
if rising_edge(system_clk) then
@ -747,8 +986,8 @@ begin
end if;
end process;

led4 <= system_clk_locked;
led5 <= not soc_rst;
led4 <= '0';
led5 <= disk_activity;
led6 <= run_outs(1) when CPUS > 1 else '0';
led7 <= run_outs(0);

@ -762,82 +1001,58 @@ begin
gpio_in(16) <= sw2;
gpio_in(17) <= sw3;

gpio_in(0) <= shield_io10;
gpio_in(1) <= shield_io11;
gpio_in(2) <= shield_io12;
gpio_in(3) <= shield_io13;
gpio_in(4) <= shield_io26;
gpio_in(5) <= shield_io27;
gpio_in(6) <= shield_io28;
gpio_in(7) <= shield_io29;
gpio_in(8) <= shield_io8;
gpio_in(0) <= '0';
gpio_in(1) <= '0';
gpio_in(2) <= '0';
gpio_in(3) <= '0';
gpio_in(4) <= '0';
gpio_in(5) <= '0';
gpio_in(6) <= '0';
gpio_in(7) <= '0';
gpio_in(8) <= '0';

gpio_in(9) <= shield_io9;
--gpio_in(10) <= shield_io10;
--gpio_in(11) <= shield_io11;
--gpio_in(12) <= shield_io12;
--gpio_in(13) <= shield_io13;
--gpio_in(14) <= shield_io26;
--gpio_in(15) <= shield_io27;
--gpio_in(16) <= shield_io28;
--gpio_in(17) <= shield_io29;
gpio_in(18) <= shield_io30;
gpio_in(19) <= shield_io31;
gpio_in(20) <= shield_io32;
gpio_in(21) <= shield_io33;
gpio_in(22) <= shield_io34;
gpio_in(23) <= shield_io35;
gpio_in(24) <= shield_io36;
gpio_in(25) <= shield_io37;
gpio_in(26) <= shield_io38;
gpio_in(27) <= shield_io39;
gpio_in(28) <= shield_io40;
gpio_in(29) <= shield_io41;
gpio_in(30) <= shield_io43;
gpio_in(31) <= shield_io44;

led_b_pwm(1) <= gpio_out(0) when gpio_dir(0) = '1' else 'Z';
led_g_pwm(1) <= gpio_out(1) when gpio_dir(1) = '1' else 'Z';
led_r_pwm(1) <= gpio_out(2) when gpio_dir(2) = '1' else 'Z';

led_b_pwm(2) <= gpio_out(3) when gpio_dir(3) = '1' else 'Z';
led_g_pwm(2) <= gpio_out(4) when gpio_dir(4) = '1' else 'Z';
led_r_pwm(2) <= gpio_out(5) when gpio_dir(5) = '1' else 'Z';

led_b_pwm(3) <= gpio_out(6) when gpio_dir(6) = '1' else 'Z';
led_g_pwm(3) <= gpio_out(7) when gpio_dir(7) = '1' else 'Z';
led_r_pwm(3) <= gpio_out(8) when gpio_dir(8) = '1' else 'Z';

--shield_io0 <= gpio_out(0) when gpio_dir(0) = '1' else 'Z';
--shield_io1 <= gpio_out(1) when gpio_dir(1) = '1' else 'Z';
--shield_io2 <= gpio_out(2) when gpio_dir(2) = '1' else 'Z';
--shield_io3 <= gpio_out(3) when gpio_dir(3) = '1' else 'Z';
--shield_io4 <= gpio_out(4) when gpio_dir(4) = '1' else 'Z';
--shield_io5 <= gpio_out(5) when gpio_dir(5) = '1' else 'Z';
--shield_io6 <= gpio_out(6) when gpio_dir(6) = '1' else 'Z';
--shield_io7 <= gpio_out(7) when gpio_dir(7) = '1' else 'Z';
--shield_io8 <= gpio_out(8) when gpio_dir(8) = '1' else 'Z';
gpio_in(22) <= i2c_rtc_d;
gpio_in(23) <= i2c_rtc_c;
gpio_in(24) <= pmod_jb_1;
gpio_in(25) <= pmod_jb_2;
gpio_in(26) <= pmod_jb_3;
gpio_in(27) <= pmod_jb_4;
gpio_in(28) <= pmod_jb_7;
gpio_in(29) <= pmod_jb_8;
gpio_in(30) <= pmod_jb_9;
gpio_in(31) <= pmod_jb_10;

led_b_pwm(1) <= gpio_out(0) and gpio_dir(0);
led_g_pwm(1) <= gpio_out(1) and gpio_dir(1);
led_r_pwm(1) <= gpio_out(2) and gpio_dir(2);

led_b_pwm(2) <= gpio_out(3) and gpio_dir(3);
led_g_pwm(2) <= gpio_out(4) and gpio_dir(4);
led_r_pwm(2) <= gpio_out(5) and gpio_dir(5);

led_b_pwm(3) <= gpio_out(6) and gpio_dir(6);
led_g_pwm(3) <= gpio_out(7) and gpio_dir(7);
led_r_pwm(3) <= gpio_out(8) and gpio_dir(8);

shield_io9 <= gpio_out(9) when gpio_dir(9) = '1' else 'Z';
shield_io10 <= gpio_out(10) when gpio_dir(10) = '1' else 'Z';
shield_io11 <= gpio_out(11) when gpio_dir(11) = '1' else 'Z';
shield_io12 <= gpio_out(12) when gpio_dir(12) = '1' else 'Z';
shield_io13 <= gpio_out(13) when gpio_dir(13) = '1' else 'Z';
shield_io26 <= gpio_out(14) when gpio_dir(14) = '1' else 'Z';
shield_io27 <= gpio_out(15) when gpio_dir(15) = '1' else 'Z';
shield_io28 <= gpio_out(16) when gpio_dir(16) = '1' else 'Z';
shield_io29 <= gpio_out(17) when gpio_dir(17) = '1' else 'Z';
shield_io30 <= gpio_out(18) when gpio_dir(18) = '1' else 'Z';
shield_io31 <= gpio_out(19) when gpio_dir(19) = '1' else 'Z';
shield_io32 <= gpio_out(20) when gpio_dir(20) = '1' else 'Z';
shield_io33 <= gpio_out(21) when gpio_dir(21) = '1' else 'Z';
shield_io34 <= gpio_out(22) when gpio_dir(22) = '1' else 'Z';
shield_io35 <= gpio_out(23) when gpio_dir(23) = '1' else 'Z';
shield_io36 <= gpio_out(24) when gpio_dir(24) = '1' else 'Z';
shield_io37 <= gpio_out(25) when gpio_dir(25) = '1' else 'Z';
shield_io38 <= gpio_out(26) when gpio_dir(26) = '1' else 'Z';
shield_io39 <= gpio_out(27) when gpio_dir(27) = '1' else 'Z';
shield_io40 <= gpio_out(28) when gpio_dir(28) = '1' else 'Z';
shield_io41 <= gpio_out(29) when gpio_dir(29) = '1' else 'Z';
shield_io43 <= gpio_out(30) when gpio_dir(30) = '1' else 'Z';
shield_io44 <= gpio_out(31) when gpio_dir(31) = '1' else 'Z';
i2c_rtc_d <= gpio_out(22) when gpio_dir(22) = '1' else 'Z';
i2c_rtc_c <= gpio_out(23) when gpio_dir(23) = '1' else 'Z';
pmod_jb_1 <= gpio_out(24) when gpio_dir(24) = '1' else 'Z';
pmod_jb_2 <= gpio_out(25) when gpio_dir(25) = '1' else 'Z';
pmod_jb_3 <= gpio_out(26) when gpio_dir(26) = '1' else 'Z';
pmod_jb_4 <= gpio_out(27) when gpio_dir(27) = '1' else 'Z';
pmod_jb_7 <= gpio_out(28) when gpio_dir(28) = '1' else 'Z';
pmod_jb_8 <= gpio_out(29) when gpio_dir(29) = '1' else 'Z';
pmod_jb_9 <= gpio_out(30) when gpio_dir(30) = '1' else 'Z';
pmod_jb_10 <= gpio_out(31) when gpio_dir(31) = '1' else 'Z';

end architecture behaviour;

@ -19,6 +19,7 @@
#define LETH_CSR_BASE 0xc8020000 /* LiteEth CSR registers */
#define LETH_SRAM_BASE 0xc8030000 /* LiteEth MMIO space */
#define LSDC_CSR_BASE 0xc8040000 /* LiteSDCard MMIO space */
#define LSDC2_CSR_BASE 0xc8048000 /* 2nd LiteSDCard MMIO space */
#define SPI_FLASH_BASE 0xf0000000 /* SPI Flash memory map */
#define DRAM_INIT_BASE 0xff000000 /* Internal DRAM init firmware */

@ -30,6 +31,7 @@
#define IRQ_UART1 2
#define IRQ_SDCARD 3
#define IRQ_GPIO 4
#define IRQ_SDCARD2 5

/*
* Register definitions for the syscon registers
@ -46,6 +48,7 @@
#define SYS_REG_INFO_HAS_UART1 (1ull << 6)
#define SYS_REG_INFO_HAS_ARTB (1ull << 7)
#define SYS_REG_INFO_HAS_LITESDCARD (1ull << 8)
#define SYS_REG_INFO_HAS_LITESDCARD2 (1ull << 9)
#define SYS_REG_BRAMINFO 0x10
#define SYS_REG_BRAMINFO_SIZE_MASK 0xfffffffffffffull
#define SYS_REG_DRAMINFO 0x18

@ -139,6 +139,10 @@ filesets:
uart16550:
depend : [":microwatt:uart16550"]

lcdts:
files:
- fpga/arty-lcd-ts.vhdl : {file_type : vhdlSource-2008}

targets:
nexys_a7:
default_tool: vivado
@ -315,7 +319,7 @@ targets:

arty_a7-100-nodram:
default_tool: vivado
filesets: [core, arty_a7, soc, fpga, debug_xilinx, uart16550, xilinx_specific, litesdcard]
filesets: [core, arty_a7, soc, fpga, debug_xilinx, uart16550, xilinx_specific, litesdcard, lcdts]
parameters :
- memory_size
- ram_init_file
@ -336,7 +340,7 @@ targets:

arty_a7-100:
default_tool: vivado
filesets: [core, arty_a7, soc, fpga, debug_xilinx, litedram, liteeth, uart16550, xilinx_specific, litesdcard]
filesets: [core, arty_a7, soc, fpga, debug_xilinx, litedram, liteeth, uart16550, xilinx_specific, litesdcard, lcdts]
parameters:
- cpus
- memory_size
@ -344,6 +348,7 @@ targets:
- use_litedram=true
- use_liteeth=true
- use_litesdcard
- use_lcd
- disable_flatten_core
- no_bram
- spi_flash_offset=4194304
@ -570,6 +575,12 @@ parameters:
paramtype : generic
default : false

use_lcd:
datatype : bool
description : Use LCD touchscreen interface
paramtype : generic
default : false

uart_is_16550:
datatype : bool
description : Use 16550-compatible UART from OpenCores

@ -34,6 +34,7 @@ use work.wishbone_types.all;
-- 0xc8020000: LiteEth CSRs (*)
-- 0xc8030000: LiteEth MMIO (*)
-- 0xc8040000: LiteSDCard CSRs
-- 0xc8050000: LCD touchscreen interface

-- (*) LiteEth must be a single aligned 32KB block as the CSRs and MMIOs
-- are actually decoded as a single wishbone which LiteEth will
@ -50,6 +51,7 @@ use work.wishbone_types.all;
-- 2 : UART1
-- 3 : SD card
-- 4 : GPIO
-- 5 : SD card 2

-- Resets:
-- The soc can be reset externally by its parent top- entity (via rst port),
@ -93,6 +95,8 @@ entity soc is
DCACHE_TLB_SET_SIZE : natural := 64;
DCACHE_TLB_NUM_WAYS : natural := 2;
HAS_SD_CARD : boolean := false;
HAS_SD_CARD2 : boolean := false;
HAS_LCD : boolean := false;
HAS_GPIO : boolean := false;
NGPIO : natural := 32
);
@ -114,6 +118,7 @@ entity soc is
wb_ext_is_dram_init : out std_ulogic;
wb_ext_is_eth : out std_ulogic;
wb_ext_is_sdcard : out std_ulogic;
wb_ext_is_lcd : out std_ulogic;

-- external DMA wishbone with 32-bit data/address
wishbone_dma_in : out wb_io_slave_out := wb_io_slave_out_init;
@ -122,6 +127,7 @@ entity soc is
-- External interrupts
ext_irq_eth : in std_ulogic := '0';
ext_irq_sdcard : in std_ulogic := '0';
ext_irq_sdcard2 : in std_ulogic := '0';

-- UART0 signals:
uart0_txd : out std_ulogic;
@ -683,6 +689,7 @@ begin
wb_ext_is_dram_csr <= '0';
wb_ext_is_eth <= '0';
wb_ext_is_sdcard <= '0';
wb_ext_is_lcd <= '0';
end if;
if do_cyc = '1' then
-- Decode I/O address
@ -712,6 +719,10 @@ begin
slave_io := SLAVE_IO_EXTERNAL;
io_cycle_external <= '1';
wb_ext_is_sdcard <= '1';
elsif std_match(match, x"--05-") and HAS_LCD then
slave_io := SLAVE_IO_EXTERNAL;
io_cycle_external <= '1';
wb_ext_is_lcd <= '1';
else
io_cycle_none <= '1';
end if;
@ -822,6 +833,7 @@ begin
SPI_FLASH_OFFSET => SPI_FLASH_OFFSET,
HAS_LITEETH => HAS_LITEETH,
HAS_SD_CARD => HAS_SD_CARD,
HAS_SD_CARD2 => HAS_SD_CARD2,
UART0_IS_16550 => UART0_IS_16550,
HAS_UART1 => HAS_UART1
)
@ -1031,6 +1043,7 @@ begin
int_level_in(2) <= uart1_irq;
int_level_in(3) <= ext_irq_sdcard;
int_level_in(4) <= gpio_intr;
int_level_in(5) <= ext_irq_sdcard2;
end process;

-- BRAM Memory slave

@ -21,6 +21,7 @@ entity syscon is
SPI_FLASH_OFFSET : integer;
HAS_LITEETH : boolean;
HAS_SD_CARD : boolean;
HAS_SD_CARD2 : boolean;
UART0_IS_16550 : boolean;
HAS_UART1 : boolean
);
@ -75,6 +76,7 @@ architecture behaviour of syscon is
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
constant SYS_REG_INFO_HAS_SDCARD2 : integer := 9; -- Has 2nd 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
@ -129,6 +131,7 @@ architecture behaviour of syscon is
signal info_has_spif : std_ulogic;
signal info_has_leth : std_ulogic;
signal info_has_lsdc : std_ulogic;
signal info_has_lsd2 : 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);
@ -155,6 +158,7 @@ begin
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_lsd2 <= '1' when HAS_SD_CARD2 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,
@ -163,6 +167,7 @@ begin
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_SDCARD2 => info_has_lsd2,
SYS_REG_INFO_HAS_LSYS => '1',
SYS_REG_INFO_HAS_URT1 => info_has_urt1,
others => '0');

@ -960,7 +960,7 @@ begin
CEALUMODE => valid_1,
CEB1 => '0',
CEB2 => valid_1,
CEC => valid_1,
CEC => '0',
CECARRYIN => '0',
CECTRL => '0',
CED => '0',

Loading…
Cancel
Save