OpenCores
URL https://opencores.org/ocsvn/ps2core/ps2core/trunk

Subversion Repositories ps2core

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

/trunk/gpl.txt
0,0 → 1,220
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
 
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
 
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
 
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
 
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
 
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
 
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
 
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
 
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
 
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
 
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
 
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
 
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
 
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
 
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
 
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
 
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
 
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
 
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
 
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
 
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
 
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
 
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
 
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
 
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
 
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
 
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
 
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
 
NO WARRANTY
 
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
 
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
/trunk/rtl/vhdl/ps2_wishbone.vhd
0,0 → 1,155
-------------------------------------------------------------------------------
-- Title : PS/2 Wishbone Interface
-- Project :
-------------------------------------------------------------------------------
-- File : ps2_wishbone.vhd
-- Author : Daniel Quinter <danielqg@infonegocio.com>
-- Company : Itoo Software
-- Created : 2003-05-08
-- Last update: 2003-10-30
-- Platform : VHDL'87
-------------------------------------------------------------------------------
-- Description: PS/2 mice/keyboard wishbone interface
-------------------------------------------------------------------------------
-- This code is distributed under the terms and conditions of the
-- GNU General Public License
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2003-05-08 1.0 daniel Created
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
 
 
entity ps2_wb is
port ( -- Wishbone interface
wb_clk_i : in std_logic;
wb_rst_i : in std_logic;
wb_dat_i : in std_logic_vector(7 downto 0);
wb_dat_o : out std_logic_vector(7 downto 0);
wb_adr_i : in std_logic_vector(0 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
 
-- IRQ output
irq_o : out std_logic;
 
-- PS2 signals
ps2_clk : inout std_logic;
ps2_dat : inout std_logic);
end ps2_wb;
 
 
architecture rtl of ps2_wb is
component ps2
port (
clk_i : in std_logic;
rst_i : in std_logic;
data_o : out std_logic_vector(7 downto 0);
data_i : in std_logic_vector(7 downto 0);
ibf_clr_i : in std_logic;
obf_set_i : in std_logic;
ibf_o : out std_logic;
obf_o : out std_logic;
frame_err_o : out std_logic;
parity_err_o : out std_logic;
busy_o : out std_logic;
err_clr_i : in std_logic;
wdt_o : out std_logic;
ps2_clk_io : inout std_logic;
ps2_data_io : inout std_logic);
end component;
 
signal nrst : std_logic;
signal ps2_data_o : std_logic_vector(7 downto 0);
signal ps2_data_i : std_logic_vector(7 downto 0);
signal ibf_clr : std_logic;
signal obf_set : std_logic;
signal ibf : std_logic;
signal obf : std_logic;
signal frame_err : std_logic;
signal parity_err : std_logic;
signal busy : std_logic;
signal err_clr : std_logic;
signal wdt : std_logic;
 
signal status_reg : std_logic_vector(7 downto 0);
signal control_reg : std_logic_vector(7 downto 0);
 
signal irq_rx_enb : std_logic;
signal irq_tx_enb : std_logic;
 
begin
 
ps2_uart : ps2
port map (
clk_i => wb_clk_i,
rst_i => nrst,
data_o => ps2_data_o,
data_i => ps2_data_i,
ibf_clr_i => ibf_clr,
obf_set_i => obf_set,
ibf_o => ibf,
obf_o => obf,
frame_err_o => frame_err,
parity_err_o => parity_err,
busy_o => busy,
err_clr_i => err_clr,
wdt_o => wdt,
ps2_clk_io => ps2_clk,
ps2_data_io => ps2_dat);
 
nrst <= not wb_rst_i;
 
-- clear error flags when clear it's
err_clr <= '1' when wb_stb_i = '1' and wb_we_i = '1' and wb_adr_i = "1" and wb_dat_i(3) = '0'
else '0';
 
-- clear In Buffer Full (IBF) flag when clear it
ibf_clr <= '1' when wb_stb_i = '1' and wb_we_i = '1' and wb_adr_i = "1" and wb_dat_i(0) = '0'
else '0';
 
-- set Out Buffer Full when write to data register
obf_set <= '1' when wb_stb_i = '1' and wb_we_i = '1' and wb_adr_i = "0"
else '0';
 
-- Status register
status_reg(7) <= irq_tx_enb;
status_reg(6) <= irq_rx_enb;
status_reg(5 downto 4) <= "00";
status_reg(3) <= parity_err or frame_err;
status_reg(2) <= obf;
status_reg(1) <= ibf;
status_reg(0) <= busy;
 
-- Control register
irq_rx_enb <= control_reg(6);
irq_tx_enb <= control_reg(7);
 
-- purpose: Control register latch
control_reg_proc : process (wb_clk_i)
begin
if (wb_clk_i'event and wb_clk_i = '1') then
if wb_rst_i = '1' then -- Synchronous reset
control_reg(7 downto 6) <= (others => '0');
elsif (wb_stb_i and wb_we_i) = '1' and wb_adr_i = "1" then -- control_write
control_reg(7 downto 6) <= wb_dat_i(7 downto 6);
end if;
end if;
 
end process control_reg_proc;
 
-- output data/status
wb_dat_o <= ps2_data_o when wb_adr_i = "0" else status_reg;
ps2_data_i <= wb_dat_i;
 
-- Irq generation
irq_o <= (ibf and irq_rx_enb) or ((not obf) and irq_tx_enb);
 
-- no wait states for all acceses
wb_ack_o <= wb_stb_i;
 
end rtl;
/trunk/rtl/vhdl/ps2_test.vhd
0,0 → 1,198
-------------------------------------------------------------------------------
-- Title : PS/2 Syntetizable interface Test
-- Project :
-------------------------------------------------------------------------------
-- File : ps2.vhd
-- Author : Daniel Quintero <danielqg@infonegocio.com>
-- Company : Itoo Software
-- Created : 2003-04-14
-- Last update: 2003-10-30
-- Platform : VHDL'87
-------------------------------------------------------------------------------
-- Description: Test interface for PS2 mouse
-------------------------------------------------------------------------------
-- This code is distributed under the terms and conditions of the
-- GNU General Public License
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2003-04-14 1.0 daniel Created
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;
 
entity mouse_test is
port (
clk_i : in std_logic;
rst_i : in std_logic;
 
ps2_data_io : inout std_logic;
ps2_clk_io : inout std_logic;
activity_o : out std_logic;
beep_o : out std_logic;
data_o : out std_logic_vector(23 downto 0);
perr_o : out std_logic;
ferr_o : out std_logic);
end mouse_test;
 
 
 
architecture rtl of mouse_test is
component ps2
port (
clk_i : in std_logic;
rst_i : in std_logic;
data_o : out std_logic_vector(7 downto 0);
data_i : in std_logic_vector(7 downto 0);
ibf_clr_i : in std_logic;
obf_set_i : in std_logic;
ibf_o : out std_logic;
obf_o : out std_logic;
frame_err_o : out std_logic;
parity_err_o : out std_logic;
err_clr_i : in std_logic;
wdt_o : out std_logic;
ps2_clk_io : inout std_logic;
ps2_data_io : inout std_logic);
end component;
 
constant BEEP_TIMEOUT : integer := 24000; -- clks to debounce the ps2_clk signal
constant BEEP_BITS : integer := 15;
 
signal rst : std_logic := '0';
signal ps2_wdt : std_logic;
--signal rst_cnt_cao : std_logic;
--signal rst_cnt : std_logic_vector(24 downto 0);
signal beep_cnt_cao : std_logic;
signal beep_cnt : std_logic_vector(BEEP_BITS-1 downto 0);
signal beep_freq : std_logic;
signal data_cnt : std_logic_vector(1 downto 0);
signal data_out : std_logic_vector(7 downto 0);
signal data_in : std_logic_vector(7 downto 0);
signal mouse_data : std_logic_vector(23 downto 0);
signal ibf_clr, obf_set : std_logic;
signal ibf, obf : std_logic;
signal parity_err : std_logic;
signal frame_err : std_logic;
signal err_clr : std_logic;
type states is (reset, setup0, setup1, wait_packet,
wait_data, recv_data, process_data);
signal state : states;
begin
syscon : process (clk_i)
begin
 
if clk_i'event and clk_i = '1' then
rst <= rst_i; -- and (not rst_cnt_cao);
end if;
end process;
 
-- rst_wdt : process (clk_i, rst_i)
-- begin
-- if rst_i = '0' then
-- rst_cnt <= (others => '0');
-- elsif clk_i'event and clk_i = '1' then
-- if rst_cnt_cao = '1' then
-- rst_cnt <= (others => '0');
-- else
-- rst_cnt <= rst_cnt + 1;
-- end if;
-- end if;
-- end process;
-- rst_cnt_cao <= rst_cnt(24);
-- rst_cnt_cao <= '0';
 
beepcnt : process (clk_i, rst_i)
begin
if rst_i = '0' then
beep_cnt <= (others => '0');
beep_freq <= '0';
elsif clk_i'event and clk_i = '1' then
if beep_cnt_cao = '1' then
beep_cnt <= (others => '0');
beep_freq <= not beep_freq;
else
beep_cnt <= beep_cnt + 1;
end if;
end if;
end process;
beep_cnt_cao <= '1' when beep_cnt =
CONV_STD_LOGIC_VECTOR(BEEP_TIMEOUT-1, BEEP_BITS)
else '0';
 
ps2_uart: ps2
port map (
clk_i => clk_i,
rst_i => rst,
data_o => data_in,
data_i => data_out,
ibf_clr_i => ibf_clr,
obf_set_i => obf_set,
ibf_o => ibf,
obf_o => obf,
frame_err_o => frame_err,
parity_err_o => parity_err,
err_clr_i => err_clr,
wdt_o => ps2_wdt,
ps2_clk_io => ps2_clk_io,
ps2_data_io => ps2_data_io);
 
stm : process (clk_i, rst)
begin -- process stm
if rst = '0' then -- asynchronous reset (active low)
state <= reset;
data_cnt <= "00";
mouse_data <= (others => '0');
data_out <= (others => '0');
elsif clk_i'event and clk_i = '1' then -- rising clock edge
case state is
when reset => state <= setup0;
 
when setup0 => data_out <= "11110100"; -- F4h - Enable data reporting
state <= setup1;
 
when setup1 => if obf = '0' then
state <= wait_packet;
end if;
 
when wait_packet => data_cnt <= "00";
state <= wait_data;
 
when wait_data => if data_cnt = "11" then
state <= process_data;
elsif ibf = '1' then
state <= recv_data;
elsif ps2_wdt = '1' and
data_cnt /= "00" then
state <= wait_packet;
end if;
 
when recv_data => if data_cnt = "00" then
mouse_data(7 downto 0) <= data_in;
elsif data_cnt = "01" then
mouse_data(15 downto 8) <= data_in;
elsif data_cnt = "10" then
mouse_data(23 downto 16) <= data_in;
end if;
data_cnt <= data_cnt + 1;
state <= wait_data;
 
when process_data => state <= wait_packet;
 
when others => null;
end case;
end if;
end process stm;
obf_set <= '1' when state = setup0 else '0';
ibf_clr <= '1' when state = recv_data else '0';
err_clr <= ps2_wdt;
 
data_o <= mouse_data;
activity_o <= mouse_data(0) or mouse_data(1) or mouse_data(2) or not rst;
beep_o <= beep_freq and (mouse_data(0) or mouse_data(1) or mouse_data(2));
perr_o <= parity_err;
ferr_o <= frame_err;
end rtl;
/trunk/rtl/vhdl/ps2.vhd
0,0 → 1,360
-------------------------------------------------------------------------------
-- Title : PS/2 interface
-- Project :
-------------------------------------------------------------------------------
-- File : ps2.vhd
-- Author : Daniel Quintero <danielqg@infonegocio.com>
-- Company : Itoo Software
-- Created : 2003-04-14
-- Last update: 2003-10-30
-- Platform : VHDL'87
-------------------------------------------------------------------------------
-- Description: PS/2 generic UART for mice/keyboard
-------------------------------------------------------------------------------
-- This code is distributed under the terms and conditions of the
-- GNU General Public License
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2003-04-14 1.0 daniel Created
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
 
entity ps2 is
port (
clk_i : in std_logic; -- Global clk
rst_i : in std_logic; -- GLobal Asinchronous reset
 
data_o : out std_logic_vector(7 downto 0); -- Data in
data_i : in std_logic_vector(7 downto 0); -- Data out
ibf_clr_i : in std_logic; -- Ifb flag clear input
obf_set_i : in std_logic; -- Obf flag set input
ibf_o : out std_logic; -- Received data available
obf_o : out std_logic; -- Data ready to sent
 
frame_err_o : out std_logic; -- Error receiving data
parity_err_o : out std_logic; -- Error in received data parity
busy_o : out std_logic; -- uart busy
err_clr_i : in std_logic; -- Clear error flags
 
wdt_o : out std_logic; -- Watchdog timer out every 400uS
 
ps2_clk_io : inout std_logic; -- PS2 Clock line
ps2_data_io : inout std_logic); -- PS2 Data line
end ps2;
 
architecture rtl of ps2 is
 
type states is (idle, write_request, start, data, parity, stop);
type debounce_states is (stable, rise, fall, wait_stable);
 
--constant DEBOUNCE_TIMEOUT : integer := 200; -- clks to debounce the ps2_clk signal
constant DEBOUNCE_BITS : integer := 8;
--constant WATCHDOG_TIMEOUT : integer := 19200 / DEBOUNCE_TIMEOUT; -- clks to wait 400uS
constant WATCHDOG_BITS : integer := 8;
 
signal state : states;
signal debounce_state : debounce_states;
signal debounce_cnt : std_logic_vector(DEBOUNCE_BITS-1 downto 0);
signal debounce_cao : std_logic;
signal ps2_clk_syn : std_logic; -- PS2 clock input syncronized
signal ps2_clk_clean : std_logic; -- PS2 clock debounced and clean
signal ps2_clk_fall : std_logic; -- PS2 clock fall edge
signal ps2_clk_rise : std_logic; -- PS2 clock rise edge
signal ps2_data_syn : std_logic; -- PS2 data input syncronized
signal ps2_clk_out : std_logic; -- PS2 clock output
signal ps2_data_out : std_logic; -- PS2 clock output
signal writing : std_logic; -- read / write cycle flag
signal shift_cnt : std_logic_vector(2 downto 0);
signal shift_cao : std_logic; -- Shift counter carry out
signal shift_reg : std_logic_vector(8 downto 0);
signal shift_in : std_logic; -- Shift register to right
signal shift_load : std_logic; -- Shift register parallel load
signal shift_calc_parity : std_logic; -- Shift register set parity
signal wdt_cnt : std_logic_vector(WATCHDOG_BITS-1 downto 0);
signal wdt_rst : std_logic; -- watchdog reset
signal wdt_cao : std_logic; -- watchdog carry out
signal shift_parity : std_logic; -- Current parity of shift_reg
signal ibf : std_logic; -- IBF, In Buffer Full
signal obf : std_logic; -- OBF, Out Buffer Full
signal parity_err : std_logic; -- Parity error
signal frame_err : std_logic; -- Frame error
 
begin -- rtl
 
-- Sincronize input signals
syn_ps2 : process (clk_i, rst_i)
begin
if rst_i = '0' then -- asynchronous reset (active low)
ps2_clk_syn <= '0';
ps2_data_syn <= '0';
elsif clk_i'event and clk_i = '1' then -- rising clock edge
ps2_clk_syn <= TO_X01(ps2_clk_io);
ps2_data_syn <= TO_X01(ps2_data_io);
end if;
end process syn_ps2;
 
-- clk debounce timer
debounce_count : process (clk_i, rst_i)
begin
if rst_i = '0' then -- asynchronous reset (active low)
debounce_cnt <= (others => '0');
elsif clk_i'event and clk_i = '1' then -- rising clock edge
if (ps2_clk_fall or ps2_clk_rise or debounce_cao) = '1' then
debounce_cnt <= (others => '0');
else
debounce_cnt <= debounce_cnt + 1;
end if;
end if;
end process;
debounce_cao <= debounce_cnt(DEBOUNCE_BITS-1);
-- debounce_cao <= '1' when debounce_cnt =
-- CONV_STD_LOGIC_VECTOR(DEBOUNCE_TIMEOUT-1, DEBOUNCE_BITS)
-- else '0';
 
-- PS2 clock debounce and edge detector
debounce_stm : process (clk_i, rst_i)
begin
if rst_i = '0' then
debounce_state <= stable;
ps2_clk_clean <= '0';
elsif clk_i'event and clk_i = '1' then
case debounce_state is
when stable =>
if ps2_clk_clean /= ps2_clk_syn then
if ps2_clk_syn = '1' then
debounce_state <= rise;
else
debounce_state <= fall;
end if;
end if;
when wait_stable =>
if debounce_cao = '1' then
debounce_state <= stable;
end if;
when rise => debounce_state <= wait_stable;
ps2_clk_clean <= '1';
when fall => debounce_state <= wait_stable;
ps2_clk_clean <= '0';
when others => null;
end case;
end if;
end process;
ps2_clk_fall <= '1' when debounce_state = fall else '0';
ps2_clk_rise <= '1' when debounce_state = rise else '0';
 
-- PS2 watchdog
wdt_proc : process(clk_i, rst_i)
begin
if rst_i = '0' then -- asynchronous reset (active low)
wdt_cnt <= (others => '0');
elsif clk_i'event and clk_i = '1' then -- rising clock edge
if (wdt_rst or wdt_cao) = '1' then
wdt_cnt <= (others => '0');
elsif debounce_cao = '1' then
wdt_cnt <= wdt_cnt + 1;
end if;
end if;
end process;
wdt_cao <= wdt_cnt(WATCHDOG_BITS-1);
-- wdt_cao <= '1' when wdt_cnt =
-- CONV_STD_LOGIC_VECTOR(WATCHDOG_TIMEOUT-1, WATCHDOG_BITS)
-- else '0';
wdt_rst <= ps2_clk_fall;
 
 
-- Shift register
shift : process (clk_i, rst_i)
begin
if rst_i = '0' then -- asynchronous reset (active low)
shift_reg <= (others => '0');
elsif clk_i'event and clk_i = '1' then -- rising clock edge
if shift_load = '1' then
shift_reg(7 downto 0) <= data_i;
shift_reg(8) <= '0';
elsif shift_calc_parity = '1' then
shift_reg(8) <= not shift_parity;
elsif shift_in = '1' then
shift_reg(7 downto 0) <= shift_reg(8 downto 1);
shift_reg(8) <= ps2_data_syn;
end if;
end if;
end process;
 
-- Shift counter
sft_cnt : process(clk_i, rst_i)
begin
if rst_i = '0' then -- asynchronous reset (active low)
shift_cnt <= (others => '0');
elsif clk_i'event and clk_i = '1' then -- rising clock edge
if state = start then
shift_cnt <= (others => '0');
elsif state = data and ps2_clk_fall = '1' then
shift_cnt <= shift_cnt + 1;
end if;
end if;
end process;
shift_cao <= '1' when shift_cnt = "111" else '0';
 
-- Odd Parity generator
shift_parity <= (shift_reg(0) xor
shift_reg(1) xor
shift_reg(2) xor
shift_reg(3) xor
shift_reg(4) xor
shift_reg(5) xor
shift_reg(6) xor
shift_reg(7));
 
 
-- Main State Machine
stm : process (clk_i, rst_i)
begin
if rst_i = '0' then -- asynchronous reset (active low)
state <= idle;
writing <= '0';
elsif clk_i'event and clk_i = '1' then -- rising clock edge
case state is
 
-- Waiting for clk
when idle => if obf_set_i = '1' and writing = '0' then
state <= write_request;
writing <= '1';
elsif ps2_clk_fall = '1' then
state <= start;
end if;
 
-- Write request, clk low
when write_request => if wdt_cao = '1' then
state <= idle;
end if;
 
-- Clock 1, start bit
when start => if wdt_cao = '1' then
state <= idle;
elsif ps2_clk_fall = '1' then
state <= data;
end if;
 
-- Clocks 2-9, Data bits (LSB first)
when data => if wdt_cao = '1' then
state <= idle;
elsif ps2_clk_fall = '1' and
shift_cao = '1' then
state <= parity;
end if;
 
-- Clock 10, Parity bit
when parity => if wdt_cao = '1' then
state <= idle;
elsif ps2_clk_fall = '1' then
state <= stop;
end if;
 
-- Clock 11, Stop bit
when stop => writing <= '0';
state <= idle;
when others => null;
end case;
end if;
end process;
 
-- State flags
flags_proc : process (clk_i, rst_i, state, writing)
begin -- process stm_out
-- Input Buffer write flag
if rst_i = '0' then -- asynchronous reset (active low)
--obf <= '0';
ibf <= '0';
parity_err <= '0';
frame_err <= '0';
elsif clk_i'event and clk_i = '1' then -- rising clock edge
 
-- Parity error flag
if err_clr_i = '1' then
parity_err <= '0';
elsif writing = '0' and state = stop then
if shift_reg(8) /= not shift_parity then
parity_err <= '1';
end if;
end if;
 
-- Frame error flag
if err_clr_i = '1' then
frame_err <= '0';
elsif (state = start or
state = data or state = parity) and wdt_cao = '1' then
frame_err <= '1';
end if;
 
-- Input Buffer full flag
if ibf_clr_i = '1' then
ibf <= '0';
elsif writing = '0' and state = stop then
if shift_reg(8) = not shift_parity then
ibf <= '1';
end if;
end if;
 
-- Output buffer full flag
--if state = stop and writing = '1' then
-- obf <= '0';
--elsif obf_set_i = '1' then
-- obf <= '1';
--end if;
end if;
end process;
 
obf <= writing;
 
-- Shift register control
shift_load <= '1' when obf_set_i = '1' else '0';
shift_calc_parity <= '1' when state = idle and writing = '1' else '0';
shift_in <= ps2_clk_fall when state = data or state = start else '0';
 
 
-- PS2 Registered outputs
syn_ps2_out : process (clk_i, rst_i)
begin
if rst_i = '0' then -- asynchronous reset (active low)
ps2_data_out <= '1';
ps2_clk_out <= '1';
elsif clk_i'event and clk_i = '1' then -- rising clock edge
 
-- PS2 Data out
if writing = '1' then
if state = idle then
ps2_data_out <= '0';
elsif state = data or state = start then
ps2_data_out <= shift_reg(0);
else
ps2_data_out <= '1';
end if;
end if;
 
-- PS2 Clk out
if state = write_request then
ps2_clk_out <= '0';
else
ps2_clk_out <= '1';
end if;
end if;
end process;
 
data_o <= shift_reg(7 downto 0);
ibf_o <= ibf;
obf_o <= obf;
busy_o <= '0' when state = idle and writing = '0' else '1';
parity_err_o <= parity_err;
frame_err_o <= frame_err;
wdt_o <= wdt_cao;
 
ps2_clk_io <= '0' when ps2_clk_out = '0' else 'Z';
ps2_data_io <= '0' when ps2_data_out = '0' else 'Z';
 
end rtl;
 
/trunk/sim/bin/compile.do
0,0 → 1,12
# Compile PS2 Design
 
vcom ../../rtl/vhdl/ps2.vhd
vcom ../../rtl/vhdl/ps2_test.vhd
vcom ../../rtl/vhdl/ps2_wishbone.vhd
 
# Compile Testbeches
 
vcom -93 ../vhdl/ps2_mouse.vhd
vcom -93 ../vhdl/wb_test.vhd
vcom -93 ../vhdl/wb_ps2_tb.vhd
 
/trunk/sim/vhdl/wb_ps2_tb.vhd
0,0 → 1,165
-------------------------------------------------------------------------------
-- Title : PS/2 interface Testbench
-- Project :
-------------------------------------------------------------------------------
-- File : ps2.vhd
-- Author : Daniel Quintero <danielqg@infonegocio.com>
-- Company : Itoo Software
-- Created : 2003-04-14
-- Last update: 2003-10-30
-- Platform : VHDL'87
-------------------------------------------------------------------------------
-- Description: PS/2 generic UART for mice/keyboard, Wishbone Testbench
-------------------------------------------------------------------------------
-- This code is distributed under the terms and conditions of the
-- GNU General Public License
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2003-04-14 1.0 daniel Created
-------------------------------------------------------------------------------
 
library ieee, work;
use ieee.std_logic_1164.all;
use work.wb_test.all;
 
entity wb_ps2_tb is
-- Generic declarations of the tested unit
generic(
addr_width : positive := 1;
bus_width : positive := 8);
end wb_ps2_tb;
 
 
architecture sim of wb_ps2_tb is
-- Component declaration of the tested unit
component ps2_wb
port (
wb_clk_i : in std_logic;
wb_rst_i : in std_logic;
wb_dat_i : in std_logic_vector(7 downto 0);
wb_dat_o : out std_logic_vector(7 downto 0);
wb_adr_i : in std_logic_vector(0 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
irq_o : out std_logic;
ps2_clk : inout std_logic;
ps2_dat : inout std_logic);
end component;
 
 
component ps2mouse
port (
PS2_clk : inout std_logic;
PS2_data : inout std_logic);
end component;
 
 
 
signal adr_i : std_logic_vector (addr_width-1 downto 0) := (others => '0');
-- Stimulus signals - signals mapped to the input and inout ports of tested entity
signal clk_i : std_logic := '0';
signal rst_i : std_logic := '0';
signal cyc_i : std_logic;
signal stb_i : std_logic;
signal we_i : std_logic;
signal dat_i : std_logic_vector((bus_width-1) downto 0);
 
-- Observed signals - signals mapped to the output ports of tested entity
signal ack_o : std_logic;
signal dat_o : std_logic_vector((bus_width-1) downto 0);
signal irq_o : std_logic;
signal ps2_clk : std_logic;
signal ps2_dat : std_logic;
 
signal done : boolean := false;
 
-- Add your code here ...
 
begin
-- Unit Under Test port map
ps2_wb_1 : ps2_wb
port map (
wb_clk_i => clk_i,
wb_rst_i => rst_i,
wb_dat_i => dat_i,
wb_dat_o => dat_o,
wb_adr_i => adr_i,
wb_stb_i => stb_i,
wb_we_i => we_i,
wb_ack_o => ack_o,
irq_o => irq_o,
ps2_clk => ps2_clk,
ps2_dat => ps2_dat);
 
ps2mouse_1 : ps2mouse
port map (
PS2_clk => ps2_clk,
PS2_data => ps2_dat);
 
clk : process is
begin
while not done loop
clk_i <= not clk_i;
wait for 25 ns; -- 20Mhz clock
end loop;
wait;
end process;
 
reset : process is
begin
rst_i <= '1';
wait for 150 ns;
rst_i <= '0';
wait;
end process;
 
master : process is
variable status : std_logic_vector(7 downto 0);
begin
we_i <= '0';
cyc_i <= '0';
stb_i <= '0';
adr_i <= (others => '0');
dat_i <= (others => '0');
wait until clk_i'event and clk_i = '1';
wait until clk_i'event and clk_i = '1';
wait until clk_i'event and clk_i = '1';
wait until clk_i'event and clk_i = '1';
wait until clk_i'event and clk_i = '1';
wait until clk_i'event and clk_i = '1';
wait until clk_i'event and clk_i = '1';
 
-- Check control register, interrupt status bits
wr_chk_val (clk_i, adr_i, dat_o, dat_i, we_i, cyc_i, stb_i, ack_o, "1","11000000");
wr_chk_val (clk_i, adr_i, dat_o, dat_i, we_i, cyc_i, stb_i, ack_o, "1","10000000");
wr_chk_val (clk_i, adr_i, dat_o, dat_i, we_i, cyc_i, stb_i, ack_o, "1","01000000");
wr_chk_val (clk_i, adr_i, dat_o, dat_i, we_i, cyc_i, stb_i, ack_o, "1","00000000");
 
-- Check for transmit
wr_val (clk_i, adr_i, dat_o, dat_i, we_i, cyc_i, stb_i, ack_o, "1","11000000");
wr_val (clk_i, adr_i, dat_o, dat_i, we_i, cyc_i, stb_i, ack_o, "0","01010101");
 
-- wait for end of transmit
status := (others => '1');
while status(0) = '1' loop
rd_val (clk_i, adr_i, dat_o, dat_i, we_i, cyc_i, stb_i, ack_o, "1",status);
end loop;
 
-- wait for receive data
while status(1) = '0' loop
rd_val (clk_i, adr_i, dat_o, dat_i, we_i, cyc_i, stb_i, ack_o, "1",status);
end loop;
 
-- Get data
rd_val (clk_i, adr_i, dat_o, dat_i, we_i, cyc_i, stb_i, ack_o, "1",status);
 
-- Clear flag
wr_val (clk_i, adr_i, dat_o, dat_i, we_i, cyc_i, stb_i, ack_o, "1","11000000");
 
 
done <= true;
end process;
end sim;
 
/trunk/sim/vhdl/ps2mouse_tb.vhd
0,0 → 1,187
-------------------------------------------------------------------------------
-- Title : PS/2 interface Testbench
-- Project :
-------------------------------------------------------------------------------
-- File : ps2.vhd
-- Author : Daniel Quintero <danielqg@infonegocio.com>
-- Company : Itoo Software
-- Created : 2003-04-14
-- Last update: 2003-10-30
-- Platform : VHDL'87
-------------------------------------------------------------------------------
-- Description: PS/2 generic UART for mice/keyboard, Low level Testbench
-------------------------------------------------------------------------------
-- This code is distributed under the terms and conditions of the
-- GNU General Public License
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2003-04-14 1.0 daniel Created
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use std.textio.all;
 
entity ps2mouse_tb is
end ps2mouse_tb;
 
architecture sim of ps2mouse_tb is
 
procedure PS2SendByte(byte : in std_logic_vector(7 downto 0);
signal PS2_clk : inout std_logic;
signal PS2_data : inout std_logic) is
begin
--wait until (PS2_clk = 'H');
for i in 0 to 10 loop
if i = 0 then
PS2_Data <= '0';
elsif i = 9 then
PS2_Data <= not (Byte(0) xor
Byte(1) xor
Byte(2) xor
Byte(3) xor
Byte(4) xor
Byte(5) xor
Byte(6) xor
Byte(7));
elsif i = 10 then
PS2_Data <= 'H';
else
if Byte(i - 1) = '1' then
PS2_Data <= '1';
else
PS2_Data <= '0';
end if;
end if;
wait for 20 us;
PS2_Clk <= '0';
wait for 20 us;
PS2_Clk <= '1';
end loop;
PS2_Clk <= 'H';
end;
 
procedure PS2RecvByte(byte : out std_logic_vector(7 downto 0);
signal PS2_clk : inout std_logic;
signal PS2_data : inout std_logic) is
variable parity : std_logic;
variable buf : std_logic_vector(7 downto 0);
begin
PS2_Data <= 'H';
for i in 0 to 10 loop
wait for 20 us;
PS2_Clk <= '0';
if i = 0 then
if PS2_data /= '0' then
write(output, string'("Warning, not start bit from Host"));
end if;
elsif i = 9 then
parity := To_X01(PS2_data);
elsif i = 10 then
PS2_Data <= '0'; -- Ack
else
buf(i - 1) := To_X01(PS2_data);
end if;
wait for 20 us;
PS2_Clk <= '1';
end loop;
 
if parity /= not (buf(0) xor buf(1) xor buf(2) xor buf(3) xor
buf(4) xor buf(5) xor buf(6) xor buf(7)) then
write(output, string'("Waring, parity check error in host data"));
end if;
Byte := buf;
PS2_Clk <= 'H';
PS2_Data <= 'H';
end;
 
procedure PS2Write(signal req, rw : out std_logic;
signal ack : in std_logic) is
begin
wait for 20 us;
req <= '1';
rw <= '0';
wait until ack = '1';
req <= '0' after 10 ns;
rw <= '1' after 10 ns;
end;
 
 
function stdvec_to_str(inp : std_logic_vector) return string is
variable temp : string(inp'left+1 downto 1) := (others => 'X');
begin
for i in inp'reverse_range loop
if (inp(i) = '1') then
temp(i+1) := '1';
elsif (inp(i) = '0') then
temp(i+1) := '0';
end if;
end loop;
return temp;
end function stdvec_to_str;
 
 
signal stop : boolean := false;
signal listen, read, send : boolean := false;
signal clk : std_logic := '0';
signal rst : std_logic;
signal cmd_in : std_logic_vector(7 downto 0) := (others => '0');
 
signal PS2_clk : std_logic := 'H';
signal PS2_data : std_logic := 'H';
begin
 
u0 : entity mouse_test(rtl)
port map(clk_i => clk, rst_i => rst,
ps2_clk_io => PS2_Clk, ps2_data_io => PS2_Data);
 
-- Clk generation
process
begin
clk <= not clk; -- 50Mhz clk
wait for 10 ns;
if stop then
wait;
end if;
end process;
rst <= '0', '1' after 1 ns;
stop <= true after 25 ms;
process
variable data_in : std_logic_vector(7 downto 0) := (others => '0');
variable cmd : integer;
begin
--wait for 100 us;
-- Send BAT cycle successful, 0xAA
--PS2SendByte("10101010", PS2_clk, PS2_data);
-- Send PS/2 device ID, 0x00
--PS2SendByte("00000000", PS2_clk, PS2_data);
wait for 10 us;
listen <= true;
wait;
end process;
 
process
variable data_in : std_logic_vector(7 downto 0) := (others => '0');
variable cmd : integer;
begin
wait on PS2_clk;
if PS2_clk = '0' then --and listen and not send then
wait on PS2_clk;
PS2RecvByte(data_in, PS2_clk, PS2_data);
write(output, string'("Received data from host : "));
write(output, stdvec_to_str(data_in));
send <= true;
 
elsif PS2_clk /= '0' and send then
wait for 1 ms;
PS2SendByte("00001000", PS2_clk, PS2_data);
PS2SendByte("00000100", PS2_clk, PS2_data);
PS2SendByte("00000101", PS2_clk, PS2_data);
end if;
if stop then
wait;
end if;
end process;
 
end sim;
/trunk/sim/vhdl/wb_test.vhd
0,0 → 1,343
--
-- Wishbone bus tester utilities.
--
-- (c) Copyright Andras Tantos <andras_tantos@yahoo.com> 2001/04/17
-- This code is distributed under the terms and conditions of the GNU General Public Lince.
--
--
-- ELEMENTS:
-- procedure wr_chk_val: writes a value, reads it back an checks if it's the same
-- procedure wr_val: writes a value
-- procedure rd_val: reads a value
-- procedure chk_val: checks (after read) a value
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
 
package wb_test is
procedure wr_chk_val(
signal clk_i: in STD_LOGIC;
signal adr_i: out STD_LOGIC_VECTOR;
signal dat_o: in STD_LOGIC_VECTOR;
signal dat_i: out STD_LOGIC_VECTOR;
signal we_i: out STD_LOGIC;
signal cyc_i: out std_logic;
signal stb_i: out STD_LOGIC;
signal ack_o: in STD_LOGIC;
constant addr: in STD_LOGIC_VECTOR;
constant data: in STD_LOGIC_VECTOR
);
procedure wr_val(
signal clk_i: in STD_LOGIC;
signal adr_i: out STD_LOGIC_VECTOR;
signal dat_o: in STD_LOGIC_VECTOR;
signal dat_i: out STD_LOGIC_VECTOR;
signal we_i: out STD_LOGIC;
signal cyc_i: out std_logic;
signal stb_i: out STD_LOGIC;
signal ack_o: in STD_LOGIC;
constant addr: in STD_LOGIC_VECTOR;
constant data: in STD_LOGIC_VECTOR
);
procedure rd_val(
signal clk_i: in STD_LOGIC;
signal adr_i: out STD_LOGIC_VECTOR;
signal dat_o: in STD_LOGIC_VECTOR;
signal dat_i: out STD_LOGIC_VECTOR;
signal we_i: out STD_LOGIC;
signal cyc_i: out std_logic;
signal stb_i: out STD_LOGIC;
signal ack_o: in STD_LOGIC;
constant addr: in STD_LOGIC_VECTOR;
variable data: out STD_LOGIC_VECTOR
);
procedure chk_val(
signal clk_i: in STD_LOGIC;
signal adr_i: out STD_LOGIC_VECTOR;
signal dat_o: in STD_LOGIC_VECTOR;
signal dat_i: out STD_LOGIC_VECTOR;
signal we_i: out STD_LOGIC;
signal cyc_i: out std_logic;
signal stb_i: out STD_LOGIC;
signal ack_o: in STD_LOGIC;
constant addr: in STD_LOGIC_VECTOR;
constant data: in STD_LOGIC_VECTOR
);
 
 
procedure wr_chk_val(
signal clk_i: in STD_LOGIC;
signal adr_i: out STD_LOGIC_VECTOR;
signal dat_o: in STD_LOGIC_VECTOR;
signal dat_i: out STD_LOGIC_VECTOR;
signal we_i: out STD_LOGIC;
signal cyc_i: out std_logic;
signal stb_i: out STD_LOGIC;
signal ack_o: in STD_LOGIC;
constant addr: in integer;
constant data: in STD_LOGIC_VECTOR
);
procedure wr_val(
signal clk_i: in STD_LOGIC;
signal adr_i: out STD_LOGIC_VECTOR;
signal dat_o: in STD_LOGIC_VECTOR;
signal dat_i: out STD_LOGIC_VECTOR;
signal we_i: out STD_LOGIC;
signal cyc_i: out std_logic;
signal stb_i: out STD_LOGIC;
signal ack_o: in STD_LOGIC;
constant addr: in integer;
constant data: in STD_LOGIC_VECTOR
);
procedure rd_val(
signal clk_i: in STD_LOGIC;
signal adr_i: out STD_LOGIC_VECTOR;
signal dat_o: in STD_LOGIC_VECTOR;
signal dat_i: out STD_LOGIC_VECTOR;
signal we_i: out STD_LOGIC;
signal cyc_i: out std_logic;
signal stb_i: out STD_LOGIC;
signal ack_o: in STD_LOGIC;
constant addr: in integer;
variable data: out STD_LOGIC_VECTOR
);
procedure chk_val(
signal clk_i: in STD_LOGIC;
signal adr_i: out STD_LOGIC_VECTOR;
signal dat_o: in STD_LOGIC_VECTOR;
signal dat_i: out STD_LOGIC_VECTOR;
signal we_i: out STD_LOGIC;
signal cyc_i: out std_logic;
signal stb_i: out STD_LOGIC;
signal ack_o: in STD_LOGIC;
constant addr: in integer;
constant data: in STD_LOGIC_VECTOR
);
end wb_test;
 
 
package body wb_test is
procedure wr_chk_val(
signal clk_i: in STD_LOGIC;
signal adr_i: out STD_LOGIC_VECTOR;
signal dat_o: in STD_LOGIC_VECTOR;
signal dat_i: out STD_LOGIC_VECTOR;
signal we_i: out STD_LOGIC;
signal cyc_i: out std_logic;
signal stb_i: out STD_LOGIC;
signal ack_o: in STD_LOGIC;
constant addr: in STD_LOGIC_VECTOR;
constant data: in STD_LOGIC_VECTOR
) is
variable adr_zero: STD_LOGIC_VECTOR(adr_i'RANGE) := (others => '0');
variable dat_undef: STD_LOGIC_VECTOR(dat_i'RANGE) := (others => 'U');
begin
adr_i <= adr_zero;
dat_i <= dat_undef;
stb_i <= '0';
we_i <= '0';
cyc_i <= '0';
wait until clk_i'EVENT and clk_i = '1';
wait until clk_i'EVENT and clk_i = '1';
wait until clk_i'EVENT and clk_i = '1';
adr_i <= addr;
dat_i <= data;
cyc_i <= '1';
stb_i <= '1';
we_i <= '1';
wait until clk_i'EVENT and clk_i = '1' and ack_o = '1';
adr_i <= adr_zero;
dat_i <= dat_undef;
cyc_i <= '0';
stb_i <= '0';
we_i <= '0';
wait until clk_i'EVENT and clk_i = '1';
adr_i <= addr;
dat_i <= dat_undef;
cyc_i <= '1';
stb_i <= '1';
we_i <= '0';
wait until clk_i'EVENT and clk_i = '1' and ack_o = '1';
assert dat_o = data report "Value does not match!" severity ERROR;
adr_i <= adr_zero;
stb_i <= '0';
cyc_i <= '0';
end;
 
procedure wr_val(
signal clk_i: in STD_LOGIC;
signal adr_i: out STD_LOGIC_VECTOR;
signal dat_o: in STD_LOGIC_VECTOR;
signal dat_i: out STD_LOGIC_VECTOR;
signal we_i: out STD_LOGIC;
signal cyc_i: out std_logic;
signal stb_i: out STD_LOGIC;
signal ack_o: in STD_LOGIC;
constant addr: in STD_LOGIC_VECTOR;
constant data: in STD_LOGIC_VECTOR
) is
variable adr_zero: STD_LOGIC_VECTOR(adr_i'RANGE) := (others => '0');
variable dat_undef: STD_LOGIC_VECTOR(dat_i'RANGE) := (others => 'U');
begin
adr_i <= adr_zero;
dat_i <= dat_undef;
stb_i <= '0';
we_i <= '0';
cyc_i <= '0';
wait until clk_i'EVENT and clk_i = '1';
wait until clk_i'EVENT and clk_i = '1';
wait until clk_i'EVENT and clk_i = '1';
adr_i <= addr;
dat_i <= data;
cyc_i <= '1';
stb_i <= '1';
we_i <= '1';
wait until clk_i'EVENT and clk_i = '1' and ack_o = '1';
adr_i <= adr_zero;
dat_i <= dat_undef;
cyc_i <= '0';
stb_i <= '0';
we_i <= '0';
end;
 
procedure rd_val(
signal clk_i: in STD_LOGIC;
signal adr_i: out STD_LOGIC_VECTOR;
signal dat_o: in STD_LOGIC_VECTOR;
signal dat_i: out STD_LOGIC_VECTOR;
signal we_i: out STD_LOGIC;
signal cyc_i: out std_logic;
signal stb_i: out STD_LOGIC;
signal ack_o: in STD_LOGIC;
constant addr: in STD_LOGIC_VECTOR;
variable data: out STD_LOGIC_VECTOR
) is
variable adr_zero: STD_LOGIC_VECTOR(adr_i'RANGE) := (others => '0');
variable dat_undef: STD_LOGIC_VECTOR(dat_i'RANGE) := (others => 'U');
begin
adr_i <= adr_zero;
dat_i <= dat_undef;
cyc_i <= '0';
stb_i <= '0';
we_i <= '0';
wait until clk_i'EVENT and clk_i = '1';
wait until clk_i'EVENT and clk_i = '1';
wait until clk_i'EVENT and clk_i = '1';
adr_i <= addr;
dat_i <= dat_undef;
cyc_i <= '1';
stb_i <= '1';
we_i <= '0';
wait until clk_i'EVENT and clk_i = '1' and ack_o = '1';
data := dat_o;
adr_i <= adr_zero;
stb_i <= '0';
cyc_i <= '0';
end;
 
procedure chk_val(
signal clk_i: in STD_LOGIC;
signal adr_i: out STD_LOGIC_VECTOR;
signal dat_o: in STD_LOGIC_VECTOR;
signal dat_i: out STD_LOGIC_VECTOR;
signal we_i: out STD_LOGIC;
signal cyc_i: out std_logic;
signal stb_i: out STD_LOGIC;
signal ack_o: in STD_LOGIC;
constant addr: in STD_LOGIC_VECTOR;
constant data: in STD_LOGIC_VECTOR
) is
variable adr_zero: STD_LOGIC_VECTOR(adr_i'RANGE) := (others => '0');
variable dat_undef: STD_LOGIC_VECTOR(dat_i'RANGE) := (others => 'U');
begin
adr_i <= adr_zero;
dat_i <= dat_undef;
cyc_i <= '0';
stb_i <= '0';
we_i <= '0';
wait until clk_i'EVENT and clk_i = '1';
wait until clk_i'EVENT and clk_i = '1';
wait until clk_i'EVENT and clk_i = '1';
adr_i <= addr;
dat_i <= dat_undef;
cyc_i <= '1';
stb_i <= '1';
we_i <= '0';
wait until clk_i'EVENT and clk_i = '1' and ack_o = '1';
assert dat_o = data report "Value does not match!" severity ERROR;
adr_i <= adr_zero;
stb_i <= '0';
cyc_i <= '0';
end;
 
procedure wr_chk_val(
signal clk_i: in STD_LOGIC;
signal adr_i: out STD_LOGIC_VECTOR;
signal dat_o: in STD_LOGIC_VECTOR;
signal dat_i: out STD_LOGIC_VECTOR;
signal we_i: out STD_LOGIC;
signal cyc_i: out std_logic;
signal stb_i: out STD_LOGIC;
signal ack_o: in STD_LOGIC;
constant addr: in integer;
constant data: in STD_LOGIC_VECTOR
) is
variable sadr: std_logic_vector(adr_i'RANGE);
begin
sadr := CONV_STD_LOGIC_VECTOR(addr,adr_i'HIGH+1);
wr_chk_val(clk_i,adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,sadr,data);
end;
procedure wr_val(
signal clk_i: in STD_LOGIC;
signal adr_i: out STD_LOGIC_VECTOR;
signal dat_o: in STD_LOGIC_VECTOR;
signal dat_i: out STD_LOGIC_VECTOR;
signal we_i: out STD_LOGIC;
signal cyc_i: out std_logic;
signal stb_i: out STD_LOGIC;
signal ack_o: in STD_LOGIC;
constant addr: in integer;
constant data: in STD_LOGIC_VECTOR
) is
variable sadr: std_logic_vector(adr_i'RANGE);
begin
sadr := CONV_STD_LOGIC_VECTOR(addr,adr_i'HIGH+1);
wr_val(clk_i,adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,sadr,data);
end;
procedure rd_val(
signal clk_i: in STD_LOGIC;
signal adr_i: out STD_LOGIC_VECTOR;
signal dat_o: in STD_LOGIC_VECTOR;
signal dat_i: out STD_LOGIC_VECTOR;
signal we_i: out STD_LOGIC;
signal cyc_i: out std_logic;
signal stb_i: out STD_LOGIC;
signal ack_o: in STD_LOGIC;
constant addr: in integer;
variable data: out STD_LOGIC_VECTOR
) is
variable sadr: std_logic_vector(adr_i'RANGE);
begin
sadr := CONV_STD_LOGIC_VECTOR(addr,adr_i'HIGH+1);
rd_val(clk_i,adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,sadr,data);
end;
procedure chk_val(
signal clk_i: in STD_LOGIC;
signal adr_i: out STD_LOGIC_VECTOR;
signal dat_o: in STD_LOGIC_VECTOR;
signal dat_i: out STD_LOGIC_VECTOR;
signal we_i: out STD_LOGIC;
signal cyc_i: out std_logic;
signal stb_i: out STD_LOGIC;
signal ack_o: in STD_LOGIC;
constant addr: in integer;
constant data: in STD_LOGIC_VECTOR
) is
variable sadr: std_logic_vector(adr_i'RANGE);
begin
sadr := CONV_STD_LOGIC_VECTOR(addr,adr_i'HIGH+1);
chk_val(clk_i,adr_i,dat_o,dat_i,we_i,cyc_i,stb_i,ack_o,sadr,data);
end;
 
end;
/trunk/sim/vhdl/ps2_mouse.vhd
0,0 → 1,172
-------------------------------------------------------------------------------
-- Title : PS/2 interface Testbench
-- Project :
-------------------------------------------------------------------------------
-- File : ps2.vhd
-- Author : Daniel Quintero <danielqg@infonegocio.com>
-- Company : Itoo Software
-- Created : 2003-04-14
-- Last update: 2003-10-30
-- Platform : VHDL'87
-------------------------------------------------------------------------------
-- Description: PS/2 mice model
-------------------------------------------------------------------------------
-- This code is distributed under the terms and conditions of the
-- GNU General Public License
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2003-04-14 1.0 daniel Created
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use std.textio.all;
 
entity ps2mouse is
port (
PS2_clk : inout std_logic;
PS2_data : inout std_logic);
end ps2mouse;
 
architecture sim of ps2mouse is
 
procedure PS2SendByte(byte : in std_logic_vector(7 downto 0);
signal PS2_clk : inout std_logic;
signal PS2_data : inout std_logic) is
begin
--wait until (PS2_clk = 'H');
for i in 0 to 10 loop
if i = 0 then
PS2_Data <= '0';
elsif i = 9 then
PS2_Data <= not (Byte(0) xor
Byte(1) xor
Byte(2) xor
Byte(3) xor
Byte(4) xor
Byte(5) xor
Byte(6) xor
Byte(7));
elsif i = 10 then
PS2_Data <= 'H';
else
if Byte(i - 1) = '1' then
PS2_Data <= '1';
else
 
end if;
end if;
wait for 20 us;
PS2_Clk <= '0';
wait for 20 us;
PS2_Clk <= '1';
end loop;
PS2_Clk <= 'H';
end;
 
procedure PS2RecvByte(byte : out std_logic_vector(7 downto 0);
signal PS2_clk : inout std_logic;
signal PS2_data : inout std_logic) is
variable parity : std_logic;
variable buf : std_logic_vector(7 downto 0);
begin
PS2_Data <= 'H';
for i in 0 to 10 loop
wait for 20 us;
PS2_Clk <= '0';
if i = 0 then
if PS2_data /= '0' then
write(output, string'("Warning, not start bit from Host"));
end if;
elsif i = 9 then
parity := To_X01(PS2_data);
elsif i = 10 then
PS2_Data <= '0'; -- Ack
else
buf(i - 1) := To_X01(PS2_data);
end if;
wait for 20 us;
PS2_Clk <= '1';
end loop;
 
if parity /= not (buf(0) xor buf(1) xor buf(2) xor buf(3) xor
buf(4) xor buf(5) xor buf(6) xor buf(7)) then
write(output, string'("Waring, parity check error in host data"));
end if;
Byte := buf;
PS2_Clk <= 'H';
PS2_Data <= 'H';
end;
 
procedure PS2Write(signal req, rw : out std_logic;
signal ack : in std_logic) is
begin
wait for 20 us;
req <= '1';
rw <= '0';
wait until ack = '1';
req <= '0' after 10 ns;
rw <= '1' after 10 ns;
end;
 
 
function stdvec_to_str(inp : std_logic_vector) return string is
variable temp : string(inp'left+1 downto 1) := (others => 'X');
begin
for i in inp'reverse_range loop
if (inp(i) = '1') then
temp(i+1) := '1';
elsif (inp(i) = '0') then
temp(i+1) := '0';
end if;
end loop;
return temp;
end function stdvec_to_str;
 
 
signal stop : boolean := false;
signal listen, read, send : boolean := false;
signal clk : std_logic := '0';
signal rst : std_logic;
signal cmd_in : std_logic_vector(7 downto 0) := (others => '0');
 
begin
process
variable data_in : std_logic_vector(7 downto 0) := (others => '0');
variable cmd : integer;
begin
--wait for 100 us;
-- Send BAT cycle successful, 0xAA
--PS2SendByte("10101010", PS2_clk, PS2_data);
-- Send PS/2 device ID, 0x00
--PS2SendByte("00000000", PS2_clk, PS2_data);
wait for 10 us;
listen <= true;
wait;
end process;
 
process
variable data_in : std_logic_vector(7 downto 0) := (others => '0');
variable cmd : integer;
begin
PS2_clk <= 'H';
PS2_data <= 'H';
wait on PS2_clk;
if PS2_clk = '0' then --and listen and not send then
wait on PS2_clk;
PS2RecvByte(data_in, PS2_clk, PS2_data);
write(output, string'("PS2MOUSE - Received data from host : "));
write(output, stdvec_to_str(data_in));
send <= true;
elsif PS2_clk /= '0' and send then
wait for 1 ms;
PS2SendByte("00001000", PS2_clk, PS2_data);
PS2SendByte("00000100", PS2_clk, PS2_data);
PS2SendByte("00000101", PS2_clk, PS2_data);
wait;
end if;
end process;
 
 
end sim;
/trunk/syn/ps2_burched.ucf
0,0 → 1,34
# Pin locations for Burched B5-X300E FPGA board
 
NET "rst_i" LOC = "P57" ;
NET "ps2_data_io" LOC = "P70" ;
NET "ps2_clk_io" LOC = "P69" ;
NET "perr_o" LOC = "P48" ;
NET "ferr_o" LOC = "P49" ;
NET "data_o<23>" LOC = "P34" ;
NET "data_o<22>" LOC = "P33" ;
NET "data_o<21>" LOC = "P31" ;
NET "data_o<20>" LOC = "P30" ;
NET "data_o<19>" LOC = "P29" ;
NET "data_o<18>" LOC = "P27" ;
NET "data_o<17>" LOC = "P24" ;
NET "data_o<16>" LOC = "P23" ;
NET "data_o<15>" LOC = "P22" ;
NET "data_o<14>" LOC = "P21" ;
NET "data_o<13>" LOC = "P20" ;
NET "data_o<12>" LOC = "P18" ;
NET "data_o<11>" LOC = "P17" ;
NET "data_o<10>" LOC = "P16" ;
NET "data_o<9>" LOC = "P15" ;
NET "data_o<8>" LOC = "P11" ;
NET "data_o<7>" LOC = "P10" ;
NET "data_o<6>" LOC = "P9" ;
NET "data_o<5>" LOC = "P8" ;
NET "data_o<4>" LOC = "P7" ;
NET "data_o<3>" LOC = "P6" ;
NET "data_o<2>" LOC = "P5" ;
NET "data_o<1>" LOC = "P4" ;
NET "data_o<0>" LOC = "P3" ;
NET "clk_i" LOC = "P77" ;
NET "beep_o" LOC = "P71" ;
NET "activity_o" LOC = "P82" ;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.