-- Bus-exposed registers
signal ctrl_reg: std_logic_vector(7 downto 0);
signal imask_reg: std_logic_vector(7 downto 0);
- signal iflag_reg: std_logic_vector(7 downto 0);
+ --signal iflag_reg: std_logic_vector(7 downto 0);
+ signal iflags: std_logic_vector(7 downto 0);
+ signal iflag_oer_reg: std_logic;
+ signal iflag_fer_reg: std_logic;
+ signal iflag_per_reg: std_logic;
signal error_vec: std_logic_vector(7 downto 0);
-- Control register bit signals
begin
-- Wishbone interface
- process (rst_i, clk_i, cyc_i, stb_i, we_i, adr_i, dat_i)
+ process (rst_i, clk_i, cyc_i, stb_i, we_i, adr_i, dat_i, rxqh_stb)
begin
if rising_edge(clk_i) then
if rst_i = '1' then
- ctrl_reg <= (others => '0');
- imask_reg <= (others => '0');
- iflag_reg <= (others => '0');
+ ctrl_reg <= (others => '0');
+ imask_reg <= (others => '0');
+ iflag_oer_reg <= '0';
+ iflag_fer_reg <= '0';
+ iflag_per_reg <= '0';
else
-- Perform write cycle
if cyc_i = '1' and stb_i = '1' and we_i = '1' then
case adr_i is
when "000" => ctrl_reg <= dat_i;
when "001" => imask_reg <= dat_i;
- when "010" => iflag_reg <= iflag_reg and (not dat_i); -- W1C
+ when "010" => -- W1C
+ iflag_oer_reg <= iflag_oer_reg and dat_i(7);
+ iflag_fer_reg <= iflag_fer_reg and dat_i(6);
+ iflag_per_reg <= iflag_per_reg and dat_i(5);
when "011" => null; -- RO
when "100" => null; -- Attached to FIFOs
when others => null;
end case;
end if;
- -- Latch interrupt flags
- iflag_reg(0) <= rxqt_stb; -- using !rxq_empty will trigger interrupt before data makes it through the pipeline FIFO
- iflag_reg(1) <= rxq_full;
- iflag_reg(2) <= not txq_full;
- iflag_reg(3) <= txq_empty;
-
-- Catch receive error flags when the interface reports a new byte
if rxqh_stb = '1' then
- iflag_reg(5) <= iflag_reg(5) or rx_err_parity;
- iflag_reg(6) <= iflag_reg(6) or rx_err_start or rx_err_stop;
- iflag_reg(7) <= iflag_reg(7) or rx_err_missed;
+ iflag_oer_reg <= iflag_oer_reg or rx_err_missed;
+ iflag_fer_reg <= iflag_fer_reg or rx_err_start or rx_err_stop;
+ iflag_per_reg <= iflag_per_reg or rx_err_parity;
end if;
end if;
end if;
error_vec <= "00000" & tx_err_timeout & rx_err_timeout & tx_err_nack;
+ iflags <= iflag_oer_reg &
+ iflag_fer_reg &
+ iflag_per_reg &
+ '0' &
+ txq_empty &
+ (not txq_full) &
+ rxq_full &
+ (not rxq_empty);
+
with adr_i select dat_o <=
ctrl_reg when "000",
imask_reg when "001",
- iflag_reg when "010",
+ iflags when "010",
error_vec when "011",
rxqt_dat when "100",
(others => '1') when others;
ack_o <= '1';
-- Interrupt output signals
- rx_ready <= iflag_reg(0) and imask_reg(0);
- rx_full <= iflag_reg(1) and imask_reg(1);
- tx_ready <= iflag_reg(2) and imask_reg(2);
- tx_empty <= iflag_reg(3) and imask_reg(3);
-
- err_missed <= iflag_reg(5) and imask_reg(5);
- err_framing <= iflag_reg(6) and imask_reg(6);
- err_parity <= iflag_reg(7) and imask_reg(7);
+ rx_ready <= iflags(0) and imask_reg(0);
+ rx_full <= iflags(1) and imask_reg(1);
+ tx_ready <= iflags(2) and imask_reg(2);
+ tx_empty <= iflags(3) and imask_reg(3);
+
+ err_missed <= iflags(5) and imask_reg(5);
+ err_framing <= iflags(6) and imask_reg(6);
+ err_parity <= iflags(7) and imask_reg(7);
err_nack <= tx_err_nack;
err_rxto <= rx_err_timeout;