Skip to content
Snippets Groups Projects
Commit bc75b8b2 authored by Wesley W. Terpstra's avatar Wesley W. Terpstra
Browse files

TX path synthesizes!

parent 786c393f
Branches
Tags
No related merge requests found
......@@ -14,7 +14,7 @@ entity pcie_altera is
pcie_rx_i : in std_logic_vector(3 downto 0);
pcie_tx_o : out std_logic_vector(3 downto 0);
cfg_busdev : out std_logic_vector(12 downto 0); -- Configured Bus#:Dev#
cfg_busdev_o : out std_logic_vector(12 downto 0); -- Configured Bus#:Dev#
-- Simplified wishbone output stream
wb_clk_o : out std_logic;
......@@ -474,7 +474,7 @@ begin
end if;
if tl_cfg_delay(tl_cfg_delay'left) = '1' and is_zero(tl_cfg_delay(tl_cfg_delay'left-1 downto 0)) = '1' then
cfg_busdev <= tl_cfg_ctl(12 downto 0);
cfg_busdev_o <= tl_cfg_ctl(12 downto 0);
end if;
end if;
end process;
......@@ -573,8 +573,8 @@ begin
end process;
-- can only accept data if A pointer has not wrapped around the buffer to point at the R pointer
tx_rdy_o <= active_high(r_idxa(buf_bits-1 downto 0) = r_idxr(buf_bits-1 downto 0)) and
active_high(r_idxa(buf_bits) /= r_idxr(buf_bits));
tx_rdy_o <= active_high(r_idxa(buf_bits-1 downto 0) /= r_idxr(buf_bits-1 downto 0)) or
active_high(r_idxa(buf_bits) = r_idxr(buf_bits));
s_idxw_p1 <= r_idxw + 1;
tx_data64_w : process(core_clk_out)
......@@ -597,6 +597,7 @@ begin
end if;
if tx_alloc_i = '1' then
-- !!! insanely wasteful. fix.
r_idxa <= r_idxa + 1;
end if;
end if;
......
......@@ -12,11 +12,13 @@ entity pcie_tlp is
rx_wb_dat_i : in std_logic_vector(31 downto 0);
rx_wb_stall_o : out std_logic;
tx_rdy_i : out std_logic;
tx_alloc_o : in std_logic;
tx_en_o : in std_logic;
tx_dat_o : in std_logic_vector(31 downto 0);
tx_eop_o : in std_logic;
tx_rdy_i : in std_logic;
tx_alloc_o : out std_logic;
tx_en_o : out std_logic;
tx_dat_o : out std_logic_vector(31 downto 0);
tx_eop_o : out std_logic;
cfg_busdev_i : in std_logic_vector(12 downto 0);
wb_stb_o : out std_logic;
wb_adr_o : out std_logic_vector(63 downto 0);
......@@ -30,10 +32,11 @@ entity pcie_tlp is
end pcie_tlp;
architecture rtl of pcie_tlp is
type state_type is (h0, h_completion1, h_completion2, h_request, h_high_addr, h_low_addr, p_w0, p_wx, p_we, p_r0, p_rx, p_re);
type rx_state_type is (h0, h_completion1, h_completion2, h_request, h_high_addr, h_low_addr, p_w0, p_wx, p_we, p_rs, p_r0, p_rx, p_re);
type tx_state_type is (c0, c1, c2, c_block, c_queue);
signal state : state_type := h0;
signal progress : std_logic;
signal rx_state : rx_state_type := h0;
signal tx_state : tx_state_type := c0;
-- Bar0 Registers
-- signal csr : std_logic_vector(63 downto 0); -- bit0: CYC
......@@ -43,12 +46,20 @@ architecture rtl of pcie_tlp is
-- Header fields
signal s_fmttype : std_logic_vector(7 downto 0);
signal s_attr : std_logic_vector(2 downto 0);
signal s_tc : std_logic_vector(2 downto 0);
signal s_length : unsigned(9 downto 0);
signal s_transaction : std_logic_vector(23 downto 0);
signal s_last_be : std_logic_vector(3 downto 0);
signal s_first_be : std_logic_vector(3 downto 0);
signal s_missing : unsigned(2 downto 0);
signal s_bytes : std_logic_vector(11 downto 0);
signal s_low_addr : std_logic_vector(6 downto 0);
signal r_fmttype : std_logic_vector(7 downto 0);
signal r_attr : std_logic_vector(2 downto 0);
signal r_tc : std_logic_vector(2 downto 0);
signal r_length : unsigned(9 downto 0);
signal r_transaction : std_logic_vector(23 downto 0);
signal r_last_be : std_logic_vector(3 downto 0);
......@@ -67,6 +78,9 @@ architecture rtl of pcie_tlp is
-- Inflight reads and writes
signal wb_stb : std_logic;
signal r_flight_count : unsigned(4 downto 0);
signal r_tx_en, r_tx_alloc, r_rx_alloc : std_logic;
signal r_pending_ack : unsigned(9 downto 0);
begin
rx_wb_stall_o <= r_always_stall or (not r_never_stall and wb_stall_i);
wb_stb <= r_always_stb or (not r_never_stb and rx_wb_stb_i);
......@@ -76,6 +90,8 @@ begin
-- Fields in the rx_data
s_fmttype <= rx_wb_dat_i(31 downto 24);
s_tc <= rx_wb_dat_i(22 downto 20);
s_attr <= rx_wb_dat_i(18) & rx_wb_dat_i(13 downto 12);
s_length <= unsigned(rx_wb_dat_i(9 downto 0));
s_transaction <= rx_wb_dat_i(31 downto 8);
s_last_be <= rx_wb_dat_i(7 downto 4);
......@@ -88,19 +104,21 @@ begin
s_address_p4 <= r_address(63 downto 24) &
std_logic_vector(unsigned(r_address(23 downto 0)) + to_unsigned(4, 24));
state_machine : process(clk_i) is
variable next_state : state_type;
rx_state_machine : process(clk_i) is
variable next_state : rx_state_type;
begin
if rising_edge(clk_i) then
if rstn_i = '0' then
state <= h0;
rx_state <= h0;
else
----------------- Pre-transition actions --------------------
case state is
case rx_state is
when h0 =>
r_fmttype <= s_fmttype;
r_length <= s_length;
r_attr <= s_attr;
r_tc <= s_tc;
when h_completion1 => null;
when h_completion2 =>
r_transaction <= s_transaction;
......@@ -117,14 +135,15 @@ begin
when p_w0 => null;
when p_wx => null;
when p_we => null;
when p_rs => null;
when p_r0 => null;
when p_rx => null;
when p_re => null;
end case;
----------------- Transition rules --------------------
next_state := state;
case state is
next_state := rx_state;
case rx_state is
when h0 =>
if rx_wb_stb_i = '1' then
if s_fmttype(3) = '1' then
......@@ -162,7 +181,7 @@ begin
if r_fmttype(6) = '1' then
next_state := p_w0;
else
next_state := p_r0;
next_state := p_rs;
end if;
end if;
when p_w0 =>
......@@ -189,6 +208,10 @@ begin
if (rx_wb_stb_i and not wb_stall_i) = '1' then
next_state := h0;
end if;
when p_rs =>
if tx_state = c_queue then
next_state := p_r0;
end if;
when p_r0 =>
if (not wb_stall_i) = '1' then
if s_length_eq1 then
......@@ -216,14 +239,15 @@ begin
end case;
----------------- Post-transition actions --------------------
wb_we_o <= 'X';
wb_sel_o <= (others => 'X');
wb_we_o <= '-';
wb_sel_o <= (others => '-');
r_always_stall <= '0';
r_never_stall <= '1' ;
r_always_stb <= '0';
r_never_stb <= '1';
r_rx_alloc <= '0';
state <= next_state;
rx_state <= next_state;
case next_state is
when h0 => null;
when h_completion1 => null;
......@@ -246,19 +270,23 @@ begin
r_never_stb <= '0';
wb_sel_o <= r_last_be;
wb_we_o <= '1';
when p_rs => null;
when p_r0 =>
r_always_stall <= '1';
r_always_stb <= '1';
r_always_stb <= tx_rdy_i;
r_rx_alloc <= tx_rdy_i;
wb_sel_o <= r_first_be;
wb_we_o <= '0';
when p_rx =>
r_always_stall <= '1';
r_always_stb <= '1';
r_always_stb <= tx_rdy_i;
r_rx_alloc <= tx_rdy_i;
wb_sel_o <= x"f";
wb_we_o <= '0';
when p_re =>
r_always_stall <= '1';
r_always_stb <= '1';
r_always_stb <= tx_rdy_i;
r_rx_alloc <= tx_rdy_i;
wb_sel_o <= r_last_be;
wb_we_o <= '0';
end case;
......@@ -266,6 +294,135 @@ begin
end if;
end process;
-- These tables are copied from the PCI express standard:
s_missing <=
"000" when r_first_be = "1--1" and r_last_be = "0000" else
"001" when r_first_be = "01-1" and r_last_be = "0000" else
"001" when r_first_be = "1-10" and r_last_be = "0000" else
"010" when r_first_be = "0011" and r_last_be = "0000" else
"010" when r_first_be = "0110" and r_last_be = "0000" else
"010" when r_first_be = "1100" and r_last_be = "0000" else
"011" when r_first_be = "0001" and r_last_be = "0000" else
"011" when r_first_be = "0010" and r_last_be = "0000" else
"011" when r_first_be = "0100" and r_last_be = "0000" else
"011" when r_first_be = "1000" and r_last_be = "0000" else
"000" when r_first_be = "---1" and r_last_be = "1---" else
"001" when r_first_be = "---1" and r_last_be = "01--" else
"010" when r_first_be = "---1" and r_last_be = "001-" else
"011" when r_first_be = "---1" and r_last_be = "0001" else
"001" when r_first_be = "--10" and r_last_be = "1---" else
"010" when r_first_be = "--10" and r_last_be = "01--" else
"011" when r_first_be = "--10" and r_last_be = "001-" else
"100" when r_first_be = "--10" and r_last_be = "0001" else
"010" when r_first_be = "-100" and r_last_be = "1---" else
"011" when r_first_be = "-100" and r_last_be = "01--" else
"100" when r_first_be = "-100" and r_last_be = "001-" else
"101" when r_first_be = "-100" and r_last_be = "0001" else
"011" when r_first_be = "1000" and r_last_be = "1---" else
"100" when r_first_be = "1000" and r_last_be = "01--" else
"101" when r_first_be = "1000" and r_last_be = "001-" else
"110" when r_first_be = "1000" and r_last_be = "0001" else
"---";
s_bytes <= std_logic_vector(unsigned(r_length & "00") - s_missing);
s_low_addr(6 downto 2) <= r_address(6 downto 2);
s_low_addr(1 downto 0) <=
"00" when r_first_be = "0000" else
"00" when r_first_be = "---1" else
"01" when r_first_be = "--10" else
"10" when r_first_be = "-100" else
"11" when r_first_be = "1000" else
"--";
-- register: tx_en_o and tx_alloc_o
tx_en_o <= r_tx_en;
tx_alloc_o <= r_tx_alloc or r_rx_alloc;
tx_state_machine : process(clk_i) is
variable next_state : tx_state_type;
begin
if rising_edge(clk_i) then
if rstn_i = '0' then
tx_state <= c0;
r_tx_en <= '0';
r_tx_alloc <= '0';
else
----------------- Transition rules --------------------
next_state := tx_state;
case tx_state is
when c0 =>
if r_tx_en = '1' then
next_state := c1;
end if;
when c1 =>
if r_tx_en = '1' then
next_state := c2;
end if;
when c2 =>
if r_tx_en = '1' then
if r_flight_count = 0 then
next_state := c_queue;
else
next_state := c_block;
end if;
end if;
when c_block =>
if r_flight_count = 0 then
next_state := c_queue;
end if;
when c_queue =>
if r_pending_ack = 0 then
next_state := c0;
end if;
end case;
----------------- Post-transition actions --------------------
r_tx_en <= '0';
r_tx_alloc <= '0';
tx_eop_o <= '0';
tx_dat_o <= (others => '-');
tx_state <= next_state;
case next_state is
when c0 =>
r_pending_ack <= r_length;
-- r_length, r_tc, r_attr: all set on exit of h0
tx_dat_o <= "01001010" -- Completion with data
& "0" & r_tc & "0" & r_attr(2 downto 2) & "00"
& "00" & r_attr(1 downto 0) & "00" & std_logic_vector(r_length);
if r_fmttype(6) = '0' and r_fmttype(3) = '0' and rx_state /= h0 and tx_rdy_i = '1' then
r_tx_alloc <= '1';
r_tx_en <= '1';
end if;
when c1 =>
-- s_bytes: depends on first_be/last_be: set on exit of h_request
tx_dat_o <= cfg_busdev_i & "0000000" & s_bytes;
if rx_state /= h_request and tx_rdy_i = '1' then
r_tx_alloc <= '1';
r_tx_en <= '1';
end if;
when c2 =>
-- s_low_addr: set on exit of h_low_addr
tx_dat_o <= r_transaction & "0" & s_low_addr;
if rx_state /= h_high_addr and rx_state /= h_low_addr and tx_rdy_i = '1' then
r_tx_alloc <= '1';
r_tx_en <= '1';
end if;
when c_block =>
null;
when c_queue =>
tx_dat_o <= wb_dat_i;
if r_pending_ack = 1 then
tx_eop_o <= '1';
end if;
if (wb_ack_i or wb_err_i) = '1' then
r_tx_en <= '1';
r_pending_ack <= r_pending_ack - 1;
end if;
end case;
end if;
end if;
end process;
flight_counter : process(clk_i)
begin
if rising_edge(clk_i) then
......
......@@ -53,6 +53,8 @@ architecture rtl of pcie_wb is
signal wb_stb_o, wb_we_o, wb_ack_i : std_logic;
signal wb_dat_o, wb_dat_i, demo_reg : std_logic_vector(31 downto 0);
signal cfg_busdev : std_logic_vector(12 downto 0);
begin
reset : pow_reset
......@@ -79,10 +81,15 @@ begin
pcie_rstn_i => pcie_rstn_i,
pcie_rx_i => pcie_rx_i,
pcie_tx_o => pcie_tx_o,
cfg_busdev_o => cfg_busdev,
wb_clk_o => wb_clk,
rx_wb_stb_o => rx_wb_stb,
rx_wb_dat_o => rx_wb_dat,
rx_wb_stall_i => rx_wb_stall,
tx_rdy_o => tx_rdy,
tx_alloc_i => tx_alloc,
tx_en_i => tx_en,
......@@ -98,6 +105,14 @@ begin
rx_wb_dat_i => rx_wb_dat,
rx_wb_stall_o => rx_wb_stall,
tx_rdy_i => tx_rdy,
tx_alloc_o => tx_alloc,
tx_en_o => tx_en,
tx_dat_o => tx_dat,
tx_eop_o => tx_eop,
cfg_busdev_i => cfg_busdev,
wb_stb_o => wb_stb_o,
wb_adr_o => open,
wb_we_o => wb_we_o,
......@@ -133,5 +148,5 @@ begin
end process;
led_o(0) <= led_r;
led_o(1 to 7) <= (others => '1');
led_o(1 to 7) <= not demo_reg(6 downto 0);
end rtl;
......@@ -15,7 +15,7 @@ package pcie_wb_pkg is
pcie_rx_i : in std_logic_vector(3 downto 0);
pcie_tx_o : out std_logic_vector(3 downto 0);
cfg_busdev : out std_logic_vector(12 downto 0); -- Configured Bus#:Dev#
cfg_busdev_o : out std_logic_vector(12 downto 0); -- Configured Bus#:Dev#
-- Simplified wishbone output stream
wb_clk_o : out std_logic;
......@@ -44,11 +44,13 @@ package pcie_wb_pkg is
rx_wb_dat_i : in std_logic_vector(31 downto 0);
rx_wb_stall_o : out std_logic;
tx_rdy_i : out std_logic;
tx_alloc_o : in std_logic;
tx_en_o : in std_logic;
tx_dat_o : in std_logic_vector(31 downto 0);
tx_eop_o : in std_logic;
tx_rdy_i : in std_logic;
tx_alloc_o : out std_logic;
tx_en_o : out std_logic;
tx_dat_o : out std_logic_vector(31 downto 0);
tx_eop_o : out std_logic;
cfg_busdev_i : in std_logic_vector(12 downto 0);
wb_stb_o : out std_logic;
wb_adr_o : out std_logic_vector(63 downto 0);
......
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