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" ; |