Commit 807eabd8 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

hdl/top/sfpga_bootloader: fix bus errors when exiting VME mode (clipped DTACK)

parent 03828317
......@@ -6,7 +6,7 @@
-- Author : Tomasz Wlostowski
-- Company : CERN
-- Created : 2011-01-24
-- Last update: 2013-01-25
-- Last update: 2014-01-15
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
......@@ -75,7 +75,9 @@ entity flash_boot is
spi_cs_n_o : out std_logic;
spi_sclk_o : out std_logic;
spi_mosi_o : out std_logic;
spi_miso_i : in std_logic
spi_miso_i : in std_logic;
no_bitstream_p1_o : out std_logic
);
end flash_boot;
......@@ -133,8 +135,8 @@ architecture behavioral of flash_boot is
signal byte_count : unsigned(23 downto 0);
signal state : t_boot_state;
signal state : t_boot_state;
signal no_bitstream_int, no_bitstream_int_d0 : std_logic;
begin -- rtl
U_Flash_Controller : m25p_flash
......@@ -169,11 +171,12 @@ begin -- rtl
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' or enable_i = '0' then
state <= STARTUP;
flash_set_addr <= '0';
flash_read <= '0';
xldr_start_o <= '0';
xldr_empty_o <= '1';
state <= STARTUP;
flash_set_addr <= '0';
flash_read <= '0';
xldr_start_o <= '0';
xldr_empty_o <= '1';
no_bitstream_int <= '0';
else
case state is
-- Wait until we are allowed to start flash boot sequence
......@@ -267,7 +270,8 @@ begin -- rtl
-- We have no (or invalid) bitstream. Wait until reset
when NO_BITSTREAM =>
flash_read <= '0';
flash_read <= '0';
no_bitstream_int <= '1';
if enable_i = '0' then
state <= STARTUP;
end if;
......@@ -280,6 +284,20 @@ begin -- rtl
end if;
end if;
end process;
p_gen_no_bitstream_pulse : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
no_bitstream_p1_o <= '0';
no_bitstream_int_d0 <= '0';
else
no_bitstream_int_d0 <= no_bitstream_int;
no_bitstream_p1_o <= no_bitstream_int and not no_bitstream_int_d0;
end if;
end if;
end process;
end behavioral;
......@@ -6,7 +6,7 @@
-- Author : Tomasz Wlostowski
-- Company : CERN
-- Created : 2012-01-20
-- Last update: 2013-01-25
-- Last update: 2014-01-13
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
......@@ -75,7 +75,10 @@ entity xmini_vme is
-- Wishbone master
master_o : out t_wishbone_master_out;
master_i : in t_wishbone_master_in
master_i : in t_wishbone_master_in;
-- VME bus idle
idle_o: out std_logic
);
end xmini_vme;
......@@ -207,7 +210,7 @@ begin -- rtl
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
state <= IDLE;
idle_o <= '1';
VME_DATA_DIR_o <= '0';
VME_DATA_OE_N_o <= '0';
VME_DTACK_n_o <= '0';
......@@ -215,12 +218,14 @@ begin -- rtl
else
case state is
when IDLE =>
idle_o <= '1';
VME_DATA_DIR_o <= '0';
VME_DTACK_n_o <= '1';
VME_DTACK_OE_o <= '0';
dtack_counter <= (others => '0');
if(addr_valid = '1' and data_valid = '1') then
idle_o <= '0';
state <= DECODE_ADDR;
end if;
......@@ -268,7 +273,7 @@ begin -- rtl
dtack_counter <= dtack_counter + 1;
if(ds_synced = '1') then
if(ds_synced = '1' and as_synced = '1') then
state <= IDLE;
end if;
......
......@@ -148,26 +148,27 @@ architecture behavioral of sfpga_bootloader is
component flash_boot
port (
clk_sys_i : in std_logic;
rst_n_i : in std_logic;
regs_i : in t_sxldr_out_registers;
regs_o : out t_sxldr_in_registers;
enable_i : in std_logic;
xldr_start_o : out std_logic;
xldr_mode_o : out std_logic;
xldr_data_o : out std_logic_vector(31 downto 0);
xldr_dsize_o : out std_logic_vector(1 downto 0);
xldr_dlast_o : out std_logic;
xldr_msbf_o : out std_logic;
xldr_done_i : in std_logic;
xldr_rd_i : in std_logic;
xldr_empty_o : out std_logic;
xldr_startup_o : out std_logic;
xldr_clk_div_o : out std_logic_vector(6 downto 0);
spi_cs_n_o : out std_logic;
spi_sclk_o : out std_logic;
spi_mosi_o : out std_logic;
spi_miso_i : in std_logic);
clk_sys_i : in std_logic;
rst_n_i : in std_logic;
regs_i : in t_sxldr_out_registers;
regs_o : out t_sxldr_in_registers;
enable_i : in std_logic;
xldr_start_o : out std_logic;
xldr_mode_o : out std_logic;
xldr_data_o : out std_logic_vector(31 downto 0);
xldr_dsize_o : out std_logic_vector(1 downto 0);
xldr_dlast_o : out std_logic;
xldr_msbf_o : out std_logic;
xldr_done_i : in std_logic;
xldr_rd_i : in std_logic;
xldr_empty_o : out std_logic;
xldr_startup_o : out std_logic;
xldr_clk_div_o : out std_logic_vector(6 downto 0);
spi_cs_n_o : out std_logic;
spi_sclk_o : out std_logic;
spi_mosi_o : out std_logic;
spi_miso_i : in std_logic;
no_bitstream_p1_o : out std_logic);
end component;
component xilinx_loader
......@@ -207,10 +208,11 @@ architecture behavioral of sfpga_bootloader is
signal from_flash_ldr, from_host_ldr, to_xilinx_boot : t_xilinx_boot_in;
signal to_flash_ldr, to_host_ldr, from_xilinx_boot : t_xilinx_boot_out;
signal boot_state : t_bootseq_state;
signal boot_source : t_boot_source;
signal boot_trig_p1_int : std_logic;
signal flash_enable : std_logic;
signal boot_state : t_bootseq_state;
signal boot_source : t_boot_source;
signal boot_trig_p1_int : std_logic;
signal flash_enable : std_logic;
signal flash_no_bitstream_p1 : std_logic;
-- Trivial helper for boot sequence detection. Advances the state machine if
-- a matching byte has been detected or goes back to the starting point.
......@@ -249,25 +251,26 @@ begin -- behavioral
U_Flash_Boot_Engine : flash_boot
port map (
clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i,
regs_i => regs_in,
regs_o => regs_out_flash,
enable_i => flash_enable,
xldr_start_o => from_flash_ldr.start,
xldr_data_o => from_flash_ldr.data,
xldr_dsize_o => from_flash_ldr.dsize,
xldr_dlast_o => from_flash_ldr.dlast,
xldr_msbf_o => from_flash_ldr.msbf,
xldr_done_i => to_flash_ldr.done,
xldr_rd_i => to_flash_ldr.rd,
xldr_empty_o => from_flash_ldr.empty,
xldr_startup_o => from_flash_ldr.startup,
xldr_clk_div_o => from_flash_ldr.clk_div,
spi_cs_n_o => spi_cs_n_o,
spi_sclk_o => spi_sclk_o,
spi_mosi_o => spi_mosi_o,
spi_miso_i => spi_miso_i);
clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i,
regs_i => regs_in,
regs_o => regs_out_flash,
enable_i => flash_enable,
xldr_start_o => from_flash_ldr.start,
xldr_data_o => from_flash_ldr.data,
xldr_dsize_o => from_flash_ldr.dsize,
xldr_dlast_o => from_flash_ldr.dlast,
xldr_msbf_o => from_flash_ldr.msbf,
xldr_done_i => to_flash_ldr.done,
xldr_rd_i => to_flash_ldr.rd,
xldr_empty_o => from_flash_ldr.empty,
xldr_startup_o => from_flash_ldr.startup,
xldr_clk_div_o => from_flash_ldr.clk_div,
spi_cs_n_o => spi_cs_n_o,
spi_sclk_o => spi_sclk_o,
spi_mosi_o => spi_mosi_o,
spi_miso_i => spi_miso_i,
no_bitstream_p1_o => flash_no_bitstream_p1);
-- Route host registers to the boot source multiplexer (p_select_boot_source).
from_host_ldr.start <= regs_in.csr_start_o and boot_en_i;
......@@ -361,7 +364,7 @@ begin -- behavioral
end if;
end process;
boot_trig_p1_o <= boot_trig_p1_int;
boot_trig_p1_o <= boot_trig_p1_int or flash_no_bitstream_p1;
boot_exit_p1_o <= regs_in.csr_exit_o;
xlx_m_o <= "11"; -- permamently select Passive serial
......
files = [ "svec_sfpga_top.vhd", "svec_sfpga_top.ucf" ]
files = [ "svec_sfpga_top.vhd", "svec_sfpga_top.ucf", "reset_gen.vhd" ]
fetchto = "../../ip_cores"
modules = {
"local" : ["../../rtl/bootloader" ],
"git" : [ "git://ohwr.org/hdl-core-lib/general-cores.git" ]
"git" : [ "git://ohwr.org/hdl-core-lib/general-cores.git::proposed_master" ]
}
#===============================================================================
# IO Location Constraints
#===============================================================================
#----------------------------------------
# VME interface
#----------------------------------------
......@@ -115,11 +114,10 @@ NET "boot_done_i" LOC = C16;
NET "boot_dout_o" LOC = F13;
NET "boot_status_i" LOC = E16;
NET "debugled_o[2]" LOC = P15;
NET "debugled_o[1]" LOC = L16;
NET "debugled_n_o[2]" LOC = P15;
NET "debugled_n_o[1]" LOC = L16;
#IO standards
NET "vme_write_n_i" IOSTANDARD="LVCMOS33";
NET "vme_rst_n_i" IOSTANDARD="LVCMOS33";
#NET "vme_retry_oe_o" IOSTANDARD="LVCMOS33";
......@@ -230,8 +228,8 @@ NET "boot_done_i" IOSTANDARD="LVCMOS33";
NET "boot_dout_o" IOSTANDARD="LVCMOS33";
NET "boot_status_i" IOSTANDARD="LVCMOS33";
NET "debugled_o[2]" IOSTANDARD="LVCMOS33";
NET "debugled_o[1]" IOSTANDARD="LVCMOS33";
NET "debugled_n_o[2]" IOSTANDARD="LVCMOS33";
NET "debugled_n_o[1]" IOSTANDARD="LVCMOS33";
NET "spi_sclk_o" IOSTANDARD="LVCMOS33";
NET "spi_cs_n_o" IOSTANDARD="LVCMOS33";
......@@ -244,7 +242,6 @@ NET "spi_mosi_o" LOC = T10;
NET "spi_miso_i" LOC = P10;
# Clocks/resets
NET "rst_n_i" LOC = E15;
NET "lclk_n_i" LOC = H5;
......@@ -252,4 +249,7 @@ NET "rst_n_i" IOSTANDARD="LVCMOS33";
NET "lclk_n_i" IOSTANDARD="LVCMOS33";
NET "pll_ce_o" IOSTANDARD="LVCMOS33";
NET "pll_ce_o" LOC=G14;
\ No newline at end of file
NET "pll_ce_o" LOC=G14;
#Created by Constraints Editor (xc6slx9-ftg256-2) - 2014/01/15
NET "lclk_n_i" TNM_NET = lclk_n_i;
TIMESPEC TS_lclk_n_i = PERIOD "lclk_n_i" 20 MHz HIGH 50%;
......@@ -102,7 +102,7 @@ entity svec_sfpga_top is
spi_miso_i : in std_logic;
spi_sclk_o : out std_logic;
debugled_o : out std_logic_vector(2 downto 1);
debugled_n_o : out std_logic_vector(2 downto 1);
-- Onboard PLL enable signal. Must be one for the clock system to work.
pll_ce_o : out std_logic
......@@ -112,6 +112,14 @@ end svec_sfpga_top;
architecture rtl of svec_sfpga_top is
component reset_gen
port (
clk_sys_i : in std_logic;
rst_vme_n_a_i : in std_logic;
rst_local_n_a_i : in std_logic;
rst_n_o : out std_logic);
end component;
component xmini_vme
generic (
g_user_csr_start : unsigned(20 downto 0);
......@@ -134,7 +142,8 @@ architecture rtl of svec_sfpga_top is
VME_DATA_DIR_o : out std_logic;
VME_DATA_OE_N_o : out std_logic;
master_o : out t_wishbone_master_out;
master_i : in t_wishbone_master_in);
master_i : in t_wishbone_master_in;
idle_o : out std_logic);
end component;
component sfpga_bootloader
......@@ -193,11 +202,11 @@ architecture rtl of svec_sfpga_top is
signal wb_vme_in : t_wishbone_master_out;
signal wb_vme_out : t_wishbone_master_in;
signal passive : std_logic := '0';
signal passive : std_logic;
-- VME bootloader is inactive by default
signal boot_en : std_logic := '0';
signal boot_en : std_logic := '1';
signal boot_trig_p1, boot_exit_p1 : std_logic;
signal CONTROL : std_logic_vector(35 downto 0);
signal CLK : std_logic;
......@@ -210,7 +219,9 @@ architecture rtl of svec_sfpga_top is
signal erase_afpga_n, erase_afpga_n_d0 : std_logic;
signal pllout_clk_fb_sys, pllout_clk_sys, clk_sys : std_logic;
signal rst_n_sys: std_logic;
signal rst_n_sys : std_logic;
signal go_passive : std_logic;
signal vme_idle : std_logic;
begin
-- PLL for producing 62.5 MHz system clock (clk_sys) from a 20 MHz reference.
......@@ -222,7 +233,7 @@ begin
DIVCLK_DIVIDE => 1,
CLKFBOUT_MULT => 50,
CLKFBOUT_PHASE => 0.000,
CLKOUT0_DIVIDE => 12, -- 62.5 MHz
CLKOUT0_DIVIDE => 12, -- 83.3 MHz
CLKOUT0_PHASE => 0.000,
CLKOUT0_DUTY_CYCLE => 0.500,
CLKOUT1_DIVIDE => 16, -- 62.5 MHz
......@@ -251,13 +262,12 @@ begin
O => clk_sys,
I => pllout_clk_sys);
U_Sync_Reset : gc_sync_ffs
U_Powerup_Reset : reset_gen
port map (
clk_i => clk_sys,
rst_n_i => '1',
data_i => rst_n_i,
synced_o => rst_n_sys);
clk_sys_i => clk_sys,
rst_vme_n_a_i => VME_RST_n_i,
rst_local_n_a_i => rst_n_i,
rst_n_o => rst_n_sys);
-------------------------------------------------------------------------------
-- Chipscope instantiation (for VME bus monitoring, I sincerely hate VMetro)
......@@ -294,6 +304,8 @@ begin
trig2(24) <= '1';
trig2(25) <= VME_RST_n_i;
trig2(26) <= passive;
trig2(27) <= vme_idle;
trig2(28) <= rst_n_sys;
U_MiniVME : xmini_vme
generic map (
......@@ -317,7 +329,8 @@ begin
VME_DATA_DIR_o => vme_data_dir_int,
VME_DATA_OE_N_o => VME_DATA_OE_N_int,
master_o => wb_vme_in,
master_i => wb_vme_out);
master_i => wb_vme_out,
idle_o => vme_idle);
U_Bootloader_Core : sfpga_bootloader
generic map (
......@@ -365,19 +378,26 @@ begin
-- on a single bus.
boot_config_o <= boot_config_int and (not erase_afpga_n);
p_enable_disable_bootloader : process(clk_sys, VME_RST_n_i, rst_n_i)
p_enable_disable_bootloader : process(clk_sys)
begin
if(rst_n_i = '0' or VME_RST_n_i = '0') then
boot_en <= '0'; -- VME bootloader is inactive after reset
elsif rising_edge(clk_sys) then
erase_afpga_n_d0 <= erase_afpga_n;
-- VME activation occurs after erasing the AFPGA
if(erase_afpga_n = '0' and erase_afpga_n_d0 = '1') then
boot_en <= '1';
elsif(boot_exit_p1 = '1') then
boot_en <= '0';
if rising_edge(clk_sys) then
if(rst_n_sys = '0') then
boot_en <= '0'; -- VME bootloader is inactive after reset
go_passive <= '0';
else
erase_afpga_n_d0 <= erase_afpga_n;
-- VME activation occurs after erasing the AFPGA
if(erase_afpga_n = '0' and erase_afpga_n_d0 = '1') then
boot_en <= '1';
go_passive <= '0';
elsif(boot_exit_p1 = '1') then
go_passive <= '1';
elsif (go_passive = '1' and vme_idle = '1') then
go_passive <= '0';
boot_en <= '0';
end if;
end if;
end if;
end process;
......@@ -396,10 +416,10 @@ begin
VME_ADDR_DIR_o <= '0' when passive = '0' else 'Z';
VME_LWORD_n_b <= 'Z';
debugled_o(1) <= '0';
debugled_o(2) <= boot_en;
debugled_n_o(1) <= '1';
debugled_n_o(2) <= not boot_en;
-- Permanently enable onboard PLL
-- Permanently enable onboard PLL
pll_ce_o <= '1';
end rtl;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment