]> git.the-white-hart.net Git - vhdl/commitdiff
Fix PS2 interface interrupt and error flags
authorrs <>
Sat, 4 Oct 2025 02:53:43 +0000 (21:53 -0500)
committerrs <>
Sat, 4 Oct 2025 02:53:43 +0000 (21:53 -0500)
libraries/ps2/ps2_host_opt.vhd
libraries/ps2/ps2_host_wb_opt.vhd

index 3ed255f20e6984a1b81ce65aa0d95f1b9e604bec..d56d18ef88b0024e62b7c5780542c1d47e93fb9e 100644 (file)
@@ -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 =>
index b1ab7b3e1553ef7bb23130f35cdf6f8b003916aa..947b7f498b13af6257db037666ec8b83f545c7a6 100644 (file)
@@ -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;