Skip to content
Snippets Groups Projects
Commit f86eb04b authored by Mathias Kreider's avatar Mathias Kreider
Browse files

Merge branch 'master' of ohwr.org:hdl-core-lib/etherbone-core

parents a32fbd1f f29b0683
No related merge requests found
modules = { "local": ["hdl/eb_slave_core"] } modules = { "local": ["hdl/eb_slave_core", "hdl/eb_usb_core"] }
...@@ -11,4 +11,5 @@ files = [ ...@@ -11,4 +11,5 @@ files = [
"sipo_flag.vhd", "sipo_flag.vhd",
"vhdl_2008_workaround_pkg.vhd", "vhdl_2008_workaround_pkg.vhd",
"WB_bus_adapter_streaming_sg.vhd", "WB_bus_adapter_streaming_sg.vhd",
"eb_usb_slave_core.vhd",
"xetherbone_core.vhd"]; "xetherbone_core.vhd"];
...@@ -68,7 +68,7 @@ entity eb_usb_slave_core is ...@@ -68,7 +68,7 @@ entity eb_usb_slave_core is
end eb_usb_slave_core; end eb_usb_slave_core;
architecture behavioral of eb_slave_core is architecture behavioral of eb_usb_slave_core is
signal s_status_en : std_logic; signal s_status_en : std_logic;
signal s_status_clr : std_logic; signal s_status_clr : std_logic;
...@@ -95,6 +95,8 @@ architecture behavioral of eb_slave_core is ...@@ -95,6 +95,8 @@ architecture behavioral of eb_slave_core is
signal s_eb_main_fsm_2_scatter : t_wishbone_slave_in; signal s_eb_main_fsm_2_scatter : t_wishbone_slave_in;
signal slim_src_o_dat : std_logic_vector(7 downto 0); signal slim_src_o_dat : std_logic_vector(7 downto 0);
signal B_SEL_o : std_logic_vector(0 downto 0);
begin begin
...@@ -142,7 +144,7 @@ gather : WB_bus_adapter_streaming_sg generic map (g_adr_width_A => 32, ...@@ -142,7 +144,7 @@ gather : WB_bus_adapter_streaming_sg generic map (g_adr_width_A => 32,
A_CYC_i => snk_i.cyc, A_CYC_i => snk_i.cyc,
A_STB_i => snk_i.stb, A_STB_i => snk_i.stb,
A_ADR_i => snk_i.adr, A_ADR_i => snk_i.adr,
A_SEL_i => snk_i.sel, A_SEL_i => snk_i.sel(0 downto 0),
A_WE_i => snk_i.we, A_WE_i => snk_i.we,
A_DAT_i => snk_i.dat(7 downto 0), A_DAT_i => snk_i.dat(7 downto 0),
A_ACK_o => snk_o.ack, A_ACK_o => snk_o.ack,
...@@ -189,7 +191,7 @@ scatter: WB_bus_adapter_streaming_sg generic map (g_adr_width_A => 32, ...@@ -189,7 +191,7 @@ scatter: WB_bus_adapter_streaming_sg generic map (g_adr_width_A => 32,
B_CYC_o => src_o.cyc, B_CYC_o => src_o.cyc,
B_STB_o => src_o.stb, B_STB_o => src_o.stb,
B_ADR_o => src_o.adr, B_ADR_o => src_o.adr,
B_SEL_o => src_o.sel, B_SEL_o => B_SEL_o,
B_WE_o => src_o.we, B_WE_o => src_o.we,
B_DAT_o => slim_src_o_dat, B_DAT_o => slim_src_o_dat,
B_ACK_i => src_i.ack, B_ACK_i => src_i.ack,
...@@ -198,6 +200,9 @@ scatter: WB_bus_adapter_streaming_sg generic map (g_adr_width_A => 32, ...@@ -198,6 +200,9 @@ scatter: WB_bus_adapter_streaming_sg generic map (g_adr_width_A => 32,
B_STALL_i => src_i.stall, B_STALL_i => src_i.stall,
B_DAT_i => (others => '0')); B_DAT_i => (others => '0'));
src_o.sel <= "000" & B_SEL_o;
EB : eb_main_fsm EB : eb_main_fsm
port map( port map(
--general --general
......
...@@ -565,7 +565,7 @@ static void Initialize(void) { ...@@ -565,7 +565,7 @@ static void Initialize(void) {
EP1OUTCFG = 0xa0; syncdelay(); // 1-10 ---- 1=valid, out,10=bulk, 64, single EP1OUTCFG = 0xa0; syncdelay(); // 1-10 ---- 1=valid, out,10=bulk, 64, single
EP1INCFG = 0xb0; syncdelay(); // 1-11 ---- 1=valid, in, 11=int, 64, single EP1INCFG = 0xb0; syncdelay(); // 1-11 ---- 1=valid, in, 11=int, 64, single
EP2CFG = 0xa2; syncdelay(); // 1010 0-10 1=valid, out,10=bulk,0=512,10=double EP2CFG = 0xa2; syncdelay(); // 1010 0-10 1=valid,0=out,10=bulk,0=512,10=double
EP4CFG = 0xa0; syncdelay(); // 1010 ---- 1=valid,0=out,10=bulk, 512, double EP4CFG = 0xa0; syncdelay(); // 1010 ---- 1=valid,0=out,10=bulk, 512, double
EP6CFG = 0xe2; syncdelay(); // 1110 0-10 1=valid,1=in, 10=bulk,0=512,10=double EP6CFG = 0xe2; syncdelay(); // 1110 0-10 1=valid,1=in, 10=bulk,0=512,10=double
EP8CFG = 0xe0; syncdelay(); // 1110 ---- 1=valid,1=in, 10=bulk, 512, double EP8CFG = 0xe0; syncdelay(); // 1110 ---- 1=valid,1=in, 10=bulk, 512, double
...@@ -580,10 +580,15 @@ static void Initialize(void) { ...@@ -580,10 +580,15 @@ static void Initialize(void) {
FIFORESET = 0x80; syncdelay(); // NAK all requests from host. FIFORESET = 0x80; syncdelay(); // NAK all requests from host.
FIFORESET = 0x00; syncdelay(); // Resume normal operation. FIFORESET = 0x00; syncdelay(); // Resume normal operation.
// Prime the pump for output buffers
OUTPKTEND = 0x82; syncdelay(); OUTPKTEND = 0x82; syncdelay();
OUTPKTEND = 0x82; syncdelay(); OUTPKTEND = 0x82; syncdelay();
OUTPKTEND = 0x82; syncdelay(); OUTPKTEND = 0x82; syncdelay();
OUTPKTEND = 0x82; syncdelay(); OUTPKTEND = 0x82; syncdelay();
OUTPKTEND = 0x84; syncdelay();
OUTPKTEND = 0x84; syncdelay();
OUTPKTEND = 0x84; syncdelay();
OUTPKTEND = 0x84; syncdelay();
// bit7: 0 // bit7: 0
// bit6: INFM6 See TRM 15-29 (p.351): Signal line one clock earlier. // bit6: INFM6 See TRM 15-29 (p.351): Signal line one clock earlier.
......
...@@ -184,6 +184,8 @@ begin ...@@ -184,6 +184,8 @@ begin
baud_tick_o => baud_tick, baud_tick_o => baud_tick,
baud8_tick_o => baud8_tick); baud8_tick_o => baud8_tick);
-- all bytes sent to the device will be delivered reliably
-- ... but, of course, the WR LM32 driver drops bytes like mad
U_TX : uart_async_tx -- USB2UART U_TX : uart_async_tx -- USB2UART
port map( port map(
clk_sys_i => clk_sys_i, clk_sys_i => clk_sys_i,
...@@ -199,6 +201,7 @@ begin ...@@ -199,6 +201,7 @@ begin
usb2uart_uart_o.dat <= (others => '0'); usb2uart_uart_o.dat <= (others => '0');
usb2uart_uart_o.int <= '0'; usb2uart_uart_o.int <= '0';
-- this will drop bytes once buffers are full (no host connected)
U_RX : uart_async_rx -- UART2USB U_RX : uart_async_rx -- UART2USB
port map( port map(
clk_sys_i => clk_sys_i, clk_sys_i => clk_sys_i,
...@@ -227,21 +230,19 @@ begin ...@@ -227,21 +230,19 @@ begin
w_master_o => usb2eb_eb_i, w_master_o => usb2eb_eb_i,
w_master_i => usb2eb_eb_o); w_master_i => usb2eb_eb_o);
master_o <= cc_dummy_slave_in; EB : eb_usb_slave_core
-- EB : eb_usb_slave_core generic map(
-- generic map( g_sdb_address => x"00000000" & g_sdb_address)
-- g_sdb_address => x"00000000" & g_sdb_address) port map(
-- port map( clk_i => clk_sys_i,
-- clk_i => clk_sys_i, nRst_i => rstn_i,
-- nRst_i => rstn_i, snk_i => usb2eb_eb_i,
-- snk_i => usb2eb_eb_i, snk_o => usb2eb_eb_o,
-- snk_o => usb2eb_eb_o, src_o => eb2usb_m,
-- src_o => eb2usb_m, src_i => eb2usb_s,
-- src_i => eb2usb_s, cfg_slave_o => open,
-- cfg_slave_o => open, cfg_slave_i => cc_dummy_slave_in,
-- cfg_slave_i => cc_dummy_slave_in, master_o => master_o,
-- master_o => master_o, master_i => master_i);
-- master_i => master_i);
end rtl; end rtl;
...@@ -33,9 +33,7 @@ entity ez_usb_fifos is ...@@ -33,9 +33,7 @@ entity ez_usb_fifos is
g_board_delay : integer := 2; -- path length from FPGA to chip g_board_delay : integer := 2; -- path length from FPGA to chip
g_margin : integer := 4; -- too lazy to consider FPGA timing constraints? increase this. g_margin : integer := 4; -- too lazy to consider FPGA timing constraints? increase this.
g_fifo_width : integer := 8; -- # of FIFO data pins connected (8 or 16) g_fifo_width : integer := 8; -- # of FIFO data pins connected (8 or 16)
g_num_fifos : integer := 4 -- always 4 for FX2LP (EP2, EP4, EP6, EP8) g_num_fifos : integer := 4); -- always 4 for FX2LP (EP2, EP4, EP6, EP8)
);
port( port(
clk_sys_i : in std_logic; clk_sys_i : in std_logic;
rstn_i : in std_logic; rstn_i : in std_logic;
...@@ -61,8 +59,8 @@ end ez_usb_fifos; ...@@ -61,8 +59,8 @@ end ez_usb_fifos;
architecture rtl of ez_usb_fifos is architecture rtl of ez_usb_fifos is
-- Timing constants from EZ-USB data sheet -- Timing constants from EZ-USB data sheet
constant c_tXFLG_a : integer := 11; -- FIFOADR to FLAGS output propagation delay constant c_tXFLG_a : integer := 11; -- FIFOADR to FLAGS output propagation delay
constant c_tXFLG_r : integer := 70; -- SLRD to FLAGS output propagation delay constant c_tXFLG_r : integer := 70+10; -- SLRD to FLAGS output propagation delay (+10 b/c datasheet lies!)
constant c_tXFLG_w : integer := 70; -- SLWR to FLAGS output propagation delay constant c_tXFLG_w : integer := 70+10; -- SLWR to FLAGS output propagation delay
constant c_tXFLG_e : integer := 115; -- PKTEND to FLAGS output propagation delay constant c_tXFLG_e : integer := 115; -- PKTEND to FLAGS output propagation delay
constant c_tSFA : integer := 10; -- FIFOADR to SLRD/SLWR/PKTEND setup time (adr -> falling edge) constant c_tSFA : integer := 10; -- FIFOADR to SLRD/SLWR/PKTEND setup time (adr -> falling edge)
constant c_tFAH : integer := 10; -- RD/WR/PKTEND to FIFOADR hold time (rising edge -> adr) constant c_tFAH : integer := 10; -- RD/WR/PKTEND to FIFOADR hold time (rising edge -> adr)
...@@ -101,22 +99,25 @@ architecture rtl of ez_usb_fifos is ...@@ -101,22 +99,25 @@ architecture rtl of ez_usb_fifos is
constant c_latch_flags : integer := 2; -- >= 2 to synchronize async signal constant c_latch_flags : integer := 2; -- >= 2 to synchronize async signal
constant c_dispatch : integer := 1; constant c_dispatch : integer := 1;
constant c_set_addr : integer := f_cycles(f_max(c_tXFLG_a + g_board_delay*2, constant c_set_addr : integer := f_cycles(f_max(c_tXFLG_a + g_board_delay*2,
c_tSFA - f_ns(c_latch_flags+c_dispatch))); c_tSFA - f_ns(c_latch_flags+c_dispatch)));
constant c_drive_read : integer := f_cycles(f_max(c_tOEon, c_tXFD) + g_board_delay*2); constant c_drive_read : integer := f_cycles(f_max(c_tOEon, c_tXFD) + g_board_delay*2);
constant c_latch_data : integer := f_cycles(c_tRDpwl - f_ns(c_drive_read)); constant c_latch_data : integer := f_cycles(c_tRDpwl - f_ns(c_drive_read));
constant c_idle_read : integer := f_cycles(f_max(c_tRDpwh - f_ns(c_latch_flags+c_dispatch), constant c_idle_read : integer := f_cycles(f_max(c_tRDpwh - f_ns(c_latch_flags+c_dispatch),
f_max(c_tXFLG_r - f_ns(c_drive_read+c_latch_data), f_max(c_tXFLG_r + g_board_delay*2
f_max(c_tOEoff - f_ns(c_latch_data), - f_ns(c_drive_read+c_latch_data),
c_tFAH)))); f_max(c_tOEoff - f_ns(c_latch_data+c_latch_flags+c_dispatch),
c_tFAH - f_ns(c_latch_flags+c_dispatch)))));
constant c_drive_write : integer := f_cycles(f_max(c_tWRpwl, c_tSFD)); constant c_drive_write : integer := f_cycles(f_max(c_tWRpwl, c_tSFD));
constant c_idle_write : integer := f_cycles(c_tFDH); constant c_idle_write : integer := f_cycles(c_tFDH);
constant c_idle_data : integer := f_cycles(f_max(c_tWRpwh - f_ns(c_latch_flags+c_dispatch+c_idle_write), constant c_idle_data : integer := f_cycles(f_max(c_tWRpwh - f_ns(c_latch_flags+c_dispatch+c_idle_write),
f_max(c_tXFLG_w - f_ns(c_drive_write+c_idle_write), f_max(c_tXFLG_w + g_board_delay*2
c_tFAH - f_ns(c_idle_write)))); - f_ns(c_drive_write+c_idle_write),
c_tFAH - f_ns(c_idle_write+c_latch_flags+c_dispatch))));
constant c_drive_pktend : integer := f_cycles(c_tPEpwl); constant c_drive_pktend : integer := f_cycles(c_tPEpwl);
constant c_idle_pktend : integer := f_cycles(f_max(c_tPEpwh - f_ns(c_latch_flags+c_dispatch), constant c_idle_pktend : integer := f_cycles(f_max(c_tPEpwh - f_ns(c_latch_flags+c_dispatch),
f_max(c_tXFLG_e - f_ns(c_drive_pktend), f_max(c_tXFLG_e + g_board_delay*2
c_tFAH))); - f_ns(c_drive_pktend),
c_tFAH - f_ns(c_latch_flags+c_dispatch))));
constant c_max_count : integer := constant c_max_count : integer :=
f_max(c_latch_flags, f_max(c_dispatch, f_max(c_set_addr, f_max(c_drive_read, f_max(c_latch_flags, f_max(c_dispatch, f_max(c_set_addr, f_max(c_drive_read,
...@@ -132,6 +133,7 @@ architecture rtl of ez_usb_fifos is ...@@ -132,6 +133,7 @@ architecture rtl of ez_usb_fifos is
signal notfull : std_logic_vector(c_latch_flags-1 downto 0) := (others => '0'); signal notfull : std_logic_vector(c_latch_flags-1 downto 0) := (others => '0');
signal count : unsigned(f_ceil_log2(c_max_count)-1 downto 0) := (others => '0'); signal count : unsigned(f_ceil_log2(c_max_count)-1 downto 0) := (others => '0');
signal addr : unsigned(f_ceil_log2(g_num_fifos)-1 downto 0) := (others => '0'); signal addr : unsigned(f_ceil_log2(g_num_fifos)-1 downto 0) := (others => '0');
signal fd_r : word := (others => '0');
signal dat4usb : words(g_num_fifos-1 downto 0) := (others => (others => '0')); signal dat4usb : words(g_num_fifos-1 downto 0) := (others => (others => '0'));
signal dat4wb : words(g_num_fifos-1 downto 0) := (others => (others => '0')); signal dat4wb : words(g_num_fifos-1 downto 0) := (others => (others => '0'));
signal needend : std_logic_vector(g_num_fifos-1 downto 0) := (others => '0'); signal needend : std_logic_vector(g_num_fifos-1 downto 0) := (others => '0');
...@@ -163,6 +165,7 @@ begin ...@@ -163,6 +165,7 @@ begin
notfull <= (others => '0'); notfull <= (others => '0');
count <= (others => '0'); count <= (others => '0');
addr <= (others => '0'); addr <= (others => '0');
fd_r <= (others => '0');
dat4usb <= (others => (others => '0')); dat4usb <= (others => (others => '0'));
dat4wb <= (others => (others => '0')); dat4wb <= (others => (others => '0'));
needend <= (others => '0'); needend <= (others => '0');
...@@ -183,6 +186,8 @@ begin ...@@ -183,6 +186,8 @@ begin
case state is case state is
when LATCH_FLAGS => when LATCH_FLAGS =>
ack(to_integer(addr)) <= '0';
notfull <= flagbn_i & notfull(notfull'left downto 1); notfull <= flagbn_i & notfull(notfull'left downto 1);
notempty <= flagcn_i & notempty(notempty'left downto 1); notempty <= flagcn_i & notempty(notempty'left downto 1);
...@@ -258,7 +263,7 @@ begin ...@@ -258,7 +263,7 @@ begin
sloen_o <= '1'; sloen_o <= '1';
if count = 0 then if count = 0 then
dat4wb(to_integer(addr)) <= fd_i; fd_r <= fd_i;
end if; end if;
if count /= c_latch_data-1 then if count /= c_latch_data-1 then
...@@ -266,18 +271,18 @@ begin ...@@ -266,18 +271,18 @@ begin
else else
state <= IDLE_READ; state <= IDLE_READ;
count <= (others => '0'); count <= (others => '0');
ack(to_integer(addr)) <= '1';
end if; end if;
when IDLE_READ => when IDLE_READ =>
dat4wb(to_integer(addr)) <= fd_r;
slrdn_o <= '1'; slrdn_o <= '1';
ack(to_integer(addr)) <= '0';
if count /= c_idle_read-1 then if count /= c_idle_read-1 then
count <= count + 1; count <= count + 1;
else else
state <= LATCH_FLAGS; state <= LATCH_FLAGS;
count <= (others => '0'); count <= (others => '0');
ack(to_integer(addr)) <= '1';
end if; end if;
when DRIVE_WRITE => when DRIVE_WRITE =>
...@@ -291,12 +296,10 @@ begin ...@@ -291,12 +296,10 @@ begin
else else
state <= IDLE_WRITE; state <= IDLE_WRITE;
count <= (others => '0'); count <= (others => '0');
ack(to_integer(addr)) <= '1';
end if; end if;
when IDLE_WRITE => when IDLE_WRITE =>
slwrn_o <= '1'; slwrn_o <= '1';
ack(to_integer(addr)) <= '0';
if count /= c_idle_write-1 then if count /= c_idle_write-1 then
count <= count + 1; count <= count + 1;
...@@ -313,6 +316,7 @@ begin ...@@ -313,6 +316,7 @@ begin
else else
state <= LATCH_FLAGS; state <= LATCH_FLAGS;
count <= (others => '0'); count <= (others => '0');
ack(to_integer(addr)) <= '1';
end if; end if;
when DRIVE_PKTEND => when DRIVE_PKTEND =>
......
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