From e9de00f817a3c81807023afb871399781fd74445 Mon Sep 17 00:00:00 2001 From: rs <> Date: Fri, 3 Oct 2025 21:53:43 -0500 Subject: [PATCH] Fix PS2 interface interrupt and error flags --- libraries/ps2/ps2_host_opt.vhd | 1 + libraries/ps2/ps2_host_wb_opt.vhd | 60 ++++++++++++++++++------------- 2 files changed, 37 insertions(+), 24 deletions(-) diff --git a/libraries/ps2/ps2_host_opt.vhd b/libraries/ps2/ps2_host_opt.vhd index 3ed255f..d56d18e 100644 --- a/libraries/ps2/ps2_host_opt.vhd +++ b/libraries/ps2/ps2_host_opt.vhd @@ -226,6 +226,7 @@ begin rx_timeout_set <= '0'; -- Don't flag RX timeout rx_missed_rst <= '0'; -- Don't reset the RX missed flag transmit <= '0'; + tx_nack_update <= '0'; case state_reg is when S_READY => diff --git a/libraries/ps2/ps2_host_wb_opt.vhd b/libraries/ps2/ps2_host_wb_opt.vhd index b1ab7b3..947b7f4 100644 --- a/libraries/ps2/ps2_host_wb_opt.vhd +++ b/libraries/ps2/ps2_host_wb_opt.vhd @@ -130,7 +130,11 @@ architecture behavioral of ps2_host_wb_opt is -- 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 @@ -173,37 +177,36 @@ architecture behavioral of ps2_host_wb_opt is 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; @@ -211,10 +214,19 @@ begin 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; @@ -222,14 +234,14 @@ begin 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; -- 2.43.0